Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3d2b31e

Browse files
committed
Fix brin_summarize_new_values() to check index type and ownership.
brin_summarize_new_values() did not check that the passed OID was foran index at all, much less that it was a BRIN index, and would fail inobscure ways if it wasn't (possibly damaging data first?). It alsolacked any permissions test; by analogy to VACUUM, we should only allowthe table's owner to summarize.Noted by Jeff Janes, fix by Michael Paquier and me
1 parent8014c44 commit3d2b31e

File tree

3 files changed

+55
-3
lines changed

3 files changed

+55
-3
lines changed

‎src/backend/access/brin/brin.c

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -787,14 +787,50 @@ Datum
787787
brin_summarize_new_values(PG_FUNCTION_ARGS)
788788
{
789789
Oidindexoid=PG_GETARG_OID(0);
790+
Oidheapoid;
790791
RelationindexRel;
791792
RelationheapRel;
792793
doublenumSummarized=0;
793794

794-
heapRel=heap_open(IndexGetRelation(indexoid, false),
795-
ShareUpdateExclusiveLock);
795+
/*
796+
* We must lock table before index to avoid deadlocks. However, if the
797+
* passed indexoid isn't an index then IndexGetRelation() will fail.
798+
* Rather than emitting a not-very-helpful error message, postpone
799+
* complaining, expecting that the is-it-an-index test below will fail.
800+
*/
801+
heapoid=IndexGetRelation(indexoid, true);
802+
if (OidIsValid(heapoid))
803+
heapRel=heap_open(heapoid,ShareUpdateExclusiveLock);
804+
else
805+
heapRel=NULL;
806+
796807
indexRel=index_open(indexoid,ShareUpdateExclusiveLock);
797808

809+
/* Must be a BRIN index */
810+
if (indexRel->rd_rel->relkind!=RELKIND_INDEX||
811+
indexRel->rd_rel->relam!=BRIN_AM_OID)
812+
ereport(ERROR,
813+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
814+
errmsg("\"%s\" is not a BRIN index",
815+
RelationGetRelationName(indexRel))));
816+
817+
/* User must own the index (comparable to privileges needed for VACUUM) */
818+
if (!pg_class_ownercheck(indexoid,GetUserId()))
819+
aclcheck_error(ACLCHECK_NOT_OWNER,ACL_KIND_CLASS,
820+
RelationGetRelationName(indexRel));
821+
822+
/*
823+
* Since we did the IndexGetRelation call above without any lock, it's
824+
* barely possible that a race against an index drop/recreation could have
825+
* netted us the wrong table. Recheck.
826+
*/
827+
if (heapRel==NULL||heapoid!=IndexGetRelation(indexoid, false))
828+
ereport(ERROR,
829+
(errcode(ERRCODE_UNDEFINED_TABLE),
830+
errmsg("could not open parent table of index %s",
831+
RelationGetRelationName(indexRel))));
832+
833+
/* OK, do it */
798834
brinsummarize(indexRel,heapRel,&numSummarized,NULL);
799835

800836
relation_close(indexRel,ShareUpdateExclusiveLock);
@@ -962,7 +998,7 @@ summarize_range(IndexInfo *indexInfo, BrinBuildState *state, Relation heapRel,
962998
*/
963999
state->bs_currRangeStart=heapBlk;
9641000
scanNumBlks=heapBlk+state->bs_pagesPerRange <=heapNumBlks ?
965-
state->bs_pagesPerRange :heapNumBlks-heapBlk;
1001+
state->bs_pagesPerRange :heapNumBlks-heapBlk;
9661002
IndexBuildHeapRangeScan(heapRel,state->bs_irel,indexInfo, false, true,
9671003
heapBlk,scanNumBlks,
9681004
brinbuildCallback, (void*)state);

‎src/test/regress/expected/brin.out

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,3 +407,14 @@ FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5;
407407
VACUUM brintest; -- force a summarization cycle in brinidx
408408
UPDATE brintest SET int8col = int8col * int4col;
409409
UPDATE brintest SET textcol = '' WHERE textcol IS NOT NULL;
410+
-- Tests for brin_summarize_new_values
411+
SELECT brin_summarize_new_values('brintest'); -- error, not an index
412+
ERROR: "brintest" is not an index
413+
SELECT brin_summarize_new_values('tenk1_unique1'); -- error, not a BRIN index
414+
ERROR: "tenk1_unique1" is not a BRIN index
415+
SELECT brin_summarize_new_values('brinidx'); -- ok, no change expected
416+
brin_summarize_new_values
417+
---------------------------
418+
0
419+
(1 row)
420+

‎src/test/regress/sql/brin.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,3 +416,8 @@ VACUUM brintest; -- force a summarization cycle in brinidx
416416

417417
UPDATE brintestSET int8col= int8col* int4col;
418418
UPDATE brintestSET textcol=''WHERE textcolIS NOT NULL;
419+
420+
-- Tests for brin_summarize_new_values
421+
SELECT brin_summarize_new_values('brintest');-- error, not an index
422+
SELECT brin_summarize_new_values('tenk1_unique1');-- error, not a BRIN index
423+
SELECT brin_summarize_new_values('brinidx');-- ok, no change expected

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp