aboutsummaryrefslogtreecommitdiff
path: root/src/backend/tcop/postgres.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r--src/backend/tcop/postgres.c74
1 files changed, 72 insertions, 2 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 7a9ada2c719..e4c6e3d406e 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -633,6 +633,12 @@ pg_parse_query(const char *query_string)
}
#endif
+ /*
+ * Currently, outfuncs/readfuncs support is missing for many raw parse
+ * tree nodes, so we don't try to implement WRITE_READ_PARSE_PLAN_TREES
+ * here.
+ */
+
TRACE_POSTGRESQL_QUERY_PARSE_DONE(query_string);
return raw_parsetree_list;
@@ -763,7 +769,7 @@ pg_rewrite_query(Query *query)
ShowUsage("REWRITER STATISTICS");
#ifdef COPY_PARSE_PLAN_TREES
- /* Optional debugging check: pass querytree output through copyObject() */
+ /* Optional debugging check: pass querytree through copyObject() */
{
List *new_list;
@@ -776,6 +782,46 @@ pg_rewrite_query(Query *query)
}
#endif
+#ifdef WRITE_READ_PARSE_PLAN_TREES
+ /* Optional debugging check: pass querytree through outfuncs/readfuncs */
+ {
+ List *new_list = NIL;
+ ListCell *lc;
+
+ /*
+ * We currently lack outfuncs/readfuncs support for most utility
+ * statement types, so only attempt to write/read non-utility queries.
+ */
+ foreach(lc, querytree_list)
+ {
+ Query *query = castNode(Query, lfirst(lc));
+
+ if (query->commandType != CMD_UTILITY)
+ {
+ char *str = nodeToString(query);
+ Query *new_query = stringToNodeWithLocations(str);
+
+ /*
+ * queryId is not saved in stored rules, but we must preserve
+ * it here to avoid breaking pg_stat_statements.
+ */
+ new_query->queryId = query->queryId;
+
+ new_list = lappend(new_list, new_query);
+ pfree(str);
+ }
+ else
+ new_list = lappend(new_list, query);
+ }
+
+ /* This checks both outfuncs/readfuncs and the equal() routines... */
+ if (!equal(new_list, querytree_list))
+ elog(WARNING, "outfuncs/readfuncs failed to produce equal parse tree");
+ else
+ querytree_list = new_list;
+ }
+#endif
+
if (Debug_print_rewritten)
elog_node_display(LOG, "rewritten parse tree", querytree_list,
Debug_pretty_print);
@@ -812,7 +858,7 @@ pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams)
ShowUsage("PLANNER STATISTICS");
#ifdef COPY_PARSE_PLAN_TREES
- /* Optional debugging check: pass plan output through copyObject() */
+ /* Optional debugging check: pass plan tree through copyObject() */
{
PlannedStmt *new_plan = copyObject(plan);
@@ -830,6 +876,30 @@ pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams)
}
#endif
+#ifdef WRITE_READ_PARSE_PLAN_TREES
+ /* Optional debugging check: pass plan tree through outfuncs/readfuncs */
+ {
+ char *str;
+ PlannedStmt *new_plan;
+
+ str = nodeToString(plan);
+ new_plan = stringToNodeWithLocations(str);
+ pfree(str);
+
+ /*
+ * equal() currently does not have routines to compare Plan nodes, so
+ * don't try to test equality here. Perhaps fix someday?
+ */
+#ifdef NOT_USED
+ /* This checks both outfuncs/readfuncs and the equal() routines... */
+ if (!equal(new_plan, plan))
+ elog(WARNING, "outfuncs/readfuncs failed to produce an equal plan tree");
+ else
+#endif
+ plan = new_plan;
+ }
+#endif
+
/*
* Print plan if debugging.
*/