diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 2a78e38fe0..f3bd34fde2 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.298 2002/10/06 03:56:03 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.299 2002/10/08 17:17:19 tgl Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -716,20 +716,33 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */ /* * process utility functions (create, destroy, etc..) */ + Node *utilityStmt = querytree->utilityStmt; + elog(DEBUG2, "ProcessUtility"); + /* set snapshot if utility stmt needs one */ + /* XXX maybe cleaner to list those that shouldn't set one? */ + if (IsA(utilityStmt, AlterTableStmt) || + IsA(utilityStmt, ClusterStmt) || + IsA(utilityStmt, CopyStmt) || + IsA(utilityStmt, ExecuteStmt) || + IsA(utilityStmt, ExplainStmt) || + IsA(utilityStmt, IndexStmt) || + IsA(utilityStmt, PrepareStmt) || + IsA(utilityStmt, ReindexStmt)) + SetQuerySnapshot(); + if (querytree->originalQuery) { /* utility statement can override default tag string */ - ProcessUtility(querytree->utilityStmt, dest, - completionTag); + ProcessUtility(utilityStmt, dest, completionTag); if (completionTag[0]) commandTag = completionTag; } else { /* utility added by rewrite cannot override tag */ - ProcessUtility(querytree->utilityStmt, dest, NULL); + ProcessUtility(utilityStmt, dest, NULL); } } else @@ -739,14 +752,20 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */ */ Plan *plan; + /* + * Initialize snapshot state for query. This has to + * be done before running the planner, because it might + * try to evaluate immutable or stable functions, which + * in turn might run queries. + */ + SetQuerySnapshot(); + + /* Make the plan */ plan = pg_plan_query(querytree); /* if we got a cancel signal whilst planning, quit */ CHECK_FOR_INTERRUPTS(); - /* Initialize snapshot state for query */ - SetQuerySnapshot(); - /* * execute the plan */ @@ -1701,7 +1720,7 @@ PostgresMain(int argc, char *argv[], const char *username) if (!IsUnderPostmaster) { puts("\nPOSTGRES backend interactive interface "); - puts("$Revision: 1.298 $ $Date: 2002/10/06 03:56:03 $\n"); + puts("$Revision: 1.299 $ $Date: 2002/10/08 17:17:19 $\n"); } /* @@ -1886,6 +1905,9 @@ PostgresMain(int argc, char *argv[], const char *username) /* start an xact for this function invocation */ start_xact_command(); + /* assume it may need a snapshot */ + SetQuerySnapshot(); + if (HandleFunctionRequest() == EOF) { /* lost frontend connection during F message input */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index c6bd305082..1b857a816d 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.178 2002/09/26 22:58:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.179 2002/10/08 17:17:19 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -380,14 +380,7 @@ ProcessUtility(Node *parsetree, break; case T_CopyStmt: - { - CopyStmt *stmt = (CopyStmt *) parsetree; - - if (!stmt->is_from) - SetQuerySnapshot(); - - DoCopy(stmt); - } + DoCopy((CopyStmt *) parsetree); break; case T_PrepareStmt: diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c index f5314526b8..d6a329fa31 100644 --- a/src/backend/utils/time/tqual.c +++ b/src/backend/utils/time/tqual.c @@ -16,7 +16,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.60 2002/09/04 20:31:33 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.61 2002/10/08 17:17:19 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -977,8 +977,8 @@ CopyQuerySnapshot(void) { Snapshot snapshot; - if (QuerySnapshot == NULL) /* should be set already, but... */ - SetQuerySnapshot(); + if (QuerySnapshot == NULL) /* should be set beforehand */ + elog(ERROR, "CopyQuerySnapshot: no snapshot has been set"); snapshot = (Snapshot) palloc(sizeof(SnapshotData)); memcpy(snapshot, QuerySnapshot, sizeof(SnapshotData));