diff options
-rw-r--r-- | src/backend/nodes/outfuncs.c | 1 | ||||
-rw-r--r-- | src/backend/optimizer/path/indxpath.c | 7 | ||||
-rw-r--r-- | src/backend/optimizer/util/plancat.c | 6 | ||||
-rw-r--r-- | src/backend/utils/adt/selfuncs.c | 4 | ||||
-rw-r--r-- | src/include/nodes/relation.h | 3 |
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; |