Summarize the process of sublink restriction

This commit is contained in:
thoshiai 2023-08-25 17:49:49 +09:00
parent 0ad579f339
commit 3a35f22c81
3 changed files with 22 additions and 8 deletions

View file

@ -66,7 +66,8 @@ typedef struct
{
bool has_agg;
bool has_subquery;
bool in_exists_subquery; /* true, if it is in a exists subquery */
bool in_exists_subquery; /* true, if it is in a exists subquery */
bool in_jointree; /* true, if it is in a join tree */
List *exists_qual_vars;
int sublevels_up;
} check_ivm_restriction_context;
@ -746,7 +747,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, NIL, 0};
check_ivm_restriction_context context = {false, false, false, false, NIL, 0};
check_ivm_restriction_walker(node, &context);
}
@ -968,11 +969,6 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context)
case T_TargetEntry:
{
TargetEntry *tle = (TargetEntry *)node;
if (IsA(tle->expr, SubLink))
ereport(ERROR,
(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 (isIvmName(tle->resname))
ereport(ERROR,
@ -986,6 +982,16 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context)
expression_tree_walker(node, check_ivm_restriction_walker, (void *) context);
break;
}
case T_FromExpr:
{
FromExpr *from = (FromExpr *) node;
check_ivm_restriction_walker((Node *)from->fromlist, context);
context->in_jointree = true;
check_ivm_restriction_walker(from->quals, context);
context->in_jointree = false;
break;
}
case T_JoinExpr:
{
JoinExpr *joinexpr = (JoinExpr *)node;
@ -1043,7 +1049,7 @@ check_ivm_restriction_walker(Node *node, check_ivm_restriction_context *context)
/* Currently, EXISTS clause is supported only */
Query *subselect;
SubLink *sublink = (SubLink *) node;
if (sublink->subLinkType != EXISTS_SUBLINK)
if (!context->in_jointree || sublink->subLinkType != EXISTS_SUBLINK)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("this query is not allowed on incrementally maintainable materialized view"),

View file

@ -848,6 +848,12 @@ ERROR: nested sublink is not supported on incrementally maintainable materializ
SELECT create_immv('mv_ivm_subquery', 'SELECT EXISTS(SELECT 1 from mv_base_b) FROM mv_base_a a');
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 false OR EXISTS(SELECT 1 FROM mv_base_a) FROM 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 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
-- 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

@ -272,6 +272,8 @@ SELECT create_immv('mv_ivm_subquery', 'SELECT a.j FROM mv_base_a a WHERE EXISTS(
SELECT create_immv('mv_ivm_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) OR a.i > 2');
SELECT create_immv('mv_ivm_subquery', 'SELECT a.j FROM mv_base_a a WHERE EXISTS(SELECT 1 FROM mv_base_a a2 WHERE EXISTS(SELECT 1 FROM mv_base_b b WHERE a2.i = b.i))');
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');
-- support join subquery in FROM clause
BEGIN;