Fix EXISTS restriction

reinforce EXISTS restriction, only support the AND condition.
This commit is contained in:
thoshiai 2023-09-09 17:38:29 +09:00
parent 6f99049848
commit cf821d7850
3 changed files with 22 additions and 2 deletions

View file

@ -66,6 +66,7 @@ typedef struct
typedef struct
{
bool has_agg;
bool has_sublinks;
bool has_subquery;
bool in_exists_subquery; /* true, if it is in a exists subquery */
bool in_jointree; /* true, if it is in a join tree */
@ -748,7 +749,7 @@ CreateIvmTrigger(Oid relOid, Oid viewOid, int16 type, int16 timing, bool ex_lock
static void
check_ivm_restriction(Node *node)
{
check_ivm_restriction_context context = {false, false, false, false, NIL, 0};
check_ivm_restriction_context context = {false, false, false, false, false, NIL, 0};
check_ivm_restriction_walker(node, &context);
}
@ -815,6 +816,8 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("recursive query is not supported on incrementally maintainable materialized view")));
context->has_sublinks |= qry->hasSubLinks;
/* system column restrictions */
vars = pull_vars_of_level((Node *) qry, 0);
foreach(lc, vars)
@ -1008,10 +1011,23 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context)
FromExpr *from = (FromExpr *) node;
check_ivm_restriction_walker((Node *)from->fromlist, context);
/*
* check the sublink restrictions.
* Currently, EXISTS subqueries with condition other than 'AND' is not supported.
*/
if (from->quals == NULL)
break;
if (context->has_sublinks && !context->in_exists_subquery &&
!IsA(from->quals, SubLink) && !IsA(from->quals, BoolExpr))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("this query is not allowed on incrementally maintainable materialized view"),
errhint("sublink only supports simple conditions with EXISTS clause in WHERE clause")));
context->in_jointree = true;
check_ivm_restriction_walker(from->quals, context);
context->in_jointree = false;
break;
break;
}
case T_JoinExpr:
{

View file

@ -888,6 +888,9 @@ HINT: sublink only supports subquery with EXISTS clause in WHERE clause
SELECT create_immv('mv_ivm_subquery', 'SELECT * FROM generate_series(1, CASE EXISTS(SELECT 1 FROM mv_base_a) WHEN true THEN 100 ELSE 10 END), mv_base_b');
ERROR: this query is not allowed on incrementally maintainable materialized view
HINT: sublink only supports subquery with EXISTS clause in WHERE clause
SELECT create_immv('mv_ivm_subquery', 'SELECT * FROM mv_base_a a WHERE CASE EXISTS(SELECT 1 FROM mv_base_b b WHERE a.i = b.i) WHEN true THEN false ELSE true END');
ERROR: this query is not allowed on incrementally maintainable materialized view
HINT: sublink only supports simple conditions with EXISTS clause in WHERE clause
-- 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');

View file

@ -292,6 +292,7 @@ SELECT create_immv('mv_ivm_subquery', 'SELECT a.j FROM mv_base_a a WHERE EXISTS(
SELECT create_immv('mv_ivm_subquery', 'SELECT EXISTS(SELECT 1 from mv_base_b) FROM mv_base_a a');
SELECT create_immv('mv_ivm_subquery', 'SELECT false OR EXISTS(SELECT 1 FROM mv_base_a) FROM mv_base_b');
SELECT create_immv('mv_ivm_subquery', 'SELECT * FROM generate_series(1, CASE EXISTS(SELECT 1 FROM mv_base_a) WHEN true THEN 100 ELSE 10 END), mv_base_b');
SELECT create_immv('mv_ivm_subquery', 'SELECT * FROM mv_base_a a WHERE CASE EXISTS(SELECT 1 FROM mv_base_b b WHERE a.i = b.i) WHEN true THEN false ELSE true END');
-- support join subquery in FROM clause
BEGIN;