Fix not to create IMMV including other IMMV(#30) (#31)

Previously, IMMV including IMMV in its definition can be created by
create_immv(), but it should not be supported by IMMV because we
cannot maintain it recursively for now. This patch prevents it by raising
an error for such view definition on create_immv().
This commit is contained in:
thoshiai 2022-10-18 15:51:41 +09:00 committed by GitHub
parent 6eddcd2a63
commit 24dc053659
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 0 deletions

View file

@ -793,6 +793,11 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("VALUES is not supported on incrementally maintainable materialized view")));
if (rte->relkind == RELKIND_RELATION && isImmv(rte->relid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("including IMMV in definition is not supported on incrementally maintainable materialized view")));
if (rte->rtekind == RTE_SUBQUERY)
{
context->has_subquery = true;

View file

@ -26,6 +26,11 @@ SELECT immvrelid, get_immv_def(immvrelid) FROM pg_ivm_immv ORDER BY 1;
| WHERE ((i % 2) = 0)
(2 rows)
-- contain immv
SELECT create_immv('mv_in_immv01', 'SELECT i FROM mv');
ERROR: including IMMV in definition is not supported on incrementally maintainable materialized view
SELECT create_immv('mv_in_immv02', 'SELECT t.i FROM t INNER JOIN mv2 ON t.i = mv2.x');
ERROR: including IMMV in definition is not supported on incrementally maintainable materialized view
DROP TABLE t;
ERROR: cannot drop table t because other objects depend on it
DETAIL: table mv depends on table t

View file

@ -396,3 +396,33 @@ PgIvmObjectAccessHook(ObjectAccessType access, Oid classId,
table_close(pgIvmImmv, NoLock);
}
}
/*
* isImmv
*
* Check if this is a IMMV from oid.
*/
bool
isImmv(Oid immv_oid)
{
Relation pgIvmImmv = table_open(PgIvmImmvRelationId(), AccessShareLock);
SysScanDesc scan;
ScanKeyData key;
HeapTuple tup;
ScanKeyInit(&key,
Anum_pg_ivm_immv_immvrelid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(immv_oid));
scan = systable_beginscan(pgIvmImmv, PgIvmImmvPrimaryKeyIndexId(),
true, NULL, 1, &key);
tup = systable_getnext(scan);
systable_endscan(scan);
table_close(pgIvmImmv, NoLock);
if (!HeapTupleIsValid(tup))
return false;
else
return true;
}

View file

@ -30,6 +30,7 @@
extern void CreateChangePreventTrigger(Oid matviewOid);
extern Oid PgIvmImmvRelationId(void);
extern Oid PgIvmImmvPrimaryKeyIndexId(void);
extern bool isImmv(Oid immv_oid);
/* createas.c */

View file

@ -8,6 +8,10 @@ SELECT create_immv('mv3', 'WITH d AS (DELETE FROM t RETURNING NULL) SELECT * FRO
SELECT immvrelid, get_immv_def(immvrelid) FROM pg_ivm_immv ORDER BY 1;
-- contain immv
SELECT create_immv('mv_in_immv01', 'SELECT i FROM mv');
SELECT create_immv('mv_in_immv02', 'SELECT t.i FROM t INNER JOIN mv2 ON t.i = mv2.x');
DROP TABLE t;
DROP TABLE mv;