Remove global variable scanCommandId in favor of storing a command ID
authorTom Lane <[email protected]>
Tue, 21 May 2002 22:05:55 +0000 (22:05 +0000)
committerTom Lane <[email protected]>
Tue, 21 May 2002 22:05:55 +0000 (22:05 +0000)
in snapshots, per my proposal of a few days ago.  Also, tweak heapam.c
routines (heap_insert, heap_update, heap_delete, heap_mark4update) to
be passed the command ID to use, instead of doing GetCurrentCommandID.
For catalog updates they'll still get passed current command ID, but
for updates generated from the main executor they'll get passed the
command ID saved in the snapshot the query is using.  This should fix
some corner cases associated with functions and triggers that advance
current command ID while an outer query is still in progress.

37 files changed:
src/backend/access/heap/heapam.c
src/backend/access/heap/tuptoaster.c
src/backend/access/transam/xact.c
src/backend/bootstrap/bootstrap.c
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/catalog/pg_aggregate.c
src/backend/catalog/pg_largeobject.c
src/backend/catalog/pg_namespace.c
src/backend/catalog/pg_operator.c
src/backend/catalog/pg_proc.c
src/backend/catalog/pg_type.c
src/backend/commands/analyze.c
src/backend/commands/async.c
src/backend/commands/cluster.c
src/backend/commands/comment.c
src/backend/commands/copy.c
src/backend/commands/dbcommands.c
src/backend/commands/portalcmds.c
src/backend/commands/proclang.c
src/backend/commands/sequence.c
src/backend/commands/tablecmds.c
src/backend/commands/trigger.c
src/backend/commands/user.c
src/backend/executor/execMain.c
src/backend/executor/functions.c
src/backend/executor/spi.c
src/backend/rewrite/rewriteDefine.c
src/backend/storage/ipc/sinval.c
src/backend/storage/large_object/inv_api.c
src/backend/utils/mmgr/portalmem.c
src/backend/utils/time/tqual.c
src/include/access/heapam.h
src/include/access/xact.h
src/include/executor/spi_priv.h
src/include/utils/portal.h
src/include/utils/tqual.h

index 551f5e0c589eeac8f4df753a0ea4ce23d3a12886..4b9bbdcfbf42f14cd1d8aef8ff3d66222f79a512 100644 (file)
@@ -1059,15 +1059,14 @@ heap_get_latest_tid(Relation relation,
        return tid;
 }
 
-/* ----------------
- *             heap_insert             - insert tuple into a heap
+/*
+ *     heap_insert             - insert tuple into a heap
  *
- *             The assignment of t_min (and thus the others) should be
- *             removed eventually.
- * ----------------
+ * The new tuple is stamped with current transaction ID and the specified
+ * command ID.
  */
 Oid
-heap_insert(Relation relation, HeapTuple tup)
+heap_insert(Relation relation, HeapTuple tup, CommandId cid)
 {
        Buffer          buffer;
 
@@ -1093,8 +1092,9 @@ heap_insert(Relation relation, HeapTuple tup)
        }
 
        TransactionIdStore(GetCurrentTransactionId(), &(tup->t_data->t_xmin));
-       tup->t_data->t_cmin = GetCurrentCommandId();
+       tup->t_data->t_cmin = cid;
        StoreInvalidTransactionId(&(tup->t_data->t_xmax));
+       tup->t_data->t_cmax = FirstCommandId;
        tup->t_data->t_infomask &= ~(HEAP_XACT_MASK);
        tup->t_data->t_infomask |= HEAP_XMAX_INVALID;
        tup->t_tableOid = relation->rd_id;
@@ -1178,6 +1178,19 @@ heap_insert(Relation relation, HeapTuple tup)
        return tup->t_data->t_oid;
 }
 
+/*
+ *     simple_heap_insert - insert a tuple
+ *
+ * Currently, this routine differs from heap_insert only in supplying
+ * a default command ID.  But it should be used rather than using
+ * heap_insert directly in most places where we are modifying system catalogs.
+ */
+Oid
+simple_heap_insert(Relation relation, HeapTuple tup)
+{
+       return heap_insert(relation, tup, GetCurrentCommandId());
+}
+
 /*
  *     heap_delete             - delete a tuple
  *
@@ -1185,7 +1198,8 @@ heap_insert(Relation relation, HeapTuple tup)
  * concurrent-update conditions.  Use simple_heap_delete instead.
  */
 int
-heap_delete(Relation relation, ItemPointer tid, ItemPointer ctid)
+heap_delete(Relation relation, ItemPointer tid,
+                       ItemPointer ctid, CommandId cid)
 {
        ItemId          lp;
        HeapTupleData tp;
@@ -1215,7 +1229,7 @@ heap_delete(Relation relation, ItemPointer tid, ItemPointer ctid)
        tp.t_tableOid = relation->rd_id;
 
 l1:
-       result = HeapTupleSatisfiesUpdate(&tp);
+       result = HeapTupleSatisfiesUpdate(&tp, cid);
 
        if (result == HeapTupleInvisible)
        {
@@ -1265,7 +1279,7 @@ l1:
        START_CRIT_SECTION();
        /* store transaction information of xact deleting the tuple */
        TransactionIdStore(GetCurrentTransactionId(), &(tp.t_data->t_xmax));
-       tp.t_data->t_cmax = GetCurrentCommandId();
+       tp.t_data->t_cmax = cid;
        tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
                                                         HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
        /* XLOG stuff */
@@ -1336,7 +1350,7 @@ simple_heap_delete(Relation relation, ItemPointer tid)
        ItemPointerData ctid;
        int                     result;
 
-       result = heap_delete(relation, tid, &ctid);
+       result = heap_delete(relation, tid, &ctid, GetCurrentCommandId());
        switch (result)
        {
                case HeapTupleSelfUpdated:
@@ -1356,7 +1370,6 @@ simple_heap_delete(Relation relation, ItemPointer tid)
                        elog(ERROR, "Unknown status %u from heap_delete", result);
                        break;
        }
-
 }
 
 /*
@@ -1367,7 +1380,7 @@ simple_heap_delete(Relation relation, ItemPointer tid)
  */
 int
 heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
-                       ItemPointer ctid)
+                       ItemPointer ctid, CommandId cid)
 {
        ItemId          lp;
        HeapTupleData oldtup;
@@ -1407,7 +1420,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
         */
 
 l2:
-       result = HeapTupleSatisfiesUpdate(&oldtup);
+       result = HeapTupleSatisfiesUpdate(&oldtup, cid);
 
        if (result == HeapTupleInvisible)
        {
@@ -1457,7 +1470,7 @@ l2:
        /* Fill in OID and transaction status data for newtup */
        newtup->t_data->t_oid = oldtup.t_data->t_oid;
        TransactionIdStore(GetCurrentTransactionId(), &(newtup->t_data->t_xmin));
-       newtup->t_data->t_cmin = GetCurrentCommandId();
+       newtup->t_data->t_cmin = cid;
        StoreInvalidTransactionId(&(newtup->t_data->t_xmax));
        newtup->t_data->t_infomask &= ~(HEAP_XACT_MASK);
        newtup->t_data->t_infomask |= (HEAP_XMAX_INVALID | HEAP_UPDATED);
@@ -1496,7 +1509,7 @@ l2:
 
                TransactionIdStore(GetCurrentTransactionId(),
                                                   &(oldtup.t_data->t_xmax));
-               oldtup.t_data->t_cmax = GetCurrentCommandId();
+               oldtup.t_data->t_cmax = cid;
                oldtup.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
                                                                           HEAP_XMAX_INVALID |
                                                                           HEAP_MARKED_FOR_UPDATE);
@@ -1588,7 +1601,7 @@ l2:
        {
                TransactionIdStore(GetCurrentTransactionId(),
                                                   &(oldtup.t_data->t_xmax));
-               oldtup.t_data->t_cmax = GetCurrentCommandId();
+               oldtup.t_data->t_cmax = cid;
                oldtup.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
                                                                           HEAP_XMAX_INVALID |
                                                                           HEAP_MARKED_FOR_UPDATE);
@@ -1653,7 +1666,7 @@ simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup)
        ItemPointerData ctid;
        int                     result;
 
-       result = heap_update(relation, otid, tup, &ctid);
+       result = heap_update(relation, otid, tup, &ctid, GetCurrentCommandId());
        switch (result)
        {
                case HeapTupleSelfUpdated:
@@ -1679,7 +1692,8 @@ simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup)
  *     heap_mark4update                - mark a tuple for update
  */
 int
-heap_mark4update(Relation relation, HeapTuple tuple, Buffer *buffer)
+heap_mark4update(Relation relation, HeapTuple tuple, Buffer *buffer,
+                                CommandId cid)
 {
        ItemPointer tid = &(tuple->t_self);
        ItemId          lp;
@@ -1704,7 +1718,7 @@ heap_mark4update(Relation relation, HeapTuple tuple, Buffer *buffer)
        tuple->t_len = ItemIdGetLength(lp);
 
 l3:
-       result = HeapTupleSatisfiesUpdate(tuple);
+       result = HeapTupleSatisfiesUpdate(tuple, cid);
 
        if (result == HeapTupleInvisible)
        {
@@ -1758,7 +1772,7 @@ l3:
 
        /* store transaction information of xact marking the tuple */
        TransactionIdStore(GetCurrentTransactionId(), &(tuple->t_data->t_xmax));
-       tuple->t_data->t_cmax = GetCurrentCommandId();
+       tuple->t_data->t_cmax = cid;
        tuple->t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID);
        tuple->t_data->t_infomask |= HEAP_MARKED_FOR_UPDATE;
 
@@ -2400,9 +2414,8 @@ _heap_unlock_tuple(void *data)
 
        htup = (HeapTupleHeader) PageGetItem(page, lp);
 
-       if (!TransactionIdEquals(htup->t_xmax, GetCurrentTransactionId()) ||
-               htup->t_cmax != GetCurrentCommandId())
-               elog(PANIC, "_heap_unlock_tuple: invalid xmax/cmax in rollback");
+       if (!TransactionIdEquals(htup->t_xmax, GetCurrentTransactionId()))
+               elog(PANIC, "_heap_unlock_tuple: invalid xmax in rollback");
        htup->t_infomask &= ~HEAP_XMAX_UNLOGGED;
        htup->t_infomask |= HEAP_XMAX_INVALID;
        UnlockAndWriteBuffer(buffer);
index 5e5d6db5546a783489ffb0bbb8dcc257473fe59f..b981f79e0426f21a4270c1f5b9597fd90a687d6d 100644 (file)
@@ -911,7 +911,7 @@ toast_save_datum(Relation rel, Datum value)
                if (!HeapTupleIsValid(toasttup))
                        elog(ERROR, "Failed to build TOAST tuple");
 
-               heap_insert(toastrel, toasttup);
+               simple_heap_insert(toastrel, toasttup);
 
                /*
                 * Create the index entry.      We cheat a little here by not using
index fabc42b92458c56542b31c6539f4117437b27d39..2cda0f0aab6ac28585776828d0b6a6b67c08328e 100644 (file)
@@ -350,14 +350,6 @@ GetCurrentCommandId(void)
        return s->commandId;
 }
 
-CommandId
-GetScanCommandId(void)
-{
-       TransactionState s = CurrentTransactionState;
-
-       return s->scanCommandId;
-}
-
 
 /* --------------------------------
  *             GetCurrentTransactionStartTime
@@ -418,17 +410,6 @@ CommandIdIsCurrentCommandId(CommandId cid)
        return (cid == s->commandId) ? true : false;
 }
 
-bool
-CommandIdGEScanCommandId(CommandId cid)
-{
-       TransactionState s = CurrentTransactionState;
-
-       if (AMI_OVERRIDE)
-               return false;
-
-       return (cid >= s->scanCommandId) ? true : false;
-}
-
 
 /* --------------------------------
  *             CommandCounterIncrement
@@ -437,11 +418,17 @@ CommandIdGEScanCommandId(CommandId cid)
 void
 CommandCounterIncrement(void)
 {
-       CurrentTransactionStateData.commandId += 1;
-       if (CurrentTransactionStateData.commandId == FirstCommandId)
+       TransactionState s = CurrentTransactionState;
+
+       s->commandId += 1;
+       if (s->commandId == FirstCommandId)     /* check for overflow */
                elog(ERROR, "You may only have 2^32-1 commands per transaction");
 
-       CurrentTransactionStateData.scanCommandId = CurrentTransactionStateData.commandId;
+       /* Propagate new command ID into query snapshots, if set */
+       if (QuerySnapshot)
+               QuerySnapshot->curcid = s->commandId;
+       if (SerializableSnapshot)
+               SerializableSnapshot->curcid = s->commandId;
 
        /*
         * make cache changes visible to me.  AtCommit_LocalCache() instead of
@@ -451,11 +438,6 @@ CommandCounterIncrement(void)
        AtStart_Cache();
 }
 
-void
-SetScanCommandId(CommandId savedId)
-{
-       CurrentTransactionStateData.scanCommandId = savedId;
-}
 
 /* ----------------------------------------------------------------
  *                                             StartTransaction stuff
@@ -889,10 +871,6 @@ StartTransaction(void)
         * initialize current transaction state fields
         */
        s->commandId = FirstCommandId;
-       s->scanCommandId = FirstCommandId;
-#if NOT_USED
-       s->startTime = GetCurrentAbsoluteTime();
-#endif
        s->startTime = GetCurrentAbsoluteTimeUsec(&(s->startTimeUsec));
 
        /*
index 16761775bdb04f360f338c4061e73792f7e3a70a..f6d8b623c5b2be30ffdb95dbdcab6fe4d31c4686 100644 (file)
@@ -680,7 +680,7 @@ InsertOneTuple(Oid objectid)
 
        if (objectid != (Oid) 0)
                tuple->t_data->t_oid = objectid;
-       heap_insert(boot_reldesc, tuple);
+       simple_heap_insert(boot_reldesc, tuple);
        heap_freetuple(tuple);
        elog(DEBUG3, "row inserted");
 
index eb65f30de1331ac061037fa3b537bdc68794dd30..0d61e3fc5e6bd2a98d60602c021f78ace2aeaa7b 100644 (file)
@@ -440,7 +440,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
                                                         ATTRIBUTE_TUPLE_SIZE,
                                                         (void *) *dpp);
 
-               heap_insert(rel, tup);
+               simple_heap_insert(rel, tup);
 
                if (hasindex)
                        CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
@@ -474,7 +474,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
                        /* attStruct->attstattarget = 0; */
                        /* attStruct->attcacheoff = -1; */
 
-                       heap_insert(rel, tup);
+                       simple_heap_insert(rel, tup);
 
                        if (hasindex)
                                CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
@@ -574,7 +574,7 @@ AddNewRelationTuple(Relation pg_class_desc,
        /*
         * finally insert the new tuple and free it.
         */
-       heap_insert(pg_class_desc, tup);
+       simple_heap_insert(pg_class_desc, tup);
 
        if (!IsIgnoringSystemIndexes())
        {
@@ -1308,7 +1308,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin)
                                                                                                 CStringGetDatum(adsrc));
        adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
        tuple = heap_formtuple(adrel->rd_att, values, nulls);
-       heap_insert(adrel, tuple);
+       simple_heap_insert(adrel, tuple);
        CatalogOpenIndices(Num_pg_attrdef_indices, Name_pg_attrdef_indices,
                                           idescs);
        CatalogIndexInsert(idescs, Num_pg_attrdef_indices, adrel, tuple);
@@ -1388,7 +1388,7 @@ StoreRelCheck(Relation rel, char *ccname, char *ccbin)
                                                                                                 CStringGetDatum(ccsrc));
        rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
        tuple = heap_formtuple(rcrel->rd_att, values, nulls);
-       heap_insert(rcrel, tuple);
+       simple_heap_insert(rcrel, tuple);
        CatalogOpenIndices(Num_pg_relcheck_indices, Name_pg_relcheck_indices,
                                           idescs);
        CatalogIndexInsert(idescs, Num_pg_relcheck_indices, rcrel, tuple);
index 84488eb78a95e34f144f2ef823b8177a464a193b..459f0200bf5642dd3d324a068898e86c9480eaa9 100644 (file)
@@ -327,7 +327,7 @@ UpdateRelationRelation(Relation indexRelation)
         * sure would be embarrassing to do this sort of thing in polite company.
         */
        tuple->t_data->t_oid = RelationGetRelid(indexRelation);
-       heap_insert(pg_class, tuple);
+       simple_heap_insert(pg_class, tuple);
 
        /*
         * During normal processing, we need to make sure that the system
@@ -408,7 +408,7 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
                                                                   ATTRIBUTE_TUPLE_SIZE,
                                                                   (void *) indexTupDesc->attrs[i]);
 
-               heap_insert(pg_attribute, new_tuple);
+               simple_heap_insert(pg_attribute, new_tuple);
 
                if (hasind)
                        CatalogIndexInsert(idescs, Num_pg_attr_indices, pg_attribute, new_tuple);
@@ -500,7 +500,7 @@ UpdateIndexRelation(Oid indexoid,
        /*
         * insert the tuple into the pg_index
         */
-       heap_insert(pg_index, tuple);
+       simple_heap_insert(pg_index, tuple);
 
        /*
         * add index tuples for it
@@ -1010,7 +1010,8 @@ LockClassinfoForUpdate(Oid relid, HeapTuple rtup,
                ItemPointerData tidsave;
 
                ItemPointerCopy(&(rtup->t_self), &tidsave);
-               test = heap_mark4update(relationRelation, rtup, buffer);
+               test = heap_mark4update(relationRelation, rtup, buffer,
+                                                               GetCurrentCommandId());
                switch (test)
                {
                        case HeapTupleSelfUpdated:
index ec8618c414dc46ae392b674b6e69dfae8009403c..60a8508e1f6ea91292bbea59609d8a85ffe0710a 100644 (file)
@@ -174,7 +174,7 @@ AggregateCreate(const char *aggName,
        tupDesc = aggdesc->rd_att;
 
        tup = heap_formtuple(tupDesc, values, nulls);
-       heap_insert(aggdesc, tup);
+       simple_heap_insert(aggdesc, tup);
 
        if (RelationGetForm(aggdesc)->relhasindex)
        {
index 8114cf6693189b9a7a76dc2719db6b782e604e6c..c3b3a426440267827856a7aafce53fd685cf440d 100644 (file)
@@ -63,7 +63,7 @@ LargeObjectCreate(Oid loid)
        /*
         * Insert it
         */
-       heap_insert(pg_largeobject, ntup);
+       simple_heap_insert(pg_largeobject, ntup);
 
        /*
         * Update indices
index 085d3e6bdda79268666b0646492165b89b4b00d7..974eb3cd4bcd96b2584308306835da97840c2c52 100644 (file)
@@ -61,13 +61,10 @@ NamespaceCreate(const char *nspName, int32 ownerSysId)
 
        nspdesc = heap_openr(NamespaceRelationName, RowExclusiveLock);
        tupDesc = nspdesc->rd_att;
-       if (!HeapTupleIsValid(tup = heap_formtuple(tupDesc,
-                                                                                          values,
-                                                                                          nulls)))
-               elog(ERROR, "NamespaceCreate: heap_formtuple failed");
-       nspoid = heap_insert(nspdesc, tup);
-       if (!OidIsValid(nspoid))
-               elog(ERROR, "NamespaceCreate: heap_insert failed");
+
+       tup = heap_formtuple(tupDesc, values, nulls);
+       nspoid = simple_heap_insert(nspdesc, tup);
+       Assert(OidIsValid(nspoid));
 
        if (RelationGetForm(nspdesc)->relhasindex)
        {
index 0a8cfcfbe79f4047c0b78a661c81f991e7a5e613..9c58ca6bdee484cbeab5af2be23b40dff9ae1d01 100644 (file)
@@ -260,8 +260,7 @@ OperatorShellMake(const char *operatorName,
        /*
         * insert our "shell" operator tuple
         */
-       heap_insert(pg_operator_desc, tup);
-       operatorObjectId = tup->t_data->t_oid;
+       operatorObjectId = simple_heap_insert(pg_operator_desc, tup);
 
        if (RelationGetForm(pg_operator_desc)->relhasindex)
        {
@@ -360,7 +359,7 @@ OperatorShellMake(const char *operatorName,
  *      get the t_self from the modified tuple and call RelationReplaceHeapTuple
  * else if a new operator is being created
  *      create a tuple using heap_formtuple
- *      call heap_insert
+ *      call simple_heap_insert
  */
 void
 OperatorCreate(const char *operatorName,
@@ -647,8 +646,7 @@ OperatorCreate(const char *operatorName,
                tupDesc = pg_operator_desc->rd_att;
                tup = heap_formtuple(tupDesc, values, nulls);
 
-               heap_insert(pg_operator_desc, tup);
-               operatorObjectId = tup->t_data->t_oid;
+               operatorObjectId = simple_heap_insert(pg_operator_desc, tup);
        }
 
        /* Must update the indexes in either case */
index dced7752709393b00110c4c0602ec2711d61250d..6a686e8a4f04d5d39ec08b6cb02ab38ab8fb8cdd 100644 (file)
@@ -298,7 +298,7 @@ ProcedureCreate(const char *procedureName,
                nulls[Anum_pg_proc_proacl-1] = 'n';
 
                tup = heap_formtuple(tupDesc, values, nulls);
-               heap_insert(rel, tup);
+               simple_heap_insert(rel, tup);
        }
 
        /* Need to update indices for either the insert or update case */
index b41cda9deed4f54b294361bdd9cf8ae7e77613ed..716d37ae230eb3c52266bbe79ecda56413bf9299 100644 (file)
@@ -102,8 +102,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
        /*
         * insert the tuple in the relation and get the tuple's oid.
         */
-       heap_insert(pg_type_desc, tup);
-       typoid = tup->t_data->t_oid;
+       typoid = simple_heap_insert(pg_type_desc, tup);
 
        if (RelationGetForm(pg_type_desc)->relhasindex)
        {
@@ -286,9 +285,7 @@ TypeCreate(const char *typeName,
                /* preassign tuple Oid, if one was given */
                tup->t_data->t_oid = assignedTypeOid;
 
-               heap_insert(pg_type_desc, tup);
-
-               typeObjectId = tup->t_data->t_oid;
+               typeObjectId = simple_heap_insert(pg_type_desc, tup);
        }
 
        /* Update indices (not necessary if bootstrapping) */
index ee1defbc97c53504b6fc67c00a6de92118f3be1f..0e4da7753ea439716f25f4e3f9f54a14270e77cc 100644 (file)
@@ -1787,7 +1787,7 @@ update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
                {
                        /* No, insert new tuple */
                        stup = heap_formtuple(sd->rd_att, values, nulls);
-                       heap_insert(sd, stup);
+                       simple_heap_insert(sd, stup);
                }
 
                /* update indices too */
index ed503ea97b6c389b3bb2cdaceda12aa7e36483ac..42a5f1deced8ce479d826bb81ce10448a0eaa446 100644 (file)
@@ -242,7 +242,7 @@ Async_Listen(char *relname, int pid)
        values[i++] = (Datum) 0;        /* no notifies pending */
 
        tuple = heap_formtuple(RelationGetDescr(lRel), values, nulls);
-       heap_insert(lRel, tuple);
+       simple_heap_insert(lRel, tuple);
 
 #ifdef NOT_USED                                        /* currently there are no indexes */
        if (RelationGetForm(lRel)->relhasindex)
index 2929ade5fa96f94a60829b975afe530056b186ac..8cde67425c3bfb0ab05c913b9e422f0c7b3bdfaf 100644 (file)
@@ -241,7 +241,7 @@ rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
                 */
                HeapTuple       copiedTuple = heap_copytuple(LocalHeapTuple);
 
-               heap_insert(LocalNewHeap, copiedTuple);
+               simple_heap_insert(LocalNewHeap, copiedTuple);
                heap_freetuple(copiedTuple);
 
                CHECK_FOR_INTERRUPTS();
index c6fbf2d1f27461232aab410a506472f942fb302f..272e14a6ef8dd840a90141d66c6a035a508bb524 100644 (file)
@@ -199,7 +199,7 @@ CreateComments(Oid oid, Oid classoid, int32 subid, char *comment)
        {
                newtuple = heap_formtuple(RelationGetDescr(description),
                                                                  values, nulls);
-               heap_insert(description, newtuple);
+               simple_heap_insert(description, newtuple);
        }
 
        /* Update indexes, if necessary */
index a8e7bb48daf977c57227d3be3131681dac7ca7fc..efeef4045f94d5a501084feedd47451da97fec0e 100644 (file)
@@ -947,7 +947,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
                        /*
                         * OK, store the tuple and create index entries for it
                         */
-                       heap_insert(rel, tuple);
+                       simple_heap_insert(rel, tuple);
 
                        if (resultRelInfo->ri_NumIndices > 0)
                                ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false);
index 8b7aba30de93bf0133b6277241c5a03699ff1391..8f0fbca8126548571d870d2b4eafa60d2b2dc787 100644 (file)
@@ -293,7 +293,7 @@ createdb(const char *dbname, const char *dbowner,
        tuple->t_data->t_oid = dboid;           /* override heap_insert's OID
                                                                                 * selection */
 
-       heap_insert(pg_database_rel, tuple);
+       simple_heap_insert(pg_database_rel, tuple);
 
        /*
         * Update indexes
index aa7e60952fd10da7093ae08c51f7a8e6f910d585..97c02451ae426fc4cfa1871b5bffd6284345b4b8 100644 (file)
@@ -74,7 +74,6 @@ PerformPortalFetch(char *name,
        EState     *estate;
        MemoryContext oldcontext;
        ScanDirection direction;
-       CommandId       savedId;
        bool            temp_desc = false;
 
        /* initialize completion status in case of early exit */
@@ -131,14 +130,6 @@ PerformPortalFetch(char *name,
                temp_desc = true;
        }
 
-       /*
-        * Restore the scanCommandId that was current when the cursor was
-        * opened.  This ensures that we see the same tuples throughout the
-        * execution of the cursor.
-        */
-       savedId = GetScanCommandId();
-       SetScanCommandId(PortalGetCommandId(portal));
-
        /*
         * Determine which direction to go in, and check to see if we're
         * already at the end of the available tuples in that direction.  If
@@ -185,11 +176,6 @@ PerformPortalFetch(char *name,
                                 (dest == None) ? "MOVE" : "FETCH",
                                 estate->es_processed);
 
-       /*
-        * Restore outer command ID.
-        */
-       SetScanCommandId(savedId);
-
        /*
         * Clean up and switch back to old context.
         */
index 026ef84bfc2884e9a5b7bda54eb3ad01b8732a28..75f4546dba74f2ccfb0a56171178b85cf7db96ea 100644 (file)
@@ -102,7 +102,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
        tupDesc = rel->rd_att;
        tup = heap_formtuple(tupDesc, values, nulls);
 
-       heap_insert(rel, tup);
+       simple_heap_insert(rel, tup);
 
        if (RelationGetForm(rel)->relhasindex)
        {
index fa05386f4f4880e2436520fe1d10da94faee0516..90c5c3258a12574832de9e9b09df97a2ab6c8a77 100644 (file)
@@ -197,7 +197,7 @@ DefineSequence(CreateSeqStmt *seq)
 
        /* Now form & insert sequence tuple */
        tuple = heap_formtuple(tupDesc, value, null);
-       heap_insert(rel, tuple);
+       simple_heap_insert(rel, tuple);
 
        Assert(ItemPointerGetOffsetNumber(&(tuple->t_self)) == FirstOffsetNumber);
 
index bdfdece412c5b1e656dccbdd3bd7f54907ec1d2e..d5ae5b7e86d2cdc61c2cf83a8d3a987572880ea2 100644 (file)
@@ -821,7 +821,7 @@ StoreCatalogInheritance(Oid relationId, List *supers)
 
                tuple = heap_formtuple(desc, datum, nullarr);
 
-               heap_insert(relation, tuple);
+               simple_heap_insert(relation, tuple);
 
                if (RelationGetForm(relation)->relhasindex)
                {
@@ -1673,7 +1673,7 @@ AlterTableAddColumn(Oid myrelid,
 
        ReleaseSysCache(typeTuple);
 
-       heap_insert(attrdesc, attributeTuple);
+       simple_heap_insert(attrdesc, attributeTuple);
 
        /* Update indexes on pg_attribute */
        if (RelationGetForm(attrdesc)->relhasindex)
@@ -2890,7 +2890,8 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
        classtuple.t_self = reltup->t_self;
        ReleaseSysCache(reltup);
 
-       switch (heap_mark4update(class_rel, &classtuple, &buffer))
+       switch (heap_mark4update(class_rel, &classtuple, &buffer,
+                                                        GetCurrentCommandId()))
        {
                case HeapTupleSelfUpdated:
                case HeapTupleMayBeUpdated:
index d28c0653a6ef1e194fd156fd75010f80129d4c39..cc430066f34b86b2ba05c8b38cf229c818cf266a 100644 (file)
@@ -270,7 +270,7 @@ CreateTrigger(CreateTrigStmt *stmt)
        /*
         * Insert tuple into pg_trigger.
         */
-       heap_insert(tgrel, tuple);
+       simple_heap_insert(tgrel, tuple);
        CatalogOpenIndices(Num_pg_trigger_indices, Name_pg_trigger_indices, idescs);
        CatalogIndexInsert(idescs, Num_pg_trigger_indices, tgrel, tuple);
        CatalogCloseIndices(Num_pg_trigger_indices, idescs);
@@ -1183,7 +1183,8 @@ GetTupleForTrigger(EState *estate, ResultRelInfo *relinfo,
                *newSlot = NULL;
                tuple.t_self = *tid;
 ltrmark:;
-               test = heap_mark4update(relation, &tuple, &buffer);
+               test = heap_mark4update(relation, &tuple, &buffer,
+                                                               GetCurrentCommandId());
                switch (test)
                {
                        case HeapTupleSelfUpdated:
index b3ab1b996654b0235318a1e0aaf66df6871f1b5b..0c34c2bb8f9197cf774af8d384f3d7fc1e97a2a6 100644 (file)
@@ -596,7 +596,7 @@ CreateUser(CreateUserStmt *stmt)
        /*
         * Insert new record in the pg_shadow table
         */
-       heap_insert(pg_shadow_rel, tuple);
+       simple_heap_insert(pg_shadow_rel, tuple);
 
        /*
         * Update indexes
@@ -1213,9 +1213,9 @@ CreateGroup(CreateGroupStmt *stmt)
        tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls);
 
        /*
-        * Insert a new record in the pg_group_table
+        * Insert a new record in the pg_group table
         */
-       heap_insert(pg_group_rel, tuple);
+       simple_heap_insert(pg_group_rel, tuple);
 
        /*
         * Update indexes
index 6290b74bc364c07be155d182086c6344922a2921..2b37ec82677c515688b4bd7ee801af14ed9c2f25 100644 (file)
@@ -101,6 +101,7 @@ TupleDesc
 ExecutorStart(QueryDesc *queryDesc, EState *estate)
 {
        TupleDesc       result;
+       Snapshot        es_snapshot;
 
        /* sanity checks */
        Assert(queryDesc != NULL);
@@ -114,22 +115,28 @@ ExecutorStart(QueryDesc *queryDesc, EState *estate)
        }
 
        /*
-        * Make our own private copy of the current queries snapshot data
+        * Make our own private copy of the current query snapshot data.
+        *
+        * This "freezes" our idea of which tuples are good and which are not
+        * for the life of this query, even if it outlives the current command
+        * and current snapshot.
         */
-       if (QuerySnapshot == NULL)
-               estate->es_snapshot = NULL;
-       else
+       if (QuerySnapshot == NULL)      /* should be set already, but... */
+               SetQuerySnapshot();
+
+       es_snapshot = (Snapshot) palloc(sizeof(SnapshotData));
+       memcpy(es_snapshot, QuerySnapshot, sizeof(SnapshotData));
+       if (es_snapshot->xcnt > 0)
        {
-               estate->es_snapshot = (Snapshot) palloc(sizeof(SnapshotData));
-               memcpy(estate->es_snapshot, QuerySnapshot, sizeof(SnapshotData));
-               if (estate->es_snapshot->xcnt > 0)
-               {
-                       estate->es_snapshot->xip = (TransactionId *)
-                               palloc(estate->es_snapshot->xcnt * sizeof(TransactionId));
-                       memcpy(estate->es_snapshot->xip, QuerySnapshot->xip,
-                                  estate->es_snapshot->xcnt * sizeof(TransactionId));
-               }
+               es_snapshot->xip = (TransactionId *)
+                       palloc(es_snapshot->xcnt * sizeof(TransactionId));
+               memcpy(es_snapshot->xip, QuerySnapshot->xip,
+                          es_snapshot->xcnt * sizeof(TransactionId));
        }
+       else
+               es_snapshot->xip = NULL;
+
+       estate->es_snapshot = es_snapshot;
 
        /*
         * Initialize the plan
@@ -1031,7 +1038,8 @@ lnext:    ;
                                                         erm->resname);
 
                                        tuple.t_self = *((ItemPointer) DatumGetPointer(datum));
-                                       test = heap_mark4update(erm->relation, &tuple, &buffer);
+                                       test = heap_mark4update(erm->relation, &tuple, &buffer,
+                                                                                       estate->es_snapshot->curcid);
                                        ReleaseBuffer(buffer);
                                        switch (test)
                                        {
@@ -1163,7 +1171,8 @@ ExecRetrieve(TupleTableSlot *slot,
         */
        if (estate->es_into_relation_descriptor != NULL)
        {
-               heap_insert(estate->es_into_relation_descriptor, tuple);
+               heap_insert(estate->es_into_relation_descriptor, tuple,
+                                       estate->es_snapshot->curcid);
                IncrAppended();
        }
 
@@ -1239,7 +1248,8 @@ ExecAppend(TupleTableSlot *slot,
        /*
         * insert the tuple
         */
-       newId = heap_insert(resultRelationDesc, tuple);
+       newId = heap_insert(resultRelationDesc, tuple,
+                                               estate->es_snapshot->curcid);
 
        IncrAppended();
        (estate->es_processed)++;
@@ -1301,7 +1311,9 @@ ExecDelete(TupleTableSlot *slot,
         * delete the tuple
         */
 ldelete:;
-       result = heap_delete(resultRelationDesc, tupleid, &ctid);
+       result = heap_delete(resultRelationDesc, tupleid,
+                                                &ctid,
+                                                estate->es_snapshot->curcid);
        switch (result)
        {
                case HeapTupleSelfUpdated:
@@ -1433,7 +1445,9 @@ lreplace:;
        /*
         * replace the heap tuple
         */
-       result = heap_update(resultRelationDesc, tupleid, tuple, &ctid);
+       result = heap_update(resultRelationDesc, tupleid, tuple,
+                                                &ctid,
+                                                estate->es_snapshot->curcid);
        switch (result)
        {
                case HeapTupleSelfUpdated:
index 7ac372ef1916bd5ba60ede361d66cb8863d6705e..84b2cd943a3f6c25e0ebf316f250efb599618d36 100644 (file)
@@ -465,7 +465,6 @@ fmgr_sql(PG_FUNCTION_ARGS)
        SQLFunctionCachePtr fcache;
        execution_state *es;
        Datum           result = 0;
-       CommandId       savedId;
 
        /*
         * Switch to context in which the fcache lives.  This ensures that
@@ -474,14 +473,6 @@ fmgr_sql(PG_FUNCTION_ARGS)
         */
        oldcontext = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
 
-       /*
-        * Before we start do anything we must save CurrentScanCommandId to
-        * restore it before return to upper Executor. Also, we have to set
-        * CurrentScanCommandId equal to CurrentCommandId. - vadim 08/29/97
-        */
-       savedId = GetScanCommandId();
-       SetScanCommandId(GetCurrentCommandId());
-
        /*
         * Initialize fcache and execution state if first time through.
         */
@@ -515,11 +506,6 @@ fmgr_sql(PG_FUNCTION_ARGS)
                es = es->next;
        }
 
-       /*
-        * Restore outer command ID.
-        */
-       SetScanCommandId(savedId);
-
        /*
         * If we've gone through every command in this function, we are done.
         */
index 6c1e44bff088e798419b6de7b692d825b9b35ffc..a879089db03fccf898f373b0dd5dc2d72e97a701 100644 (file)
@@ -106,11 +106,7 @@ SPI_connect(void)
        /* ... and switch to procedure's context */
        _SPI_current->savedcxt = MemoryContextSwitchTo(_SPI_current->procCxt);
 
-       _SPI_current->savedId = GetScanCommandId();
-       SetScanCommandId(GetCurrentCommandId());
-
        return SPI_OK_CONNECT;
-
 }
 
 int
@@ -129,8 +125,6 @@ SPI_finish(void)
        MemoryContextDelete(_SPI_current->execCxt);
        MemoryContextDelete(_SPI_current->procCxt);
 
-       SetScanCommandId(_SPI_current->savedId);
-
        /*
         * After _SPI_begin_call _SPI_connected == _SPI_curid. Now we are
         * closing connection to SPI and returning to upper Executor and so
@@ -1233,7 +1227,6 @@ _SPI_cursor_operation(Portal portal, bool forward, int count,
        EState     *estate;
        MemoryContext oldcontext;
        ScanDirection direction;
-       CommandId       savedId;
        CommandDest olddest;
 
        /* Check that the portal is valid */
@@ -1260,14 +1253,6 @@ _SPI_cursor_operation(Portal portal, bool forward, int count,
        olddest = querydesc->dest;
        querydesc->dest = dest;
 
-       /*
-        * Restore the scanCommandId that was current when the cursor was
-        * opened.  This ensures that we see the same tuples throughout the
-        * execution of the cursor.
-        */
-       savedId = GetScanCommandId();
-       SetScanCommandId(PortalGetCommandId(portal));
-
        /* Run the executor like PerformPortalFetch and remember states */
        if (forward)
        {
@@ -1300,11 +1285,6 @@ _SPI_cursor_operation(Portal portal, bool forward, int count,
 
        _SPI_current->processed = estate->es_processed;
 
-       /*
-        * Restore outer command ID.
-        */
-       SetScanCommandId(savedId);
-
        /* Restore the old command destination and switch back to callers */
        /* memory context */
        querydesc->dest = olddest;
index 435102fc275c23b04bc9a9ec9ae227df7a931fa1..b29c550a0d0e61eb50c3504b602252a70a9dee08 100644 (file)
@@ -88,9 +88,7 @@ InsertRule(char *rulname,
                                                 values,
                                                 nulls);
 
-       heap_insert(pg_rewrite_desc, tup);
-
-       rewriteObjectId = tup->t_data->t_oid;
+       rewriteObjectId = simple_heap_insert(pg_rewrite_desc, tup);
 
        if (RelationGetForm(pg_rewrite_desc)->relhasindex)
        {
index f6bfc11db5d77730edc8fdfc0b44b12eb398ba45..b34cd978a45d205778c2940bff0817ac7956d206 100644 (file)
@@ -397,6 +397,9 @@ GetSnapshotData(bool serializable)
        Assert(TransactionIdIsValid(MyProc->xmin));
 
        snapshot->xcnt = count;
+
+       snapshot->curcid = GetCurrentCommandId();
+
        return snapshot;
 }
 
index 8bdc36791c1087f185f601bd50408896dacc1e50..173a13fe2c83d76998b800a924793140b75a62d1 100644 (file)
@@ -555,7 +555,7 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes)
                        values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno);
                        values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
                        newtup = heap_formtuple(obj_desc->heap_r->rd_att, values, nulls);
-                       heap_insert(obj_desc->heap_r, newtup);
+                       simple_heap_insert(obj_desc->heap_r, newtup);
                        if (write_indices)
                                CatalogIndexInsert(idescs, Num_pg_largeobject_indices,
                                                                   obj_desc->heap_r, newtup);
index aff665c257e7c761a9a4fa556737e06454637393..dc5dafe8ef05581e7494fe76e78b3995738b3744 100644 (file)
@@ -168,7 +168,6 @@ PortalSetQuery(Portal portal,
 
        portal->queryDesc = queryDesc;
        portal->attinfo = attinfo;
-       portal->commandId = GetScanCommandId();
        portal->state = state;
        portal->atStart = true;         /* Allow fetch forward only */
        portal->atEnd = false;
@@ -214,7 +213,6 @@ CreatePortal(char *name)
        /* initialize portal query */
        portal->queryDesc = NULL;
        portal->attinfo = NULL;
-       portal->commandId = 0;
        portal->state = NULL;
        portal->atStart = true;         /* disallow fetches until query is set */
        portal->atEnd = true;
index 34fbd8d830913346497cb576ec69c2b210206833..427abbd3fb6ed354d3a576ae31ddefa5353979ff 100644 (file)
@@ -238,7 +238,7 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple)
                }
                else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin))
                {
-                       if (CommandIdGEScanCommandId(tuple->t_cmin))
+                       if (tuple->t_cmin >= GetCurrentCommandId())
                                return false;   /* inserted after scan started */
 
                        if (tuple->t_infomask & HEAP_XMAX_INVALID)      /* xid invalid */
@@ -249,7 +249,7 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple)
                        if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
                                return true;
 
-                       if (CommandIdGEScanCommandId(tuple->t_cmax))
+                       if (tuple->t_cmax >= GetCurrentCommandId())
                                return true;    /* deleted after scan started */
                        else
                                return false;   /* deleted before scan started */
@@ -280,7 +280,7 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple)
        {
                if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
                        return true;
-               if (CommandIdGEScanCommandId(tuple->t_cmax))
+               if (tuple->t_cmax >= GetCurrentCommandId())
                        return true;            /* deleted after scan started */
                else
                        return false;           /* deleted before scan started */
@@ -363,10 +363,12 @@ HeapTupleSatisfiesToast(HeapTupleHeader tuple)
  * HeapTupleSatisfiesUpdate
  *
  *     Same logic as HeapTupleSatisfiesNow, but returns a more detailed result
- *     code, since UPDATE needs to know more than "is it visible?".
+ *     code, since UPDATE needs to know more than "is it visible?".  Also,
+ *     tuples of my own xact are tested against the passed CommandId not
+ *     CurrentCommandId.
  */
 int
-HeapTupleSatisfiesUpdate(HeapTuple htuple)
+HeapTupleSatisfiesUpdate(HeapTuple htuple, CommandId curcid)
 {
        HeapTupleHeader tuple = htuple->t_data;
 
@@ -409,7 +411,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htuple)
                }
                else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin))
                {
-                       if (CommandIdGEScanCommandId(tuple->t_cmin))
+                       if (tuple->t_cmin >= curcid)
                                return HeapTupleInvisible;              /* inserted after scan
                                                                                                 * started */
 
@@ -421,7 +423,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htuple)
                        if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
                                return HeapTupleMayBeUpdated;
 
-                       if (CommandIdGEScanCommandId(tuple->t_cmax))
+                       if (tuple->t_cmax >= curcid)
                                return HeapTupleSelfUpdated;    /* updated after scan
                                                                                                 * started */
                        else
@@ -454,7 +456,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htuple)
        {
                if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
                        return HeapTupleMayBeUpdated;
-               if (CommandIdGEScanCommandId(tuple->t_cmax))
+               if (tuple->t_cmax >= curcid)
                        return HeapTupleSelfUpdated;            /* updated after scan
                                                                                                 * started */
                else
@@ -677,7 +679,7 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot)
                }
                else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin))
                {
-                       if (CommandIdGEScanCommandId(tuple->t_cmin))
+                       if (tuple->t_cmin >= snapshot->curcid)
                                return false;   /* inserted after scan started */
 
                        if (tuple->t_infomask & HEAP_XMAX_INVALID)      /* xid invalid */
@@ -688,7 +690,7 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot)
                        if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
                                return true;
 
-                       if (CommandIdGEScanCommandId(tuple->t_cmax))
+                       if (tuple->t_cmax >= snapshot->curcid)
                                return true;    /* deleted after scan started */
                        else
                                return false;   /* deleted before scan started */
@@ -730,7 +732,7 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot)
        {
                if (TransactionIdIsCurrentTransactionId(tuple->t_xmax))
                {
-                       if (CommandIdGEScanCommandId(tuple->t_cmax))
+                       if (tuple->t_cmax >= snapshot->curcid)
                                return true;    /* deleted after scan started */
                        else
                                return false;   /* deleted before scan started */
@@ -950,6 +952,7 @@ SetQuerySnapshot(void)
        {
                free(QuerySnapshot->xip);
                free(QuerySnapshot);
+               QuerySnapshot = NULL;
        }
 
        if (XactIsoLevel == XACT_SERIALIZABLE)
index 07fad4bb43ae706ded2447bab22192820b4270ac..f54c53a924ea2d28e816fbb864e746b2007b6cd0 100644 (file)
@@ -156,16 +156,23 @@ extern void heap_fetch(Relation relation, Snapshot snapshot,
                                           HeapTuple tuple, Buffer *userbuf,
                                           PgStat_Info *pgstat_info);
 
-extern ItemPointer heap_get_latest_tid(Relation relation, Snapshot snapshot, ItemPointer tid);
+extern ItemPointer heap_get_latest_tid(Relation relation, Snapshot snapshot,
+                                                                          ItemPointer tid);
 extern void setLastTid(const ItemPointer tid);
-extern Oid     heap_insert(Relation relation, HeapTuple tup);
-extern int     heap_delete(Relation relation, ItemPointer tid, ItemPointer ctid);
+
+extern Oid     heap_insert(Relation relation, HeapTuple tup, CommandId cid);
+extern int     heap_delete(Relation relation, ItemPointer tid, ItemPointer ctid,
+                                               CommandId cid);
 extern int heap_update(Relation relation, ItemPointer otid, HeapTuple tup,
-                       ItemPointer ctid);
-extern int     heap_mark4update(Relation relation, HeapTuple tup, Buffer *userbuf);
+                                          ItemPointer ctid, CommandId cid);
+extern int     heap_mark4update(Relation relation, HeapTuple tup,
+                                                        Buffer *userbuf, CommandId cid);
+
+extern Oid     simple_heap_insert(Relation relation, HeapTuple tup);
 extern void simple_heap_delete(Relation relation, ItemPointer tid);
 extern void simple_heap_update(Relation relation, ItemPointer otid,
                                   HeapTuple tup);
+
 extern void heap_markpos(HeapScanDesc scan);
 extern void heap_restrpos(HeapScanDesc scan);
 
index f58882f4c34e9a1fcacb653b4fce70232864aab7..8b6bb74a328939f340cf536d08f1a85a0a6ee420 100644 (file)
@@ -38,7 +38,6 @@ typedef struct TransactionStateData
 {
        TransactionId transactionIdData;
        CommandId       commandId;
-       CommandId       scanCommandId;
        AbsoluteTime startTime;
        int                     startTimeUsec;
        int                     state;
@@ -101,13 +100,10 @@ extern bool IsTransactionState(void);
 extern bool IsAbortedTransactionBlockState(void);
 extern TransactionId GetCurrentTransactionId(void);
 extern CommandId GetCurrentCommandId(void);
-extern CommandId GetScanCommandId(void);
-extern void SetScanCommandId(CommandId);
 extern AbsoluteTime GetCurrentTransactionStartTime(void);
 extern AbsoluteTime GetCurrentTransactionStartTimeUsec(int *usec);
 extern bool TransactionIdIsCurrentTransactionId(TransactionId xid);
 extern bool CommandIdIsCurrentCommandId(CommandId cid);
-extern bool CommandIdGEScanCommandId(CommandId cid);
 extern void CommandCounterIncrement(void);
 extern void StartTransactionCommand(void);
 extern void CommitTransactionCommand(void);
index 00baf1ad7e5c0ad5e1e8d4f5cf05ac1fd541f374..19efa9c69a7a096e3b3f879bd772b2d91cc690c2 100644 (file)
@@ -20,7 +20,6 @@ typedef struct
        MemoryContext procCxt;          /* procedure context */
        MemoryContext execCxt;          /* executor context */
        MemoryContext savedcxt;
-       CommandId       savedId;
 } _SPI_connection;
 
 typedef struct
index 2da8f096f96c552cf5385ed4c4145a5cab1dac4c..d5bccbebe8d83c724960ccb61e511d1eb08e7f35 100644 (file)
@@ -31,7 +31,6 @@ typedef struct PortalData
        MemoryContext heap;                     /* subsidiary memory */
        QueryDesc  *queryDesc;          /* Info about query associated with portal */
        TupleDesc       attinfo;
-       CommandId       commandId;              /* Command counter value for query */
        EState     *state;                      /* Execution state of query */
        bool            atStart;                /* T => fetch backwards is not allowed */
        bool            atEnd;                  /* T => fetch forwards is not allowed */
@@ -49,7 +48,6 @@ typedef struct PortalData
  */
 #define PortalGetQueryDesc(portal)     ((portal)->queryDesc)
 #define PortalGetTupleDesc(portal)     ((portal)->attinfo)
-#define PortalGetCommandId(portal)     ((portal)->commandId)
 #define PortalGetState(portal)         ((portal)->state)
 #define PortalGetHeapMemory(portal)    ((portal)->heap)
 
index 9605ab19c068561db123c6f1ce73f8b611050e9a..38481fa38386128ab214a665e1372f33fd17330d 100644 (file)
@@ -26,6 +26,7 @@ typedef struct SnapshotData
        uint32          xcnt;                   /* # of xact ids in xip[] */
        TransactionId *xip;                     /* array of xact IDs in progress */
        /* note: all ids in xip[] satisfy xmin <= xip[i] < xmax */
+       CommandId       curcid;                 /* in my xact, CID < curcid are visible */
        ItemPointerData tid;            /* required for Dirty snapshot -:( */
 } SnapshotData;
 
@@ -104,7 +105,8 @@ extern bool HeapTupleSatisfiesDirty(HeapTupleHeader tuple);
 extern bool HeapTupleSatisfiesToast(HeapTupleHeader tuple);
 extern bool HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple,
                                                   Snapshot snapshot);
-extern int     HeapTupleSatisfiesUpdate(HeapTuple tuple);
+extern int     HeapTupleSatisfiesUpdate(HeapTuple tuple,
+                                                                        CommandId curcid);
 extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple,
                                                 TransactionId OldestXmin);