Remove redundant restriction checks in apply_child_basequals

In apply_child_basequals, after translating a parent relation's
restriction quals for a child relation, we simplify each child qual by
calling eval_const_expressions.  Historically, the code then called
restriction_is_always_false and restriction_is_always_true to reduce
NullTest quals that are provably false or true.

However, since commit e2debb643, the planner natively performs
NullTest deduction during constant folding.  Therefore, calling
restriction_is_always_false and restriction_is_always_true immediately
afterward is redundant and wastes CPU cycles.  We can safely remove
them and simply rely on the constant folding to handle the deduction.

Author: Richard Guo <guofenglinux@gmail.com>
Discussion: https://postgr.es/m/CAMbWs4-vLmGXaUEZyOMacN0BVfqWCt2tM-eDVWdDfJnOQaauGg@mail.gmail.com
This commit is contained in:
Richard Guo 2026-03-04 10:57:43 +09:00
parent ce1c17a316
commit 1f4f87d794
2 changed files with 13 additions and 25 deletions

View file

@ -826,8 +826,7 @@ expand_appendrel_subquery(PlannerInfo *root, RelOptInfo *rel,
/*
* apply_child_basequals
* Populate childrel's base restriction quals from parent rel's quals,
* translating Vars using appinfo and re-checking for quals which are
* constant-TRUE or constant-FALSE when applied to this child relation.
* translating them using appinfo.
*
* If any of the resulting clauses evaluate to constant false or NULL, we
* return false and don't apply any quals. Caller should mark the relation as
@ -902,16 +901,9 @@ apply_child_basequals(PlannerInfo *root, RelOptInfo *parentrel,
rinfo->security_level,
NULL, NULL, NULL);
/* Restriction is proven always false */
if (restriction_is_always_false(root, childrinfo))
return false;
/* Restriction is proven always true, so drop it */
if (restriction_is_always_true(root, childrinfo))
continue;
childquals = lappend(childquals, childrinfo);
/* track minimum security level among child quals */
cq_min_security = Min(cq_min_security, rinfo->security_level);
cq_min_security = Min(cq_min_security, childrinfo->security_level);
}
}

View file

@ -394,21 +394,13 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
break;
}
/*
* We must apply the partially filled in RelOptInfo before calling
* apply_child_basequals due to some transformations within that function
* which require the RelOptInfo to be available in the simple_rel_array.
*/
root->simple_rel_array[relid] = rel;
/*
* Apply the parent's quals to the child, with appropriate substitution of
* variables. If the resulting clause is constant-FALSE or NULL after
* applying transformations, apply_child_basequals returns false to
* indicate that scanning this relation won't yield any rows. In this
* case, we mark the child as dummy right away. (We must do this
* immediately so that pruning works correctly when recursing in
* expand_partitioned_rtentry.)
* variables. If any resulting clause is reduced to constant FALSE or
* NULL, apply_child_basequals returns false to indicate that scanning
* this relation won't yield any rows. In this case, we mark the child as
* dummy right away. (We must do this immediately so that pruning works
* correctly when recursing in expand_partitioned_rtentry.)
*/
if (parent)
{
@ -418,13 +410,17 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
if (!apply_child_basequals(root, parent, rel, rte, appinfo))
{
/*
* Restriction clause reduced to constant FALSE or NULL. Mark as
* dummy so we won't scan this relation.
* A restriction clause reduced to constant FALSE or NULL after
* substitution. Mark the child as dummy so that it need not be
* scanned.
*/
mark_dummy_rel(rel);
}
}
/* Save the finished struct in the query's simple_rel_array */
root->simple_rel_array[relid] = rel;
return rel;
}