From d66bdd41e42985b9d809a81da43adf4744076798 Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Thu, 19 Feb 2026 15:23:40 +0900 Subject: [PATCH v1] 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. --- src/backend/optimizer/util/inherit.c | 12 ++---------- src/backend/optimizer/util/relnode.c | 26 +++++++++++--------------- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/src/backend/optimizer/util/inherit.c b/src/backend/optimizer/util/inherit.c index 48b5d0aac4c..8d623bf136d 100644 --- a/src/backend/optimizer/util/inherit.c +++ b/src/backend/optimizer/util/inherit.c @@ -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); } } diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index a714c83f1ba..d21b4d3bb35 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -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; } -- 2.39.5 (Apple Git-154)