Skip to content

Commit 90e2782

Browse files
committed
Replace index_unchanged_by_update with ri_ChangedIndexedCols
In execIndexing on updates we'd like to pass a hint to the indexing code when the indexed attributes are unchanged. This commit replaces the now redundant code in index_unchanged_by_update with the same information found earlier in the update path.
1 parent 641f810 commit 90e2782

File tree

4 files changed

+1
-163
lines changed

4 files changed

+1
-163
lines changed

src/backend/catalog/toasting.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
300300
indexInfo->ii_Unique = true;
301301
indexInfo->ii_NullsNotDistinct = false;
302302
indexInfo->ii_ReadyForInserts = true;
303-
indexInfo->ii_CheckedUnchanged = false;
304-
indexInfo->ii_IndexUnchanged = false;
305303
indexInfo->ii_Concurrent = false;
306304
indexInfo->ii_BrokenHotChain = false;
307305
indexInfo->ii_ParallelWorkers = 0;

src/backend/executor/execIndexing.c

Lines changed: 1 addition & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,6 @@ static bool check_exclusion_or_unique_constraint(Relation heap, Relation index,
138138
static bool index_recheck_constraint(Relation index, const Oid *constr_procs,
139139
const Datum *existing_values, const bool *existing_isnull,
140140
const Datum *new_values);
141-
static bool index_unchanged_by_update(ResultRelInfo *resultRelInfo,
142-
EState *estate, IndexInfo *indexInfo,
143-
Relation indexRelation);
144-
static bool index_expression_changed_walker(Node *node,
145-
Bitmapset *allUpdatedCols);
146141
static void ExecWithoutOverlapsNotEmpty(Relation rel, NameData attname, Datum attval,
147142
char typtype, Oid atttypid);
148143

@@ -440,10 +435,7 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo,
440435
* index. If we're being called as part of an UPDATE statement,
441436
* consider if the 'indexUnchanged' = true hint should be passed.
442437
*/
443-
indexUnchanged = update && index_unchanged_by_update(resultRelInfo,
444-
estate,
445-
indexInfo,
446-
indexRelation);
438+
indexUnchanged = update && bms_is_empty(resultRelInfo->ri_ChangedIndexedCols);
447439

448440
satisfiesConstraint =
449441
index_insert(indexRelation, /* index relation */
@@ -993,152 +985,6 @@ index_recheck_constraint(Relation index, const Oid *constr_procs,
993985
return true;
994986
}
995987

996-
/*
997-
* Check if ExecInsertIndexTuples() should pass indexUnchanged hint.
998-
*
999-
* When the executor performs an UPDATE that requires a new round of index
1000-
* tuples, determine if we should pass 'indexUnchanged' = true hint for one
1001-
* single index.
1002-
*/
1003-
static bool
1004-
index_unchanged_by_update(ResultRelInfo *resultRelInfo, EState *estate,
1005-
IndexInfo *indexInfo, Relation indexRelation)
1006-
{
1007-
Bitmapset *updatedCols;
1008-
Bitmapset *extraUpdatedCols;
1009-
Bitmapset *allUpdatedCols;
1010-
bool hasexpression = false;
1011-
List *idxExprs;
1012-
1013-
/*
1014-
* Check cache first
1015-
*/
1016-
if (indexInfo->ii_CheckedUnchanged)
1017-
return indexInfo->ii_IndexUnchanged;
1018-
indexInfo->ii_CheckedUnchanged = true;
1019-
1020-
/*
1021-
* Check for indexed attribute overlap with updated columns.
1022-
*
1023-
* Only do this for key columns. A change to a non-key column within an
1024-
* INCLUDE index should not be counted here. Non-key column values are
1025-
* opaque payload state to the index AM, a little like an extra table TID.
1026-
*
1027-
* Note that row-level BEFORE triggers won't affect our behavior, since
1028-
* they don't affect the updatedCols bitmaps generally. It doesn't seem
1029-
* worth the trouble of checking which attributes were changed directly.
1030-
*/
1031-
updatedCols = ExecGetUpdatedCols(resultRelInfo, estate);
1032-
extraUpdatedCols = ExecGetExtraUpdatedCols(resultRelInfo, estate);
1033-
for (int attr = 0; attr < indexInfo->ii_NumIndexKeyAttrs; attr++)
1034-
{
1035-
int keycol = indexInfo->ii_IndexAttrNumbers[attr];
1036-
1037-
if (keycol <= 0)
1038-
{
1039-
/*
1040-
* Skip expressions for now, but remember to deal with them later
1041-
* on
1042-
*/
1043-
hasexpression = true;
1044-
continue;
1045-
}
1046-
1047-
if (bms_is_member(keycol - FirstLowInvalidHeapAttributeNumber,
1048-
updatedCols) ||
1049-
bms_is_member(keycol - FirstLowInvalidHeapAttributeNumber,
1050-
extraUpdatedCols))
1051-
{
1052-
/* Changed key column -- don't hint for this index */
1053-
indexInfo->ii_IndexUnchanged = false;
1054-
return false;
1055-
}
1056-
}
1057-
1058-
/*
1059-
* When we get this far and index has no expressions, return true so that
1060-
* index_insert() call will go on to pass 'indexUnchanged' = true hint.
1061-
*
1062-
* The _absence_ of an indexed key attribute that overlaps with updated
1063-
* attributes (in addition to the total absence of indexed expressions)
1064-
* shows that the index as a whole is logically unchanged by UPDATE.
1065-
*/
1066-
if (!hasexpression)
1067-
{
1068-
indexInfo->ii_IndexUnchanged = true;
1069-
return true;
1070-
}
1071-
1072-
/*
1073-
* Need to pass only one bms to expression_tree_walker helper function.
1074-
* Avoid allocating memory in common case where there are no extra cols.
1075-
*/
1076-
if (!extraUpdatedCols)
1077-
allUpdatedCols = updatedCols;
1078-
else
1079-
allUpdatedCols = bms_union(updatedCols, extraUpdatedCols);
1080-
1081-
/*
1082-
* We have to work slightly harder in the event of indexed expressions,
1083-
* but the principle is the same as before: try to find columns (Vars,
1084-
* actually) that overlap with known-updated columns.
1085-
*
1086-
* If we find any matching Vars, don't pass hint for index. Otherwise
1087-
* pass hint.
1088-
*/
1089-
idxExprs = RelationGetIndexExpressions(indexRelation);
1090-
hasexpression = index_expression_changed_walker((Node *) idxExprs,
1091-
allUpdatedCols);
1092-
list_free(idxExprs);
1093-
if (extraUpdatedCols)
1094-
bms_free(allUpdatedCols);
1095-
1096-
if (hasexpression)
1097-
{
1098-
indexInfo->ii_IndexUnchanged = false;
1099-
return false;
1100-
}
1101-
1102-
/*
1103-
* Deliberately don't consider index predicates. We should even give the
1104-
* hint when result rel's "updated tuple" has no corresponding index
1105-
* tuple, which is possible with a partial index (provided the usual
1106-
* conditions are met).
1107-
*/
1108-
indexInfo->ii_IndexUnchanged = true;
1109-
return true;
1110-
}
1111-
1112-
/*
1113-
* Indexed expression helper for index_unchanged_by_update().
1114-
*
1115-
* Returns true when Var that appears within allUpdatedCols located.
1116-
*/
1117-
static bool
1118-
index_expression_changed_walker(Node *node, Bitmapset *allUpdatedCols)
1119-
{
1120-
if (node == NULL)
1121-
return false;
1122-
1123-
if (IsA(node, Var))
1124-
{
1125-
Var *var = (Var *) node;
1126-
1127-
if (bms_is_member(var->varattno - FirstLowInvalidHeapAttributeNumber,
1128-
allUpdatedCols))
1129-
{
1130-
/* Var was updated -- indicates that we should not hint */
1131-
return true;
1132-
}
1133-
1134-
/* Still haven't found a reason to not pass the hint */
1135-
return false;
1136-
}
1137-
1138-
return expression_tree_walker(node, index_expression_changed_walker,
1139-
allUpdatedCols);
1140-
}
1141-
1142988
/*
1143989
* ExecWithoutOverlapsNotEmpty - raise an error if the tuple has an empty
1144990
* range or multirange in the given attribute.

src/backend/nodes/makefuncs.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -845,8 +845,6 @@ makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid, List *expressions,
845845
n->ii_Unique = unique;
846846
n->ii_NullsNotDistinct = nulls_not_distinct;
847847
n->ii_ReadyForInserts = isready;
848-
n->ii_CheckedUnchanged = false;
849-
n->ii_IndexUnchanged = false;
850848
n->ii_Concurrent = concurrent;
851849
n->ii_Summarizing = summarizing;
852850
n->ii_WithoutOverlaps = withoutoverlaps;

src/include/nodes/execnodes.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,6 @@ typedef struct IndexInfo
202202
bool ii_NullsNotDistinct;
203203
/* is it valid for inserts? */
204204
bool ii_ReadyForInserts;
205-
/* IndexUnchanged status determined yet? */
206-
bool ii_CheckedUnchanged;
207-
/* aminsert hint, cached for retail inserts */
208-
bool ii_IndexUnchanged;
209205
/* are we doing a concurrent index build? */
210206
bool ii_Concurrent;
211207
/* did we detect any broken HOT chains? */

0 commit comments

Comments
 (0)