aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/analyze.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2016-05-23 19:08:26 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2016-05-23 19:08:26 -0400
commit465e09da6310fee89946f3ca32ee8002dd4c428a (patch)
tree5022d50b6b7541f23641cdf9cbcdb8d7b0d5f8fb /src/backend/parser/analyze.c
parent8a4930e3faffedf0c392de1f03508b816fa2244d (diff)
downloadpostgresql-465e09da6310fee89946f3ca32ee8002dd4c428a.tar.gz
postgresql-465e09da6310fee89946f3ca32ee8002dd4c428a.zip
Add support for more extensive testing of raw_expression_tree_walker().
If RAW_EXPRESSION_COVERAGE_TEST is defined, do a no-op tree walk over every basic DML statement submitted to parse analysis. If we'd had this in place earlier, bug #14153 would have been caught by buildfarm testing. The difficulty is that raw_expression_tree_walker() is only used in limited cases involving CTEs (particularly recursive ones), so it's very easy for an oversight in it to not be noticed during testing of a seemingly-unrelated feature. The type of error we can expect to catch with this is complete omission of a node type from raw_expression_tree_walker(), and perhaps also recursion into a field that doesn't contain a node tree, though that would be an unlikely mistake. It won't catch failure to add new fields that need to be recursed into, unfortunately. I'll go enable this on one or two of my own buildfarm animals once bug #14153 is dealt with. Discussion: <27861.1464040417@sss.pgh.pa.us>
Diffstat (limited to 'src/backend/parser/analyze.c')
-rw-r--r--src/backend/parser/analyze.c44
1 files changed, 44 insertions, 0 deletions
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 */