diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2016-05-24 21:04:23 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2016-05-24 21:04:35 -0400 |
commit | abaffa907588283f7673fc223857e6966421b8ca (patch) | |
tree | edb3fbc47e20a0b17a8a529073035c345251cb66 /contrib/bloom/blutils.c | |
parent | 2e8b4bf80473d0e4a4254b417424e79195a9ce6a (diff) | |
download | postgresql-abaffa907588283f7673fc223857e6966421b8ca.tar.gz postgresql-abaffa907588283f7673fc223857e6966421b8ca.zip |
Fix contrib/bloom to work for unlogged indexes.
blbuildempty did not do even approximately the right thing: it tried
to add a metapage to the relation's regular data fork, which already
has one at that point. It should look like the ambuildempty methods
for all the standard index types, ie, initialize a metapage image in
some transient storage and then write it directly to the init fork.
To support that, refactor BloomInitMetapage into two functions.
In passing, fix BloomInitMetapage so it doesn't leave the rd_options
field of the index's relcache entry pointing at transient storage.
I'm not sure this had any visible consequence, since nothing much
else is likely to look at a bloom index's rd_options, but it's
certainly poor practice.
Per bug #14155 from Zhou Digoal.
Report: <20160524144146.22598.42558@wrigleys.postgresql.org>
Diffstat (limited to 'contrib/bloom/blutils.c')
-rw-r--r-- | contrib/bloom/blutils.c | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/contrib/bloom/blutils.c b/contrib/bloom/blutils.c index 05dbe876143..4a5b343dd02 100644 --- a/contrib/bloom/blutils.c +++ b/contrib/bloom/blutils.c @@ -346,7 +346,7 @@ BloomNewBuffer(Relation index) } /* - * Initialize bloom page. + * Initialize any page of a bloom index. */ void BloomInitPage(Page page, uint16 flags) @@ -363,6 +363,8 @@ BloomInitPage(Page page, uint16 flags) /* * Adjust options of bloom index. + * + * This must produce default options when *opts is initially all-zero. */ static void adjustBloomOptions(BloomOptions *opts) @@ -378,7 +380,7 @@ adjustBloomOptions(BloomOptions *opts) errmsg("length of bloom signature (%d) is greater than maximum %d", opts->bloomLength, MAX_BLOOM_LENGTH))); - /* Check singnature length */ + /* Check signature length */ for (i = 0; i < INDEX_MAX_KEYS; i++) { /* @@ -393,45 +395,66 @@ adjustBloomOptions(BloomOptions *opts) } /* + * Fill in metapage for bloom index. + */ +void +BloomFillMetapage(Relation index, Page metaPage) +{ + BloomOptions *opts; + BloomMetaPageData *metadata; + + /* + * Choose the index's options. If reloptions have been assigned, use + * those, otherwise create default options by applying adjustBloomOptions + * to a zeroed chunk of memory. We apply adjustBloomOptions to existing + * reloptions too, just out of paranoia; they should be valid already. + */ + opts = (BloomOptions *) index->rd_options; + if (!opts) + opts = (BloomOptions *) palloc0(sizeof(BloomOptions)); + adjustBloomOptions(opts); + + /* + * Initialize contents of meta page, including a copy of the options, + * which are now frozen for the life of the index. + */ + BloomInitPage(metaPage, BLOOM_META); + metadata = BloomPageGetMeta(metaPage); + memset(metadata, 0, sizeof(BloomMetaPageData)); + metadata->magickNumber = BLOOM_MAGICK_NUMBER; + metadata->opts = *opts; + ((PageHeader) metaPage)->pd_lower += sizeof(BloomMetaPageData); +} + +/* * Initialize metapage for bloom index. */ void BloomInitMetapage(Relation index) { - Page metaPage; Buffer metaBuffer; - BloomMetaPageData *metadata; + Page metaPage; GenericXLogState *state; /* - * Make a new buffer, since it first buffer it should be associated with + * Make a new page; since it is first page it should be associated with * block number 0 (BLOOM_METAPAGE_BLKNO). */ metaBuffer = BloomNewBuffer(index); Assert(BufferGetBlockNumber(metaBuffer) == BLOOM_METAPAGE_BLKNO); - /* Initialize bloom index options */ - if (!index->rd_options) - index->rd_options = palloc0(sizeof(BloomOptions)); - adjustBloomOptions((BloomOptions *) index->rd_options); - /* Initialize contents of meta page */ state = GenericXLogStart(index); - metaPage = GenericXLogRegisterBuffer(state, metaBuffer, GENERIC_XLOG_FULL_IMAGE); - - BloomInitPage(metaPage, BLOOM_META); - metadata = BloomPageGetMeta(metaPage); - memset(metadata, 0, sizeof(BloomMetaPageData)); - metadata->magickNumber = BLOOM_MAGICK_NUMBER; - metadata->opts = *((BloomOptions *) index->rd_options); - ((PageHeader) metaPage)->pd_lower += sizeof(BloomMetaPageData); - + metaPage = GenericXLogRegisterBuffer(state, metaBuffer, + GENERIC_XLOG_FULL_IMAGE); + BloomFillMetapage(index, metaPage); GenericXLogFinish(state); + UnlockReleaseBuffer(metaBuffer); } /* - * Initialize options for bloom index. + * Parse reloptions for bloom index, producing a BloomOptions struct. */ bytea * bloptions(Datum reloptions, bool validate) |