fix a expression including EXISTS condition under AND condition
Previously, queries could not be searched correctlywhen the EXISTS clause was included in a CASE statement.
This commit is contained in:
parent
6f5ae0ee22
commit
7eb8a1da38
3 changed files with 25 additions and 2 deletions
24
createas.c
24
createas.c
|
|
@ -70,6 +70,7 @@ typedef struct
|
|||
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 */
|
||||
bool is_simple_jointree; /* true, if it is in a simple join tree or boolexpr directly under jointree */
|
||||
List *exists_qual_vars;
|
||||
int sublevels_up;
|
||||
} check_ivm_restriction_context;
|
||||
|
|
@ -741,7 +742,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, false, NIL, 0};
|
||||
check_ivm_restriction_context context = {false, false, false, false, false, false, NIL, 0};
|
||||
|
||||
check_ivm_restriction_walker(node, &context);
|
||||
}
|
||||
|
|
@ -996,6 +997,15 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context)
|
|||
expression_tree_walker(node, check_ivm_restriction_walker, (void *) context);
|
||||
break;
|
||||
}
|
||||
case T_List:
|
||||
{
|
||||
ListCell *temp;
|
||||
foreach(temp, (List *) node)
|
||||
{
|
||||
check_ivm_restriction_walker(lfirst(temp), context);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case T_FromExpr:
|
||||
{
|
||||
FromExpr *from = (FromExpr *) node;
|
||||
|
|
@ -1015,7 +1025,9 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context)
|
|||
errhint("sublink only supports simple conditions with EXISTS clause in WHERE clause")));
|
||||
|
||||
context->in_jointree = true;
|
||||
context->is_simple_jointree = true;
|
||||
check_ivm_restriction_walker(from->quals, context);
|
||||
context->is_simple_jointree = false;
|
||||
context->in_jointree = false;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1071,6 +1083,12 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context)
|
|||
context->exists_qual_vars = lappend(context->exists_qual_vars, node);
|
||||
break;
|
||||
}
|
||||
case T_BoolExpr:
|
||||
{
|
||||
BoolExpr *expr = (BoolExpr *) node;
|
||||
expression_tree_walker((Node *) expr->args, check_ivm_restriction_walker, (void *) context);
|
||||
break;
|
||||
}
|
||||
case T_SubLink:
|
||||
{
|
||||
/* Currently, EXISTS clause is supported only */
|
||||
|
|
@ -1081,7 +1099,7 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context)
|
|||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("this query is not allowed on incrementally maintainable materialized view"),
|
||||
errhint("sublink only supports subquery with EXISTS clause in WHERE clause")));
|
||||
if (context->sublevels_up > 0)
|
||||
if (context->sublevels_up > 0 || (context->in_jointree && !context->is_simple_jointree))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("nested sublink is not supported on incrementally maintainable materialized view")));
|
||||
|
|
@ -1101,6 +1119,8 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context)
|
|||
break;
|
||||
}
|
||||
default:
|
||||
// not a simple query, if a condition don't match these
|
||||
context->is_simple_jointree = false;
|
||||
expression_tree_walker(node, check_ivm_restriction_walker, (void *) context);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -891,6 +891,8 @@ 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
|
||||
SELECT create_immv('mv_ivm_subquery', 'SELECT * FROM mv_base_a a WHERE true and CASE EXISTS(SELECT 1 FROM mv_base_b b WHERE a.i = b.i) WHEN true THEN false ELSE true END');
|
||||
ERROR: nested sublink is not supported on incrementally maintainable materialized view
|
||||
-- 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');
|
||||
|
|
|
|||
|
|
@ -293,6 +293,7 @@ SELECT create_immv('mv_ivm_subquery', 'SELECT EXISTS(SELECT 1 from mv_base_b) FR
|
|||
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');
|
||||
SELECT create_immv('mv_ivm_subquery', 'SELECT * FROM mv_base_a a WHERE true and 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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue