aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/nodes/nodeFuncs.c6
-rw-r--r--src/backend/parser/analyze.c44
-rw-r--r--src/include/pg_config_manual.h7
3 files changed, 55 insertions, 2 deletions
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index 7bc5be1565f..92f32768f84 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -2991,8 +2991,10 @@ query_or_expression_tree_mutator(Node *node,
* Unlike expression_tree_walker, there is no special rule about query
* boundaries: we descend to everything that's possibly interesting.
*
- * Currently, the node type coverage extends to SelectStmt and everything
- * that could appear under it, but not other statement types.
+ * Currently, the node type coverage here extends only to DML statements
+ * (SELECT/INSERT/UPDATE/DELETE) and nodes that can appear in them, because
+ * this is used mainly during analysis of CTEs, and only DML statements can
+ * appear in CTEs.
*/
bool
raw_expression_tree_walker(Node *node,
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 7d2fedfaadf..29c8c4e94c7 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -74,6 +74,9 @@ static Query *transformCreateTableAsStmt(ParseState *pstate,
CreateTableAsStmt *stmt);
static void transformLockingClause(ParseState *pstate, Query *qry,
LockingClause *lc, bool pushedDown);
+#ifdef RAW_EXPRESSION_COVERAGE_TEST
+static bool test_raw_expression_coverage(Node *node, void *context);
+#endif
/*
@@ -220,6 +223,25 @@ transformStmt(ParseState *pstate, Node *parseTree)
{
Query *result;
+ /*
+ * We apply RAW_EXPRESSION_COVERAGE_TEST testing to basic DML statements;
+ * we can't just run it on everything because raw_expression_tree_walker()
+ * doesn't claim to handle utility statements.
+ */
+#ifdef RAW_EXPRESSION_COVERAGE_TEST
+ switch (nodeTag(parseTree))
+ {
+ case T_SelectStmt:
+ case T_InsertStmt:
+ case T_UpdateStmt:
+ case T_DeleteStmt:
+ (void) test_raw_expression_coverage(parseTree, NULL);
+ break;
+ default:
+ break;
+ }
+#endif /* RAW_EXPRESSION_COVERAGE_TEST */
+
switch (nodeTag(parseTree))
{
/*
@@ -2713,3 +2735,25 @@ applyLockingClause(Query *qry, Index rtindex,
rc->pushedDown = pushedDown;
qry->rowMarks = lappend(qry->rowMarks, rc);
}
+
+/*
+ * Coverage testing for raw_expression_tree_walker().
+ *
+ * When enabled, we run raw_expression_tree_walker() over every DML statement
+ * submitted to parse analysis. Without this provision, that function is only
+ * applied in limited cases involving CTEs, and we don't really want to have
+ * to test everything inside as well as outside a CTE.
+ */
+#ifdef RAW_EXPRESSION_COVERAGE_TEST
+
+static bool
+test_raw_expression_coverage(Node *node, void *context)
+{
+ if (node == NULL)
+ return false;
+ return raw_expression_tree_walker(node,
+ test_raw_expression_coverage,
+ context);
+}
+
+#endif /* RAW_EXPRESSION_COVERAGE_TEST */
diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h
index 8d5a3783876..a2b2b614bec 100644
--- a/src/include/pg_config_manual.h
+++ b/src/include/pg_config_manual.h
@@ -274,6 +274,13 @@
/* #define COPY_PARSE_PLAN_TREES */
/*
+ * Define this to force all raw parse trees for DML statements to be scanned
+ * by raw_expression_tree_walker(), to facilitate catching errors and
+ * omissions in that function.
+ */
+/* #define RAW_EXPRESSION_COVERAGE_TEST */
+
+/*
* Enable debugging print statements for lock-related operations.
*/
/* #define LOCK_DEBUG */