Skip to content

Commit 4594e73

Browse files
committed
Merge branch 'REL9_6_STABLE' into PGPRO9_6
2 parents 9a839db + f74f871 commit 4594e73

File tree

14 files changed

+224
-30
lines changed

14 files changed

+224
-30
lines changed

doc/src/sgml/ref/prepare_transaction.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ PREPARE TRANSACTION <replaceable class="PARAMETER">transaction_id</replaceable>
100100
It is not currently allowed to <command>PREPARE</> a transaction that
101101
has executed any operations involving temporary tables,
102102
created any cursors <literal>WITH HOLD</>, or executed
103-
<command>LISTEN</> or <command>UNLISTEN</>.
103+
<command>LISTEN</>, <command>UNLISTEN</>, or
104+
<command>NOTIFY</>.
104105
Those features are too tightly
105106
tied to the current session to be useful in a transaction to be prepared.
106107
</para>

src/backend/access/transam/parallel.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,11 @@ typedef struct FixedParallelState
7070
Oid database_id;
7171
Oid authenticated_user_id;
7272
Oid current_user_id;
73+
Oid outer_user_id;
7374
Oid temp_namespace_id;
7475
Oid temp_toast_namespace_id;
7576
int sec_context;
77+
bool is_superuser;
7678
PGPROC *parallel_master_pgproc;
7779
pid_t parallel_master_pid;
7880
BackendId parallel_master_backend_id;
@@ -310,6 +312,8 @@ InitializeParallelDSM(ParallelContext *pcxt)
310312
shm_toc_allocate(pcxt->toc, sizeof(FixedParallelState));
311313
fps->database_id = MyDatabaseId;
312314
fps->authenticated_user_id = GetAuthenticatedUserId();
315+
fps->outer_user_id = GetCurrentRoleId();
316+
fps->is_superuser = session_auth_is_superuser;
313317
GetUserIdAndSecContext(&fps->current_user_id, &fps->sec_context);
314318
GetTempNamespaceState(&fps->temp_namespace_id,
315319
&fps->temp_toast_namespace_id);
@@ -1126,6 +1130,13 @@ ParallelWorkerMain(Datum main_arg)
11261130
*/
11271131
InvalidateSystemCaches();
11281132

1133+
/*
1134+
* Restore current role id. Skip verifying whether session user is
1135+
* allowed to become this role and blindly restore the leader's state for
1136+
* current role.
1137+
*/
1138+
SetCurrentRoleId(fps->outer_user_id, fps->is_superuser);
1139+
11291140
/* Restore user ID and security context. */
11301141
SetUserIdAndSecContext(fps->current_user_id, fps->sec_context);
11311142

src/backend/catalog/dependency.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,10 +1713,24 @@ find_expr_references_walker(Node *node,
17131713
else if (IsA(node, FieldSelect))
17141714
{
17151715
FieldSelect *fselect = (FieldSelect *) node;
1716+
Oid argtype = exprType((Node *) fselect->arg);
1717+
Oid reltype = get_typ_typrelid(argtype);
17161718

1717-
/* result type might not appear anywhere else in expression */
1718-
add_object_address(OCLASS_TYPE, fselect->resulttype, 0,
1719-
context->addrs);
1719+
/*
1720+
* We need a dependency on the specific column named in FieldSelect,
1721+
* assuming we can identify the pg_class OID for it. (Probably we
1722+
* always can at the moment, but in future it might be possible for
1723+
* argtype to be RECORDOID.) If we can make a column dependency then
1724+
* we shouldn't need a dependency on the column's type; but if we
1725+
* can't, make a dependency on the type, as it might not appear
1726+
* anywhere else in the expression.
1727+
*/
1728+
if (OidIsValid(reltype))
1729+
add_object_address(OCLASS_CLASS, reltype, fselect->fieldnum,
1730+
context->addrs);
1731+
else
1732+
add_object_address(OCLASS_TYPE, fselect->resulttype, 0,
1733+
context->addrs);
17201734
/* the collation might not be referenced anywhere else, either */
17211735
if (OidIsValid(fselect->resultcollid) &&
17221736
fselect->resultcollid != DEFAULT_COLLATION_OID)
@@ -1726,10 +1740,20 @@ find_expr_references_walker(Node *node,
17261740
else if (IsA(node, FieldStore))
17271741
{
17281742
FieldStore *fstore = (FieldStore *) node;
1743+
Oid reltype = get_typ_typrelid(fstore->resulttype);
17291744

1730-
/* result type might not appear anywhere else in expression */
1731-
add_object_address(OCLASS_TYPE, fstore->resulttype, 0,
1732-
context->addrs);
1745+
/* similar considerations to FieldSelect, but multiple column(s) */
1746+
if (OidIsValid(reltype))
1747+
{
1748+
ListCell *l;
1749+
1750+
foreach(l, fstore->fieldnums)
1751+
add_object_address(OCLASS_CLASS, reltype, lfirst_int(l),
1752+
context->addrs);
1753+
}
1754+
else
1755+
add_object_address(OCLASS_TYPE, fstore->resulttype, 0,
1756+
context->addrs);
17331757
}
17341758
else if (IsA(node, RelabelType))
17351759
{

src/backend/executor/execMain.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,10 +1548,7 @@ ExecutePlan(EState *estate,
15481548
if (numberTuples || dest->mydest == DestIntoRel)
15491549
use_parallel_mode = false;
15501550

1551-
/*
1552-
* If a tuple count was supplied, we must force the plan to run without
1553-
* parallelism, because we might exit early.
1554-
*/
1551+
estate->es_use_parallel_mode = use_parallel_mode;
15551552
if (use_parallel_mode)
15561553
EnterParallelMode();
15571554

src/backend/executor/execUtils.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ CreateExecutorState(void)
140140
estate->es_epqTupleSet = NULL;
141141
estate->es_epqScanDone = NULL;
142142

143+
estate->es_use_parallel_mode = false;
144+
143145
/*
144146
* Return the executor state structure
145147
*/

src/backend/executor/nodeGather.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ ExecGather(GatherState *node)
150150
* Sometimes we might have to run without parallelism; but if parallel
151151
* mode is active then we can try to fire up some workers.
152152
*/
153-
if (gather->num_workers > 0 && IsInParallelMode())
153+
if (gather->num_workers > 0 && estate->es_use_parallel_mode)
154154
{
155155
ParallelContext *pcxt;
156156

src/backend/parser/parse_relation.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,13 +2012,22 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
20122012
varattno++;
20132013
Assert(varattno == te->resno);
20142014

2015+
/*
2016+
* In scenarios where columns have been added to a view
2017+
* since the outer query was originally parsed, there can
2018+
* be more items in the subquery tlist than the outer
2019+
* query expects. We should ignore such extra column(s)
2020+
* --- compare the behavior for composite-returning
2021+
* functions, in the RTE_FUNCTION case below.
2022+
*/
2023+
if (!aliasp_item)
2024+
break;
2025+
20152026
if (colnames)
20162027
{
2017-
/* Assume there is one alias per target item */
20182028
char *label = strVal(lfirst(aliasp_item));
20192029

20202030
*colnames = lappend(*colnames, makeString(pstrdup(label)));
2021-
aliasp_item = lnext(aliasp_item);
20222031
}
20232032

20242033
if (colvars)
@@ -2034,6 +2043,8 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
20342043

20352044
*colvars = lappend(*colvars, varnode);
20362045
}
2046+
2047+
aliasp_item = lnext(aliasp_item);
20372048
}
20382049
}
20392050
break;

src/backend/utils/misc/guc.c

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ bool default_with_oids = false;
425425
bool SQL_inheritance = true;
426426

427427
bool Password_encryption = true;
428+
bool session_auth_is_superuser;
428429

429430
int log_min_error_statement = ERROR;
430431
int log_min_messages = WARNING;
@@ -471,7 +472,6 @@ int huge_pages;
471472
* and is kept in sync by assign_hooks.
472473
*/
473474
static char *syslog_ident_str;
474-
static bool session_auth_is_superuser;
475475
static double phony_random_seed;
476476
static char *client_encoding_string;
477477
static char *datestyle_string;
@@ -8884,12 +8884,18 @@ read_nondefault_variables(void)
88848884
* constants; a few, like server_encoding and lc_ctype, are handled specially
88858885
* outside the serialize/restore procedure. Therefore, SerializeGUCState()
88868886
* never sends these, and RestoreGUCState() never changes them.
8887+
*
8888+
* Role is a special variable in the sense that its current value can be an
8889+
* invalid value and there are multiple ways by which that can happen (like
8890+
* after setting the role, someone drops it). So we handle it outside of
8891+
* serialize/restore machinery.
88878892
*/
88888893
static bool
88898894
can_skip_gucvar(struct config_generic * gconf)
88908895
{
88918896
return gconf->context == PGC_POSTMASTER ||
8892-
gconf->context == PGC_INTERNAL || gconf->source == PGC_S_DEFAULT;
8897+
gconf->context == PGC_INTERNAL || gconf->source == PGC_S_DEFAULT ||
8898+
strcmp(gconf->name, "role") == 0;
88938899
}
88948900

88958901
/*
@@ -9150,27 +9156,14 @@ SerializeGUCState(Size maxsize, char *start_address)
91509156
Size actual_size;
91519157
Size bytes_left;
91529158
int i;
9153-
int i_role = -1;
91549159

91559160
/* Reserve space for saving the actual size of the guc state */
91569161
Assert(maxsize > sizeof(actual_size));
91579162
curptr = start_address + sizeof(actual_size);
91589163
bytes_left = maxsize - sizeof(actual_size);
91599164

91609165
for (i = 0; i < num_guc_variables; i++)
9161-
{
9162-
/*
9163-
* It's pretty ugly, but we've got to force "role" to be initialized
9164-
* after "session_authorization"; otherwise, the latter will override
9165-
* the former.
9166-
*/
9167-
if (strcmp(guc_variables[i]->name, "role") == 0)
9168-
i_role = i;
9169-
else
9170-
serialize_variable(&curptr, &bytes_left, guc_variables[i]);
9171-
}
9172-
if (i_role >= 0)
9173-
serialize_variable(&curptr, &bytes_left, guc_variables[i_role]);
9166+
serialize_variable(&curptr, &bytes_left, guc_variables[i]);
91749167

91759168
/* Store actual size without assuming alignment of start_address. */
91769169
actual_size = maxsize - bytes_left - sizeof(actual_size);

src/include/nodes/execnodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,8 @@ typedef struct EState
424424
HeapTuple *es_epqTuple; /* array of EPQ substitute tuples */
425425
bool *es_epqTupleSet; /* true if EPQ tuple is provided */
426426
bool *es_epqScanDone; /* true if EPQ tuple has been fetched */
427+
428+
bool es_use_parallel_mode; /* can we use parallel workers? */
427429
} EState;
428430

429431

src/include/utils/guc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ extern bool log_btree_build_stats;
245245
extern PGDLLIMPORT bool check_function_bodies;
246246
extern bool default_with_oids;
247247
extern bool SQL_inheritance;
248+
extern bool session_auth_is_superuser;
248249

249250
extern int log_min_error_statement;
250251
extern int log_min_messages;

0 commit comments

Comments
 (0)