@@ -138,11 +138,6 @@ static bool check_exclusion_or_unique_constraint(Relation heap, Relation index,
138138static 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 );
146141static 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.
0 commit comments