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;

src/test/regress/expected/alter_table.out

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2156,6 +2156,91 @@ Foreign-key constraints:
21562156
"check_fk_presence_2_id_fkey" FOREIGN KEY (id) REFERENCES check_fk_presence_1(id)
21572157

21582158
DROP TABLE check_fk_presence_1, check_fk_presence_2;
2159+
-- check column addition within a view (bug #14876)
2160+
create table at_base_table(id int, stuff text);
2161+
insert into at_base_table values (23, 'skidoo');
2162+
create view at_view_1 as select * from at_base_table bt;
2163+
create view at_view_2 as select *, to_json(v1) as j from at_view_1 v1;
2164+
\d+ at_view_1
2165+
View "public.at_view_1"
2166+
Column | Type | Modifiers | Storage | Description
2167+
--------+---------+-----------+----------+-------------
2168+
id | integer | | plain |
2169+
stuff | text | | extended |
2170+
View definition:
2171+
SELECT bt.id,
2172+
bt.stuff
2173+
FROM at_base_table bt;
2174+
2175+
\d+ at_view_2
2176+
View "public.at_view_2"
2177+
Column | Type | Modifiers | Storage | Description
2178+
--------+---------+-----------+----------+-------------
2179+
id | integer | | plain |
2180+
stuff | text | | extended |
2181+
j | json | | extended |
2182+
View definition:
2183+
SELECT v1.id,
2184+
v1.stuff,
2185+
to_json(v1.*) AS j
2186+
FROM at_view_1 v1;
2187+
2188+
explain (verbose, costs off) select * from at_view_2;
2189+
QUERY PLAN
2190+
----------------------------------------------------------
2191+
Seq Scan on public.at_base_table bt
2192+
Output: bt.id, bt.stuff, to_json(ROW(bt.id, bt.stuff))
2193+
(2 rows)
2194+
2195+
select * from at_view_2;
2196+
id | stuff | j
2197+
----+--------+----------------------------
2198+
23 | skidoo | {"id":23,"stuff":"skidoo"}
2199+
(1 row)
2200+
2201+
create or replace view at_view_1 as select *, 2+2 as more from at_base_table bt;
2202+
\d+ at_view_1
2203+
View "public.at_view_1"
2204+
Column | Type | Modifiers | Storage | Description
2205+
--------+---------+-----------+----------+-------------
2206+
id | integer | | plain |
2207+
stuff | text | | extended |
2208+
more | integer | | plain |
2209+
View definition:
2210+
SELECT bt.id,
2211+
bt.stuff,
2212+
2 + 2 AS more
2213+
FROM at_base_table bt;
2214+
2215+
\d+ at_view_2
2216+
View "public.at_view_2"
2217+
Column | Type | Modifiers | Storage | Description
2218+
--------+---------+-----------+----------+-------------
2219+
id | integer | | plain |
2220+
stuff | text | | extended |
2221+
j | json | | extended |
2222+
View definition:
2223+
SELECT v1.id,
2224+
v1.stuff,
2225+
to_json(v1.*) AS j
2226+
FROM at_view_1 v1;
2227+
2228+
explain (verbose, costs off) select * from at_view_2;
2229+
QUERY PLAN
2230+
----------------------------------------------------------------
2231+
Seq Scan on public.at_base_table bt
2232+
Output: bt.id, bt.stuff, to_json(ROW(bt.id, bt.stuff, NULL))
2233+
(2 rows)
2234+
2235+
select * from at_view_2;
2236+
id | stuff | j
2237+
----+--------+----------------------------------------
2238+
23 | skidoo | {"id":23,"stuff":"skidoo","more":null}
2239+
(1 row)
2240+
2241+
drop view at_view_2;
2242+
drop view at_view_1;
2243+
drop table at_base_table;
21592244
--
21602245
-- lock levels
21612246
--
@@ -2682,6 +2767,23 @@ Table "public.test_tbl2_subclass"
26822767
Inherits: test_tbl2
26832768

26842769
DROP TABLE test_tbl2_subclass;
2770+
CREATE TYPE test_typex AS (a int, b text);
2771+
CREATE TABLE test_tblx (x int, y test_typex check ((y).a > 0));
2772+
ALTER TYPE test_typex DROP ATTRIBUTE a; -- fails
2773+
ERROR: cannot drop composite type test_typex column a because other objects depend on it
2774+
DETAIL: constraint test_tblx_y_check on table test_tblx depends on composite type test_typex column a
2775+
HINT: Use DROP ... CASCADE to drop the dependent objects too.
2776+
ALTER TYPE test_typex DROP ATTRIBUTE a CASCADE;
2777+
NOTICE: drop cascades to constraint test_tblx_y_check on table test_tblx
2778+
\d test_tblx
2779+
Table "public.test_tblx"
2780+
Column | Type | Modifiers
2781+
--------+------------+-----------
2782+
x | integer |
2783+
y | test_typex |
2784+
2785+
DROP TABLE test_tblx;
2786+
DROP TYPE test_typex;
26852787
-- This test isn't that interesting on its own, but the purpose is to leave
26862788
-- behind a table to test pg_upgrade with. The table has a composite type
26872789
-- column in it, and the composite type has a dropped attribute.

src/test/regress/expected/select_parallel.out

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,21 @@ explain (costs off)
9999
-> Index Only Scan using tenk1_unique1 on tenk1
100100
(3 rows)
101101

102+
-- test the sanity of parallel query after the active role is dropped.
102103
set force_parallel_mode=1;
104+
drop role if exists regress_parallel_worker;
105+
NOTICE: role "regress_parallel_worker" does not exist, skipping
106+
create role regress_parallel_worker;
107+
set role regress_parallel_worker;
108+
reset session authorization;
109+
drop role regress_parallel_worker;
110+
select count(*) from tenk1;
111+
count
112+
-------
113+
10000
114+
(1 row)
115+
116+
reset role;
103117
explain (costs off)
104118
select stringu1::int2 from tenk1 where unique1 = 1;
105119
QUERY PLAN

0 commit comments

Comments
 (0)