diff --git a/createas.c b/createas.c index 4595a70..efe777c 100644 --- a/createas.c +++ b/createas.c @@ -711,7 +711,7 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context) if (qry->havingQual != NULL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg(" HAVING clause is not supported on incrementally maintainable materialized view"))); + errmsg("HAVING clause is not supported on incrementally maintainable materialized view"))); if (qry->sortClause != NIL) /* There is a possibility that we don't need to return an error */ ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -744,11 +744,6 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("FOR UPDATE/SHARE clause is not supported on incrementally maintainable materialized view"))); - if (qry->hasSubLinks && context->sublevels_up > 0) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("this query is not allowed on incrementally maintainable materialized view"), - errhint("Only simple subquery is supported"))); /* system column restrictions */ vars = pull_vars_of_level((Node *) qry, 0); @@ -831,7 +826,7 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context) } } - query_tree_walker(qry, check_ivm_restriction_walker, (void *) context, QTW_IGNORE_RANGE_TABLE); + query_tree_walker(qry, check_ivm_restriction_walker, (void *) context, QTW_IGNORE_RT_SUBQUERIES); break; } @@ -847,12 +842,6 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("expression containing an aggregate in it is not supported on incrementally maintainable materialized view"))); - if (IsA(tle->expr, SubLink)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("this query is not allowed on incrementally maintainable materialized view"), - errhint("subquery is not supported in targetlist"))); - expression_tree_walker(node, check_ivm_restriction_walker, (void *) context); break; } @@ -865,7 +854,7 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("OUTER JOIN is not supported on incrementally maintainable materialized view"))); - expression_tree_walker(node, check_ivm_restriction_walker, NULL); + expression_tree_walker(node, check_ivm_restriction_walker, (void *) context); break; } case T_Aggref: @@ -893,15 +882,16 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("aggregate function %s is not supported on incrementally maintainable materialized view", aggname))); + + expression_tree_walker(node, check_ivm_restriction_walker, (void *) context); break; } case T_SubLink: { - /* Now, EXISTS clause is supported only */ ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("this query is not allowed on incrementally maintainable materialized view"), - errhint("Only simple subquery is supported"))); + errmsg("unsupported subquery on incrementally maintainable materialized view"), + errhint("Only simple subquery in FROM clause is supported."))); break; } default: diff --git a/expected/pg_ivm.out b/expected/pg_ivm.out index 5b57551..e8f56f1 100644 --- a/expected/pg_ivm.out +++ b/expected/pg_ivm.out @@ -662,10 +662,6 @@ SELECT * FROM mv_ri ORDER BY i2; (2 rows) ROLLBACK; --- not support subquery for using EXISTS() -SELECT create_immv('mv_ivm_exists_subquery', 'SELECT a.i, a.j FROM mv_base_a a WHERE EXISTS(SELECT 1 FROM mv_base_b b WHERE a.i = b.i)'); -ERROR: this query is not allowed on incrementally maintainable materialized view -HINT: Only simple subquery is supported -- support simple subquery in FROM clause BEGIN; SELECT create_immv('mv_ivm_subquery', 'SELECT a.i,a.j FROM mv_base_a a,( SELECT * FROM mv_base_b) b WHERE a.i = b.i'); @@ -691,6 +687,26 @@ SELECT * FROM mv_ivm_subquery ORDER BY i,j; (6 rows) ROLLBACK; +-- disallow non-simple subqueries +SELECT create_immv('mv_ivm_exists_subquery', 'SELECT a.i, a.j FROM mv_base_a a WHERE EXISTS(SELECT 1 FROM mv_base_b b WHERE a.i = b.i)'); +ERROR: unsupported subquery on incrementally maintainable materialized view +HINT: Only simple subquery in FROM clause is supported. +SELECT create_immv('mv_ivm_subquery', 'SELECT a.i,a.j FROM mv_base_a a, (SELECT i, COUNT(*) FROM mv_base_b GROUP BY i) b WHERE a.i = b.i'); +ERROR: aggregate functions in nested query are not supported on incrementally maintainable materialized view +SELECT create_immv('mv_ivm_subquery', 'SELECT a.i,a.j FROM mv_base_a a, (SELECT DISTINCT i FROM mv_base_b) b WHERE a.i = b.i'); +ERROR: DISTINCT clause in nested query are not supported on incrementally maintainable materialized view +SELECT create_immv('mv_ivm_subquery', 'SELECT i,j FROM mv_base_a WHERE i IN (SELECT i FROM mv_base_b WHERE k < 103 )'); +ERROR: unsupported subquery on incrementally maintainable materialized view +HINT: Only simple subquery in FROM clause is supported. +SELECT create_immv('mv_ivm_subquery', 'SELECT i,j, (SELECT k FROM mv_base_b LIMIT 1) FROM mv_base_a a'); +ERROR: unsupported subquery on incrementally maintainable materialized view +HINT: Only simple subquery in FROM clause is supported. +SELECT create_immv('mv_ivm_subquery', 'SELECT i,j, (SELECT k FROM mv_base_b LIMIT 1) + 1 FROM mv_base_a a'); +ERROR: unsupported subquery on incrementally maintainable materialized view +HINT: Only simple subquery in FROM clause is supported. +SELECT create_immv('mv_ivm_subquery', 'SELECT * FROM generate_series(1, (SELECT k FROM mv_base_b LIMIT 1)) AS v'); +ERROR: unsupported subquery on incrementally maintainable materialized view +HINT: Only simple subquery in FROM clause is supported. -- support join subquery in FROM clause BEGIN; SELECT create_immv('mv_ivm_join_subquery', 'SELECT i, j, k FROM ( SELECT i, a.j, b.k FROM mv_base_b b INNER JOIN mv_base_a a USING(i)) tmp'); @@ -914,21 +930,12 @@ SELECT create_immv('mv_ivm03', 'SELECT i,j,xmin::text AS x_min FROM mv_base_a'); ERROR: system column is not supported on incrementally maintainable materialized view SELECT create_immv('mv_ivm04', 'SELECT i,j,xidsend(xmin) AS x_min FROM mv_base_a'); ERROR: system column is not supported on incrementally maintainable materialized view --- contain subquery -SELECT create_immv('mv_ivm03', 'SELECT i,j FROM mv_base_a WHERE i IN (SELECT i FROM mv_base_b WHERE k < 103 )'); -ERROR: this query is not allowed on incrementally maintainable materialized view -HINT: Only simple subquery is supported -SELECT create_immv('mv_ivm04', 'SELECT a.i,a.j FROM mv_base_a a, (SELECT DISTINCT i FROM mv_base_b) b WHERE a.i = b.i'); -ERROR: DISTINCT clause in nested query are not supported on incrementally maintainable materialized view -SELECT create_immv('mv_ivm05', 'SELECT i,j, (SELECT k FROM mv_base_b b WHERE a.i = b.i) FROM mv_base_a a'); -ERROR: this query is not allowed on incrementally maintainable materialized view -HINT: subquery is not supported in targetlist -- contain ORDER BY SELECT create_immv('mv_ivm07', 'SELECT i,j,k FROM mv_base_a a INNER JOIN mv_base_b b USING(i) ORDER BY i,j,k'); ERROR: ORDER BY clause is not supported on incrementally maintainable materialized view -- contain HAVING SELECT create_immv('mv_ivm08', 'SELECT i,j,k FROM mv_base_a a INNER JOIN mv_base_b b USING(i) GROUP BY i,j,k HAVING SUM(i) > 5'); -ERROR: HAVING clause is not supported on incrementally maintainable materialized view +ERROR: HAVING clause is not supported on incrementally maintainable materialized view -- contain GROUP BY without aggregate SELECT create_immv('mv_ivm08', 'SELECT i,j FROM mv_base_a GROUP BY i,j'); ERROR: GROUP BY clause without aggregate is not supported on incrementally maintainable materialized view @@ -939,8 +946,6 @@ SELECT create_immv('mv_ivm07', 'SELECT a.i,a.j FROM mv_base_a a,b_view b WHERE a ERROR: VIEW or MATERIALIZED VIEW is not supported on incrementally maintainable materialized view SELECT create_immv('mv_ivm08', 'SELECT a.i,a.j FROM mv_base_a a,b_mview b WHERE a.i = b.i'); ERROR: VIEW or MATERIALIZED VIEW is not supported on incrementally maintainable materialized view -SELECT create_immv('mv_ivm09', 'SELECT a.i,a.j FROM mv_base_a a, (SELECT i, COUNT(*) FROM mv_base_b GROUP BY i) b WHERE a.i = b.i'); -ERROR: aggregate functions in nested query are not supported on incrementally maintainable materialized view -- contain mutable functions SELECT create_immv('mv_ivm12', 'SELECT i,j FROM mv_base_a WHERE i = random()::int'); ERROR: mutable function is not supported on incrementally maintainable materialized view diff --git a/sql/pg_ivm.sql b/sql/pg_ivm.sql index f07ebef..9c4dfec 100644 --- a/sql/pg_ivm.sql +++ b/sql/pg_ivm.sql @@ -227,9 +227,6 @@ DELETE FROM ri1 WHERE i=2; SELECT * FROM mv_ri ORDER BY i2; ROLLBACK; --- not support subquery for using EXISTS() -SELECT create_immv('mv_ivm_exists_subquery', 'SELECT a.i, a.j FROM mv_base_a a WHERE EXISTS(SELECT 1 FROM mv_base_b b WHERE a.i = b.i)'); - -- support simple subquery in FROM clause BEGIN; SELECT create_immv('mv_ivm_subquery', 'SELECT a.i,a.j FROM mv_base_a a,( SELECT * FROM mv_base_b) b WHERE a.i = b.i'); @@ -239,6 +236,15 @@ SELECT * FROM mv_ivm_subquery ORDER BY i,j; ROLLBACK; +-- disallow non-simple subqueries +SELECT create_immv('mv_ivm_exists_subquery', 'SELECT a.i, a.j FROM mv_base_a a WHERE EXISTS(SELECT 1 FROM mv_base_b b WHERE a.i = b.i)'); +SELECT create_immv('mv_ivm_subquery', 'SELECT a.i,a.j FROM mv_base_a a, (SELECT i, COUNT(*) FROM mv_base_b GROUP BY i) b WHERE a.i = b.i'); +SELECT create_immv('mv_ivm_subquery', 'SELECT a.i,a.j FROM mv_base_a a, (SELECT DISTINCT i FROM mv_base_b) b WHERE a.i = b.i'); +SELECT create_immv('mv_ivm_subquery', 'SELECT i,j FROM mv_base_a WHERE i IN (SELECT i FROM mv_base_b WHERE k < 103 )'); +SELECT create_immv('mv_ivm_subquery', 'SELECT i,j, (SELECT k FROM mv_base_b LIMIT 1) FROM mv_base_a a'); +SELECT create_immv('mv_ivm_subquery', 'SELECT i,j, (SELECT k FROM mv_base_b LIMIT 1) + 1 FROM mv_base_a a'); +SELECT create_immv('mv_ivm_subquery', 'SELECT * FROM generate_series(1, (SELECT k FROM mv_base_b LIMIT 1)) AS v'); + -- support join subquery in FROM clause BEGIN; SELECT create_immv('mv_ivm_join_subquery', 'SELECT i, j, k FROM ( SELECT i, a.j, b.k FROM mv_base_b b INNER JOIN mv_base_a a USING(i)) tmp'); @@ -352,10 +358,6 @@ SELECT create_immv('mv_ivm02', 'SELECT i,j FROM mv_base_a WHERE xmin = ''610''') SELECT create_immv('mv_ivm03', 'SELECT i,j,xmin::text AS x_min FROM mv_base_a'); SELECT create_immv('mv_ivm04', 'SELECT i,j,xidsend(xmin) AS x_min FROM mv_base_a'); --- contain subquery -SELECT create_immv('mv_ivm03', 'SELECT i,j FROM mv_base_a WHERE i IN (SELECT i FROM mv_base_b WHERE k < 103 )'); -SELECT create_immv('mv_ivm04', 'SELECT a.i,a.j FROM mv_base_a a, (SELECT DISTINCT i FROM mv_base_b) b WHERE a.i = b.i'); -SELECT create_immv('mv_ivm05', 'SELECT i,j, (SELECT k FROM mv_base_b b WHERE a.i = b.i) FROM mv_base_a a'); -- contain ORDER BY SELECT create_immv('mv_ivm07', 'SELECT i,j,k FROM mv_base_a a INNER JOIN mv_base_b b USING(i) ORDER BY i,j,k'); -- contain HAVING @@ -368,7 +370,6 @@ CREATE VIEW b_view AS SELECT i,k FROM mv_base_b; CREATE MATERIALIZED VIEW b_mview AS SELECT i,k FROM mv_base_b; SELECT create_immv('mv_ivm07', 'SELECT a.i,a.j FROM mv_base_a a,b_view b WHERE a.i = b.i'); SELECT create_immv('mv_ivm08', 'SELECT a.i,a.j FROM mv_base_a a,b_mview b WHERE a.i = b.i'); -SELECT create_immv('mv_ivm09', 'SELECT a.i,a.j FROM mv_base_a a, (SELECT i, COUNT(*) FROM mv_base_b GROUP BY i) b WHERE a.i = b.i'); -- contain mutable functions SELECT create_immv('mv_ivm12', 'SELECT i,j FROM mv_base_a WHERE i = random()::int');