From 357cfbc2622480abf6a041dc3715f439b74c789f Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 11 Mar 2024 09:15:33 +0100 Subject: [PATCH v3 6/8] WIP: AssertRangeTblEntryIsValid() This provides a function AssertRangeTblEntryIsValid() that checks that a RangeTblEntry node is filled with a valid combination of fields. This is hooked into the write/read functions so that it is executed by WRITE_READ_PARSE_PLAN_TREES. Discussion: https://www.postgresql.org/message-id/flat/4b27fc50-8cd6-46f5-ab20-88dbaadca645@eisentraut.org --- src/backend/nodes/nodeFuncs.c | 59 +++++++++++++++++++++++++++++++++++ src/backend/nodes/outfuncs.c | 2 ++ src/backend/nodes/readfuncs.c | 2 ++ src/include/nodes/nodeFuncs.h | 6 ++++ 4 files changed, 69 insertions(+) diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index 6ba8e73256..db1b9bec13 100644 --- a/src/backend/nodes/nodeFuncs.c +++ b/src/backend/nodes/nodeFuncs.c @@ -4571,3 +4571,62 @@ planstate_walk_members(PlanState **planstates, int nplans, return false; } + +#ifdef USE_ASSERT_CHECKING + +/* + * Assertion check that a RangeTblEntry node is filled with a valid + * combination of fields. + * + * Best used together with WRITE_READ_PARSE_PLAN_TREES. + */ +void +AssertRangeTblEntryIsValid(const RangeTblEntry *rte) +{ + Assert(rte->rtekind == RTE_RELATION || + rte->rtekind == RTE_SUBQUERY || + rte->rtekind == RTE_JOIN || + rte->rtekind == RTE_FUNCTION || + rte->rtekind == RTE_TABLEFUNC || + rte->rtekind == RTE_VALUES || + rte->rtekind == RTE_CTE || + rte->rtekind == RTE_NAMEDTUPLESTORE || + rte->rtekind == RTE_RESULT); + + Assert(rte->eref); + + if (rte->relid) + Assert(rte->rtekind == RTE_RELATION || rte->rtekind == RTE_SUBQUERY || rte->rtekind == RTE_NAMEDTUPLESTORE); + if (rte->inh) + Assert(rte->rtekind == RTE_RELATION || rte->rtekind == RTE_SUBQUERY); + if (rte->relkind) + Assert(rte->rtekind == RTE_RELATION || rte->rtekind == RTE_SUBQUERY); + if (rte->rellockmode) + Assert(rte->rtekind == RTE_RELATION || rte->rtekind == RTE_SUBQUERY); + if (rte->tablesample) + Assert(rte->rtekind == RTE_RELATION); + if (rte->perminfoindex) + Assert(rte->rtekind == RTE_RELATION || rte->rtekind == RTE_SUBQUERY); + if (rte->subquery) + Assert(rte->rtekind == RTE_SUBQUERY); + if (rte->security_barrier) + Assert(rte->rtekind == RTE_SUBQUERY); + if (rte->joinmergedcols || rte->joinaliasvars || rte->joinleftcols || rte->joinrightcols || rte->join_using_alias) + Assert(rte->rtekind == RTE_JOIN); + if (rte->functions || rte->funcordinality) + Assert(rte->rtekind == RTE_FUNCTION); + if (rte->tablefunc) + Assert(rte->rtekind == RTE_TABLEFUNC); + if (rte->values_lists) + Assert(rte->rtekind == RTE_VALUES); + if (rte->ctename || rte->ctelevelsup || rte->self_reference) + Assert(rte->rtekind == RTE_CTE); + if (rte->coltypes || rte->coltypmods || rte->colcollations) + Assert(rte->rtekind == RTE_TABLEFUNC || rte->rtekind == RTE_VALUES || rte->rtekind == RTE_CTE || rte->rtekind == RTE_NAMEDTUPLESTORE); + if (rte->enrname || rte->enrtuples) + Assert(rte->rtekind == RTE_NAMEDTUPLESTORE); + if (rte->lateral) + Assert(rte->rtekind == RTE_RELATION || rte->rtekind == RTE_SUBQUERY || rte->rtekind == RTE_FUNCTION || rte->rtekind == RTE_TABLEFUNC || rte->rtekind == RTE_VALUES); +} + +#endif diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index c55375e7f9..5e34584c55 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -21,6 +21,7 @@ #include "lib/stringinfo.h" #include "miscadmin.h" #include "nodes/bitmapset.h" +#include "nodes/nodeFuncs.h" #include "nodes/nodes.h" #include "nodes/pg_list.h" #include "utils/datum.h" @@ -492,6 +493,7 @@ _outExtensibleNode(StringInfo str, const ExtensibleNode *node) static void _outRangeTblEntry(StringInfo str, const RangeTblEntry *node) { + AssertRangeTblEntryIsValid(node); WRITE_NODE_TYPE("RANGETBLENTRY"); WRITE_NODE_FIELD(alias); diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index c4d01a441a..217d81041a 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -30,6 +30,7 @@ #include "miscadmin.h" #include "nodes/bitmapset.h" +#include "nodes/nodeFuncs.h" #include "nodes/readfuncs.h" @@ -432,6 +433,7 @@ _readRangeTblEntry(void) READ_BOOL_FIELD(inFromCl); READ_NODE_FIELD(securityQuals); + AssertRangeTblEntryIsValid(local_node); READ_DONE(); } diff --git a/src/include/nodes/nodeFuncs.h b/src/include/nodes/nodeFuncs.h index eaba59bed8..873ed9e9b7 100644 --- a/src/include/nodes/nodeFuncs.h +++ b/src/include/nodes/nodeFuncs.h @@ -219,4 +219,10 @@ extern bool planstate_tree_walker_impl(struct PlanState *planstate, planstate_tree_walker_callback walker, void *context); +#ifdef USE_ASSERT_CHECKING +extern void AssertRangeTblEntryIsValid(const RangeTblEntry *rte); +#else +#define AssertRangeTblEntryIsValid(rte) ((void)true) +#endif + #endif /* NODEFUNCS_H */ -- 2.44.0