]> granicus.if.org Git - postgresql/commitdiff
Change SET LOCAL/CONSTRAINTS/TRANSACTION and ABORT behavior
authorBruce Momjian <bruce@momjian.us>
Tue, 26 Nov 2013 00:19:40 +0000 (19:19 -0500)
committerBruce Momjian <bruce@momjian.us>
Tue, 26 Nov 2013 00:19:40 +0000 (19:19 -0500)
Change SET LOCAL/CONSTRAINTS/TRANSACTION behavior outside of a
transaction block from error (post-9.3) to warning.  (Was nothing in <=
9.3.)  Also change ABORT outside of a transaction block from notice to
warning.

doc/src/sgml/ref/abort.sgml
doc/src/sgml/ref/rollback.sgml
doc/src/sgml/ref/set.sgml
doc/src/sgml/ref/set_constraints.sgml
doc/src/sgml/ref/set_transaction.sgml
src/backend/access/transam/xact.c
src/backend/tcop/utility.c
src/backend/utils/misc/guc.c
src/include/access/xact.h
src/test/regress/expected/errors.out
src/test/regress/expected/guc.out

index 246e8f812687b82ce0b0e269111c974544d90bb2..f3a2fa88ff19be0fdadf00459f07fd59151f2625 100644 (file)
@@ -63,8 +63,7 @@ ABORT [ WORK | TRANSACTION ]
   </para>
 
   <para>
-   Issuing <command>ABORT</> when not inside a transaction does
-   no harm, but it will provoke a warning message.
+   Issuing <command>ABORT</> outside of a transaction block has no effect.
   </para>
  </refsect1>
 
index b26554567dbd001b8121f892ff8dc14d83ed988b..4f7962117c8acee850fe702ee141f8e1ad9c97d5 100644 (file)
@@ -59,8 +59,8 @@ ROLLBACK [ WORK | TRANSACTION ]
   </para>
 
   <para>
-   Issuing <command>ROLLBACK</> when not inside a transaction does
-   no harm, but it will provoke a warning message.
+   Issuing <command>ROLLBACK</> outside of a transaction
+   block has no effect.
   </para>
  </refsect1>
 
index 6290c9de70852cb6cb502b9e4804e456fe7c9973..5a84f697e675869fefeba596db7ec13782bc12f8 100644 (file)
@@ -110,9 +110,8 @@ SET [ SESSION | LOCAL ] TIME ZONE { <replaceable class="PARAMETER">timezone</rep
      <para>
       Specifies that the command takes effect for only the current
       transaction.  After <command>COMMIT</> or <command>ROLLBACK</>,
-      the session-level setting takes effect again.
-      <productname>PostgreSQL</productname> reports an error if
-      <command>SET LOCAL</> is used outside a transaction block.
+      the session-level setting takes effect again.  This has no effect
+      outside of a transaction block.
      </para>
     </listitem>
    </varlistentry>
index 895a5fdbc0ec60463e387d7101140c74b91c7f38..a33190cca81f884b8d2da9cb85ead8a810c3fe79 100644 (file)
@@ -99,10 +99,7 @@ SET CONSTRAINTS { ALL | <replaceable class="parameter">name</replaceable> [, ...
 
   <para>
    This command only alters the behavior of constraints within the
-   current transaction. Thus, if you execute this command outside of a
-   transaction block
-   (<command>BEGIN</command>/<command>COMMIT</command> pair), it will
-   generate an error.
+   current transaction.  This has no effect outside of a transaction block.
   </para>
  </refsect1>
 
index 391464ade8380d1c20667e935bbfa0ad52ea84cc..e90ff4af725b9ea07cc205c359d8a7dac9f82910 100644 (file)
@@ -185,7 +185,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION <replaceable class="parameter">transa
   <para>
    If <command>SET TRANSACTION</command> is executed without a prior
    <command>START TRANSACTION</command> or <command>BEGIN</command>,
-   it will generate an error.
+   it will have no effect.
   </para>
 
   <para>
index 0591f3fd56210d3f4902fce03392f5fc12ec931b..bab048d38a15703a36b4b92c7305b20515a28a77 100644 (file)
@@ -265,6 +265,8 @@ static void CallSubXactCallbacks(SubXactEvent event,
                                         SubTransactionId mySubid,
                                         SubTransactionId parentSubid);
 static void CleanupTransaction(void);
+static void CheckTransactionChain(bool isTopLevel, bool throwError,
+                                        const char *stmtType);
 static void CommitTransaction(void);
 static TransactionId RecordTransactionAbort(bool isSubXact);
 static void StartTransaction(void);
@@ -2948,6 +2950,26 @@ PreventTransactionChain(bool isTopLevel, const char *stmtType)
        /* all okay */
 }
 
+/*
+ *     These two functions allow for warnings or errors if a command is
+ *     executed outside of a transaction block.
+ *
+ *     While top-level transaction control commands (BEGIN/COMMIT/ABORT) and
+ *     SET that have no effect issue warnings, all other no-effect commands
+ *     generate errors.
+ */
+void
+WarnNoTransactionChain(bool isTopLevel, const char *stmtType)
+{
+       CheckTransactionChain(isTopLevel, false, stmtType);
+}
+
+void
+RequireTransactionChain(bool isTopLevel, const char *stmtType)
+{
+       CheckTransactionChain(isTopLevel, true, stmtType);
+}
+
 /*
  *     RequireTransactionChain
  *
@@ -2957,16 +2979,16 @@ PreventTransactionChain(bool isTopLevel, const char *stmtType)
  *     is presumably an error).  DECLARE CURSOR is an example.
  *
  *     If we appear to be running inside a user-defined function, we do not
- *     issue an error, since the function could issue more commands that make
+ *     issue anything, since the function could issue more commands that make
  *     use of the current statement's results.  Likewise subtransactions.
  *     Thus this is an inverse for PreventTransactionChain.
  *
  *     isTopLevel: passed down from ProcessUtility to determine whether we are
  *     inside a function.
- *     stmtType: statement type name, for error messages.
+ *     stmtType: statement type name, for warning or error messages.
  */
-void
-RequireTransactionChain(bool isTopLevel, const char *stmtType)
+static void
+CheckTransactionChain(bool isTopLevel, bool throwError, const char *stmtType)
 {
        /*
         * xact block already started?
@@ -2986,11 +3008,12 @@ RequireTransactionChain(bool isTopLevel, const char *stmtType)
        if (!isTopLevel)
                return;
 
-       ereport(ERROR,
+       ereport(throwError ? ERROR : WARNING,
                        (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
        /* translator: %s represents an SQL statement name */
                         errmsg("%s can only be used in transaction blocks",
                                        stmtType)));
+       return;
 }
 
 /*
@@ -3425,12 +3448,12 @@ UserAbortTransactionBlock(void)
 
                        /*
                         * The user issued ABORT when not inside a transaction. Issue a
-                        * NOTICE and go to abort state.  The upcoming call to
+                        * WARNING and go to abort state.  The upcoming call to
                         * CommitTransactionCommand() will then put us back into the
                         * default state.
                         */
                case TBLOCK_STARTED:
-                       ereport(NOTICE,
+                       ereport(WARNING,
                                        (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
                                         errmsg("there is no transaction in progress")));
                        s->blockState = TBLOCK_ABORT_PENDING;
index 6a7bf0de7d72ee111f896bb5d513f6a0b872f955..5895102b518460490ebbc8be7bce723c06249bde 100644 (file)
@@ -754,7 +754,7 @@ standard_ProcessUtility(Node *parsetree,
                        break;
 
                case T_ConstraintsSetStmt:
-                       RequireTransactionChain(isTopLevel, "SET CONSTRAINTS");
+                       WarnNoTransactionChain(isTopLevel, "SET CONSTRAINTS");
                        AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
                        break;
 
index 54d8078fe7a9e8aa13ca324a34e4f77b45e31123..cbf3186789c57168837e086a5f500601d2ab04ae 100644 (file)
@@ -6274,7 +6274,7 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
                case VAR_SET_VALUE:
                case VAR_SET_CURRENT:
                        if (stmt->is_local)
-                               RequireTransactionChain(isTopLevel, "SET LOCAL");
+                               WarnNoTransactionChain(isTopLevel, "SET LOCAL");
                        (void) set_config_option(stmt->name,
                                                                         ExtractSetVariableArgs(stmt),
                                                                         (superuser() ? PGC_SUSET : PGC_USERSET),
@@ -6295,7 +6295,7 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
                        {
                                ListCell   *head;
 
-                               RequireTransactionChain(isTopLevel, "SET TRANSACTION");
+                               WarnNoTransactionChain(isTopLevel, "SET TRANSACTION");
 
                                foreach(head, stmt->args)
                                {
@@ -6346,7 +6346,7 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
                                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                                         errmsg("SET LOCAL TRANSACTION SNAPSHOT is not implemented")));
 
-                               RequireTransactionChain(isTopLevel, "SET TRANSACTION");
+                               WarnNoTransactionChain(isTopLevel, "SET TRANSACTION");
                                Assert(IsA(con, A_Const));
                                Assert(nodeTag(&con->val) == T_String);
                                ImportSnapshot(strVal(&con->val));
@@ -6357,11 +6357,11 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
                        break;
                case VAR_SET_DEFAULT:
                        if (stmt->is_local)
-                               RequireTransactionChain(isTopLevel, "SET LOCAL");
+                               WarnNoTransactionChain(isTopLevel, "SET LOCAL");
                        /* fall through */
                case VAR_RESET:
                        if (strcmp(stmt->name, "transaction_isolation") == 0)
-                               RequireTransactionChain(isTopLevel, "RESET TRANSACTION");
+                               WarnNoTransactionChain(isTopLevel, "RESET TRANSACTION");
 
                        (void) set_config_option(stmt->name,
                                                                         NULL,
index 835f6acbee0e10ee51e5a2295429efd5141e3b77..1d3e7d8938adf35256077995898226fd02d6d639 100644 (file)
@@ -245,6 +245,7 @@ extern char TransactionBlockStatusCode(void);
 extern void AbortOutOfAnyTransaction(void);
 extern void PreventTransactionChain(bool isTopLevel, const char *stmtType);
 extern void RequireTransactionChain(bool isTopLevel, const char *stmtType);
+extern void WarnNoTransactionChain(bool isTopLevel, const char *stmtType);
 extern bool IsInTransactionChain(bool isTopLevel);
 extern void RegisterXactCallback(XactCallback callback, void *arg);
 extern void UnregisterXactCallback(XactCallback callback, void *arg);
index fa0bd82819a89e1702b4cd26957dd9988420cfbc..4061512977845bfce2150c46e9d954365f0ee404 100644 (file)
@@ -114,7 +114,7 @@ ERROR:  column name "oid" conflicts with a system column name
 -- TRANSACTION STUFF
 -- not in a xact
 abort;
-NOTICE:  there is no transaction in progress
+WARNING:  there is no transaction in progress
 -- not in a xact
 end;
 WARNING:  there is no transaction in progress
index 203fa6ef8ea2488e05c8c491f7eab50f2dedc6c7..4f0065cb7efb845652b520f1ab8a2ae20645c962 100644 (file)
@@ -29,7 +29,7 @@ SELECT '2006-08-13 12:34:56'::timestamptz;
 
 -- SET LOCAL has no effect outside of a transaction
 SET LOCAL vacuum_cost_delay TO 50;
-ERROR:  SET LOCAL can only be used in transaction blocks
+WARNING:  SET LOCAL can only be used in transaction blocks
 SHOW vacuum_cost_delay;
  vacuum_cost_delay 
 -------------------
@@ -37,7 +37,7 @@ SHOW vacuum_cost_delay;
 (1 row)
 
 SET LOCAL datestyle = 'SQL';
-ERROR:  SET LOCAL can only be used in transaction blocks
+WARNING:  SET LOCAL can only be used in transaction blocks
 SHOW datestyle;
  DateStyle 
 -----------