aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/variable.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2011-01-22 20:51:32 -0500
committerRobert Haas <rhaas@postgresql.org>2011-01-22 20:55:50 -0500
commit6f59777c65d557485e933a383ebc4c3fdfc1a2b7 (patch)
treeb5ce0b0f7d50c18b09e38b75b2a43082bf4deac3 /src/backend/commands/variable.c
parentcc73c160507588bdc5822d7f2bb79d6b3a386761 (diff)
downloadpostgresql-6f59777c65d557485e933a383ebc4c3fdfc1a2b7.tar.gz
postgresql-6f59777c65d557485e933a383ebc4c3fdfc1a2b7.zip
Code cleanup for assign_transaction_read_only.
As in commit fb4c5d2798730f60b102d775f22fb53c26a6445d on 2011-01-21, this avoids spurious debug messages and allows idempotent changes at any time. Along the way, make assign_XactIsoLevel allow idempotent changes even when not within a subtransaction, to be consistent with the new coding of assign_transaction_read_only and because there's no compelling reason to do otherwise. Kevin Grittner, with some adjustments.
Diffstat (limited to 'src/backend/commands/variable.c')
-rw-r--r--src/backend/commands/variable.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index 1e9bdc3f218..139148eec2e 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -544,13 +544,62 @@ show_log_timezone(void)
/*
+ * SET TRANSACTION READ ONLY and SET TRANSACTION READ WRITE
+ *
+ * We allow idempotent changes (r/w -> r/w and r/o -> r/o) at any time, and
+ * we also always allow changes from read-write to read-only. However,
+ * read-only to read-write may be changed only when source == PGC_S_OVERRIDE
+ * (i.e. we're aborting a read only transaction and restoring the previous
+ * setting) or in a top-level transaction that has not yet taken an initial
+ * snapshot.
+ */
+bool
+assign_transaction_read_only(bool newval, bool doit, GucSource source)
+{
+ if (source != PGC_S_OVERRIDE && newval == false && XactReadOnly)
+ {
+ /* Can't go to r/w mode inside a r/o transaction */
+ if (IsSubTransaction())
+ {
+ ereport(GUC_complaint_elevel(source),
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("cannot set transaction read-write mode inside a read-only transaction")));
+ return false;
+ }
+ /* Top level transaction can't change to r/w after first snapshot. */
+ if (FirstSnapshotSet)
+ {
+ ereport(GUC_complaint_elevel(source),
+ (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
+ errmsg("transaction read-write mode must be set before any query")));
+ return false;
+ }
+ /* Can't go to r/w mode while recovery is still active */
+ if (RecoveryInProgress())
+ {
+ ereport(GUC_complaint_elevel(source),
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("cannot set transaction read-write mode during recovery")));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/*
* SET TRANSACTION ISOLATION LEVEL
+ *
+ * We allow idempotent changes at any time, but otherwise this can only be
+ * changed from a toplevel transaction that has not yet taken a snapshot, or
+ * when source == PGC_S_OVERRIDE (i.e. we're aborting a transaction and
+ * restoring the previously set value).
*/
const char *
assign_XactIsoLevel(const char *value, bool doit, GucSource source)
{
/* source == PGC_S_OVERRIDE means do it anyway, eg at xact abort */
- if (source != PGC_S_OVERRIDE)
+ if (source != PGC_S_OVERRIDE && strcmp(value, XactIsoLevel_string) != 0)
{
if (FirstSnapshotSet)
{
@@ -560,7 +609,7 @@ assign_XactIsoLevel(const char *value, bool doit, GucSource source)
return NULL;
}
/* We ignore a subtransaction setting it to the existing value. */
- if (IsSubTransaction() && strcmp(value, XactIsoLevel_string) != 0)
+ if (IsSubTransaction())
{
ereport(GUC_complaint_elevel(source),
(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),