v1-0001-Fix-const-simplification-of-expressions-loaded-fr.patch
application/octet-stream
Filename: v1-0001-Fix-const-simplification-of-expressions-loaded-fr.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v1-0001
Subject: Fix const-simplification of expressions loaded from catalogs
| File | + | − |
|---|---|---|
| src/backend/optimizer/util/plancat.c | 40 | 18 |
From 2e0120ab571281ac69fdf20356ea5e0f2bc9a84d Mon Sep 17 00:00:00 2001
From: Richard Guo <guofenglinux@gmail.com>
Date: Wed, 20 Aug 2025 18:10:00 +0900
Subject: [PATCH v1] Fix const-simplification of expressions loaded from
catalogs
---
src/backend/optimizer/util/plancat.c | 58 +++++++++++++++++++---------
1 file changed, 40 insertions(+), 18 deletions(-)
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 6ce4efea118..c507d3ec8e6 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -77,7 +77,8 @@ static List *get_relation_constraints(PlannerInfo *root,
bool include_partition);
static List *build_index_tlist(PlannerInfo *root, IndexOptInfo *index,
Relation heapRelation);
-static List *get_relation_statistics(RelOptInfo *rel, Relation relation);
+static List *get_relation_statistics(PlannerInfo *root, RelOptInfo *rel,
+ Relation relation);
static void set_relation_partition_info(PlannerInfo *root, RelOptInfo *rel,
Relation relation);
static PartitionScheme find_partition_scheme(PlannerInfo *root,
@@ -435,6 +436,18 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
if (info->indpred && varno != 1)
ChangeVarNodes((Node *) info->indpred, 1, varno, 0);
+ /*
+ * We need to run the index expressions and predicate through
+ * const-simplification again after fixing the Vars to have the
+ * correct varno, and with a valid "root". This ensures that
+ * NullTest quals for Vars can be properly reduced.
+ */
+ info->indexprs = (List *)
+ eval_const_expressions(root, (Node *) info->indexprs);
+ info->indpred = (List *)
+ eval_const_expressions(root, (Node *) make_ands_explicit(info->indpred));
+ info->indpred = make_ands_implicit((Expr *) info->indpred);
+
/* Build targetlist using the completed indexprs data */
info->indextlist = build_index_tlist(root, info, relation);
@@ -508,7 +521,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
rel->indexlist = indexinfos;
- rel->statlist = get_relation_statistics(rel, relation);
+ rel->statlist = get_relation_statistics(root, rel, relation);
/* Grab foreign-table info using the relcache, while we have it */
if (relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
@@ -1406,6 +1419,14 @@ get_relation_constraints(PlannerInfo *root,
cexpr = stringToNode(constr->check[i].ccbin);
+ /*
+ * Fix Vars to have the desired varno. This must be done before
+ * const-simplification because eval_const_expressions reduces
+ * NullTest for Vars based on varno.
+ */
+ if (varno != 1)
+ ChangeVarNodes(cexpr, 1, varno, 0);
+
/*
* Run each expression through const-simplification and
* canonicalization. This is not just an optimization, but is
@@ -1420,10 +1441,6 @@ get_relation_constraints(PlannerInfo *root,
cexpr = (Node *) canonicalize_qual((Expr *) cexpr, true);
- /* Fix Vars to have the desired varno */
- if (varno != 1)
- ChangeVarNodes(cexpr, 1, varno, 0);
-
/*
* Finally, convert to implicit-AND format (that is, a List) and
* append the resulting item(s) to our output list.
@@ -1572,7 +1589,8 @@ get_relation_statistics_worker(List **stainfos, RelOptInfo *rel,
* just the identifying metadata. Only stats actually built are considered.
*/
static List *
-get_relation_statistics(RelOptInfo *rel, Relation relation)
+get_relation_statistics(PlannerInfo *root, RelOptInfo *rel,
+ Relation relation)
{
Index varno = rel->relid;
List *statoidlist;
@@ -1604,8 +1622,8 @@ get_relation_statistics(RelOptInfo *rel, Relation relation)
keys = bms_add_member(keys, staForm->stxkeys.values[i]);
/*
- * Preprocess expressions (if any). We read the expressions, run them
- * through eval_const_expressions, and fix the varnos.
+ * Preprocess expressions (if any). We read the expressions, fix the
+ * varnos, and run them through eval_const_expressions.
*
* XXX We don't know yet if there are any data for this stats object,
* with either stxdinherit value. But it's reasonable to assume there
@@ -1628,6 +1646,18 @@ get_relation_statistics(RelOptInfo *rel, Relation relation)
exprs = (List *) stringToNode(exprsString);
pfree(exprsString);
+ /*
+ * Modify the copies we obtain from the relcache to have the
+ * correct varno for the parent relation, so that they match
+ * up correctly against qual clauses.
+ *
+ * This must be done before const-simplification because
+ * eval_const_expressions reduces NullTest for Vars based on
+ * varno.
+ */
+ if (varno != 1)
+ ChangeVarNodes((Node *) exprs, 1, varno, 0);
+
/*
* Run the expressions through eval_const_expressions. This is
* not just an optimization, but is necessary, because the
@@ -1636,18 +1666,10 @@ get_relation_statistics(RelOptInfo *rel, Relation relation)
* We must not use canonicalize_qual, however, since these
* aren't qual expressions.
*/
- exprs = (List *) eval_const_expressions(NULL, (Node *) exprs);
+ exprs = (List *) eval_const_expressions(root, (Node *) exprs);
/* May as well fix opfuncids too */
fix_opfuncids((Node *) exprs);
-
- /*
- * Modify the copies we obtain from the relcache to have the
- * correct varno for the parent relation, so that they match
- * up correctly against qual clauses.
- */
- if (varno != 1)
- ChangeVarNodes((Node *) exprs, 1, varno, 0);
}
}
--
2.43.0