Skip to content

Commit 41c26a7

Browse files
committed
Merge remote-tracking branch 'pg/master' into fast2pc
2 parents a3c8f1d + cbb2a81 commit 41c26a7

File tree

37 files changed

+1020
-841
lines changed

37 files changed

+1020
-841
lines changed

contrib/bloom/blinsert.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ flushCachedPage(Relation index, BloomBuildState *buildstate)
4949
GenericXLogState *state;
5050

5151
state = GenericXLogStart(index);
52-
page = GenericXLogRegister(state, buffer, true);
52+
page = GenericXLogRegisterBuffer(state, buffer, GENERIC_XLOG_FULL_IMAGE);
5353
memcpy(page, buildstate->data, BLCKSZ);
5454
GenericXLogFinish(state);
5555
UnlockReleaseBuffer(buffer);
@@ -221,7 +221,7 @@ blinsert(Relation index, Datum *values, bool *isnull,
221221
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
222222

223223
state = GenericXLogStart(index);
224-
page = GenericXLogRegister(state, buffer, false);
224+
page = GenericXLogRegisterBuffer(state, buffer, 0);
225225

226226
if (BloomPageAddItem(&blstate, page, itup))
227227
{
@@ -268,7 +268,7 @@ blinsert(Relation index, Datum *values, bool *isnull,
268268
state = GenericXLogStart(index);
269269

270270
/* get modifiable copy of metapage */
271-
metaPage = GenericXLogRegister(state, metaBuffer, false);
271+
metaPage = GenericXLogRegisterBuffer(state, metaBuffer, 0);
272272
metaData = BloomPageGetMeta(metaPage);
273273

274274
if (nStart >= metaData->nEnd)
@@ -279,7 +279,7 @@ blinsert(Relation index, Datum *values, bool *isnull,
279279

280280
buffer = ReadBuffer(index, blkno);
281281
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
282-
page = GenericXLogRegister(state, buffer, false);
282+
page = GenericXLogRegisterBuffer(state, buffer, 0);
283283

284284
if (BloomPageAddItem(&blstate, page, itup))
285285
{
@@ -305,7 +305,7 @@ blinsert(Relation index, Datum *values, bool *isnull,
305305
*/
306306
buffer = BloomNewBuffer(index);
307307

308-
page = GenericXLogRegister(state, buffer, true);
308+
page = GenericXLogRegisterBuffer(state, buffer, GENERIC_XLOG_FULL_IMAGE);
309309
BloomInitPage(page, 0);
310310

311311
if (!BloomPageAddItem(&blstate, page, itup))

contrib/bloom/bloom.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,13 @@
3131
/* Opaque for bloom pages */
3232
typedef struct BloomPageOpaqueData
3333
{
34-
OffsetNumber maxoff;
35-
uint16 flags;
34+
OffsetNumber maxoff; /* number of index tuples on page */
35+
uint16 flags; /* see bit definitions below */
36+
uint16 unused; /* placeholder to force maxaligning of size
37+
* of BloomPageOpaqueData and to place
38+
* bloom_page_id exactly at the end of page
39+
*/
40+
uint16 bloom_page_id; /* for identification of BLOOM indexes */
3641
} BloomPageOpaqueData;
3742

3843
typedef BloomPageOpaqueData *BloomPageOpaque;
@@ -41,6 +46,16 @@ typedef BloomPageOpaqueData *BloomPageOpaque;
4146
#define BLOOM_META (1<<0)
4247
#define BLOOM_DELETED (2<<0)
4348

49+
/*
50+
* The page ID is for the convenience of pg_filedump and similar utilities,
51+
* which otherwise would have a hard time telling pages of different index
52+
* types apart. It should be the last 2 bytes on the page. This is more or
53+
* less "free" due to alignment considerations.
54+
*
55+
* See comments above GinPageOpaqueData.
56+
*/
57+
#define BLOOM_PAGE_ID 0xFF83
58+
4459
/* Macros for accessing bloom page structures */
4560
#define BloomPageGetOpaque(page) ((BloomPageOpaque) PageGetSpecialPointer(page))
4661
#define BloomPageGetMaxOffset(page) (BloomPageGetOpaque(page)->maxoff)

contrib/bloom/blutils.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ PG_FUNCTION_INFO_V1(blhandler);
3939
/* Kind of relation optioms for bloom index */
4040
static relopt_kind bl_relopt_kind;
4141

42-
static int32 myRand();
42+
static int32 myRand(void);
4343
static void mySrand(uint32 seed);
4444

4545
/*
@@ -173,15 +173,16 @@ initBloomState(BloomState *state, Relation index)
173173
static int32 next;
174174

175175
static int32
176-
myRand()
176+
myRand(void)
177177
{
178-
/*
178+
/*----------
179179
* Compute x = (7^5 * x) mod (2^31 - 1)
180180
* without overflowing 31 bits:
181181
* (2^31 - 1) = 127773 * (7^5) + 2836
182182
* From "Random number generators: good ones are hard to find",
183183
* Park and Miller, Communications of the ACM, vol. 31, no. 10,
184184
* October 1988, p. 1195.
185+
*----------
185186
*/
186187
int32 hi, lo, x;
187188

@@ -359,6 +360,7 @@ BloomInitPage(Page page, uint16 flags)
359360
opaque = BloomPageGetOpaque(page);
360361
memset(opaque, 0, sizeof(BloomPageOpaqueData));
361362
opaque->flags = flags;
363+
opaque->bloom_page_id = BLOOM_PAGE_ID;
362364
}
363365

364366
/*
@@ -417,7 +419,7 @@ BloomInitMetapage(Relation index)
417419

418420
/* Initialize contents of meta page */
419421
state = GenericXLogStart(index);
420-
metaPage = GenericXLogRegister(state, metaBuffer, true);
422+
metaPage = GenericXLogRegisterBuffer(state, metaBuffer, GENERIC_XLOG_FULL_IMAGE);
421423

422424
BloomInitPage(metaPage, BLOOM_META);
423425
metadata = BloomPageGetMeta(metaPage);

contrib/bloom/blvacuum.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ blbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
6565

6666
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
6767
gxlogState = GenericXLogStart(index);
68-
page = GenericXLogRegister(gxlogState, buffer, false);
68+
page = GenericXLogRegisterBuffer(gxlogState, buffer, 0);
6969

7070
if (BloomPageIsDeleted(page))
7171
{
@@ -145,7 +145,7 @@ blbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
145145
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
146146

147147
gxlogState = GenericXLogStart(index);
148-
page = GenericXLogRegister(gxlogState, buffer, false);
148+
page = GenericXLogRegisterBuffer(gxlogState, buffer, 0);
149149

150150
metaData = BloomPageGetMeta(page);
151151
memcpy(metaData->notFullPage, notFullPage, sizeof(BlockNumber) * countPage);

doc/src/sgml/generic-wal.sgml

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,18 @@
3131

3232
<listitem>
3333
<para>
34-
<function>page = GenericXLogRegister(state, buffer, isNew)</> &mdash;
35-
register a buffer to be modified within the current generic WAL
34+
<function>page = GenericXLogRegisterBuffer(state, buffer, flags)</>
35+
&mdash; register a buffer to be modified within the current generic WAL
3636
record. This function returns a pointer to a temporary copy of the
3737
buffer's page, where modifications should be made. (Do not modify the
38-
buffer's contents directly.) The third argument indicates if the page
39-
is new; if true, this will result in a full-page image rather than a
40-
delta update being included in the WAL record.
41-
<function>GenericXLogRegister</> can be repeated if the WAL-logged
42-
action needs to modify multiple pages.
38+
buffer's contents directly.) The third argument is a bitmask of flags
39+
applicable to the operation. Currently the only such flag is
40+
<literal>GENERIC_XLOG_FULL_IMAGE</>, which indicates that a full-page
41+
image rather than a delta update should be included in the WAL record.
42+
Typically this flag would be set if the page is new or has been
43+
rewritten completely.
44+
<function>GenericXLogRegisterBuffer</> can be repeated if the
45+
WAL-logged action needs to modify multiple pages.
4346
</para>
4447
</listitem>
4548

@@ -71,13 +74,13 @@
7174
<itemizedlist>
7275
<listitem>
7376
<para>
74-
No direct modifications of buffers are allowed! All modifications
75-
must be done in copies acquired from <function>GenericXLogRegister()</>.
77+
No direct modifications of buffers are allowed! All modifications must
78+
be done in copies acquired from <function>GenericXLogRegisterBuffer()</>.
7679
In other words, code that makes generic WAL records should never call
7780
<function>BufferGetPage()</> for itself. However, it remains the
7881
caller's responsibility to pin/unpin and lock/unlock the buffers at
7982
appropriate times. Exclusive lock must be held on each target buffer
80-
from before <function>GenericXLogRegister()</> until after
83+
from before <function>GenericXLogRegisterBuffer()</> until after
8184
<function>GenericXLogFinish()</>.
8285
</para>
8386
</listitem>
@@ -145,10 +148,11 @@
145148

146149
<listitem>
147150
<para>
148-
If a registered buffer is not new, the generic WAL record contains
149-
a delta between the old and the new page images. This delta is based
150-
on byte-by-byte comparison. This is not very compact for the case of
151-
moving data within a page, and might be improved in the future.
151+
If <literal>GENERIC_XLOG_FULL_IMAGE</> is not specified for a
152+
registered buffer, the generic WAL record contains a delta between
153+
the old and the new page images. This delta is based on byte-by-byte
154+
comparison. This is not very compact for the case of moving data
155+
within a page, and might be improved in the future.
152156
</para>
153157
</listitem>
154158
</itemizedlist>

src/backend/access/rmgrdesc/genericdesc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* rmgr descriptor routines for access/transam/generic_xlog.c
55
*
66
*
7-
* Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
7+
* Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* src/backend/access/rmgrdesc/genericdesc.c

src/backend/access/transam/generic_xlog.c

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
typedef struct
5151
{
5252
Buffer buffer; /* registered buffer */
53-
bool fullImage; /* are we taking a full image of this page? */
53+
int flags; /* flags for this buffer */
5454
int deltaLen; /* space consumed in delta field */
5555
char image[BLCKSZ]; /* copy of page image for modification */
5656
char delta[MAX_DELTA_SIZE]; /* delta between page images */
@@ -280,9 +280,11 @@ GenericXLogStart(Relation relation)
280280
* is what the caller should modify.
281281
*
282282
* If the buffer is already registered, just return its existing entry.
283+
* (It's not very clear what to do with the flags in such a case, but
284+
* for now we stay with the original flags.)
283285
*/
284286
Page
285-
GenericXLogRegister(GenericXLogState *state, Buffer buffer, bool isNew)
287+
GenericXLogRegisterBuffer(GenericXLogState *state, Buffer buffer, int flags)
286288
{
287289
int block_id;
288290

@@ -295,7 +297,7 @@ GenericXLogRegister(GenericXLogState *state, Buffer buffer, bool isNew)
295297
{
296298
/* Empty slot, so use it (there cannot be a match later) */
297299
page->buffer = buffer;
298-
page->fullImage = isNew;
300+
page->flags = flags;
299301
memcpy(page->image,
300302
BufferGetPage(buffer, NULL, NULL, BGP_NO_SNAPSHOT_TEST),
301303
BLCKSZ);
@@ -338,17 +340,31 @@ GenericXLogFinish(GenericXLogState *state)
338340
{
339341
PageData *pageData = &state->pages[i];
340342
Page page;
343+
PageHeader pageHeader;
341344

342345
if (BufferIsInvalid(pageData->buffer))
343346
continue;
344347

345348
page = BufferGetPage(pageData->buffer, NULL, NULL,
346349
BGP_NO_SNAPSHOT_TEST);
350+
pageHeader = (PageHeader) pageData->image;
347351

348-
if (pageData->fullImage)
352+
if (pageData->flags & GENERIC_XLOG_FULL_IMAGE)
349353
{
350-
/* A full page image does not require anything special */
351-
memcpy(page, pageData->image, BLCKSZ);
354+
/*
355+
* A full-page image does not require us to supply any xlog
356+
* data. Just apply the image, being careful to zero the
357+
* "hole" between pd_lower and pd_upper in order to avoid
358+
* divergence between actual page state and what replay would
359+
* produce.
360+
*/
361+
memcpy(page, pageData->image, pageHeader->pd_lower);
362+
memset(page + pageHeader->pd_lower, 0,
363+
pageHeader->pd_upper - pageHeader->pd_lower);
364+
memcpy(page + pageHeader->pd_upper,
365+
pageData->image + pageHeader->pd_upper,
366+
BLCKSZ - pageHeader->pd_upper);
367+
352368
XLogRegisterBuffer(i, pageData->buffer,
353369
REGBUF_FORCE_IMAGE | REGBUF_STANDARD);
354370
}
@@ -359,7 +375,15 @@ GenericXLogFinish(GenericXLogState *state)
359375
* associated with this page.
360376
*/
361377
computeDelta(pageData, page, (Page) pageData->image);
362-
memcpy(page, pageData->image, BLCKSZ);
378+
379+
/* Apply the image, with zeroed "hole" as above */
380+
memcpy(page, pageData->image, pageHeader->pd_lower);
381+
memset(page + pageHeader->pd_lower, 0,
382+
pageHeader->pd_upper - pageHeader->pd_lower);
383+
memcpy(page + pageHeader->pd_upper,
384+
pageData->image + pageHeader->pd_upper,
385+
BLCKSZ - pageHeader->pd_upper);
386+
363387
XLogRegisterBuffer(i, pageData->buffer, REGBUF_STANDARD);
364388
XLogRegisterBufData(i, pageData->delta, pageData->deltaLen);
365389
}
@@ -395,6 +419,7 @@ GenericXLogFinish(GenericXLogState *state)
395419
BGP_NO_SNAPSHOT_TEST),
396420
pageData->image,
397421
BLCKSZ);
422+
/* We don't worry about zeroing the "hole" in this case */
398423
MarkBufferDirty(pageData->buffer);
399424
}
400425
END_CRIT_SECTION();
@@ -473,6 +498,7 @@ generic_redo(XLogReaderState *record)
473498
if (action == BLK_NEEDS_REDO)
474499
{
475500
Page page;
501+
PageHeader pageHeader;
476502
char *blockDelta;
477503
Size blockDeltaSize;
478504

@@ -481,6 +507,16 @@ generic_redo(XLogReaderState *record)
481507
blockDelta = XLogRecGetBlockData(record, block_id, &blockDeltaSize);
482508
applyPageRedo(page, blockDelta, blockDeltaSize);
483509

510+
/*
511+
* Since the delta contains no information about what's in the
512+
* "hole" between pd_lower and pd_upper, set that to zero to
513+
* ensure we produce the same page state that application of the
514+
* logged action by GenericXLogFinish did.
515+
*/
516+
pageHeader = (PageHeader) page;
517+
memset(page + pageHeader->pd_lower, 0,
518+
pageHeader->pd_upper - pageHeader->pd_lower);
519+
484520
PageSetLSN(page, lsn);
485521
MarkBufferDirty(buffers[block_id]);
486522
}

src/backend/executor/spi.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2217,15 +2217,23 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
22172217
*/
22182218
if (IsA(stmt, CreateTableAsStmt))
22192219
{
2220-
Assert(strncmp(completionTag, "SELECT ", 7) == 0);
2221-
_SPI_current->processed = pg_strtouint64(completionTag + 7,
2222-
NULL, 10);
2220+
CreateTableAsStmt *ctastmt = (CreateTableAsStmt *) stmt;
2221+
2222+
if (strncmp(completionTag, "SELECT ", 7) == 0)
2223+
_SPI_current->processed =
2224+
pg_strtouint64(completionTag + 7, NULL, 10);
2225+
else
2226+
{
2227+
/* Must be an IF NOT EXISTS that did nothing */
2228+
Assert(ctastmt->if_not_exists);
2229+
_SPI_current->processed = 0;
2230+
}
22232231

22242232
/*
22252233
* For historical reasons, if CREATE TABLE AS was spelled
22262234
* as SELECT INTO, return a special return code.
22272235
*/
2228-
if (((CreateTableAsStmt *) stmt)->is_select_into)
2236+
if (ctastmt->is_select_into)
22292237
res = SPI_OK_SELINTO;
22302238
}
22312239
else if (IsA(stmt, CopyStmt))

src/backend/foreign/foreign.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ GetUserMapping(Oid userid, Oid serverid)
253253
*
254254
* If missing_ok is true, the function returns InvalidOid when it does not find
255255
* required user mapping. Otherwise, find_user_mapping() throws error if it
256-
* does not find required user mapping.
256+
* does not find required user mapping.
257257
*/
258258
Oid
259259
GetUserMappingId(Oid userid, Oid serverid, bool missing_ok)

src/backend/nodes/extensible.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ typedef struct
3333
} ExtensibleNodeEntry;
3434

3535
/*
36-
* An internal function to register a new callback structure
36+
* An internal function to register a new callback structure
3737
*/
3838
static void
3939
RegisterExtensibleNodeEntry(HTAB **p_htable, const char *htable_label,

0 commit comments

Comments
 (0)