diff --git a/createas.c b/createas.c index 79bb8d1..1a060ae 100644 --- a/createas.c +++ b/createas.c @@ -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; diff --git a/expected/create_immv.out b/expected/create_immv.out index 8bebe42..22e0e18 100644 --- a/expected/create_immv.out +++ b/expected/create_immv.out @@ -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 diff --git a/pg_ivm.c b/pg_ivm.c index a9f6d3b..b61967d 100644 --- a/pg_ivm.c +++ b/pg_ivm.c @@ -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; +} diff --git a/pg_ivm.h b/pg_ivm.h index 0bfa306..dd9429a 100644 --- a/pg_ivm.h +++ b/pg_ivm.h @@ -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 */ diff --git a/sql/create_immv.sql b/sql/create_immv.sql index 6265cb8..8d1602e 100644 --- a/sql/create_immv.sql +++ b/sql/create_immv.sql @@ -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;