mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
Get rid of ReferentialIntegritySnapshotOverride by extending Executor API
to allow es_snapshot to be set to SnapshotNow rather than a query snapshot. This solves a bug reported by Wade Klaver, wherein triggers fired as a result of RI cascade updates could misbehave.
This commit is contained in:
@@ -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 : "",
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user