diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index e664b3e494230cb49bede711b5ae529f2860e6aa..eb73c91409b25b19798384a683d6dff18ca15df1 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 - * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.115 2003/08/11 20:46:46 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.116 2003/09/25 18:58:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -207,7 +207,7 @@ ExplainOnePlan(QueryDesc *queryDesc, ExplainStmt *stmt, gettimeofday(&starttime, NULL); /* call ExecutorStart to prepare the plan for execution */ - ExecutorStart(queryDesc, !stmt->analyze); + ExecutorStart(queryDesc, false, !stmt->analyze); /* Execute the plan for statistics if asked for */ if (stmt->analyze) diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index d6868818656f587c97bc192e62fd03939500a56e..5a824ce40ee3a2d417c000e1971c8847b0790d4a 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 - * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.157 2003/09/25 06:57:58 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.158 2003/09/25 18:58:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1862,12 +1862,6 @@ DeferredTriggerExecute(DeferredTriggerEvent event, int itemno, if (rettuple != NULL && rettuple != &oldtuple && rettuple != &newtuple) heap_freetuple(rettuple); - /* - * Might have been a referential integrity constraint trigger. Reset - * the snapshot overriding flag. - */ - ReferentialIntegritySnapshotOverride = false; - /* * Release buffers */ diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 5d904f15d3d3395a6cccd3a0a0f93ff6223d120b..6b92920bcd1686f9db1564b8f4a8dada687bc990 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -26,7 +26,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.218 2003/09/25 06:57:59 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.219 2003/09/25 18:58:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -104,6 +104,9 @@ static void EvalPlanQualStop(evalPlanQual *epq); * field of the QueryDesc is filled in to describe the tuples that will be * returned, and the internal fields (estate and planstate) are set up. * + * If useSnapshotNow is true, run the query with SnapshotNow time qual rules + * instead of the normal use of QuerySnapshot. + * * If explainOnly is true, we are not actually intending to run the plan, * only to set up for EXPLAIN; so skip unwanted side-effects. * @@ -112,7 +115,7 @@ static void EvalPlanQualStop(evalPlanQual *epq); * ---------------------------------------------------------------- */ void -ExecutorStart(QueryDesc *queryDesc, bool explainOnly) +ExecutorStart(QueryDesc *queryDesc, bool useSnapshotNow, bool explainOnly) { EState *estate; MemoryContext oldcontext; @@ -154,7 +157,16 @@ ExecutorStart(QueryDesc *queryDesc, bool explainOnly) * the life of this query, even if it outlives the current command and * current snapshot. */ - estate->es_snapshot = CopyQuerySnapshot(); + if (useSnapshotNow) + { + estate->es_snapshot = SnapshotNow; + estate->es_snapshot_cid = GetCurrentCommandId(); + } + else + { + estate->es_snapshot = CopyQuerySnapshot(); + estate->es_snapshot_cid = estate->es_snapshot->curcid; + } /* * Initialize the plan state tree @@ -1106,7 +1118,7 @@ lnext: ; tuple.t_self = *((ItemPointer) DatumGetPointer(datum)); test = heap_mark4update(erm->relation, &tuple, &buffer, - estate->es_snapshot->curcid); + estate->es_snapshot_cid); ReleaseBuffer(buffer); switch (test) { @@ -1266,7 +1278,7 @@ ExecSelect(TupleTableSlot *slot, if (estate->es_into_relation_descriptor != NULL) { heap_insert(estate->es_into_relation_descriptor, tuple, - estate->es_snapshot->curcid); + estate->es_snapshot_cid); IncrAppended(); } @@ -1342,7 +1354,7 @@ ExecInsert(TupleTableSlot *slot, * insert the tuple */ newId = heap_insert(resultRelationDesc, tuple, - estate->es_snapshot->curcid); + estate->es_snapshot_cid); IncrAppended(); (estate->es_processed)++; @@ -1394,7 +1406,7 @@ ExecDelete(TupleTableSlot *slot, bool dodelete; dodelete = ExecBRDeleteTriggers(estate, resultRelInfo, tupleid, - estate->es_snapshot->curcid); + estate->es_snapshot_cid); if (!dodelete) /* "do nothing" */ return; @@ -1406,7 +1418,7 @@ ExecDelete(TupleTableSlot *slot, ldelete:; result = heap_delete(resultRelationDesc, tupleid, &ctid, - estate->es_snapshot->curcid, + estate->es_snapshot_cid, true /* wait for commit */); switch (result) { @@ -1505,7 +1517,7 @@ ExecUpdate(TupleTableSlot *slot, newtuple = ExecBRUpdateTriggers(estate, resultRelInfo, tupleid, tuple, - estate->es_snapshot->curcid); + estate->es_snapshot_cid); if (newtuple == NULL) /* "do nothing" */ return; @@ -1541,7 +1553,7 @@ lreplace:; */ result = heap_update(resultRelationDesc, tupleid, tuple, &ctid, - estate->es_snapshot->curcid, + estate->es_snapshot_cid, true /* wait for commit */); switch (result) { @@ -2027,6 +2039,7 @@ EvalPlanQualStart(evalPlanQual *epq, EState *estate, evalPlanQual *priorepq) */ epqstate->es_direction = ForwardScanDirection; epqstate->es_snapshot = estate->es_snapshot; + epqstate->es_snapshot_cid = estate->es_snapshot_cid; epqstate->es_range_table = estate->es_range_table; epqstate->es_result_relations = estate->es_result_relations; epqstate->es_num_result_relations = estate->es_num_result_relations; diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 4aa3170daa6a8995019f61df629018a99c205e7e..c9c7ef79396b26190b4ba95deeb8d5f4c507a991 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.104 2003/09/24 18:54:01 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.105 2003/09/25 18:58:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -178,6 +178,7 @@ CreateExecutorState(void) */ estate->es_direction = ForwardScanDirection; estate->es_snapshot = SnapshotNow; + estate->es_snapshot_cid = FirstCommandId; estate->es_range_table = NIL; estate->es_result_relations = NULL; diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 28276adc94d7cadaf108da3c29363b681872f28f..048a2609d7104a5882ee7f1dda146f17659c75ad 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.74 2003/09/25 06:57:59 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.75 2003/09/25 18:58:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -291,7 +291,7 @@ postquel_start(execution_state *es, SQLFunctionCachePtr fcache) /* Utility commands don't need Executor. */ if (es->qd->operation != CMD_UTILITY) - ExecutorStart(es->qd, false); + ExecutorStart(es->qd, false, false); es->status = F_EXEC_RUN; } diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index f1b96ee5d813fd0e12307dd69e3f1cbb03b0efd6..488a37b24d3f539190d94dc61e4184977dec0440 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.56 2003/09/25 06:57:59 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.57 2003/09/25 18:58:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -709,6 +709,7 @@ ExecInitSubPlan(SubPlanState *node, EState *estate) sp_estate->es_tupleTable = ExecCreateTupleTable(ExecCountSlotsNode(subplan->plan) + 10); sp_estate->es_snapshot = estate->es_snapshot; + sp_estate->es_snapshot_cid = estate->es_snapshot_cid; sp_estate->es_instrument = estate->es_instrument; /* diff --git a/src/backend/executor/nodeSubqueryscan.c b/src/backend/executor/nodeSubqueryscan.c index 34d9d0c62ff3de5686b0022f24b2cc68cabbb1fc..f8d2640349f81e829b4d104c6578e05ef2220098 100644 --- a/src/backend/executor/nodeSubqueryscan.c +++ b/src/backend/executor/nodeSubqueryscan.c @@ -12,7 +12,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeSubqueryscan.c,v 1.20 2003/08/04 02:39:59 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeSubqueryscan.c,v 1.21 2003/09/25 18:58:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -177,6 +177,7 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate) sp_estate->es_tupleTable = ExecCreateTupleTable(ExecCountSlotsNode(node->subplan) + 10); sp_estate->es_snapshot = estate->es_snapshot; + sp_estate->es_snapshot_cid = estate->es_snapshot_cid; sp_estate->es_instrument = estate->es_instrument; /* diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index d2b07d484ac66f1034fe514df1ee5b7b12a71661..2626b728e94131c35156e8bcdf3f1ff88bf7009c 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.105 2003/09/23 15:11:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.106 2003/09/25 18:58:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -32,10 +32,12 @@ static int _SPI_connected = -1; static int _SPI_curid = -1; static int _SPI_execute(const char *src, int tcount, _SPI_plan *plan); -static int _SPI_pquery(QueryDesc *queryDesc, bool runit, int tcount); +static int _SPI_pquery(QueryDesc *queryDesc, bool runit, + bool useSnapshotNow, int tcount); static int _SPI_execute_plan(_SPI_plan *plan, - Datum *Values, const char *Nulls, int tcount); + Datum *Values, const char *Nulls, + bool useSnapshotNow, int tcount); static void _SPI_cursor_operation(Portal portal, bool forward, int count, DestReceiver *dest); @@ -236,7 +238,33 @@ SPI_execp(void *plan, Datum *Values, const char *Nulls, int tcount) if (res < 0) return res; - res = _SPI_execute_plan((_SPI_plan *) plan, Values, Nulls, tcount); + res = _SPI_execute_plan((_SPI_plan *) plan, Values, Nulls, false, tcount); + + _SPI_end_call(true); + return res; +} + +/* + * SPI_execp_now -- identical to SPI_execp, except that we use SnapshotNow + * instead of the normal QuerySnapshot. This is currently not documented + * in spi.sgml because it is only intended for use by RI triggers. + */ +int +SPI_execp_now(void *plan, Datum *Values, const char *Nulls, int tcount) +{ + int res; + + if (plan == NULL || tcount < 0) + return SPI_ERROR_ARGUMENT; + + if (((_SPI_plan *) plan)->nargs > 0 && Values == NULL) + return SPI_ERROR_PARAM; + + res = _SPI_begin_call(true); + if (res < 0) + return res; + + res = _SPI_execute_plan((_SPI_plan *) plan, Values, Nulls, true, tcount); _SPI_end_call(true); return res; @@ -1068,7 +1096,7 @@ _SPI_execute(const char *src, int tcount, _SPI_plan *plan) { qdesc = CreateQueryDesc(queryTree, planTree, dest, NULL, false); - res = _SPI_pquery(qdesc, true, + res = _SPI_pquery(qdesc, true, false, queryTree->canSetTag ? tcount : 0); if (res < 0) return res; @@ -1078,7 +1106,7 @@ _SPI_execute(const char *src, int tcount, _SPI_plan *plan) { qdesc = CreateQueryDesc(queryTree, planTree, dest, NULL, false); - res = _SPI_pquery(qdesc, false, 0); + res = _SPI_pquery(qdesc, false, false, 0); if (res < 0) return res; } @@ -1096,7 +1124,7 @@ _SPI_execute(const char *src, int tcount, _SPI_plan *plan) static int _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls, - int tcount) + bool useSnapshotNow, int tcount) { List *query_list_list = plan->qtlist; List *plan_list = plan->ptlist; @@ -1167,7 +1195,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls, { qdesc = CreateQueryDesc(queryTree, planTree, dest, paramLI, false); - res = _SPI_pquery(qdesc, true, + res = _SPI_pquery(qdesc, true, useSnapshotNow, queryTree->canSetTag ? tcount : 0); if (res < 0) return res; @@ -1180,7 +1208,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls, } static int -_SPI_pquery(QueryDesc *queryDesc, bool runit, int tcount) +_SPI_pquery(QueryDesc *queryDesc, bool runit, bool useSnapshotNow, int tcount) { int operation = queryDesc->operation; int res; @@ -1217,7 +1245,7 @@ _SPI_pquery(QueryDesc *queryDesc, bool runit, int tcount) ResetUsage(); #endif - ExecutorStart(queryDesc, false); + ExecutorStart(queryDesc, useSnapshotNow, false); ExecutorRun(queryDesc, ForwardScanDirection, (long) tcount); diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c index 83dd0d54d8d83934dced908a3ad248b4f3185d1f..22cb49f973b2f35ca7ba7f60f1cc7946758b5572 100644 --- a/src/backend/tcop/pquery.c +++ b/src/backend/tcop/pquery.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.72 2003/08/12 18:23:21 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.73 2003/09/25 18:58:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -131,7 +131,7 @@ ProcessQuery(Query *parsetree, /* * Call ExecStart to prepare the plan for execution */ - ExecutorStart(queryDesc, false); + ExecutorStart(queryDesc, false, false); /* * Run the plan to completion. @@ -269,7 +269,7 @@ PortalStart(Portal portal, ParamListInfo params) /* * Call ExecStart to prepare the plan for execution */ - ExecutorStart(queryDesc, false); + ExecutorStart(queryDesc, false, false); /* * This tells PortalCleanup to shut down the executor diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 877034519c195e8a4fa72dd165c6a06edbe6e42a..6250995e1b81ca160ae513c1f9e1e085a2c87dda 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -17,7 +17,7 @@ * * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.57 2003/09/25 06:58:04 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.58 2003/09/25 18:58:35 tgl Exp $ * * ---------- */ @@ -187,8 +187,6 @@ RI_FKey_check(PG_FUNCTION_ARGS) int i; int match_type; - ReferentialIntegritySnapshotOverride = true; - /* * Check that this is a valid trigger call on the right time and * event. @@ -627,8 +625,6 @@ RI_FKey_noaction_del(PG_FUNCTION_ARGS) int i; int match_type; - ReferentialIntegritySnapshotOverride = true; - /* * Check that this is a valid trigger call on the right time and * event. @@ -807,8 +803,6 @@ RI_FKey_noaction_upd(PG_FUNCTION_ARGS) int i; int match_type; - ReferentialIntegritySnapshotOverride = true; - /* * Check that this is a valid trigger call on the right time and * event. @@ -995,8 +989,6 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS) void *qplan; int i; - ReferentialIntegritySnapshotOverride = true; - /* * Check that this is a valid trigger call on the right time and * event. @@ -1159,8 +1151,6 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS) int i; int j; - ReferentialIntegritySnapshotOverride = true; - /* * Check that this is a valid trigger call on the right time and * event. @@ -1349,8 +1339,6 @@ RI_FKey_restrict_del(PG_FUNCTION_ARGS) void *qplan; int i; - ReferentialIntegritySnapshotOverride = true; - /* * Check that this is a valid trigger call on the right time and * event. @@ -1520,8 +1508,6 @@ RI_FKey_restrict_upd(PG_FUNCTION_ARGS) void *qplan; int i; - ReferentialIntegritySnapshotOverride = true; - /* * Check that this is a valid trigger call on the right time and * event. @@ -1694,8 +1680,6 @@ RI_FKey_setnull_del(PG_FUNCTION_ARGS) void *qplan; int i; - ReferentialIntegritySnapshotOverride = true; - /* * Check that this is a valid trigger call on the right time and * event. @@ -1868,8 +1852,6 @@ RI_FKey_setnull_upd(PG_FUNCTION_ARGS) int match_type; bool use_cached_query; - ReferentialIntegritySnapshotOverride = true; - /* * Check that this is a valid trigger call on the right time and * event. @@ -2083,8 +2065,6 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS) RI_QueryKey qkey; void *qplan; - ReferentialIntegritySnapshotOverride = true; - /* * Check that this is a valid trigger call on the right time and * event. @@ -2296,8 +2276,6 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS) void *qplan; int match_type; - ReferentialIntegritySnapshotOverride = true; - /* * Check that this is a valid trigger call on the right time and * event. @@ -2936,15 +2914,19 @@ ri_PerformCheck(RI_QueryKey *qkey, void *qplan, */ limit = (expect_OK == SPI_OK_SELECT) ? 1 : 0; - /* Run the plan */ - spi_result = SPI_execp(qplan, vals, nulls, limit); + /* + * Run the plan, using SnapshotNow time qual rules so that we can see + * all committed tuples, even those committed after our own transaction + * or query started. + */ + spi_result = SPI_execp_now(qplan, vals, nulls, limit); /* Restore UID */ SetUserId(save_uid); /* Check result */ if (spi_result < 0) - elog(ERROR, "SPI_execp failed"); + elog(ERROR, "SPI_execp_now returned %d", spi_result); if (expect_OK >= 0 && spi_result != expect_OK) ri_ReportViolation(qkey, constrname ? constrname : "", diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c index 6a1ab38d14adedef20d67920aedf2536f7dadbb6..5b594fcf6801057ca804db83b47da20b41d41942 100644 --- a/src/backend/utils/time/tqual.c +++ b/src/backend/utils/time/tqual.c @@ -16,7 +16,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.68 2003/09/22 00:47:23 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.69 2003/09/25 18:58:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -39,8 +39,6 @@ Snapshot SerializableSnapshot = NULL; TransactionId RecentXmin = InvalidTransactionId; TransactionId RecentGlobalXmin = InvalidTransactionId; -bool ReferentialIntegritySnapshotOverride = false; - /* * HeapTupleSatisfiesItself @@ -665,10 +663,6 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple) bool HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot) { - /* XXX this is horribly ugly: */ - if (ReferentialIntegritySnapshotOverride) - return HeapTupleSatisfiesNow(tuple); - if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED)) { if (tuple->t_infomask & HEAP_XMIN_INVALID) @@ -978,9 +972,6 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin) void SetQuerySnapshot(void) { - /* Initialize snapshot overriding to false */ - ReferentialIntegritySnapshotOverride = false; - /* 1st call in xaction? */ if (SerializableSnapshot == NULL) { diff --git a/src/include/access/valid.h b/src/include/access/valid.h index c1b8f02127b1cce3b9ba4c1819b7673e7fa51791..3109d3e7e4d9374dc286b449d8d0603cc5b87ec8 100644 --- a/src/include/access/valid.h +++ b/src/include/access/valid.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: valid.h,v 1.30 2003/08/04 02:40:10 momjian Exp $ + * $Id: valid.h,v 1.31 2003/09/25 18:58:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -93,7 +93,7 @@ do \ relation, \ buffer, \ disk_page, \ - seeself, \ + snapshot, \ nKeys, \ key, \ res) \ @@ -112,7 +112,7 @@ do \ { \ uint16 _infomask = (tuple)->t_data->t_infomask; \ \ - (res) = HeapTupleSatisfiesVisibility((tuple), (seeself)); \ + (res) = HeapTupleSatisfiesVisibility((tuple), (snapshot)); \ if ((tuple)->t_data->t_infomask != _infomask) \ SetBufferCommitInfoNeedsSave(buffer); \ } \ diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 88449034feec56d90ff0c0294c8443fab3c9b6e8..034494b844fd9594104e0e6bbdf4d0b84f9ae0fe 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: executor.h,v 1.100 2003/08/19 01:13:41 tgl Exp $ + * $Id: executor.h,v 1.101 2003/09/25 18:58:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -85,7 +85,8 @@ extern HeapTuple ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot); /* * prototypes from functions in execMain.c */ -extern void ExecutorStart(QueryDesc *queryDesc, bool explainOnly); +extern void ExecutorStart(QueryDesc *queryDesc, bool useSnapshotNow, + bool explainOnly); extern TupleTableSlot *ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, long count); extern void ExecutorEnd(QueryDesc *queryDesc); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index c7366c1af555675ec8f8849444f44d05e770f30d..800616b56b6657151f908a3da634f67b98358c80 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -2,7 +2,7 @@ * * spi.h * - * $Id: spi.h,v 1.37 2003/08/04 00:43:31 momjian Exp $ + * $Id: spi.h,v 1.38 2003/09/25 18:58:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -84,6 +84,8 @@ extern void SPI_pop(void); extern int SPI_exec(const char *src, int tcount); extern int SPI_execp(void *plan, Datum *values, const char *Nulls, int tcount); +extern int SPI_execp_now(void *plan, Datum *values, const char *Nulls, + int tcount); extern void *SPI_prepare(const char *src, int nargs, Oid *argtypes); extern void *SPI_saveplan(void *plan); extern int SPI_freeplan(void *plan); diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 97609f583857be569ef7dc6865e255e37bd09ce2..b40df71776592cae474a44cb5a8631ed654eafd2 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: execnodes.h,v 1.105 2003/08/22 20:26:43 tgl Exp $ + * $Id: execnodes.h,v 1.106 2003/09/25 18:58:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -286,6 +286,7 @@ typedef struct EState /* Basic state for all query types: */ ScanDirection es_direction; /* current scan direction */ Snapshot es_snapshot; /* time qual to use */ + CommandId es_snapshot_cid; /* CommandId component of time qual */ List *es_range_table; /* List of RangeTableEntrys */ /* Info about target table for insert/update/delete queries: */ diff --git a/src/include/utils/tqual.h b/src/include/utils/tqual.h index c99d37953053d133afc5db243aa62b3fbc681f59..0c9f10f368cd190082a0858dfe88743a7db2dd1d 100644 --- a/src/include/utils/tqual.h +++ b/src/include/utils/tqual.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: tqual.h,v 1.46 2003/08/04 02:40:15 momjian Exp $ + * $Id: tqual.h,v 1.47 2003/09/25 18:58:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -44,14 +44,6 @@ extern DLLIMPORT Snapshot SerializableSnapshot; extern TransactionId RecentXmin; extern TransactionId RecentGlobalXmin; -extern bool ReferentialIntegritySnapshotOverride; - -#define IsSnapshotNow(snapshot) ((Snapshot) (snapshot) == SnapshotNow) -#define IsSnapshotSelf(snapshot) ((Snapshot) (snapshot) == SnapshotSelf) -#define IsSnapshotAny(snapshot) ((Snapshot) (snapshot) == SnapshotAny) -#define IsSnapshotToast(snapshot) ((Snapshot) (snapshot) == SnapshotToast) -#define IsSnapshotDirty(snapshot) ((Snapshot) (snapshot) == SnapshotDirty) - /* * HeapTupleSatisfiesVisibility @@ -62,19 +54,19 @@ extern bool ReferentialIntegritySnapshotOverride; * Beware of multiple evaluations of snapshot argument. */ #define HeapTupleSatisfiesVisibility(tuple, snapshot) \ -(IsSnapshotNow(snapshot) ? \ +((snapshot) == SnapshotNow ? \ HeapTupleSatisfiesNow((tuple)->t_data) \ : \ - (IsSnapshotSelf(snapshot) ? \ + ((snapshot) == SnapshotSelf ? \ HeapTupleSatisfiesItself((tuple)->t_data) \ : \ - (IsSnapshotAny(snapshot) ? \ + ((snapshot) == SnapshotAny ? \ true \ : \ - (IsSnapshotToast(snapshot) ? \ + ((snapshot) == SnapshotToast ? \ HeapTupleSatisfiesToast((tuple)->t_data) \ : \ - (IsSnapshotDirty(snapshot) ? \ + ((snapshot) == SnapshotDirty ? \ HeapTupleSatisfiesDirty((tuple)->t_data) \ : \ HeapTupleSatisfiesSnapshot((tuple)->t_data, snapshot) \