aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/catalog/toasting.c2
-rw-r--r--src/backend/executor/execIndexing.c31
-rw-r--r--src/backend/nodes/makefuncs.c2
3 files changed, 33 insertions, 2 deletions
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index 917bb3577e7..3c27cb1e71b 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -302,6 +302,8 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
indexInfo->ii_OpclassOptions = NULL;
indexInfo->ii_Unique = true;
indexInfo->ii_ReadyForInserts = true;
+ indexInfo->ii_CheckedUnchanged = false;
+ indexInfo->ii_IndexUnchanged = false;
indexInfo->ii_Concurrent = false;
indexInfo->ii_BrokenHotChain = false;
indexInfo->ii_ParallelWorkers = 0;
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;
}
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index dace4f7e2df..822395625b6 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -751,6 +751,8 @@ makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid, List *expressions,
Assert(n->ii_NumIndexKeyAttrs <= n->ii_NumIndexAttrs);
n->ii_Unique = unique;
n->ii_ReadyForInserts = isready;
+ n->ii_CheckedUnchanged = false;
+ n->ii_IndexUnchanged = false;
n->ii_Concurrent = concurrent;
/* expressions */