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.h3
5 files changed, 17 insertions, 4 deletions
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 681f5f85bc7..96b09fbce71 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -1764,6 +1764,7 @@ _outIndexOptInfo(StringInfo str, IndexOptInfo *node)
WRITE_NODE_FIELD(indpred);
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 fc96f4f1dac..58b8797b738 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -2179,10 +2179,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 513b6e4d740..a92d2485289 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -316,6 +316,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
ChangeVarNodes((Node *) info->indpred, 1, varno, 0);
info->predOK = false; /* set later in indxpath.c */
info->unique = index->indisunique;
+ info->immediate = index->indimmediate;
info->hypothetical = false;
/*
@@ -973,6 +974,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 8e304097db8..7a42ff03466 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -4121,7 +4121,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 f6592697e44..0aec1637c93 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -491,6 +491,9 @@ typedef struct IndexOptInfo
bool amsearchnulls; /* can AM search for NULL/NOT NULL entries? */
bool amhasgettuple; /* does AM have amgettuple interface? */
bool amhasgetbitmap; /* does AM have amgetbitmap interface? */
+
+ /* Added at end of struct to avoid ABI breakage in released branches */
+ bool immediate; /* is uniqueness enforced immediately? */
} IndexOptInfo;