aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execIndexing.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execIndexing.c')
-rw-r--r--src/backend/executor/execIndexing.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c
index 22eda9449f9..0cb0b8f1111 100644
--- a/src/backend/executor/execIndexing.c
+++ b/src/backend/executor/execIndexing.c
@@ -935,19 +935,32 @@ static bool
index_unchanged_by_update(ResultRelInfo *resultRelInfo, EState *estate,
IndexInfo *indexInfo, Relation indexRelation)
{
- Bitmapset *updatedCols = ExecGetUpdatedCols(resultRelInfo, estate);
- Bitmapset *extraUpdatedCols = ExecGetExtraUpdatedCols(resultRelInfo, estate);
+ Bitmapset *updatedCols;
+ Bitmapset *extraUpdatedCols;
Bitmapset *allUpdatedCols;
bool hasexpression = false;
List *idxExprs;
/*
+ * Check cache first
+ */
+ if (indexInfo->ii_CheckedUnchanged)
+ return indexInfo->ii_IndexUnchanged;
+ indexInfo->ii_CheckedUnchanged = true;
+
+ /*
* Check for indexed attribute overlap with updated columns.
*
* Only do this for key columns. A change to a non-key column within an
* INCLUDE index should not be counted here. Non-key column values are
* opaque payload state to the index AM, a little like an extra table TID.
+ *
+ * Note that row-level BEFORE triggers won't affect our behavior, since
+ * they don't affect the updatedCols bitmaps generally. It doesn't seem
+ * worth the trouble of checking which attributes were changed directly.
*/
+ updatedCols = ExecGetUpdatedCols(resultRelInfo, estate);
+ extraUpdatedCols = ExecGetExtraUpdatedCols(resultRelInfo, estate);
for (int attr = 0; attr < indexInfo->ii_NumIndexKeyAttrs; attr++)
{
int keycol = indexInfo->ii_IndexAttrNumbers[attr];
@@ -968,6 +981,7 @@ index_unchanged_by_update(ResultRelInfo *resultRelInfo, EState *estate,
extraUpdatedCols))
{
/* Changed key column -- don't hint for this index */
+ indexInfo->ii_IndexUnchanged = false;
return false;
}
}
@@ -981,7 +995,10 @@ index_unchanged_by_update(ResultRelInfo *resultRelInfo, EState *estate,
* shows that the index as a whole is logically unchanged by UPDATE.
*/
if (!hasexpression)
+ {
+ indexInfo->ii_IndexUnchanged = true;
return true;
+ }
/*
* Need to pass only one bms to expression_tree_walker helper function.
@@ -1008,8 +1025,18 @@ index_unchanged_by_update(ResultRelInfo *resultRelInfo, EState *estate,
bms_free(allUpdatedCols);
if (hasexpression)
+ {
+ indexInfo->ii_IndexUnchanged = false;
return false;
+ }
+ /*
+ * Deliberately don't consider index predicates. We should even give the
+ * hint when result rel's "updated tuple" has no corresponding index
+ * tuple, which is possible with a partial index (provided the usual
+ * conditions are met).
+ */
+ indexInfo->ii_IndexUnchanged = true;
return true;
}