diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2007-06-23 22:12:52 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2007-06-23 22:12:52 +0000 |
commit | 46379d6e60f0f95e127a5045ca1fa74dfdc48a85 (patch) | |
tree | 7d6fe8004575203b40a38184c154dc7f34a20345 /src/backend/tcop/postgres.c | |
parent | ec0bb02db8452d4098023f82b100ba68d8f7dfab (diff) | |
download | postgresql-46379d6e60f0f95e127a5045ca1fa74dfdc48a85.tar.gz postgresql-46379d6e60f0f95e127a5045ca1fa74dfdc48a85.zip |
Separate parse-analysis for utility commands out of parser/analyze.c
(which now deals only in optimizable statements), and put that code
into a new file parser/parse_utilcmd.c. This helps clarify and enforce
the design rule that utility statements shouldn't be processed during
the regular parse analysis phase; all interpretation of their meaning
should happen after they are given to ProcessUtility to execute.
(We need this because we don't retain any locks for a utility statement
that's in a plan cache, nor have any way to detect that it's stale.)
We are also able to simplify the API for parse_analyze() and related
routines, because they will now always return exactly one Query structure.
In passing, fix bug #3403 concerning trying to add a serial column to
an existing temp table (this is largely Heikki's work, but we needed
all that restructuring to make it safe).
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r-- | src/backend/tcop/postgres.c | 88 |
1 files changed, 38 insertions, 50 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 724f2e028d0..94fd65e5d44 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.533 2007/04/30 16:37:08 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.534 2007/06/23 22:12:52 tgl Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -165,7 +165,7 @@ static int UseNewLine = 0; /* Use EOF as query delimiters */ static int InteractiveBackend(StringInfo inBuf); static int SocketBackend(StringInfo inBuf); static int ReadCommand(StringInfo inBuf); -static List *pg_rewrite_queries(List *querytree_list); +static List *pg_rewrite_query(Query *query); static bool check_log_statement(List *stmt_list); static int errdetail_execute(List *raw_parsetree_list); static int errdetail_params(ParamListInfo params); @@ -567,6 +567,7 @@ List * pg_analyze_and_rewrite(Node *parsetree, const char *query_string, Oid *paramTypes, int numParams) { + Query *query; List *querytree_list; /* @@ -575,8 +576,7 @@ pg_analyze_and_rewrite(Node *parsetree, const char *query_string, if (log_parser_stats) ResetUsage(); - querytree_list = parse_analyze(parsetree, query_string, - paramTypes, numParams); + query = parse_analyze(parsetree, query_string, paramTypes, numParams); if (log_parser_stats) ShowUsage("PARSE ANALYSIS STATISTICS"); @@ -584,68 +584,55 @@ pg_analyze_and_rewrite(Node *parsetree, const char *query_string, /* * (2) Rewrite the queries, as necessary */ - querytree_list = pg_rewrite_queries(querytree_list); + querytree_list = pg_rewrite_query(query); return querytree_list; } /* - * Perform rewriting of a list of queries produced by parse analysis. + * Perform rewriting of a query produced by parse analysis. * - * Note: queries must just have come from the parser, because we do not do - * AcquireRewriteLocks() on them. + * Note: query must just have come from the parser, because we do not do + * AcquireRewriteLocks() on it. */ static List * -pg_rewrite_queries(List *querytree_list) +pg_rewrite_query(Query *query) { - List *new_list = NIL; - ListCell *list_item; + List *querytree_list; if (log_parser_stats) ResetUsage(); - /* - * rewritten queries are collected in new_list. Note there may be more or - * fewer than in the original list. - */ - foreach(list_item, querytree_list) - { - Query *querytree = (Query *) lfirst(list_item); - - if (Debug_print_parse) - elog_node_display(DEBUG1, "parse tree", querytree, - Debug_pretty_print); - - if (querytree->commandType == CMD_UTILITY) - { - /* don't rewrite utilities, just dump 'em into new_list */ - new_list = lappend(new_list, querytree); - } - else - { - /* rewrite regular queries */ - List *rewritten = QueryRewrite(querytree); + if (Debug_print_parse) + elog_node_display(DEBUG1, "parse tree", query, + Debug_pretty_print); - new_list = list_concat(new_list, rewritten); - } + if (query->commandType == CMD_UTILITY) + { + /* don't rewrite utilities, just dump 'em into result list */ + querytree_list = list_make1(query); + } + else + { + /* rewrite regular queries */ + querytree_list = QueryRewrite(query); } - - querytree_list = new_list; if (log_parser_stats) ShowUsage("REWRITER STATISTICS"); #ifdef COPY_PARSE_PLAN_TREES + /* Optional debugging check: pass querytree output through copyObject() */ + { + List *new_list; - /* - * Optional debugging check: pass querytree output through copyObject() - */ - new_list = (List *) copyObject(querytree_list); - /* This checks both copyObject() and the equal() routines... */ - if (!equal(new_list, querytree_list)) - elog(WARNING, "copyObject() failed to produce an equal parse tree"); - else - querytree_list = new_list; + new_list = (List *) copyObject(querytree_list); + /* This checks both copyObject() and the equal() routines... */ + if (!equal(new_list, querytree_list)) + elog(WARNING, "copyObject() failed to produce equal parse tree"); + else + querytree_list = new_list; + } #endif if (Debug_print_rewritten) @@ -1139,6 +1126,7 @@ exec_parse_message(const char *query_string, /* string to execute */ if (parsetree_list != NIL) { + Query *query; int i; raw_parse_tree = (Node *) linitial(parsetree_list); @@ -1175,10 +1163,10 @@ exec_parse_message(const char *query_string, /* string to execute */ if (log_parser_stats) ResetUsage(); - querytree_list = parse_analyze_varparams(copyObject(raw_parse_tree), - query_string, - ¶mTypes, - &numParams); + query = parse_analyze_varparams(copyObject(raw_parse_tree), + query_string, + ¶mTypes, + &numParams); /* * Check all parameter types got determined. @@ -1197,7 +1185,7 @@ exec_parse_message(const char *query_string, /* string to execute */ if (log_parser_stats) ShowUsage("PARSE ANALYSIS STATISTICS"); - querytree_list = pg_rewrite_queries(querytree_list); + querytree_list = pg_rewrite_query(query); /* * If this is the unnamed statement and it has parameters, defer query |