aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/path/indxpath.c9
-rw-r--r--src/backend/optimizer/plan/analyzejoins.c9
-rw-r--r--src/test/regress/expected/join.out17
-rw-r--r--src/test/regress/sql/join.sql9
4 files changed, 36 insertions, 8 deletions
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 1436dbc2f2f..0065c8992bd 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -3549,10 +3549,13 @@ relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
/*
* If the index is not unique, or not immediately enforced, or if it's
- * a partial index that doesn't match the query, it's useless here.
+ * a partial index, it's useless here. We're unable to make use of
+ * predOK partial unique indexes due to the fact that
+ * check_index_predicates() also makes use of join predicates to
+ * determine if the partial index is usable. Here we need proofs that
+ * hold true before any joins are evaluated.
*/
- if (!ind->unique || !ind->immediate ||
- (ind->indpred != NIL && !ind->predOK))
+ if (!ind->unique || !ind->immediate || ind->indpred != NIL)
continue;
/*
diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c
index 9161c8a2964..5f3cce873a0 100644
--- a/src/backend/optimizer/plan/analyzejoins.c
+++ b/src/backend/optimizer/plan/analyzejoins.c
@@ -801,9 +801,9 @@ rel_supports_distinctness(PlannerInfo *root, RelOptInfo *rel)
/*
* For a plain relation, we only know how to prove uniqueness by
* reference to unique indexes. Make sure there's at least one
- * suitable unique index. It must be immediately enforced, and if
- * it's a partial index, it must match the query. (Keep these
- * conditions in sync with relation_has_unique_index_for!)
+ * suitable unique index. It must be immediately enforced, and not a
+ * partial index. (Keep these conditions in sync with
+ * relation_has_unique_index_for!)
*/
ListCell *lc;
@@ -811,8 +811,7 @@ rel_supports_distinctness(PlannerInfo *root, RelOptInfo *rel)
{
IndexOptInfo *ind = (IndexOptInfo *) lfirst(lc);
- if (ind->unique && ind->immediate &&
- (ind->indpred == NIL || ind->predOK))
+ if (ind->unique && ind->immediate && ind->indpred == NIL)
return true;
}
}
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index cc4c122fdd4..0643f50078f 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -7632,6 +7632,23 @@ left join j2 on j1.id1 = j2.id1 where j1.id2 = 1;
Output: j2.id1, j2.id2
(8 rows)
+create unique index j1_id2_idx on j1(id2) where id2 is not null;
+-- ensure we don't use a partial unique index as unique proofs
+explain (verbose, costs off)
+select * from j1
+inner join j2 on j1.id2 = j2.id2;
+ QUERY PLAN
+------------------------------------------
+ Nested Loop
+ Output: j1.id1, j1.id2, j2.id1, j2.id2
+ Join Filter: (j2.id2 = j1.id2)
+ -> Seq Scan on public.j2
+ Output: j2.id1, j2.id2
+ -> Seq Scan on public.j1
+ Output: j1.id1, j1.id2
+(7 rows)
+
+drop index j1_id2_idx;
-- validate logic in merge joins which skips mark and restore.
-- it should only do this if all quals which were used to detect the unique
-- are present as join quals, and not plain quals.
diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql
index e77e4695709..adc2ef5b81d 100644
--- a/src/test/regress/sql/join.sql
+++ b/src/test/regress/sql/join.sql
@@ -2757,6 +2757,15 @@ explain (verbose, costs off)
select * from j1
left join j2 on j1.id1 = j2.id1 where j1.id2 = 1;
+create unique index j1_id2_idx on j1(id2) where id2 is not null;
+
+-- ensure we don't use a partial unique index as unique proofs
+explain (verbose, costs off)
+select * from j1
+inner join j2 on j1.id2 = j2.id2;
+
+drop index j1_id2_idx;
+
-- validate logic in merge joins which skips mark and restore.
-- it should only do this if all quals which were used to detect the unique
-- are present as join quals, and not plain quals.