mirror of
https://github.com/postgres/postgres.git
synced 2025-07-18 17:42:25 +03:00
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.
This commit is contained in:
@ -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;
|
||||
|
Reference in New Issue
Block a user