Skip to content

Commit 84eb0c5

Browse files
committed
Merge branch 'REL9_5_STABLE' into PGPRO9_5
Conflicts: doc/src/sgml/installation.sgml src/Makefile
2 parents 6fb3e6d + 025c9a7 commit 84eb0c5

File tree

16 files changed

+152
-55
lines changed

16 files changed

+152
-55
lines changed

doc/src/sgml/func.sgml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8037,12 +8037,12 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
80378037
<row>
80388038
<entry> <literal>#</literal> </entry>
80398039
<entry>Point or box of intersection</entry>
8040-
<entry><literal>'((1,-1),(-1,1))' # '((1,1),(-1,-1))'</literal></entry>
8040+
<entry><literal>box '((1,-1),(-1,1))' # box '((1,1),(-2,-2))'</literal></entry>
80418041
</row>
80428042
<row>
80438043
<entry> <literal>#</literal> </entry>
80448044
<entry>Number of points in path or polygon</entry>
8045-
<entry><literal># '((1,0),(0,1),(-1,0))'</literal></entry>
8045+
<entry><literal># path '((1,0),(0,1),(-1,0))'</literal></entry>
80468046
</row>
80478047
<row>
80488048
<entry> <literal>@-@</literal> </entry>

doc/src/sgml/installation.sgml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,7 +1474,7 @@ su - postgres
14741474
will take a few minutes depending on your
14751475
hardware. The last line displayed should be:
14761476
<screen>
1477-
All of &productname; is successfully made. Ready to install.
1477+
All of &productname; successfully made. Ready to install.
14781478
</screen>
14791479
</para>
14801480

@@ -1487,7 +1487,7 @@ All of &productname; is successfully made. Ready to install.
14871487
</screen>
14881488
The last line displayed should be:
14891489
<screen>
1490-
&productname;, contrib and HTML documentation successfully made. Ready to install.
1490+
&productname;, contrib, and documentation successfully made. Ready to install.
14911491
</screen>
14921492
</para>
14931493
</step>

doc/src/sgml/ref/alter_user_mapping.sgml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ ALTER USER MAPPING FOR { <replaceable class="parameter">user_name</replaceable>
8989
<title>Examples</title>
9090

9191
<para>
92-
Change the password for user mapping <literal>bob</>, server<literal> foo</>:
92+
Change the password for user mapping <literal>bob</>, server <literal>foo</>:
9393
<programlisting>
94-
ALTER USER MAPPING FOR bob SERVER foo OPTIONS (user 'bob', password 'public');
94+
ALTER USER MAPPING FOR bob SERVER foo OPTIONS (SET password 'public');
9595
</programlisting></para>
9696

9797
</refsect1>

src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ SUBDIRS = \
2626
pl \
2727
makefiles \
2828
test/regress \
29+
test/perl \
2930
pgpro-upgrade
3031

3132
# There are too many interdependencies between the subdirectories, so

src/backend/access/gist/gistscan.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ gistrescan(PG_FUNCTION_ARGS)
126126
* which is created on the second call and reset on later calls. Thus, in
127127
* the common case where a scan is only rescan'd once, we just put the
128128
* queue in scanCxt and don't pay the overhead of making a second memory
129-
* context. If we do rescan more than once, the first RBTree is just left
129+
* context. If we do rescan more than once, the first queue is just left
130130
* for dead until end of scan; this small wastage seems worth the savings
131131
* in the common case.
132132
*/
@@ -186,7 +186,7 @@ gistrescan(PG_FUNCTION_ARGS)
186186
ALLOCSET_DEFAULT_MAXSIZE);
187187
}
188188

189-
/* create new, empty RBTree for search queue */
189+
/* create new, empty pairing heap for search queue */
190190
oldCxt = MemoryContextSwitchTo(so->queueCxt);
191191
so->queue = pairingheap_allocate(pairingheap_GISTSearchItem_cmp, scan);
192192
MemoryContextSwitchTo(oldCxt);

src/backend/executor/nodeCtescan.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,13 @@ ExecInitCteScan(CteScan *node, EState *estate, int eflags)
224224
{
225225
/* Not the leader */
226226
Assert(IsA(scanstate->leader, CteScanState));
227+
/* Create my own read pointer, and ensure it is at start */
227228
scanstate->readptr =
228229
tuplestore_alloc_read_pointer(scanstate->leader->cte_table,
229230
scanstate->eflags);
231+
tuplestore_select_read_pointer(scanstate->leader->cte_table,
232+
scanstate->readptr);
233+
tuplestore_rescan(scanstate->leader->cte_table);
230234
}
231235

232236
/*

src/backend/postmaster/postmaster.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,16 @@ PostmasterMain(int argc, char *argv[])
569569
*/
570570
umask(S_IRWXG | S_IRWXO);
571571

572+
/*
573+
* Initialize random(3) so we don't get the same values in every run.
574+
*
575+
* Note: the seed is pretty predictable from externally-visible facts such
576+
* as postmaster start time, so avoid using random() for security-critical
577+
* random values during postmaster startup. At the time of first
578+
* connection, PostmasterRandom will select a hopefully-more-random seed.
579+
*/
580+
srandom((unsigned int) (MyProcPid ^ MyStartTime));
581+
572582
/*
573583
* By default, palloc() requests in the postmaster will be allocated in
574584
* the PostmasterContext, which is space that can be recycled by backends.
@@ -5076,6 +5086,10 @@ RandomSalt(char *md5Salt)
50765086

50775087
/*
50785088
* PostmasterRandom
5089+
*
5090+
* Caution: use this only for values needed during connection-request
5091+
* processing. Otherwise, the intended property of having an unpredictable
5092+
* delay between random_start_time and random_stop_time will be broken.
50795093
*/
50805094
static long
50815095
PostmasterRandom(void)

src/backend/storage/ipc/dsm_impl.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size,
671671
{
672672
DWORD size_high;
673673
DWORD size_low;
674+
DWORD errcode;
674675

675676
/* Shifts >= the width of the type are undefined. */
676677
#ifdef _WIN64
@@ -680,33 +681,40 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size,
680681
#endif
681682
size_low = (DWORD) request_size;
682683

684+
/* CreateFileMapping might not clear the error code on success */
685+
SetLastError(0);
686+
683687
hmap = CreateFileMapping(INVALID_HANDLE_VALUE, /* Use the pagefile */
684688
NULL, /* Default security attrs */
685689
PAGE_READWRITE, /* Memory is read/write */
686690
size_high, /* Upper 32 bits of size */
687691
size_low, /* Lower 32 bits of size */
688692
name);
693+
694+
errcode = GetLastError();
695+
if (errcode == ERROR_ALREADY_EXISTS || errcode == ERROR_ACCESS_DENIED)
696+
{
697+
/*
698+
* On Windows, when the segment already exists, a handle for the
699+
* existing segment is returned. We must close it before
700+
* returning. However, if the existing segment is created by a
701+
* service, then it returns ERROR_ACCESS_DENIED. We don't do
702+
* _dosmaperr here, so errno won't be modified.
703+
*/
704+
if (hmap)
705+
CloseHandle(hmap);
706+
return false;
707+
}
708+
689709
if (!hmap)
690710
{
691-
_dosmaperr(GetLastError());
711+
_dosmaperr(errcode);
692712
ereport(elevel,
693713
(errcode_for_dynamic_shared_memory(),
694714
errmsg("could not create shared memory segment \"%s\": %m",
695715
name)));
696716
return false;
697717
}
698-
_dosmaperr(GetLastError());
699-
if (errno == EEXIST)
700-
{
701-
/*
702-
* On Windows, when the segment already exists, a handle for the
703-
* existing segment is returned. We must close it before
704-
* returning. We don't do _dosmaperr here, so errno won't be
705-
* modified.
706-
*/
707-
CloseHandle(hmap);
708-
return false;
709-
}
710718
}
711719
else
712720
{

src/bin/pg_dump/pg_dump.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4481,19 +4481,22 @@ getFuncs(Archive *fout, int *numFuncs)
44814481
selectSourceSchema(fout, "pg_catalog");
44824482

44834483
/*
4484-
* Find all user-defined functions. Normally we can exclude functions in
4485-
* pg_catalog, which is worth doing since there are several thousand of
4486-
* 'em. However, there are some extensions that create functions in
4487-
* pg_catalog. In normal dumps we can still ignore those --- but in
4488-
* binary-upgrade mode, we must dump the member objects of the extension,
4489-
* so be sure to fetch any such functions.
4484+
* Find all interesting functions. This is a bit complicated:
44904485
*
4491-
* Also, in 9.2 and up, exclude functions that are internally dependent on
4492-
* something else, since presumably those will be created as a result of
4493-
* creating the something else. This currently only acts to suppress
4494-
* constructor functions for range types. Note that this is OK only
4495-
* because the constructors don't have any dependencies the range type
4496-
* doesn't have; otherwise we might not get creation ordering correct.
4486+
* 1. Always exclude aggregates; those are handled elsewhere.
4487+
*
4488+
* 2. Always exclude functions that are internally dependent on something
4489+
* else, since presumably those will be created as a result of creating
4490+
* the something else. This currently acts only to suppress constructor
4491+
* functions for range types (so we only need it in 9.2 and up). Note
4492+
* this is OK only because the constructors don't have any dependencies
4493+
* the range type doesn't have; otherwise we might not get creation
4494+
* ordering correct.
4495+
*
4496+
* 3. Otherwise, we normally exclude functions in pg_catalog. However, if
4497+
* they're members of extensions and we are in binary-upgrade mode then
4498+
* include them, since we want to dump extension members individually in
4499+
* that mode.
44974500
*/
44984501

44994502
if (fout->remoteVersion >= 70300)
@@ -4504,16 +4507,18 @@ getFuncs(Archive *fout, int *numFuncs)
45044507
"pronamespace, "
45054508
"(%s proowner) AS rolname "
45064509
"FROM pg_proc p "
4507-
"WHERE NOT proisagg AND ("
4508-
"pronamespace != "
4509-
"(SELECT oid FROM pg_namespace "
4510-
"WHERE nspname = 'pg_catalog')",
4510+
"WHERE NOT proisagg",
45114511
username_subquery);
45124512
if (fout->remoteVersion >= 90200)
45134513
appendPQExpBufferStr(query,
45144514
"\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
45154515
"WHERE classid = 'pg_proc'::regclass AND "
45164516
"objid = p.oid AND deptype = 'i')");
4517+
appendPQExpBufferStr(query,
4518+
"\n AND ("
4519+
"\n pronamespace != "
4520+
"(SELECT oid FROM pg_namespace "
4521+
"WHERE nspname = 'pg_catalog')");
45174522
if (dopt->binary_upgrade && fout->remoteVersion >= 90100)
45184523
appendPQExpBufferStr(query,
45194524
"\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "

src/bin/pgbench/pgbench.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ typedef struct
219219
Variable *variables; /* array of variable definitions */
220220
int nvariables;
221221
int64 txn_scheduled; /* scheduled start time of transaction (usec) */
222+
int64 sleep_until; /* scheduled start time of next cmd (usec) */
222223
instr_time txn_begin; /* used for measuring schedule lag times */
223224
instr_time stmt_begin; /* used for measuring statement latencies */
224225
int64 txn_latencies; /* cumulated latencies */
@@ -1238,6 +1239,7 @@ doCustom(TState *thread, CState *st, instr_time *conn_time, FILE *logfile, AggVa
12381239
}
12391240
}
12401241

1242+
st->sleep_until = st->txn_scheduled;
12411243
st->sleeping = 1;
12421244
st->throttling = true;
12431245
st->is_throttled = true;
@@ -1253,7 +1255,7 @@ doCustom(TState *thread, CState *st, instr_time *conn_time, FILE *logfile, AggVa
12531255
if (INSTR_TIME_IS_ZERO(now))
12541256
INSTR_TIME_SET_CURRENT(now);
12551257
now_us = INSTR_TIME_GET_MICROSEC(now);
1256-
if (st->txn_scheduled <= now_us)
1258+
if (st->sleep_until <= now_us)
12571259
{
12581260
st->sleeping = 0; /* Done sleeping, go ahead with next command */
12591261
if (st->throttling)
@@ -1721,7 +1723,7 @@ doCustom(TState *thread, CState *st, instr_time *conn_time, FILE *logfile, AggVa
17211723
usec *= 1000000;
17221724

17231725
INSTR_TIME_SET_CURRENT(now);
1724-
st->txn_scheduled = INSTR_TIME_GET_MICROSEC(now) + usec;
1726+
st->sleep_until = INSTR_TIME_GET_MICROSEC(now) + usec;
17251727
st->sleeping = 1;
17261728

17271729
st->listen = 1;
@@ -2734,9 +2736,9 @@ printResults(int ttype, int64 normal_xacts, int nclients,
27342736
}
27352737
else
27362738
{
2737-
/* only an average latency computed from the duration is available */
2739+
/* no measurement, show average latency computed from run time */
27382740
printf("latency average: %.3f ms\n",
2739-
1000.0 * duration * nclients / normal_xacts);
2741+
1000.0 * time_include * nclients / normal_xacts);
27402742
}
27412743

27422744
if (throttle_delay)

src/include/access/gist_private.h

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,11 @@ typedef struct GISTSTATE
105105
* upper index pages; this rule avoids doing extra work during a search that
106106
* ends early due to LIMIT.
107107
*
108-
* To perform an ordered search, we use an RBTree to manage the distance-order
109-
* queue. Each GISTSearchTreeItem stores all unvisited items of the same
110-
* distance; they are GISTSearchItems chained together via their next fields.
111-
*
112-
* In a non-ordered search (no order-by operators), the RBTree degenerates
113-
* to a single item, which we use as a queue of unvisited index pages only.
114-
* In this case matched heap items from the current index leaf page are
115-
* remembered in GISTScanOpaqueData.pageData[] and returned directly from
116-
* there, instead of building a separate GISTSearchItem for each one.
108+
* To perform an ordered search, we use a pairing heap to manage the
109+
* distance-order queue. In a non-ordered search (no order-by operators),
110+
* we use it to return heap tuples before unvisited index pages, to
111+
* ensure depth-first order, but all entries are otherwise considered
112+
* equal.
117113
*/
118114

119115
/* Individual heap tuple to be visited */
@@ -288,8 +284,8 @@ typedef struct
288284
#define GIST_ROOT_BLKNO 0
289285

290286
/*
291-
* Before PostgreSQL 9.1, we used rely on so-called "invalid tuples" on inner
292-
* pages to finish crash recovery of incomplete page splits. If a crash
287+
* Before PostgreSQL 9.1, we used to rely on so-called "invalid tuples" on
288+
* inner pages to finish crash recovery of incomplete page splits. If a crash
293289
* happened in the middle of a page split, so that the downlink pointers were
294290
* not yet inserted, crash recovery inserted a special downlink pointer. The
295291
* semantics of an invalid tuple was that it if you encounter one in a scan,

src/test/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ subdir = src/test
1212
top_builddir = ../..
1313
include $(top_builddir)/src/Makefile.global
1414

15-
SUBDIRS = regress isolation modules
15+
SUBDIRS = perl regress isolation modules
1616

1717
# We don't build or execute examples/, locale/, or thread/ by default,
1818
# but we do want "make clean" etc to recurse into them. Likewise for ssl/,

src/test/isolation/expected/eval-plan-qual.out

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,24 @@ ta_id ta_value tb_row
163163

164164
1 newTableAValue (1,tableBValue)
165165
step c2: COMMIT;
166+
167+
starting permutation: wrtwcte readwcte c1 c2
168+
step wrtwcte: UPDATE table_a SET value = 'tableAValue2' WHERE id = 1;
169+
step readwcte:
170+
WITH
171+
cte1 AS (
172+
SELECT id FROM table_b WHERE value = 'tableBValue'
173+
),
174+
cte2 AS (
175+
SELECT * FROM table_a
176+
WHERE id = (SELECT id FROM cte1)
177+
FOR UPDATE
178+
)
179+
SELECT * FROM cte2;
180+
<waiting ...>
181+
step c1: COMMIT;
182+
step c2: COMMIT;
183+
step readwcte: <... completed>
184+
id value
185+
186+
1 tableAValue2

src/test/isolation/specs/eval-plan-qual.spec

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,27 @@ step "readforss" {
103103
FROM table_a ta
104104
WHERE ta.id = 1 FOR UPDATE OF ta;
105105
}
106+
step "wrtwcte" { UPDATE table_a SET value = 'tableAValue2' WHERE id = 1; }
106107
step "c2" { COMMIT; }
107108

108109
session "s3"
109110
setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
110111
step "read" { SELECT * FROM accounts ORDER BY accountid; }
112+
113+
# this test exercises EvalPlanQual with a CTE, cf bug #14328
114+
step "readwcte" {
115+
WITH
116+
cte1 AS (
117+
SELECT id FROM table_b WHERE value = 'tableBValue'
118+
),
119+
cte2 AS (
120+
SELECT * FROM table_a
121+
WHERE id = (SELECT id FROM cte1)
122+
FOR UPDATE
123+
)
124+
SELECT * FROM cte2;
125+
}
126+
111127
teardown { COMMIT; }
112128

113129
permutation "wx1" "wx2" "c1" "c2" "read"
@@ -118,3 +134,4 @@ permutation "writep2" "returningp1" "c1" "c2"
118134
permutation "wx2" "partiallock" "c2" "c1" "read"
119135
permutation "wx2" "lockwithvalues" "c2" "c1" "read"
120136
permutation "updateforss" "readforss" "c1" "c2"
137+
permutation "wrtwcte" "readwcte" "c1" "c2"

0 commit comments

Comments
 (0)