5757#include "access/xlogutils.h"
5858#include "catalog/catalog.h"
5959#include "catalog/namespace.h"
60- #include "catalog/index.h"
6160#include "miscadmin.h"
6261#include "pgstat.h"
6362#include "port/atomics.h"
7675#include "utils/snapmgr.h"
7776#include "utils/syscache.h"
7877#include "utils/tqual.h"
79- #include "utils/memutils.h"
80- #include "nodes/execnodes.h"
81- #include "executor/executor.h"
78+
8279
8380/* GUC variable */
8481bool synchronize_seqscans = true;
@@ -130,7 +127,6 @@ static bool ConditionalMultiXactIdWait(MultiXactId multi, MultiXactStatus status
130127static XLogRecPtr log_heap_new_cid (Relation relation , HeapTuple tup );
131128static HeapTuple ExtractReplicaIdentity (Relation rel , HeapTuple tup , bool key_modified ,
132129 bool * copy );
133- static bool ProjIndexIsUnchanged (Relation relation , HeapTuple oldtup , HeapTuple newtup );
134130
135131
136132/*
@@ -3511,7 +3507,6 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
35113507 HTSU_Result result ;
35123508 TransactionId xid = GetCurrentTransactionId ();
35133509 Bitmapset * hot_attrs ;
3514- Bitmapset * proj_idx_attrs ;
35153510 Bitmapset * key_attrs ;
35163511 Bitmapset * id_attrs ;
35173512 Bitmapset * interesting_attrs ;
@@ -3575,11 +3570,12 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
35753570 * Note that we get copies of each bitmap, so we need not worry about
35763571 * relcache flush happening midway through.
35773572 */
3578- hot_attrs = RelationGetIndexAttrBitmap (relation , INDEX_ATTR_BITMAP_HOT );
3579- proj_idx_attrs = RelationGetIndexAttrBitmap (relation , INDEX_ATTR_BITMAP_PROJ );
3573+ hot_attrs = RelationGetIndexAttrBitmap (relation , INDEX_ATTR_BITMAP_ALL );
35803574 key_attrs = RelationGetIndexAttrBitmap (relation , INDEX_ATTR_BITMAP_KEY );
35813575 id_attrs = RelationGetIndexAttrBitmap (relation ,
35823576 INDEX_ATTR_BITMAP_IDENTITY_KEY );
3577+
3578+
35833579 block = ItemPointerGetBlockNumber (otid );
35843580 buffer = ReadBuffer (relation , block );
35853581 page = BufferGetPage (buffer );
@@ -3599,7 +3595,6 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
35993595 if (!PageIsFull (page ))
36003596 {
36013597 interesting_attrs = bms_add_members (interesting_attrs , hot_attrs );
3602- interesting_attrs = bms_add_members (interesting_attrs , proj_idx_attrs );
36033598 hot_attrs_checked = true;
36043599 }
36053600 interesting_attrs = bms_add_members (interesting_attrs , key_attrs );
@@ -3883,7 +3878,6 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
38833878 if (vmbuffer != InvalidBuffer )
38843879 ReleaseBuffer (vmbuffer );
38853880 bms_free (hot_attrs );
3886- bms_free (proj_idx_attrs );
38873881 bms_free (key_attrs );
38883882 bms_free (id_attrs );
38893883 bms_free (modified_attrs );
@@ -4191,18 +4185,11 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
41914185 /*
41924186 * Since the new tuple is going into the same page, we might be able
41934187 * to do a HOT update. Check if any of the index columns have been
4194- * changed, or if we have projection functional indexes, check whether
4195- * the old and the new values are the same. If the page was already
4196- * full, we may have skipped checking for index columns. If so, HOT
4197- * update is possible.
4188+ * changed. If the page was already full, we may have skipped checking
4189+ * for index columns. If so, HOT update is possible.
41984190 */
4199- if (hot_attrs_checked
4200- && !bms_overlap (modified_attrs , hot_attrs )
4201- && (!bms_overlap (modified_attrs , proj_idx_attrs )
4202- || ProjIndexIsUnchanged (relation , & oldtup , newtup )))
4203- {
4191+ if (hot_attrs_checked && !bms_overlap (modified_attrs , hot_attrs ))
42044192 use_hot_update = true;
4205- }
42064193 }
42074194 else
42084195 {
@@ -4364,7 +4351,6 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
43644351 heap_freetuple (old_key_tuple );
43654352
43664353 bms_free (hot_attrs );
4367- bms_free (proj_idx_attrs );
43684354 bms_free (key_attrs );
43694355 bms_free (id_attrs );
43704356 bms_free (modified_attrs );
@@ -4450,87 +4436,6 @@ heap_tuple_attr_equals(TupleDesc tupdesc, int attrnum,
44504436 }
44514437}
44524438
4453- /*
4454- * Check whether the value is unchanged after update of a projection
4455- * functional index. Compare the new and old values of the indexed
4456- * expression to see if we are able to use a HOT update or not.
4457- */
4458- static bool
4459- ProjIndexIsUnchanged (Relation relation , HeapTuple oldtup , HeapTuple newtup )
4460- {
4461- ListCell * l ;
4462- List * indexoidlist = RelationGetIndexList (relation );
4463- EState * estate = CreateExecutorState ();
4464- ExprContext * econtext = GetPerTupleExprContext (estate );
4465- TupleTableSlot * slot = MakeSingleTupleTableSlot (RelationGetDescr (relation ),
4466- & TTSOpsHeapTuple );
4467- bool equals = true;
4468- Datum old_values [INDEX_MAX_KEYS ];
4469- bool old_isnull [INDEX_MAX_KEYS ];
4470- Datum new_values [INDEX_MAX_KEYS ];
4471- bool new_isnull [INDEX_MAX_KEYS ];
4472- int indexno = 0 ;
4473-
4474- econtext -> ecxt_scantuple = slot ;
4475-
4476- foreach (l , indexoidlist )
4477- {
4478- if (bms_is_member (indexno , relation -> rd_projidx ))
4479- {
4480- Oid indexOid = lfirst_oid (l );
4481- Relation indexDesc = index_open (indexOid , AccessShareLock );
4482- IndexInfo * indexInfo = BuildIndexInfo (indexDesc );
4483- int i ;
4484-
4485- ResetExprContext (econtext );
4486- ExecStoreHeapTuple (oldtup , slot , false);
4487- FormIndexDatum (indexInfo ,
4488- slot ,
4489- estate ,
4490- old_values ,
4491- old_isnull );
4492-
4493- ExecStoreHeapTuple (newtup , slot , false);
4494- FormIndexDatum (indexInfo ,
4495- slot ,
4496- estate ,
4497- new_values ,
4498- new_isnull );
4499-
4500- for (i = 0 ; i < indexInfo -> ii_NumIndexAttrs ; i ++ )
4501- {
4502- if (old_isnull [i ] != new_isnull [i ])
4503- {
4504- equals = false;
4505- break ;
4506- }
4507- else if (!old_isnull [i ])
4508- {
4509- Form_pg_attribute att = TupleDescAttr (RelationGetDescr (indexDesc ), i );
4510-
4511- if (!datumIsEqual (old_values [i ], new_values [i ], att -> attbyval , att -> attlen ))
4512- {
4513- equals = false;
4514- break ;
4515- }
4516- }
4517- }
4518- index_close (indexDesc , AccessShareLock );
4519-
4520- if (!equals )
4521- {
4522- break ;
4523- }
4524- }
4525- indexno += 1 ;
4526- }
4527- ExecDropSingleTupleTableSlot (slot );
4528- FreeExecutorState (estate );
4529-
4530- return equals ;
4531- }
4532-
4533-
45344439/*
45354440 * Check which columns are being updated.
45364441 *
0 commit comments