diff options
author | Bruce Momjian <bruce@momjian.us> | 2013-11-25 19:19:40 -0500 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 2013-11-25 19:19:40 -0500 |
commit | a6542a4b6870a019cd952d055d2e7af2da2fe102 (patch) | |
tree | a2b0c5daba153d704f31edfbf1e66834d4955627 | |
parent | 05b476c2983a8d38bf6a0254553b4a0776896aa7 (diff) | |
download | postgresql-a6542a4b6870a019cd952d055d2e7af2da2fe102.tar.gz postgresql-a6542a4b6870a019cd952d055d2e7af2da2fe102.zip |
Change SET LOCAL/CONSTRAINTS/TRANSACTION and ABORT behavior
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.
-rw-r--r-- | doc/src/sgml/ref/abort.sgml | 3 | ||||
-rw-r--r-- | doc/src/sgml/ref/rollback.sgml | 4 | ||||
-rw-r--r-- | doc/src/sgml/ref/set.sgml | 5 | ||||
-rw-r--r-- | doc/src/sgml/ref/set_constraints.sgml | 5 | ||||
-rw-r--r-- | doc/src/sgml/ref/set_transaction.sgml | 2 | ||||
-rw-r--r-- | src/backend/access/transam/xact.c | 37 | ||||
-rw-r--r-- | src/backend/tcop/utility.c | 2 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 10 | ||||
-rw-r--r-- | src/include/access/xact.h | 1 | ||||
-rw-r--r-- | src/test/regress/expected/errors.out | 2 | ||||
-rw-r--r-- | src/test/regress/expected/guc.out | 4 |
11 files changed, 47 insertions, 28 deletions
diff --git a/doc/src/sgml/ref/abort.sgml b/doc/src/sgml/ref/abort.sgml index 246e8f81268..f3a2fa88ff1 100644 --- a/doc/src/sgml/ref/abort.sgml +++ b/doc/src/sgml/ref/abort.sgml @@ -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> diff --git a/doc/src/sgml/ref/rollback.sgml b/doc/src/sgml/ref/rollback.sgml index b26554567db..4f7962117c8 100644 --- a/doc/src/sgml/ref/rollback.sgml +++ b/doc/src/sgml/ref/rollback.sgml @@ -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> diff --git a/doc/src/sgml/ref/set.sgml b/doc/src/sgml/ref/set.sgml index 6290c9de708..5a84f697e67 100644 --- a/doc/src/sgml/ref/set.sgml +++ b/doc/src/sgml/ref/set.sgml @@ -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> diff --git a/doc/src/sgml/ref/set_constraints.sgml b/doc/src/sgml/ref/set_constraints.sgml index 895a5fdbc0e..a33190cca81 100644 --- a/doc/src/sgml/ref/set_constraints.sgml +++ b/doc/src/sgml/ref/set_constraints.sgml @@ -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> diff --git a/doc/src/sgml/ref/set_transaction.sgml b/doc/src/sgml/ref/set_transaction.sgml index 391464ade83..e90ff4af725 100644 --- a/doc/src/sgml/ref/set_transaction.sgml +++ b/doc/src/sgml/ref/set_transaction.sgml @@ -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> diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 0591f3fd562..bab048d38a1 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -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); @@ -2949,6 +2951,26 @@ PreventTransactionChain(bool isTopLevel, const char *stmtType) } /* + * 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 * * This routine is to be called by statements that must run inside @@ -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; diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 6a7bf0de7d7..5895102b518 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -754,7 +754,7 @@ standard_ProcessUtility(Node *parsetree, break; case T_ConstraintsSetStmt: - RequireTransactionChain(isTopLevel, "SET CONSTRAINTS"); + WarnNoTransactionChain(isTopLevel, "SET CONSTRAINTS"); AfterTriggerSetState((ConstraintsSetStmt *) parsetree); break; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 54d8078fe7a..cbf3186789c 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -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, diff --git a/src/include/access/xact.h b/src/include/access/xact.h index 835f6acbee0..1d3e7d8938a 100644 --- a/src/include/access/xact.h +++ b/src/include/access/xact.h @@ -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); diff --git a/src/test/regress/expected/errors.out b/src/test/regress/expected/errors.out index fa0bd82819a..40615129778 100644 --- a/src/test/regress/expected/errors.out +++ b/src/test/regress/expected/errors.out @@ -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 diff --git a/src/test/regress/expected/guc.out b/src/test/regress/expected/guc.out index 203fa6ef8ea..4f0065cb7ef 100644 --- a/src/test/regress/expected/guc.out +++ b/src/test/regress/expected/guc.out @@ -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 ----------- |