aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/optimizer/plan/initsplan.c10
-rw-r--r--src/backend/optimizer/util/joininfo.c12
-rw-r--r--src/test/regress/expected/predicate.out28
-rw-r--r--src/test/regress/sql/predicate.sql15
4 files changed, 62 insertions, 3 deletions
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index c5bc0f51e99..903c397d409 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -2767,11 +2767,18 @@ add_base_clause_to_rel(PlannerInfo *root, Index relid,
/*
* Substitute the origin qual with constant-FALSE if it is provably
- * always false. Note that we keep the same rinfo_serial.
+ * always false.
+ *
+ * Note that we need to keep the same rinfo_serial, since it is in
+ * practice the same condition. We also need to reset the
+ * last_rinfo_serial counter, which is essential to ensure that the
+ * RestrictInfos for the "same" qual condition get identical serial
+ * numbers (see deconstruct_distribute_oj_quals).
*/
if (restriction_is_always_false(root, restrictinfo))
{
int save_rinfo_serial = restrictinfo->rinfo_serial;
+ int save_last_rinfo_serial = root->last_rinfo_serial;
restrictinfo = make_restrictinfo(root,
(Expr *) makeBoolConst(false, false),
@@ -2784,6 +2791,7 @@ add_base_clause_to_rel(PlannerInfo *root, Index relid,
restrictinfo->incompatible_relids,
restrictinfo->outer_relids);
restrictinfo->rinfo_serial = save_rinfo_serial;
+ root->last_rinfo_serial = save_last_rinfo_serial;
}
}
diff --git a/src/backend/optimizer/util/joininfo.c b/src/backend/optimizer/util/joininfo.c
index 5fb0c17630a..65993bd6599 100644
--- a/src/backend/optimizer/util/joininfo.c
+++ b/src/backend/optimizer/util/joininfo.c
@@ -106,12 +106,19 @@ add_join_clause_to_rels(PlannerInfo *root,
return;
/*
- * Substitute constant-FALSE for the origin qual if it is always false.
- * Note that we keep the same rinfo_serial.
+ * Substitute the origin qual with constant-FALSE if it is provably always
+ * false.
+ *
+ * Note that we need to keep the same rinfo_serial, since it is in
+ * practice the same condition. We also need to reset the
+ * last_rinfo_serial counter, which is essential to ensure that the
+ * RestrictInfos for the "same" qual condition get identical serial
+ * numbers (see deconstruct_distribute_oj_quals).
*/
if (restriction_is_always_false(root, restrictinfo))
{
int save_rinfo_serial = restrictinfo->rinfo_serial;
+ int save_last_rinfo_serial = root->last_rinfo_serial;
restrictinfo = make_restrictinfo(root,
(Expr *) makeBoolConst(false, false),
@@ -124,6 +131,7 @@ add_join_clause_to_rels(PlannerInfo *root,
restrictinfo->incompatible_relids,
restrictinfo->outer_relids);
restrictinfo->rinfo_serial = save_rinfo_serial;
+ root->last_rinfo_serial = save_last_rinfo_serial;
}
cur_relid = -1;
diff --git a/src/test/regress/expected/predicate.out b/src/test/regress/expected/predicate.out
index 6f1cc0d54cd..965a3a76161 100644
--- a/src/test/regress/expected/predicate.out
+++ b/src/test/regress/expected/predicate.out
@@ -290,3 +290,31 @@ SELECT * FROM pred_parent WHERE a IS NULL;
(2 rows)
DROP TABLE pred_parent, pred_child;
+-- Validate the additional constant-FALSE qual does not cause inconsistent
+-- RestrictInfo serial numbers
+CREATE TABLE pred_tab (a int PRIMARY KEY, b int);
+INSERT INTO pred_tab SELECT i, i FROM generate_series(1, 10)i;
+ANALYZE pred_tab;
+EXPLAIN (COSTS OFF)
+SELECT 1 FROM pred_tab t1
+ LEFT JOIN
+ (pred_tab t2 LEFT JOIN pred_tab t3 ON t2.a = t3.a) ON TRUE
+ LEFT JOIN pred_tab t4 ON t1.a IS NULL AND t1.b = 1
+ RIGHT JOIN pred_tab t5 ON t1.b = t5.b;
+ QUERY PLAN
+---------------------------------------------------
+ Hash Right Join
+ Hash Cond: (t1.b = t5.b)
+ -> Nested Loop Left Join
+ -> Nested Loop Left Join
+ Join Filter: (false AND (t1.b = 1))
+ -> Seq Scan on pred_tab t1
+ -> Result
+ One-Time Filter: false
+ -> Materialize
+ -> Seq Scan on pred_tab t2
+ -> Hash
+ -> Seq Scan on pred_tab t5
+(12 rows)
+
+DROP TABLE pred_tab;
diff --git a/src/test/regress/sql/predicate.sql b/src/test/regress/sql/predicate.sql
index 63f6a7786f3..661013ff7e4 100644
--- a/src/test/regress/sql/predicate.sql
+++ b/src/test/regress/sql/predicate.sql
@@ -147,3 +147,18 @@ EXPLAIN (COSTS OFF)
SELECT * FROM pred_parent WHERE a IS NULL;
DROP TABLE pred_parent, pred_child;
+
+-- Validate the additional constant-FALSE qual does not cause inconsistent
+-- RestrictInfo serial numbers
+CREATE TABLE pred_tab (a int PRIMARY KEY, b int);
+INSERT INTO pred_tab SELECT i, i FROM generate_series(1, 10)i;
+ANALYZE pred_tab;
+
+EXPLAIN (COSTS OFF)
+SELECT 1 FROM pred_tab t1
+ LEFT JOIN
+ (pred_tab t2 LEFT JOIN pred_tab t3 ON t2.a = t3.a) ON TRUE
+ LEFT JOIN pred_tab t4 ON t1.a IS NULL AND t1.b = 1
+ RIGHT JOIN pred_tab t5 ON t1.b = t5.b;
+
+DROP TABLE pred_tab;