fix-bug-18545-wip.patch
text/x-diff
Filename: fix-bug-18545-wip.patch
Type: text/x-diff
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/access/transam/parallel.c | 8 | 4 |
| src/backend/commands/variable.c | 18 | 3 |
diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index 8613fc6fb5..06331d906a 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -1410,10 +1410,6 @@ ParallelWorkerMain(Datum main_arg)
libraryspace = shm_toc_lookup(toc, PARALLEL_KEY_LIBRARY, false);
StartTransactionCommand();
RestoreLibraryState(libraryspace);
-
- /* Restore GUC values from launching backend. */
- gucspace = shm_toc_lookup(toc, PARALLEL_KEY_GUC, false);
- RestoreGUCState(gucspace);
CommitTransactionCommand();
/* Crank up a transaction state appropriate to a parallel worker. */
@@ -1455,6 +1451,14 @@ ParallelWorkerMain(Datum main_arg)
*/
InvalidateSystemCaches();
+ /*
+ * Restore GUC values from launching backend. We can't do this earlier,
+ * because GUCs that do catalog lookups (such as session_authorization)
+ * need to see the same database state as the leader.
+ */
+ gucspace = shm_toc_lookup(toc, PARALLEL_KEY_GUC, false);
+ RestoreGUCState(gucspace);
+
/*
* Restore current role id. Skip verifying whether session user is
* allowed to become this role and blindly restore the leader's state for
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index 9345131711..b2a00ae0f0 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -577,14 +577,16 @@ check_transaction_read_only(bool *newval, void **extra, GucSource source)
* We allow idempotent changes at any time, but otherwise this can only be
* changed in a toplevel transaction that has not yet taken a snapshot.
*
- * As in check_transaction_read_only, allow it if not inside a transaction.
+ * As in check_transaction_read_only, allow it if not inside a transaction,
+ * or if restoring state in a parallel worker.
*/
bool
check_transaction_isolation(int *newval, void **extra, GucSource source)
{
int newXactIsoLevel = *newval;
- if (newXactIsoLevel != XactIsoLevel && IsTransactionState())
+ if (newXactIsoLevel != XactIsoLevel &&
+ IsTransactionState() && !InitializingParallelWorker)
{
if (FirstSnapshotSet)
{
@@ -619,6 +621,10 @@ check_transaction_isolation(int *newval, void **extra, GucSource source)
bool
check_transaction_deferrable(bool *newval, void **extra, GucSource source)
{
+ /* Just accept the value when restoring state in a parallel worker */
+ if (InitializingParallelWorker)
+ return true;
+
if (IsSubTransaction())
{
GUC_check_errcode(ERRCODE_ACTIVE_SQL_TRANSACTION);
@@ -811,6 +817,15 @@ check_session_authorization(char **newval, void **extra, GucSource source)
if (*newval == NULL)
return true;
+ /*
+ * Do nothing if initializing a parallel worker: ParallelWorkerMain is
+ * responsible for setting the active role. We just need to absorb the
+ * leader's value of session_authorization in case some user code looks at
+ * it.
+ */
+ if (InitializingParallelWorker)
+ return true;
+
if (!IsTransactionState())
{
/*
@@ -886,7 +901,7 @@ assign_session_authorization(const char *newval, void *extra)
{
role_auth_extra *myextra = (role_auth_extra *) extra;
- /* Do nothing for the boot_val default of NULL */
+ /* Do nothing for the boot_val default of NULL, and in parallel workers */
if (!myextra)
return;