diff --git a/src/common/backend/utils/misc/guc.cpp b/src/common/backend/utils/misc/guc.cpp index d4315717dd5296d1799552c1ff270c8623eb0dbf..ad245c9fe46db9b0100d38ad10851c9d81e9f985 100755 --- a/src/common/backend/utils/misc/guc.cpp +++ b/src/common/backend/utils/misc/guc.cpp @@ -1537,7 +1537,7 @@ static void InitConfigureNamesBool() CLIENT_CONN_STATEMENT, gettext_noop("Sets the current transaction's read-only status."), NULL, - GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE}, + GUC_NO_RESET | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE}, &u_sess->attr.attr_common.XactReadOnly, false, check_transaction_read_only, @@ -8034,6 +8034,21 @@ int set_config_option(const char* name, const char* value, GucContext context, G } } + if (record->flags & GUC_NO_RESET) { + if (value == NULL) { + ereport(elevel, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot reset parameter \"%s\"", name))); + return 0; + } + + if (action == GUC_ACTION_SAVE) { + ereport(elevel, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot set parameter \"%s\" locally within functions", name))); + return 0; + } + } /* * Should we set reset/stacked values? (If so, the behavior is not * transactional.) This is done either when we get a default value from diff --git a/src/common/backend/utils/misc/guc/guc_storage.cpp b/src/common/backend/utils/misc/guc/guc_storage.cpp index 6a9afc4c18af231ac0cfbbbde7d78a96ebcb440a..153f4a5765d04baa461e26da9b201083a9062111 100755 --- a/src/common/backend/utils/misc/guc/guc_storage.cpp +++ b/src/common/backend/utils/misc/guc/guc_storage.cpp @@ -627,7 +627,7 @@ static void InitStorageConfigureNamesBool() gettext_noop("Whether to defer a read-only serializable transaction until it can be executed with no " "possible serialization failures."), NULL, - GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE}, + GUC_NO_RESET | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE}, &u_sess->attr.attr_storage.XactDeferrable, false, check_transaction_deferrable, @@ -4580,7 +4580,7 @@ static void InitStorageConfigureNamesString() CLIENT_CONN_STATEMENT, gettext_noop("Sets the current transaction's isolation level."), NULL, - GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE}, + GUC_NO_RESET | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE}, &u_sess->attr.attr_storage.XactIsoLevel_string, "default", check_XactIsoLevel, diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index c884de5a0ba2982d8565653a10a32b3e22007ea6..18f689dff62f3157f807e38092161e58d7b3fc3f 100755 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -207,6 +207,7 @@ typedef struct { #define GUC_LIST_INPUT 0x0001 /* input can be list format */ #define GUC_LIST_QUOTE 0x0002 /* double-quote list elements */ #define GUC_NO_SHOW_ALL 0x0004 /* exclude from SHOW ALL */ +#define GUC_NO_RESET 0x10000 /* disallow reset for specific variable */ #define GUC_NO_RESET_ALL 0x0008 /* exclude from RESET ALL */ #define GUC_REPORT 0x0010 /* auto-report changes to client */ #define GUC_NOT_IN_SAMPLE 0x0020 /* not in postgresql.conf.sample */ diff --git a/src/test/regress/expected/transactions_test.out b/src/test/regress/expected/transactions_test.out index b32f061f3f864f94da5bba2dd02f6e08c5e03588..76259411b5d7fcf3fb2a17f3a4a703a1bd5e4df9 100644 --- a/src/test/regress/expected/transactions_test.out +++ b/src/test/regress/expected/transactions_test.out @@ -1,3 +1,37 @@ +CREATE TABLE no_reset_test(a int); +insert into no_reset_test values(1); +-- Test transaction variable cannot be reset. +BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; +select count(*) from no_reset_test; + count +------- + 1 +(1 row) + +reset transaction_isolation; --error +ERROR: cannot reset parameter "transaction_isolation" +END; +BEGIN TRANSACTION READ ONLY; +select count(*) from no_reset_test; + count +------- + 1 +(1 row) + +reset transaction_read_only; --error +ERROR: cannot reset parameter "transaction_read_only" +END; +BEGIN TRANSACTION DEFERRABLE; +select count(*) from no_reset_test; + count +------- + 1 +(1 row) + +reset transaction_deferrable; --error +ERROR: cannot reset parameter "transaction_deferrable" +END; +DROP TABLE no_reset_test; SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY; START TRANSACTION READ WRITE; CREATE TABLE transaction_test_table(a int); diff --git a/src/test/regress/sql/transactions_test.sql b/src/test/regress/sql/transactions_test.sql index a384641a389064f984b909e2caf313c0f5af2614..84b079cf03ed3fcbe6c876d6b701ce27d0ea3e8e 100644 --- a/src/test/regress/sql/transactions_test.sql +++ b/src/test/regress/sql/transactions_test.sql @@ -1,3 +1,24 @@ +CREATE TABLE no_reset_test(a int); +insert into no_reset_test values(1); + +-- Test transaction variable cannot be reset. +BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; +select count(*) from no_reset_test; +reset transaction_isolation; --error +END; + +BEGIN TRANSACTION READ ONLY; +select count(*) from no_reset_test; +reset transaction_read_only; --error +END; + +BEGIN TRANSACTION DEFERRABLE; +select count(*) from no_reset_test; +reset transaction_deferrable; --error +END; + +DROP TABLE no_reset_test; + SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY; START TRANSACTION READ WRITE; CREATE TABLE transaction_test_table(a int);