diff options
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/access/heap/heapam.c | 8 | ||||
| -rw-r--r-- | src/backend/access/heap/tuptoaster.c | 4 | ||||
| -rw-r--r-- | src/backend/access/transam/xact.c | 67 | ||||
| -rw-r--r-- | src/backend/commands/async.c | 5 | ||||
| -rw-r--r-- | src/backend/commands/copy.c | 6 | ||||
| -rw-r--r-- | src/backend/commands/explain.c | 4 | ||||
| -rw-r--r-- | src/backend/commands/trigger.c | 29 | ||||
| -rw-r--r-- | src/backend/executor/execMain.c | 65 | ||||
| -rw-r--r-- | src/backend/executor/execUtils.c | 4 | ||||
| -rw-r--r-- | src/backend/executor/spi.c | 4 | ||||
| -rw-r--r-- | src/backend/storage/ipc/procarray.c | 4 | ||||
| -rw-r--r-- | src/backend/utils/cache/inval.c | 15 | ||||
| -rw-r--r-- | src/backend/utils/time/tqual.c | 8 |
13 files changed, 143 insertions, 80 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 20027592b5..1a4fc92f1c 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.245 2007/11/15 21:14:32 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.246 2007/11/30 21:22:53 tgl Exp $ * * * INTERFACE ROUTINES @@ -1891,7 +1891,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, Oid simple_heap_insert(Relation relation, HeapTuple tup) { - return heap_insert(relation, tup, GetCurrentCommandId(), true, true); + return heap_insert(relation, tup, GetCurrentCommandId(true), true, true); } /* @@ -2174,7 +2174,7 @@ simple_heap_delete(Relation relation, ItemPointer tid) result = heap_delete(relation, tid, &update_ctid, &update_xmax, - GetCurrentCommandId(), InvalidSnapshot, + GetCurrentCommandId(true), InvalidSnapshot, true /* wait for commit */ ); switch (result) { @@ -2817,7 +2817,7 @@ simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup) result = heap_update(relation, otid, tup, &update_ctid, &update_xmax, - GetCurrentCommandId(), InvalidSnapshot, + GetCurrentCommandId(true), InvalidSnapshot, true /* wait for commit */ ); switch (result) { diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c index 0a8873f994..f26fa9f4a6 100644 --- a/src/backend/access/heap/tuptoaster.c +++ b/src/backend/access/heap/tuptoaster.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.79 2007/11/15 21:14:32 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.80 2007/11/30 21:22:53 tgl Exp $ * * * INTERFACE ROUTINES @@ -1086,7 +1086,7 @@ toast_save_datum(Relation rel, Datum value, TupleDesc toasttupDesc; Datum t_values[3]; bool t_isnull[3]; - CommandId mycid = GetCurrentCommandId(); + CommandId mycid = GetCurrentCommandId(true); struct varlena *result; struct varatt_external toast_pointer; struct diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 04804c3871..ce0dd81281 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.253 2007/11/15 21:14:32 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.254 2007/11/30 21:22:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -161,6 +161,7 @@ static TransactionState CurrentTransactionState = &TopTransactionStateData; */ static SubTransactionId currentSubTransactionId; static CommandId currentCommandId; +static bool currentCommandIdUsed; /* * xactStartTimestamp is the value of transaction_timestamp(). @@ -435,11 +436,18 @@ GetCurrentSubTransactionId(void) /* * GetCurrentCommandId + * + * "used" must be TRUE if the caller intends to use the command ID to mark + * inserted/updated/deleted tuples. FALSE means the ID is being fetched + * for read-only purposes (ie, as a snapshot validity cutoff). See + * CommandCounterIncrement() for discussion. */ CommandId -GetCurrentCommandId(void) +GetCurrentCommandId(bool used) { /* this is global to a transaction, not subtransaction-local */ + if (used) + currentCommandIdUsed = true; return currentCommandId; } @@ -566,25 +574,50 @@ TransactionIdIsCurrentTransactionId(TransactionId xid) void CommandCounterIncrement(void) { - currentCommandId += 1; - if (currentCommandId == FirstCommandId) /* check for overflow */ + /* + * If the current value of the command counter hasn't been "used" to + * mark tuples, we need not increment it, since there's no need to + * distinguish a read-only command from others. This helps postpone + * command counter overflow, and keeps no-op CommandCounterIncrement + * operations cheap. + */ + if (currentCommandIdUsed) { - currentCommandId -= 1; - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + currentCommandId += 1; + if (currentCommandId == FirstCommandId) /* check for overflow */ + { + currentCommandId -= 1; + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("cannot have more than 2^32-1 commands in a transaction"))); - } + } + currentCommandIdUsed = false; - /* Propagate new command ID into static snapshots, if set */ - if (SerializableSnapshot) - SerializableSnapshot->curcid = currentCommandId; - if (LatestSnapshot) - LatestSnapshot->curcid = currentCommandId; + /* Propagate new command ID into static snapshots, if set */ + if (SerializableSnapshot) + SerializableSnapshot->curcid = currentCommandId; + if (LatestSnapshot) + LatestSnapshot->curcid = currentCommandId; + + /* + * Make any catalog changes done by the just-completed command + * visible in the local syscache. We obviously don't need to do + * this after a read-only command. (But see hacks in inval.c + * to make real sure we don't think a command that queued inval + * messages was read-only.) + */ + AtCommit_LocalCache(); + } /* - * make cache changes visible to me. + * Make any other backends' catalog changes visible to me. + * + * XXX this is probably in the wrong place: CommandCounterIncrement + * should be purely a local operation, most likely. However fooling + * with this will affect asynchronous cross-backend interactions, + * which doesn't seem like a wise thing to do in late beta, so save + * improving this for another day - tgl 2007-11-30 */ - AtCommit_LocalCache(); AtStart_Cache(); } @@ -1416,6 +1449,7 @@ StartTransaction(void) s->subTransactionId = TopSubTransactionId; currentSubTransactionId = TopSubTransactionId; currentCommandId = FirstCommandId; + currentCommandIdUsed = false; /* * must initialize resource-management stuff first @@ -4007,13 +4041,14 @@ ShowTransactionStateRec(TransactionState s) /* use ereport to suppress computation if msg will not be printed */ ereport(DEBUG3, - (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u, nestlvl: %d, children: %s", + (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s", PointerIsValid(s->name) ? s->name : "unnamed", BlockStateAsString(s->blockState), TransStateAsString(s->state), (unsigned int) s->transactionId, (unsigned int) s->subTransactionId, (unsigned int) currentCommandId, + currentCommandIdUsed ? " (used)" : "", s->nestingLevel, nodeToString(s->childXids)))); } diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index 55b99f8c92..c32dd2b19f 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.136 2007/04/12 06:53:46 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.137 2007/11/30 21:22:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -562,7 +562,8 @@ AtCommit_Notify(void) */ result = heap_update(lRel, &lTuple->t_self, rTuple, &update_ctid, &update_xmax, - GetCurrentCommandId(), InvalidSnapshot, + GetCurrentCommandId(true), + InvalidSnapshot, false /* no wait for commit */ ); switch (result) { diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index ef7e04ca28..c68d828fea 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.288 2007/11/15 21:14:33 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.289 2007/11/30 21:22:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1033,7 +1033,7 @@ DoCopy(const CopyStmt *stmt, const char *queryString) * which COPY can be invoked, I think it's OK, because the active * snapshot shouldn't be shared with anything else anyway.) */ - ActiveSnapshot->curcid = GetCurrentCommandId(); + ActiveSnapshot->curcid = GetCurrentCommandId(false); /* Create dest receiver for COPY OUT */ dest = CreateDestReceiver(DestCopyOut, NULL); @@ -1637,7 +1637,7 @@ CopyFrom(CopyState cstate) ExprContext *econtext; /* used for ExecEvalExpr for default atts */ MemoryContext oldcontext = CurrentMemoryContext; ErrorContextCallback errcontext; - CommandId mycid = GetCurrentCommandId(); + CommandId mycid = GetCurrentCommandId(true); bool use_wal = true; /* by default, use WAL logging */ bool use_fsm = true; /* by default, use FSM for free space */ diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index a9aa2cb3e1..f77f8cdc5e 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994-5, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.167 2007/11/15 22:25:15 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.168 2007/11/30 21:22:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -233,7 +233,7 @@ ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params, * EXPLAIN can be invoked, I think it's OK, because the active snapshot * shouldn't be shared with anything else anyway.) */ - ActiveSnapshot->curcid = GetCurrentCommandId(); + ActiveSnapshot->curcid = GetCurrentCommandId(false); /* Create a QueryDesc requesting no output */ queryDesc = CreateQueryDesc(plannedstmt, diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 7dc1950534..1b66bd22ba 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.224 2007/11/16 01:51:22 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.225 2007/11/30 21:22:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -51,7 +51,6 @@ static void InsertTrigger(TriggerDesc *trigdesc, Trigger *trigger, int indx); static HeapTuple GetTupleForTrigger(EState *estate, ResultRelInfo *relinfo, ItemPointer tid, - CommandId cid, TupleTableSlot **newSlot); static HeapTuple ExecCallTriggerFunc(TriggerData *trigdata, int tgindx, @@ -1801,8 +1800,7 @@ ExecASDeleteTriggers(EState *estate, ResultRelInfo *relinfo) bool ExecBRDeleteTriggers(EState *estate, ResultRelInfo *relinfo, - ItemPointer tupleid, - CommandId cid) + ItemPointer tupleid) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; int ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_DELETE]; @@ -1814,7 +1812,7 @@ ExecBRDeleteTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *newSlot; int i; - trigtuple = GetTupleForTrigger(estate, relinfo, tupleid, cid, &newSlot); + trigtuple = GetTupleForTrigger(estate, relinfo, tupleid, &newSlot); if (trigtuple == NULL) return false; @@ -1871,9 +1869,7 @@ ExecARDeleteTriggers(EState *estate, ResultRelInfo *relinfo, if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0) { HeapTuple trigtuple = GetTupleForTrigger(estate, relinfo, - tupleid, - (CommandId) 0, - NULL); + tupleid, NULL); AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_DELETE, true, trigtuple, NULL); @@ -1952,8 +1948,7 @@ ExecASUpdateTriggers(EState *estate, ResultRelInfo *relinfo) HeapTuple ExecBRUpdateTriggers(EState *estate, ResultRelInfo *relinfo, - ItemPointer tupleid, HeapTuple newtuple, - CommandId cid) + ItemPointer tupleid, HeapTuple newtuple) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; int ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_UPDATE]; @@ -1965,7 +1960,7 @@ ExecBRUpdateTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *newSlot; int i; - trigtuple = GetTupleForTrigger(estate, relinfo, tupleid, cid, &newSlot); + trigtuple = GetTupleForTrigger(estate, relinfo, tupleid, &newSlot); if (trigtuple == NULL) return NULL; @@ -2025,9 +2020,7 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo, if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0) { HeapTuple trigtuple = GetTupleForTrigger(estate, relinfo, - tupleid, - (CommandId) 0, - NULL); + tupleid, NULL); AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_UPDATE, true, trigtuple, newtuple); @@ -2038,7 +2031,7 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo, static HeapTuple GetTupleForTrigger(EState *estate, ResultRelInfo *relinfo, - ItemPointer tid, CommandId cid, + ItemPointer tid, TupleTableSlot **newSlot) { Relation relation = relinfo->ri_RelationDesc; @@ -2060,7 +2053,8 @@ GetTupleForTrigger(EState *estate, ResultRelInfo *relinfo, ltrmark:; tuple.t_self = *tid; test = heap_lock_tuple(relation, &tuple, &buffer, - &update_ctid, &update_xmax, cid, + &update_ctid, &update_xmax, + estate->es_output_cid, LockTupleExclusive, false); switch (test) { @@ -2086,8 +2080,7 @@ ltrmark:; epqslot = EvalPlanQual(estate, relinfo->ri_RangeTableIndex, &update_ctid, - update_xmax, - cid); + update_xmax); if (!TupIsNull(epqslot)) { *tid = update_ctid; diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 4b6ad47adb..5886234a1e 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -26,7 +26,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.300 2007/11/15 22:25:15 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.301 2007/11/30 21:22:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -161,6 +161,30 @@ ExecutorStart(QueryDesc *queryDesc, int eflags) palloc0(queryDesc->plannedstmt->nParamExec * sizeof(ParamExecData)); /* + * If non-read-only query, set the command ID to mark output tuples with + */ + switch (queryDesc->operation) + { + case CMD_SELECT: + /* SELECT INTO and SELECT FOR UPDATE/SHARE need to mark tuples */ + if (queryDesc->plannedstmt->intoClause != NULL || + queryDesc->plannedstmt->rowMarks != NIL) + estate->es_output_cid = GetCurrentCommandId(true); + break; + + case CMD_INSERT: + case CMD_DELETE: + case CMD_UPDATE: + estate->es_output_cid = GetCurrentCommandId(true); + break; + + default: + elog(ERROR, "unrecognized operation code: %d", + (int) queryDesc->operation); + break; + } + + /* * Copy other important information into the EState */ estate->es_snapshot = queryDesc->snapshot; @@ -1285,7 +1309,7 @@ lnext: ; test = heap_lock_tuple(erm->relation, &tuple, &buffer, &update_ctid, &update_xmax, - estate->es_snapshot->curcid, + estate->es_output_cid, lockmode, erm->noWait); ReleaseBuffer(buffer); switch (test) @@ -1309,8 +1333,7 @@ lnext: ; newSlot = EvalPlanQual(estate, erm->rti, &update_ctid, - update_xmax, - estate->es_snapshot->curcid); + update_xmax); if (!TupIsNull(newSlot)) { slot = planSlot = newSlot; @@ -1503,7 +1526,7 @@ ExecInsert(TupleTableSlot *slot, * t_self field. */ newId = heap_insert(resultRelationDesc, tuple, - estate->es_snapshot->curcid, + estate->es_output_cid, true, true); IncrAppended(); @@ -1557,8 +1580,7 @@ ExecDelete(ItemPointer tupleid, { bool dodelete; - dodelete = ExecBRDeleteTriggers(estate, resultRelInfo, tupleid, - estate->es_snapshot->curcid); + dodelete = ExecBRDeleteTriggers(estate, resultRelInfo, tupleid); if (!dodelete) /* "do nothing" */ return; @@ -1575,7 +1597,7 @@ ExecDelete(ItemPointer tupleid, ldelete:; result = heap_delete(resultRelationDesc, tupleid, &update_ctid, &update_xmax, - estate->es_snapshot->curcid, + estate->es_output_cid, estate->es_crosscheck_snapshot, true /* wait for commit */ ); switch (result) @@ -1599,8 +1621,7 @@ ldelete:; epqslot = EvalPlanQual(estate, resultRelInfo->ri_RangeTableIndex, &update_ctid, - update_xmax, - estate->es_snapshot->curcid); + update_xmax); if (!TupIsNull(epqslot)) { *tupleid = update_ctid; @@ -1708,8 +1729,7 @@ ExecUpdate(TupleTableSlot *slot, HeapTuple newtuple; newtuple = ExecBRUpdateTriggers(estate, resultRelInfo, - tupleid, tuple, - estate->es_snapshot->curcid); + tupleid, tuple); if (newtuple == NULL) /* "do nothing" */ return; @@ -1755,7 +1775,7 @@ lreplace:; */ result = heap_update(resultRelationDesc, tupleid, tuple, &update_ctid, &update_xmax, - estate->es_snapshot->curcid, + estate->es_output_cid, estate->es_crosscheck_snapshot, true /* wait for commit */ ); switch (result) @@ -1779,8 +1799,7 @@ lreplace:; epqslot = EvalPlanQual(estate, resultRelInfo->ri_RangeTableIndex, &update_ctid, - update_xmax, - estate->es_snapshot->curcid); + update_xmax); if (!TupIsNull(epqslot)) { *tupleid = update_ctid; @@ -1973,7 +1992,6 @@ ExecProcessReturning(ProjectionInfo *projectReturning, * rti - rangetable index of table containing tuple * *tid - t_ctid from the outdated tuple (ie, next updated version) * priorXmax - t_xmax from the outdated tuple - * curCid - command ID of current command of my transaction * * *tid is also an output parameter: it's modified to hold the TID of the * latest version of the tuple (note this may be changed even on failure) @@ -1983,7 +2001,7 @@ ExecProcessReturning(ProjectionInfo *projectReturning, */ TupleTableSlot * EvalPlanQual(EState *estate, Index rti, - ItemPointer tid, TransactionId priorXmax, CommandId curCid) + ItemPointer tid, TransactionId priorXmax) { evalPlanQual *epq; EState *epqstate; @@ -2063,17 +2081,17 @@ EvalPlanQual(EState *estate, Index rti, /* * If tuple was inserted by our own transaction, we have to check - * cmin against curCid: cmin >= curCid means our command cannot - * see the tuple, so we should ignore it. Without this we are - * open to the "Halloween problem" of indefinitely re-updating the - * same tuple. (We need not check cmax because + * cmin against es_output_cid: cmin >= current CID means our + * command cannot see the tuple, so we should ignore it. Without + * this we are open to the "Halloween problem" of indefinitely + * re-updating the same tuple. (We need not check cmax because * HeapTupleSatisfiesDirty will consider a tuple deleted by our * transaction dead, regardless of cmax.) We just checked that * priorXmax == xmin, so we can test that variable instead of * doing HeapTupleHeaderGetXmin again. */ if (TransactionIdIsCurrentTransactionId(priorXmax) && - HeapTupleHeaderGetCmin(tuple.t_data) >= curCid) + HeapTupleHeaderGetCmin(tuple.t_data) >= estate->es_output_cid) { ReleaseBuffer(buffer); return NULL; @@ -2360,6 +2378,7 @@ EvalPlanQualStart(evalPlanQual *epq, EState *estate, evalPlanQual *priorepq) epqstate->es_snapshot = estate->es_snapshot; epqstate->es_crosscheck_snapshot = estate->es_crosscheck_snapshot; epqstate->es_range_table = estate->es_range_table; + epqstate->es_output_cid = estate->es_output_cid; epqstate->es_result_relations = estate->es_result_relations; epqstate->es_num_result_relations = estate->es_num_result_relations; epqstate->es_result_relation_info = estate->es_result_relation_info; @@ -2718,7 +2737,7 @@ intorel_receive(TupleTableSlot *slot, DestReceiver *self) heap_insert(estate->es_into_relation_descriptor, tuple, - estate->es_snapshot->curcid, + estate->es_output_cid, estate->es_into_relation_use_wal, false); /* never any point in using FSM */ diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 230d5c919f..12ddc910f4 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.152 2007/11/15 21:14:34 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.153 2007/11/30 21:22:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -178,6 +178,8 @@ CreateExecutorState(void) estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */ estate->es_range_table = NIL; + estate->es_output_cid = (CommandId) 0; + estate->es_result_relations = NULL; estate->es_num_result_relations = 0; estate->es_result_relation_info = NULL; diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index a5601ecdfc..e08e91cb0a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.185 2007/11/30 18:38:34 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.186 2007/11/30 21:22:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1593,7 +1593,7 @@ _SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, */ ActiveSnapshot = CopySnapshot(snapshot); if (!read_only) - ActiveSnapshot->curcid = GetCurrentCommandId(); + ActiveSnapshot->curcid = GetCurrentCommandId(false); } if (IsA(stmt, PlannedStmt) && diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index d7c8d706fd..156f947604 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -23,7 +23,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.37 2007/11/15 21:14:38 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.38 2007/11/30 21:22:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -814,7 +814,7 @@ GetSnapshotData(Snapshot snapshot, bool serializable) snapshot->xcnt = count; snapshot->subxcnt = subcount; - snapshot->curcid = GetCurrentCommandId(); + snapshot->curcid = GetCurrentCommandId(false); return snapshot; } diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c index 844dbc2be0..803727f084 100644 --- a/src/backend/utils/cache/inval.c +++ b/src/backend/utils/cache/inval.c @@ -80,7 +80,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.81 2007/11/15 21:14:39 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.82 2007/11/30 21:22:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -403,6 +403,14 @@ RegisterRelcacheInvalidation(Oid dbId, Oid relId) dbId, relId); /* + * Most of the time, relcache invalidation is associated with system + * catalog updates, but there are a few cases where it isn't. Quick + * hack to ensure that the next CommandCounterIncrement() will think + * that we need to do CommandEndInvalidationMessages(). + */ + (void) GetCurrentCommandId(true); + + /* * If the relation being invalidated is one of those cached in the * relcache init file, mark that we need to zap that file at commit. */ @@ -420,6 +428,11 @@ RegisterSmgrInvalidation(RelFileNode rnode) { AddSmgrInvalidationMessage(&transInvalInfo->CurrentCmdInvalidMsgs, rnode); + + /* + * As above, just in case there is not an associated catalog change. + */ + (void) GetCurrentCommandId(true); } /* diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c index 4c128e4446..dad379573c 100644 --- a/src/backend/utils/time/tqual.c +++ b/src/backend/utils/time/tqual.c @@ -31,7 +31,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.107 2007/11/15 21:14:41 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.108 2007/11/30 21:22:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -382,7 +382,7 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) } else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple))) { - if (HeapTupleHeaderGetCmin(tuple) >= GetCurrentCommandId()) + if (HeapTupleHeaderGetCmin(tuple) >= GetCurrentCommandId(false)) return false; /* inserted after scan started */ if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */ @@ -401,7 +401,7 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) return true; } - if (HeapTupleHeaderGetCmax(tuple) >= GetCurrentCommandId()) + if (HeapTupleHeaderGetCmax(tuple) >= GetCurrentCommandId(false)) return true; /* deleted after scan started */ else return false; /* deleted before scan started */ @@ -443,7 +443,7 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) { if (tuple->t_infomask & HEAP_IS_LOCKED) return true; - if (HeapTupleHeaderGetCmax(tuple) >= GetCurrentCommandId()) + if (HeapTupleHeaderGetCmax(tuple) >= GetCurrentCommandId(false)) return true; /* deleted after scan started */ else return false; /* deleted before scan started */ |
