Move responsibility for setting QuerySnapshot for utility statements
authorTom Lane
Tue, 8 Oct 2002 17:17:19 +0000 (17:17 +0000)
committerTom Lane
Tue, 8 Oct 2002 17:17:19 +0000 (17:17 +0000)
into postgres.c; make sure it happens for all cases that seem to need it.
Perhaps it would be better to explicitly exclude just a few utility
statement types from setting a snapshot?

src/backend/tcop/postgres.c
src/backend/tcop/utility.c
src/backend/utils/time/tqual.c

index 2a78e38fe0ced4c216779d639bf0dadd7922e4f7..f3bd34fde270733950d8978830449399a514d299 100644 (file)
@@ -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 */
index c6bd3050825bb5fa6c14e82698aee84d33f6f91e..1b857a816d47018015509b4610c21bb39ad95d1a 100644 (file)
@@ -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:
index f5314526b8873af4ba676dcc51e1e9b116c1bf89..d6a329fa318c33af71abebe6ba51557e941de860 100644 (file)
@@ -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));