mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
Fix another palloc in critical section.
Also add a regression test for a GIN index with enough items with the same key, so that a GIN posting tree gets created. Apparently none of the existing GIN tests were large enough for that. This code is new, no backpatching required.
This commit is contained in:
parent
6862ca6970
commit
ffbba6ee12
@ -1706,22 +1706,16 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
|
||||
{
|
||||
BlockNumber blkno;
|
||||
Buffer buffer;
|
||||
Page tmppage;
|
||||
Page page;
|
||||
Pointer ptr;
|
||||
int nrootitems;
|
||||
int rootsize;
|
||||
|
||||
/*
|
||||
* Create the root page.
|
||||
*/
|
||||
buffer = GinNewBuffer(index);
|
||||
page = BufferGetPage(buffer);
|
||||
blkno = BufferGetBlockNumber(buffer);
|
||||
|
||||
START_CRIT_SECTION();
|
||||
|
||||
GinInitPage(page, GIN_DATA | GIN_LEAF | GIN_COMPRESSED, BLCKSZ);
|
||||
GinPageGetOpaque(page)->rightlink = InvalidBlockNumber;
|
||||
/* Construct the new root page in memory first. */
|
||||
tmppage = (Page) palloc(BLCKSZ);
|
||||
GinInitPage(tmppage, GIN_DATA | GIN_LEAF | GIN_COMPRESSED, BLCKSZ);
|
||||
GinPageGetOpaque(tmppage)->rightlink = InvalidBlockNumber;
|
||||
|
||||
/*
|
||||
* Write as many of the items to the root page as fit. In segments
|
||||
@ -1729,7 +1723,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
|
||||
*/
|
||||
nrootitems = 0;
|
||||
rootsize = 0;
|
||||
ptr = (Pointer) GinDataLeafPageGetPostingList(page);
|
||||
ptr = (Pointer) GinDataLeafPageGetPostingList(tmppage);
|
||||
while (nrootitems < nitems)
|
||||
{
|
||||
GinPostingList *segment;
|
||||
@ -1750,10 +1744,19 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
|
||||
nrootitems += npacked;
|
||||
pfree(segment);
|
||||
}
|
||||
GinDataLeafPageSetPostingListSize(page, rootsize);
|
||||
MarkBufferDirty(buffer);
|
||||
GinDataLeafPageSetPostingListSize(tmppage, rootsize);
|
||||
|
||||
elog(DEBUG2, "created GIN posting tree with %d items", nrootitems);
|
||||
/*
|
||||
* All set. Get a new physical page, and copy the in-memory page to it.
|
||||
*/
|
||||
buffer = GinNewBuffer(index);
|
||||
page = BufferGetPage(buffer);
|
||||
blkno = BufferGetBlockNumber(buffer);
|
||||
|
||||
START_CRIT_SECTION();
|
||||
|
||||
PageRestoreTempPage(tmppage, page);
|
||||
MarkBufferDirty(buffer);
|
||||
|
||||
if (RelationNeedsWAL(index))
|
||||
{
|
||||
@ -1787,6 +1790,8 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
|
||||
if (buildStats)
|
||||
buildStats->nDataPages++;
|
||||
|
||||
elog(DEBUG2, "created GIN posting tree with %d items", nrootitems);
|
||||
|
||||
/*
|
||||
* Add any remaining TIDs to the newly-created posting tree.
|
||||
*/
|
||||
|
@ -2221,6 +2221,20 @@ RESET enable_seqscan;
|
||||
RESET enable_indexscan;
|
||||
RESET enable_bitmapscan;
|
||||
--
|
||||
-- Try a GIN index with a lot of items with same key. (GIN creates a posting
|
||||
-- tree when there are enough duplicates)
|
||||
--
|
||||
CREATE TABLE array_gin_test (a int[]);
|
||||
INSERT INTO array_gin_test SELECT ARRAY[1, g%5, g] FROM generate_series(1, 10000) g;
|
||||
CREATE INDEX array_gin_test_idx ON array_gin_test USING gin (a);
|
||||
SELECT COUNT(*) FROM array_gin_test WHERE a @> '{2}';
|
||||
count
|
||||
-------
|
||||
2000
|
||||
(1 row)
|
||||
|
||||
DROP TABLE array_gin_test;
|
||||
--
|
||||
-- HASH
|
||||
--
|
||||
CREATE INDEX hash_i4_index ON hash_i4_heap USING hash (random int4_ops);
|
||||
|
@ -636,6 +636,20 @@ RESET enable_seqscan;
|
||||
RESET enable_indexscan;
|
||||
RESET enable_bitmapscan;
|
||||
|
||||
--
|
||||
-- Try a GIN index with a lot of items with same key. (GIN creates a posting
|
||||
-- tree when there are enough duplicates)
|
||||
--
|
||||
CREATE TABLE array_gin_test (a int[]);
|
||||
|
||||
INSERT INTO array_gin_test SELECT ARRAY[1, g%5, g] FROM generate_series(1, 10000) g;
|
||||
|
||||
CREATE INDEX array_gin_test_idx ON array_gin_test USING gin (a);
|
||||
|
||||
SELECT COUNT(*) FROM array_gin_test WHERE a @> '{2}';
|
||||
|
||||
DROP TABLE array_gin_test;
|
||||
|
||||
--
|
||||
-- HASH
|
||||
--
|
||||
|
Loading…
Reference in New Issue
Block a user