aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/nodes/outfuncs.c1
-rw-r--r--src/backend/optimizer/path/indxpath.c7
-rw-r--r--src/backend/optimizer/util/plancat.c6
-rw-r--r--src/backend/utils/adt/selfuncs.c4
-rw-r--r--src/include/nodes/relation.h1
5 files changed, 15 insertions, 4 deletions
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 98a02b27ddf..f7d39edf6fd 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -1770,6 +1770,7 @@ _outIndexOptInfo(StringInfo str, IndexOptInfo *node)
WRITE_NODE_FIELD(indextlist);
WRITE_BOOL_FIELD(predOK);
WRITE_BOOL_FIELD(unique);
+ WRITE_BOOL_FIELD(immediate);
WRITE_BOOL_FIELD(hypothetical);
}
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 940efb38b66..77df5a24ea2 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -2277,10 +2277,11 @@ relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
int c;
/*
- * If the index is not unique or if it's a partial index that doesn't
- * match the query, it's useless here.
+ * 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.
*/
- if (!ind->unique || (ind->indpred != NIL && !ind->predOK))
+ if (!ind->unique || !ind->immediate ||
+ (ind->indpred != NIL && !ind->predOK))
continue;
/*
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index bb809522424..de629e93c9a 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -324,6 +324,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
info->predOK = false; /* set later in indxpath.c */
info->unique = index->indisunique;
+ info->immediate = index->indimmediate;
info->hypothetical = false;
/*
@@ -1076,6 +1077,11 @@ join_selectivity(PlannerInfo *root,
* Detect whether there is a unique index on the specified attribute
* of the specified relation, thus allowing us to conclude that all
* the (non-null) values of the attribute are distinct.
+ *
+ * This function does not check the index's indimmediate property, which
+ * means that uniqueness may transiently fail to hold intra-transaction.
+ * That's appropriate when we are making statistical estimates, but beware
+ * of using this for any correctness proofs.
*/
bool
has_unique_index(RelOptInfo *rel, AttrNumber attno)
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 96946281dab..f05cc4f87ee 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -4129,7 +4129,9 @@ get_join_variables(PlannerInfo *root, List *args, SpecialJoinInfo *sjinfo,
* commonly the same as the exposed type of the variable argument,
* but can be different in binary-compatible-type cases.
* isunique: TRUE if we were able to match the var to a unique index,
- * implying its values are unique for this query.
+ * implying its values are unique for this query. (Caution: this
+ * should be trusted for statistical purposes only, since we do not
+ * check indimmediate.)
*
* Caller is responsible for doing ReleaseVariableStats() before exiting.
*/
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 2925d7e7659..ede97571e06 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -488,6 +488,7 @@ typedef struct IndexOptInfo
bool predOK; /* true if predicate matches query */
bool unique; /* true if a unique index */
+ bool immediate; /* is uniqueness enforced immediately? */
bool hypothetical; /* true if index doesn't really exist */
bool amcanorderbyop; /* does AM support order by operator result? */
bool amcanreturn; /* can AM return IndexTuples? */