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.c219
1 files changed, 88 insertions, 131 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index a70418637f7..65b6bfbd6c0 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.148 2000/03/23 23:16:48 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.149 2000/04/04 21:44:39 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@@ -377,22 +377,23 @@ ReadCommand(StringInfo inBuf)
return result;
}
+
+/*
+ * Parse a query string and pass it through the rewriter.
+ *
+ * A list of Query nodes is returned, since the string might contain
+ * multiple queries and/or the rewriter might expand one query to several.
+ */
List *
-pg_parse_and_plan(char *query_string, /* string to execute */
- Oid *typev, /* argument types */
- int nargs, /* number of arguments */
- List **queryListP, /* returned pointer to the parse
- * trees */
- CommandDest dest, /* where results should go */
- bool aclOverride)
+pg_parse_and_rewrite(char *query_string, /* string to execute */
+ Oid *typev, /* argument types */
+ int nargs, /* number of arguments */
+ bool aclOverride)
{
- List *querytree_list = NIL;
- List *plan_list = NIL;
+ List *querytree_list;
List *querytree_list_item;
Query *querytree;
- Plan *plan;
List *new_list;
- List *rewritten;
if (DebugPrintQuery)
{
@@ -448,15 +449,16 @@ pg_parse_and_plan(char *query_string, /* string to execute */
else
{
/* rewrite regular queries */
- rewritten = QueryRewrite(querytree);
+ List *rewritten = QueryRewrite(querytree);
new_list = nconc(new_list, rewritten);
}
}
querytree_list = new_list;
- /*
- * Override ACL checking if requested
+ /* ----------------
+ * (3) If ACL override is requested, mark queries for no ACL check.
+ * ----------------
*/
if (aclOverride)
{
@@ -503,87 +505,54 @@ pg_parse_and_plan(char *query_string, /* string to execute */
}
}
- foreach(querytree_list_item, querytree_list)
- {
- querytree = (Query *) lfirst(querytree_list_item);
-
- /*
- * For each query that isn't a utility invocation, generate a
- * plan.
- */
-
- if (querytree->commandType != CMD_UTILITY)
- {
+ return querytree_list;
+}
- if (IsAbortedTransactionBlockState())
- {
- /* ----------------
- * the EndCommand() stuff is to tell the frontend
- * that the command ended. -cim 6/1/90
- * ----------------
- */
- char *tag = "*ABORT STATE*";
- EndCommand(tag, dest);
+/* Generate a plan for a single query. */
+Plan *
+pg_plan_query(Query *querytree)
+{
+ Plan *plan;
- elog(NOTICE, "(transaction aborted): %s",
- "queries ignored until END");
+ /* Utility commands have no plans. */
+ if (querytree->commandType == CMD_UTILITY)
+ return NULL;
- if (queryListP)
- *queryListP = NIL;
- return NIL;
- }
+ if (ShowPlannerStats)
+ ResetUsage();
- if (ShowPlannerStats)
- ResetUsage();
+ /* call that optimizer */
+ plan = planner(querytree);
- /* call that optimizer */
- plan = planner(querytree);
+ if (ShowPlannerStats)
+ {
+ fprintf(stderr, "! Planner Stats:\n");
+ ShowUsage();
+ }
- if (ShowPlannerStats)
- {
- fprintf(stderr, "! Planner Stats:\n");
- ShowUsage();
- }
- plan_list = lappend(plan_list, plan);
-#ifdef INDEXSCAN_PATCH
- /* ----------------
- * Print plan if debugging.
- * This has been moved here to get debugging output
- * also for queries in functions. DZ - 27-8-1996
- * ----------------
- */
- if (DebugPrintPlan || DebugPPrintPlan)
- {
- if (DebugPPrintPlan)
- {
- TPRINTF(TRACE_PRETTY_PLAN, "plan:");
- nodeDisplay(plan);
- }
- else
- {
- TPRINTF(TRACE_PLAN, "plan:");
- printf("\n%s\n\n", nodeToString(plan));
- }
- }
-#endif
+ /* ----------------
+ * Print plan if debugging.
+ * ----------------
+ */
+ if (DebugPrintPlan || DebugPPrintPlan)
+ {
+ if (DebugPPrintPlan)
+ {
+ TPRINTF(TRACE_PRETTY_PLAN, "plan:");
+ nodeDisplay(plan);
}
-
- /*
- * If the command is an utility append a null plan. This is needed
- * to keep the plan_list aligned with the querytree_list or the
- * function executor will crash. DZ - 30-8-1996
- */
else
- plan_list = lappend(plan_list, NULL);
+ {
+ TPRINTF(TRACE_PLAN, "plan:");
+ printf("\n%s\n\n", nodeToString(plan));
+ }
}
- if (queryListP)
- *queryListP = querytree_list;
-
- return plan_list;
+ return plan;
}
+
/* ----------------------------------------------------------------
* pg_exec_query()
*
@@ -620,39 +589,31 @@ pg_exec_query_dest(char *query_string, /* string to execute */
* of superusers */
{
List *querytree_list;
- List *plan_list;
- Query *querytree;
- Plan *plan;
- int j;
- /* plan the queries */
- plan_list = pg_parse_and_plan(query_string, NULL, 0,
- &querytree_list, dest, aclOverride);
-
- /* if we got a cancel signal whilst planning, quit */
- if (QueryCancel)
- CancelQuery();
-
- /* OK, do it to it! */
+ /* parse and rewrite the queries */
+ querytree_list = pg_parse_and_rewrite(query_string, NULL, 0,
+ aclOverride);
/*
* NOTE: we do not use "foreach" here because we want to be sure the
- * list pointers have been advanced before the query is executed. We
+ * list pointer has been advanced before the query is executed. We
* need to do that because VACUUM has a nasty little habit of doing
* CommitTransactionCommand at startup, and that will release the
- * memory holding our parse/plan lists :-(. This needs a better
+ * memory holding our parse list :-(. This needs a better
* solution --- currently, the code will crash if someone submits
* "vacuum; something-else" in a single query string. But memory
* allocation needs redesigned anyway, so this will have to do for
* now.
*/
-
while (querytree_list)
{
- querytree = (Query *) lfirst(querytree_list);
+ Query *querytree = (Query *) lfirst(querytree_list);
+
querytree_list = lnext(querytree_list);
- plan = (Plan *) lfirst(plan_list);
- plan_list = lnext(plan_list);
+
+ /* if we got a cancel signal in parsing or prior command, quit */
+ if (QueryCancel)
+ CancelQuery();
if (querytree->commandType == CMD_UTILITY)
{
@@ -668,42 +629,38 @@ pg_exec_query_dest(char *query_string, /* string to execute */
else if (Verbose)
TPRINTF(TRACE_VERBOSE, "ProcessUtility");
- /*
- * We have to set query SnapShot in the case of FETCH or COPY TO.
- */
- if (nodeTag(querytree->utilityStmt) == T_FetchStmt ||
- (nodeTag(querytree->utilityStmt) == T_CopyStmt &&
- ((CopyStmt *)(querytree->utilityStmt))->direction != FROM))
- SetQuerySnapshot();
ProcessUtility(querytree->utilityStmt, dest);
}
else
{
-#ifdef INDEXSCAN_PATCH
+ Plan *plan;
+ int j;
- /*
- * Print moved in pg_parse_and_plan. DZ - 27-8-1996
- */
-#else
- /* ----------------
- * print plan if debugging
- * ----------------
- */
- if (DebugPrintPlan || DebugPPrintPlan)
+ /* If aborted transaction, quit now */
+ if (IsAbortedTransactionBlockState())
{
- if (DebugPPrintPlan)
- {
- TPRINTF(TRACE_PRETTY_PLAN, "plan:");
- nodeDisplay(plan);
- }
- else
- {
- TPRINTF(TRACE_PLAN, "plan:");
- printf("\n%s\n\n", nodeToString(plan));
- }
+ /* ----------------
+ * the EndCommand() stuff is to tell the frontend
+ * that the command ended. -cim 6/1/90
+ * ----------------
+ */
+ char *tag = "*ABORT STATE*";
+
+ elog(NOTICE, "current transaction is aborted, "
+ "queries ignored until end of transaction block");
+
+ EndCommand(tag, dest);
+
+ break;
}
-#endif
+ plan = pg_plan_query(querytree);
+
+ /* if we got a cancel signal whilst planning, quit */
+ if (QueryCancel)
+ CancelQuery();
+
+ /* Initialize snapshot state for query */
SetQuerySnapshot();
/*
@@ -1505,7 +1462,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
if (!IsUnderPostmaster)
{
puts("\nPOSTGRES backend interactive interface ");
- puts("$Revision: 1.148 $ $Date: 2000/03/23 23:16:48 $\n");
+ puts("$Revision: 1.149 $ $Date: 2000/04/04 21:44:39 $\n");
}
/*