Skip to content

Commit 5cd21bd

Browse files
committed
Merge branch 'REL9_6_STABLE' into PGPRO9_6
Conflicts: src/backend/parser/analyze.c
2 parents 49ee95f + 89d1dfa commit 5cd21bd

File tree

42 files changed

+612
-343
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+612
-343
lines changed

contrib/bloom/blinsert.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,18 @@ blbuildempty(Relation index)
164164
metapage = (Page) palloc(BLCKSZ);
165165
BloomFillMetapage(index, metapage);
166166

167-
/* Write the page. If archiving/streaming, XLOG it. */
167+
/*
168+
* Write the page and log it. It might seem that an immediate sync
169+
* would be sufficient to guarantee that the file exists on disk, but
170+
* recovery itself might remove it while replaying, for example, an
171+
* XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE record. Therefore, we
172+
* need this even when wal_level=minimal.
173+
*/
168174
PageSetChecksumInplace(metapage, BLOOM_METAPAGE_BLKNO);
169175
smgrwrite(index->rd_smgr, INIT_FORKNUM, BLOOM_METAPAGE_BLKNO,
170176
(char *) metapage, true);
171-
if (XLogIsNeeded())
172-
log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
173-
BLOOM_METAPAGE_BLKNO, metapage, false);
177+
log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
178+
BLOOM_METAPAGE_BLKNO, metapage, false);
174179

175180
/*
176181
* An immediate sync is required even if we xlog'd the page, because the

doc/src/sgml/func.sgml

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,11 +1534,12 @@
15341534
</entry>
15351535
<entry><type>text</type></entry>
15361536
<entry>
1537-
Remove the longest string containing only the
1537+
Remove the longest string containing only characters from
15381538
<parameter>characters</parameter> (a space by default) from the
1539-
start/end/both ends of the <parameter>string</parameter>
1539+
start, end, or both ends (<literal>both</> is the default)
1540+
of <parameter>string</parameter>
15401541
</entry>
1541-
<entry><literal>trim(both 'x' from 'xTomxx')</literal></entry>
1542+
<entry><literal>trim(both 'xyz' from 'yxTomxx')</literal></entry>
15421543
<entry><literal>Tom</literal></entry>
15431544
</row>
15441545

@@ -1547,14 +1548,14 @@
15471548
<literal><function>trim(<optional>leading | trailing
15481549
| both</optional> <optional>from</optional>
15491550
<parameter>string</parameter>
1550-
<optional><parameter>, characters</parameter></optional>
1551+
<optional>, <parameter>characters</parameter></optional>
15511552
)</function></literal>
15521553
</entry>
15531554
<entry><type>text</type></entry>
15541555
<entry>
1555-
Non-standard version of <function>trim()</>
1556+
Non-standard syntax for <function>trim()</>
15561557
</entry>
1557-
<entry><literal>trim(both from 'xTomxx', 'x')</literal></entry>
1558+
<entry><literal>trim(both from 'yxTomxx', 'xyz')</literal></entry>
15581559
<entry><literal>Tom</literal></entry>
15591560
</row>
15601561

@@ -1626,7 +1627,7 @@
16261627
in <parameter>characters</parameter> (a space by default)
16271628
from the start and end of <parameter>string</parameter>
16281629
</entry>
1629-
<entry><literal>btrim('xyxtrimyyx', 'xy')</literal></entry>
1630+
<entry><literal>btrim('xyxtrimyyx', 'xyz')</literal></entry>
16301631
<entry><literal>trim</literal></entry>
16311632
</row>
16321633

@@ -1895,8 +1896,8 @@
18951896
<parameter>characters</parameter> (a space by default) from the start of
18961897
<parameter>string</parameter>
18971898
</entry>
1898-
<entry><literal>ltrim('zzzytrim', 'xyz')</literal></entry>
1899-
<entry><literal>trim</literal></entry>
1899+
<entry><literal>ltrim('zzzytest', 'xyz')</literal></entry>
1900+
<entry><literal>test</literal></entry>
19001901
</row>
19011902

19021903
<row>
@@ -2201,8 +2202,8 @@
22012202
<parameter>characters</parameter> (a space by default) from the end of
22022203
<parameter>string</parameter>
22032204
</entry>
2204-
<entry><literal>rtrim('trimxxxx', 'x')</literal></entry>
2205-
<entry><literal>trim</literal></entry>
2205+
<entry><literal>rtrim('testxxzx', 'xyz')</literal></entry>
2206+
<entry><literal>test</literal></entry>
22062207
</row>
22072208

22082209
<row>
@@ -3467,11 +3468,11 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
34673468
</entry>
34683469
<entry><type>bytea</type></entry>
34693470
<entry>
3470-
Remove the longest string containing only the bytes in
3471+
Remove the longest string containing only bytes appearing in
34713472
<parameter>bytes</parameter> from the start
34723473
and end of <parameter>string</parameter>
34733474
</entry>
3474-
<entry><literal>trim(E'\\000'::bytea from E'\\000Tom\\000'::bytea)</literal></entry>
3475+
<entry><literal>trim(E'\\000\\001'::bytea from E'\\000Tom\\001'::bytea)</literal></entry>
34753476
<entry><literal>Tom</literal></entry>
34763477
</row>
34773478
</tbody>
@@ -3510,11 +3511,11 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
35103511
</entry>
35113512
<entry><type>bytea</type></entry>
35123513
<entry>
3513-
Remove the longest string consisting only of bytes
3514-
in <parameter>bytes</parameter> from the start and end of
3514+
Remove the longest string containing only bytes appearing in
3515+
<parameter>bytes</parameter> from the start and end of
35153516
<parameter>string</parameter>
35163517
</entry>
3517-
<entry><literal>btrim(E'\\000trim\\000'::bytea, E'\\000'::bytea)</literal></entry>
3518+
<entry><literal>btrim(E'\\000trim\\001'::bytea, E'\\000\\001'::bytea)</literal></entry>
35183519
<entry><literal>trim</literal></entry>
35193520
</row>
35203521

doc/src/sgml/parallel.sgml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,15 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
218218
</para>
219219
</listitem>
220220

221+
<listitem>
222+
<para>
223+
A prepared statement is executed using a <literal>CREATE TABLE .. AS
224+
EXECUTE ..</literal> statement. This construct converts what otherwise
225+
would have been a read-only operation into a read-write operation,
226+
making it ineligible for parallel query.
227+
</para>
228+
</listitem>
229+
221230
<listitem>
222231
<para>
223232
The transaction isolation level is serializable. This situation
@@ -240,7 +249,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
240249
copy of the output result set, so the query would not run any faster
241250
than normal but would produce incorrect results. Instead, the parallel
242251
portion of the plan must be what is known internally to the query
243-
optimizer as a <firstterm>partial plan</>; that is, it must constructed
252+
optimizer as a <firstterm>partial plan</>; that is, it must be constructed
244253
so that each process which executes the plan will generate only a
245254
subset of the output rows in such a way that each required output row
246255
is guaranteed to be generated by exactly one of the cooperating processes.

doc/src/sgml/ref/pg_dump.sgml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,11 @@ doc/src/sgml/ref/pg_dump.sgml
138138
<para>
139139
Include large objects in the dump. This is the default behavior
140140
except when <option>--schema</>, <option>--table</>, or
141-
<option>--schema-only</> is specified, so the <option>-b</>
142-
switch is only useful to add large objects to selective dumps.
141+
<option>--schema-only</> is specified. The <option>-b</>
142+
switch is therefore only useful to add large objects to dumps
143+
where a specific schema or table has been requested. Note that
144+
blobs are considered data and therefore will be included when
145+
--data-only is used, but not when --schema-only is.
143146
</para>
144147
</listitem>
145148
</varlistentry>

doc/src/sgml/ref/psql-ref.sgml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3798,8 +3798,9 @@ $endif
37983798
If the query results do not fit on the screen, they are piped
37993799
through this command. Typical values are
38003800
<literal>more</literal> or <literal>less</literal>. The default
3801-
is platform-dependent. The use of the pager can be disabled by
3802-
using the <command>\pset</command> command.
3801+
is platform-dependent. Use of the pager can be disabled by setting
3802+
<envar>PAGER</envar> to empty, or by using pager-related options of
3803+
the <command>\pset</command> command.
38033804
</para>
38043805
</listitem>
38053806
</varlistentry>
@@ -4170,7 +4171,7 @@ second | four
41704171
with the <command>\crosstabview</command> command:
41714172
<programlisting>
41724173
testdb=&gt; <userinput>SELECT first, second, first &gt; 2 AS gt2 FROM my_table;</userinput>
4173-
first | second | ge2
4174+
first | second | gt2
41744175
-------+--------+-----
41754176
1 | one | f
41764177
2 | two | f

src/backend/access/nbtree/nbtree.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,18 @@ btbuildempty(Relation index)
243243
metapage = (Page) palloc(BLCKSZ);
244244
_bt_initmetapage(metapage, P_NONE, 0);
245245

246-
/* Write the page. If archiving/streaming, XLOG it. */
246+
/*
247+
* Write the page and log it. It might seem that an immediate sync
248+
* would be sufficient to guarantee that the file exists on disk, but
249+
* recovery itself might remove it while replaying, for example, an
250+
* XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE record. Therefore, we
251+
* need this even when wal_level=minimal.
252+
*/
247253
PageSetChecksumInplace(metapage, BTREE_METAPAGE);
248254
smgrwrite(index->rd_smgr, INIT_FORKNUM, BTREE_METAPAGE,
249255
(char *) metapage, true);
250-
if (XLogIsNeeded())
251-
log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
252-
BTREE_METAPAGE, metapage, false);
256+
log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
257+
BTREE_METAPAGE, metapage, false);
253258

254259
/*
255260
* An immediate sync is required even if we xlog'd the page, because the

src/backend/access/rmgrdesc/gindesc.c

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,13 @@ gin_desc(StringInfo buf, XLogReaderState *record)
8787
case XLOG_GIN_INSERT:
8888
{
8989
ginxlogInsert *xlrec = (ginxlogInsert *) rec;
90-
char *payload = rec + sizeof(ginxlogInsert);
9190

9291
appendStringInfo(buf, "isdata: %c isleaf: %c",
9392
(xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
9493
(xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
9594
if (!(xlrec->flags & GIN_INSERT_ISLEAF))
9695
{
96+
char *payload = rec + sizeof(ginxlogInsert);
9797
BlockNumber leftChildBlkno;
9898
BlockNumber rightChildBlkno;
9999

@@ -104,27 +104,27 @@ gin_desc(StringInfo buf, XLogReaderState *record)
104104
appendStringInfo(buf, " children: %u/%u",
105105
leftChildBlkno, rightChildBlkno);
106106
}
107-
if (!(xlrec->flags & GIN_INSERT_ISDATA))
108-
appendStringInfo(buf, " isdelete: %c",
109-
(((ginxlogInsertEntry *) payload)->isDelete) ? 'T' : 'F');
110-
else if (xlrec->flags & GIN_INSERT_ISLEAF)
111-
{
112-
ginxlogRecompressDataLeaf *insertData =
113-
(ginxlogRecompressDataLeaf *) payload;
114-
115-
if (XLogRecHasBlockImage(record, 0))
116-
appendStringInfoString(buf, " (full page image)");
117-
else
118-
desc_recompress_leaf(buf, insertData);
119-
}
107+
if (XLogRecHasBlockImage(record, 0))
108+
appendStringInfoString(buf, " (full page image)");
120109
else
121110
{
122-
ginxlogInsertDataInternal *insertData = (ginxlogInsertDataInternal *) payload;
111+
char *payload = XLogRecGetBlockData(record, 0, NULL);
123112

124-
appendStringInfo(buf, " pitem: %u-%u/%u",
125-
PostingItemGetBlockNumber(&insertData->newitem),
126-
ItemPointerGetBlockNumber(&insertData->newitem.key),
127-
ItemPointerGetOffsetNumber(&insertData->newitem.key));
113+
if (!(xlrec->flags & GIN_INSERT_ISDATA))
114+
appendStringInfo(buf, " isdelete: %c",
115+
(((ginxlogInsertEntry *) payload)->isDelete) ? 'T' : 'F');
116+
else if (xlrec->flags & GIN_INSERT_ISLEAF)
117+
desc_recompress_leaf(buf, (ginxlogRecompressDataLeaf *) payload);
118+
else
119+
{
120+
ginxlogInsertDataInternal *insertData =
121+
(ginxlogInsertDataInternal *) payload;
122+
123+
appendStringInfo(buf, " pitem: %u-%u/%u",
124+
PostingItemGetBlockNumber(&insertData->newitem),
125+
ItemPointerGetBlockNumber(&insertData->newitem.key),
126+
ItemPointerGetOffsetNumber(&insertData->newitem.key));
127+
}
128128
}
129129
}
130130
break;
@@ -144,12 +144,15 @@ gin_desc(StringInfo buf, XLogReaderState *record)
144144
break;
145145
case XLOG_GIN_VACUUM_DATA_LEAF_PAGE:
146146
{
147-
ginxlogVacuumDataLeafPage *xlrec = (ginxlogVacuumDataLeafPage *) rec;
148-
149147
if (XLogRecHasBlockImage(record, 0))
150148
appendStringInfoString(buf, " (full page image)");
151149
else
150+
{
151+
ginxlogVacuumDataLeafPage *xlrec =
152+
(ginxlogVacuumDataLeafPage *) XLogRecGetBlockData(record, 0, NULL);
153+
152154
desc_recompress_leaf(buf, &xlrec->data);
155+
}
153156
}
154157
break;
155158
case XLOG_GIN_DELETE_PAGE:

src/backend/access/spgist/spginsert.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -161,33 +161,36 @@ spgbuildempty(Relation index)
161161
page = (Page) palloc(BLCKSZ);
162162
SpGistInitMetapage(page);
163163

164-
/* Write the page. If archiving/streaming, XLOG it. */
164+
/*
165+
* Write the page and log it unconditionally. This is important
166+
* particularly for indexes created on tablespaces and databases
167+
* whose creation happened after the last redo pointer as recovery
168+
* removes any of their existing content when the corresponding
169+
* create records are replayed.
170+
*/
165171
PageSetChecksumInplace(page, SPGIST_METAPAGE_BLKNO);
166172
smgrwrite(index->rd_smgr, INIT_FORKNUM, SPGIST_METAPAGE_BLKNO,
167173
(char *) page, true);
168-
if (XLogIsNeeded())
169-
log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
170-
SPGIST_METAPAGE_BLKNO, page, false);
174+
log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
175+
SPGIST_METAPAGE_BLKNO, page, false);
171176

172177
/* Likewise for the root page. */
173178
SpGistInitPage(page, SPGIST_LEAF);
174179

175180
PageSetChecksumInplace(page, SPGIST_ROOT_BLKNO);
176181
smgrwrite(index->rd_smgr, INIT_FORKNUM, SPGIST_ROOT_BLKNO,
177182
(char *) page, true);
178-
if (XLogIsNeeded())
179-
log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
180-
SPGIST_ROOT_BLKNO, page, true);
183+
log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
184+
SPGIST_ROOT_BLKNO, page, true);
181185

182186
/* Likewise for the null-tuples root page. */
183187
SpGistInitPage(page, SPGIST_LEAF | SPGIST_NULLS);
184188

185189
PageSetChecksumInplace(page, SPGIST_NULL_BLKNO);
186190
smgrwrite(index->rd_smgr, INIT_FORKNUM, SPGIST_NULL_BLKNO,
187191
(char *) page, true);
188-
if (XLogIsNeeded())
189-
log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
190-
SPGIST_NULL_BLKNO, page, true);
192+
log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
193+
SPGIST_NULL_BLKNO, page, true);
191194

192195
/*
193196
* An immediate sync is required even if we xlog'd the pages, because the

src/backend/catalog/heap.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,18 +1370,19 @@ heap_create_with_catalog(const char *relname,
13701370

13711371
/*
13721372
* Set up an init fork for an unlogged table so that it can be correctly
1373-
* reinitialized on restart. Since we're going to do an immediate sync, we
1374-
* only need to xlog this if archiving or streaming is enabled. And the
1375-
* immediate sync is required, because otherwise there's no guarantee that
1376-
* this will hit the disk before the next checkpoint moves the redo pointer.
1373+
* reinitialized on restart. An immediate sync is required even if the
1374+
* page has been logged, because the write did not go through
1375+
* shared_buffers and therefore a concurrent checkpoint may have moved
1376+
* the redo pointer past our xlog record. Recovery may as well remove it
1377+
* while replaying, for example, XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE
1378+
* record. Therefore, logging is necessary even if wal_level=minimal.
13771379
*/
13781380
void
13791381
heap_create_init_fork(Relation rel)
13801382
{
13811383
RelationOpenSmgr(rel);
13821384
smgrcreate(rel->rd_smgr, INIT_FORKNUM, false);
1383-
if (XLogIsNeeded())
1384-
log_smgrcreate(&rel->rd_smgr->smgr_rnode.node, INIT_FORKNUM);
1385+
log_smgrcreate(&rel->rd_smgr->smgr_rnode.node, INIT_FORKNUM);
13851386
smgrimmedsync(rel->rd_smgr, INIT_FORKNUM);
13861387
}
13871388

src/backend/commands/prepare.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString)
159159
nargs,
160160
NULL,
161161
NULL,
162-
0, /* default cursor options */
162+
CURSOR_OPT_PARALLEL_OK, /* allow parallel mode */
163163
true); /* fixed result */
164164

165165
/*

src/backend/executor/execMain.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,9 +1541,11 @@ ExecutePlan(EState *estate,
15411541

15421542
/*
15431543
* If a tuple count was supplied, we must force the plan to run without
1544-
* parallelism, because we might exit early.
1544+
* parallelism, because we might exit early. Also disable parallelism
1545+
* when writing into a relation, because no database changes are allowed
1546+
* in parallel mode.
15451547
*/
1546-
if (numberTuples)
1548+
if (numberTuples || dest->mydest == DestIntoRel)
15471549
use_parallel_mode = false;
15481550

15491551
/*

src/backend/executor/nodeGather.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ ExecGather(GatherState *node)
172172
if (pcxt->nworkers_launched > 0)
173173
{
174174
node->nreaders = 0;
175+
node->nextreader = 0;
175176
node->reader =
176177
palloc(pcxt->nworkers_launched * sizeof(TupleQueueReader *));
177178

@@ -334,6 +335,7 @@ gather_readnext(GatherState *gatherstate)
334335
CHECK_FOR_INTERRUPTS();
335336

336337
/* Attempt to read a tuple, but don't block if none is available. */
338+
Assert(gatherstate->nextreader < gatherstate->nreaders);
337339
reader = gatherstate->reader[gatherstate->nextreader];
338340
tup = TupleQueueReaderNext(reader, true, &readerdone);
339341

src/backend/optimizer/path/allpaths.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel,
537537
*/
538538
if (rte->tablesample != NULL)
539539
{
540-
Oid proparallel = func_parallel(rte->tablesample->tsmhandler);
540+
char proparallel = func_parallel(rte->tablesample->tsmhandler);
541541

542542
if (proparallel != PROPARALLEL_SAFE)
543543
return;

0 commit comments

Comments
 (0)