From d77ed8e30efec8431f9edb267527532ead7a4b98 Mon Sep 17 00:00:00 2001 From: Yugo Nagata Date: Thu, 14 May 2020 17:59:24 +0900 Subject: [PATCH] Add a query check for expressions containing aggregates in it IMMV is not supported for expresion which contains aggragate function in targetlist. Previously, There are cases in which column value of IMMV is incorrect, bacause it was not checked if it used the above expression. GitHub issue #96 --- doc/src/sgml/ref/create_materialized_view.sgml | 10 ++++++++-- doc/src/sgml/rules.sgml | 8 +++++++- src/backend/commands/createas.c | 5 +++++ src/test/regress/expected/incremental_matview.out | 9 +++++++-- src/test/regress/sql/incremental_matview.sql | 8 ++++++-- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/doc/src/sgml/ref/create_materialized_view.sgml b/doc/src/sgml/ref/create_materialized_view.sgml index a984f755d4d..b643ff6d993 100644 --- a/doc/src/sgml/ref/create_materialized_view.sgml +++ b/doc/src/sgml/ref/create_materialized_view.sgml @@ -225,7 +225,7 @@ a, (SELECT i, COUNT(*) FROM mv_base_b GROUP BY i) b WHERE a.i = b.i; - Aggregations other than count, sum, avg, min and max. + Aggregations other than built-in count, sum, avg, min and max. @@ -277,11 +277,17 @@ ERROR: functions in IMMV must be marked IMMUTABLE + + + IMMVs including expressions which contains aggregates in it + + + IMMVs not supported by logical replication. - + diff --git a/doc/src/sgml/rules.sgml b/doc/src/sgml/rules.sgml index fa7318f07bd..a978677f44f 100644 --- a/doc/src/sgml/rules.sgml +++ b/doc/src/sgml/rules.sgml @@ -1519,7 +1519,13 @@ Time: 16386.245 ms (00:16.386) - targetlist cannot contain hidden columns which name start with __ivm_. + targetlist cannot contain hidden columns whose name start with __ivm_. + + + + + + targetlist cannot contain expressions which contain an aggregate in it. diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 26463945217..3dfb55de50c 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -43,6 +43,7 @@ #include "nodes/nodeFuncs.h" #include "parser/parse_clause.h" #include "rewrite/rewriteHandler.h" +#include "rewrite/rewriteManip.h" #include "storage/smgr.h" #include "tcop/tcopprot.h" #include "utils/builtins.h" @@ -1119,6 +1120,10 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *ctx, int ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("column name %s is not supported on incrementally maintainable materialized view", tle->resname))); + if (ctx->has_agg && !IsA(tle->expr, Aggref) && contain_aggs_of_level((Node *) tle->expr, 0)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("expression containing an aggregate in it is not supported on incrementally maintainable materialized view"))); check_ivm_restriction_walker((Node *) tle->expr, ctx, depth); } diff --git a/src/test/regress/expected/incremental_matview.out b/src/test/regress/expected/incremental_matview.out index 28f25805f27..c0f63f7f442 100644 --- a/src/test/regress/expected/incremental_matview.out +++ b/src/test/regress/expected/incremental_matview.out @@ -5640,7 +5640,7 @@ CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm19 AS SELECT array_agg(j ORDER BY i ERROR: aggregate function with ORDER clause is not supported on incrementally maintainable materialized view CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm20 AS SELECT i,SUM(j) FROM mv_base_a GROUP BY GROUPING SETS((i),()); ERROR: GROUPING SETS, ROLLUP, or CUBE clauses is not supported on incrementally maintainable materialized view --- inheritance parent is not supported with IVM" +-- inheritance parent is not supported BEGIN; CREATE TABLE parent (i int, v int); CREATE TABLE child_a(options text) INHERITS(parent); @@ -5667,7 +5667,12 @@ ERROR: column name __ivm_count__ is not supported on incrementally maintainable -- expressions specified in GROUP BY must appear in the target list. CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm29 AS SELECT COUNT(i) FROM mv_base_a GROUP BY i; ERROR: GROUP BY expression not appeared in select list is not supported on incrementally maintainable materialized view --- base table has row level security +-- experssions containing an aggregate is not supported +CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm30 AS SELECT sum(i)*0.5 FROM mv_base_a; +ERROR: expression containing an aggregate in it is not supported on incrementally maintainable materialized view +CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm31 AS SELECT sum(i)/sum(j) FROM mv_base_a; +ERROR: expression containing an aggregate in it is not supported on incrementally maintainable materialized view +-- base table which has row level security DROP USER IF EXISTS ivm_admin; NOTICE: role "ivm_admin" does not exist, skipping DROP USER IF EXISTS ivm_user; diff --git a/src/test/regress/sql/incremental_matview.sql b/src/test/regress/sql/incremental_matview.sql index ec8e29546e1..60b05560c28 100644 --- a/src/test/regress/sql/incremental_matview.sql +++ b/src/test/regress/sql/incremental_matview.sql @@ -1629,7 +1629,7 @@ CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm18 AS SELECT COUNT(DISTINCT i) FROM CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm19 AS SELECT array_agg(j ORDER BY i DESC) FROM mv_base_a; CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm20 AS SELECT i,SUM(j) FROM mv_base_a GROUP BY GROUPING SETS((i),()); --- inheritance parent is not supported with IVM" +-- inheritance parent is not supported BEGIN; CREATE TABLE parent (i int, v int); CREATE TABLE child_a(options text) INHERITS(parent); @@ -1655,7 +1655,11 @@ CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm28 AS SELECT i AS "__ivm_count__" FR -- expressions specified in GROUP BY must appear in the target list. CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm29 AS SELECT COUNT(i) FROM mv_base_a GROUP BY i; --- base table has row level security +-- experssions containing an aggregate is not supported +CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm30 AS SELECT sum(i)*0.5 FROM mv_base_a; +CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm31 AS SELECT sum(i)/sum(j) FROM mv_base_a; + +-- base table which has row level security DROP USER IF EXISTS ivm_admin; DROP USER IF EXISTS ivm_user; CREATE USER ivm_admin;