mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
Fix brin_summarize_new_values() to check index type and ownership.
brin_summarize_new_values() did not check that the passed OID was for an index at all, much less that it was a BRIN index, and would fail in obscure ways if it wasn't (possibly damaging data first?). It also lacked any permissions test; by analogy to VACUUM, we should only allow the table's owner to summarize. Noted by Jeff Janes, fix by Michael Paquier and me
This commit is contained in:
parent
8014c44e82
commit
3d2b31e30e
@ -787,14 +787,50 @@ Datum
|
|||||||
brin_summarize_new_values(PG_FUNCTION_ARGS)
|
brin_summarize_new_values(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Oid indexoid = PG_GETARG_OID(0);
|
Oid indexoid = PG_GETARG_OID(0);
|
||||||
|
Oid heapoid;
|
||||||
Relation indexRel;
|
Relation indexRel;
|
||||||
Relation heapRel;
|
Relation heapRel;
|
||||||
double numSummarized = 0;
|
double numSummarized = 0;
|
||||||
|
|
||||||
heapRel = heap_open(IndexGetRelation(indexoid, false),
|
/*
|
||||||
ShareUpdateExclusiveLock);
|
* We must lock table before index to avoid deadlocks. However, if the
|
||||||
|
* passed indexoid isn't an index then IndexGetRelation() will fail.
|
||||||
|
* Rather than emitting a not-very-helpful error message, postpone
|
||||||
|
* complaining, expecting that the is-it-an-index test below will fail.
|
||||||
|
*/
|
||||||
|
heapoid = IndexGetRelation(indexoid, true);
|
||||||
|
if (OidIsValid(heapoid))
|
||||||
|
heapRel = heap_open(heapoid, ShareUpdateExclusiveLock);
|
||||||
|
else
|
||||||
|
heapRel = NULL;
|
||||||
|
|
||||||
indexRel = index_open(indexoid, ShareUpdateExclusiveLock);
|
indexRel = index_open(indexoid, ShareUpdateExclusiveLock);
|
||||||
|
|
||||||
|
/* Must be a BRIN index */
|
||||||
|
if (indexRel->rd_rel->relkind != RELKIND_INDEX ||
|
||||||
|
indexRel->rd_rel->relam != BRIN_AM_OID)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||||
|
errmsg("\"%s\" is not a BRIN index",
|
||||||
|
RelationGetRelationName(indexRel))));
|
||||||
|
|
||||||
|
/* User must own the index (comparable to privileges needed for VACUUM) */
|
||||||
|
if (!pg_class_ownercheck(indexoid, GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
|
||||||
|
RelationGetRelationName(indexRel));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since we did the IndexGetRelation call above without any lock, it's
|
||||||
|
* barely possible that a race against an index drop/recreation could have
|
||||||
|
* netted us the wrong table. Recheck.
|
||||||
|
*/
|
||||||
|
if (heapRel == NULL || heapoid != IndexGetRelation(indexoid, false))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_TABLE),
|
||||||
|
errmsg("could not open parent table of index %s",
|
||||||
|
RelationGetRelationName(indexRel))));
|
||||||
|
|
||||||
|
/* OK, do it */
|
||||||
brinsummarize(indexRel, heapRel, &numSummarized, NULL);
|
brinsummarize(indexRel, heapRel, &numSummarized, NULL);
|
||||||
|
|
||||||
relation_close(indexRel, ShareUpdateExclusiveLock);
|
relation_close(indexRel, ShareUpdateExclusiveLock);
|
||||||
|
@ -407,3 +407,14 @@ FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5;
|
|||||||
VACUUM brintest; -- force a summarization cycle in brinidx
|
VACUUM brintest; -- force a summarization cycle in brinidx
|
||||||
UPDATE brintest SET int8col = int8col * int4col;
|
UPDATE brintest SET int8col = int8col * int4col;
|
||||||
UPDATE brintest SET textcol = '' WHERE textcol IS NOT NULL;
|
UPDATE brintest SET textcol = '' WHERE textcol IS NOT NULL;
|
||||||
|
-- Tests for brin_summarize_new_values
|
||||||
|
SELECT brin_summarize_new_values('brintest'); -- error, not an index
|
||||||
|
ERROR: "brintest" is not an index
|
||||||
|
SELECT brin_summarize_new_values('tenk1_unique1'); -- error, not a BRIN index
|
||||||
|
ERROR: "tenk1_unique1" is not a BRIN index
|
||||||
|
SELECT brin_summarize_new_values('brinidx'); -- ok, no change expected
|
||||||
|
brin_summarize_new_values
|
||||||
|
---------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
@ -416,3 +416,8 @@ VACUUM brintest; -- force a summarization cycle in brinidx
|
|||||||
|
|
||||||
UPDATE brintest SET int8col = int8col * int4col;
|
UPDATE brintest SET int8col = int8col * int4col;
|
||||||
UPDATE brintest SET textcol = '' WHERE textcol IS NOT NULL;
|
UPDATE brintest SET textcol = '' WHERE textcol IS NOT NULL;
|
||||||
|
|
||||||
|
-- Tests for brin_summarize_new_values
|
||||||
|
SELECT brin_summarize_new_values('brintest'); -- error, not an index
|
||||||
|
SELECT brin_summarize_new_values('tenk1_unique1'); -- error, not a BRIN index
|
||||||
|
SELECT brin_summarize_new_values('brinidx'); -- ok, no change expected
|
||||||
|
Loading…
x
Reference in New Issue
Block a user