Re: Heads up: 7.3.3 this Wednesday
| От | Jan Wieck |
|---|---|
| Тема | Re: Heads up: 7.3.3 this Wednesday |
| Дата | |
| Msg-id | 3ECA82E7.2010601@Yahoo.com обсуждение исходный текст |
| Ответ на | Re: Heads up: 7.3.3 this Wednesday ("scott.marlowe" <scott.marlowe@ihs.com>) |
| Список | pgsql-hackers |
scott.marlowe wrote:
> On Tue, 20 May 2003, Tom Lane wrote:
>
>
>>"scott.marlowe" <scott.marlowe@ihs.com> writes:
>>
>>>I'd be glad to test it, but we don't have any issues with fk deadlocks
>>>since our load is 99% read, 1% write, and most of the tables with fks on
>>>them only have a handful of writers, so any testing I would do would
>>>probably just be the "we used it in production and it didn't die" kind of
>>>testing.
>>
>>That's what I'm looking for mostly: that it does not have any adverse
>>side-effects.
>
>
> So where's that patch again? The search function of the mail archives is
> broken, so I can't seem to find it.
>
Attached.
Jan
--
#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#================================================== JanWieck@Yahoo.com #
*** ri_triggers.c.orig Fri Apr 4 10:41:45 2003
--- ri_triggers.c Sun Apr 6 12:36:54 2003
***************
*** 391,403 ****
}
/*
! * Note: We cannot avoid the check on UPDATE, even if old and new key
! * are the same. Otherwise, someone could DELETE the PK that consists
! * of the DEFAULT values, and if there are any references, a ON DELETE
! * SET DEFAULT action would update the references to exactly these
! * values but we wouldn't see that weired case (this is the only place
! * to see it).
*/
if (SPI_connect() != SPI_OK_CONNECT)
elog(WARNING, "SPI_connect() failed in RI_FKey_check()");
--- 391,409 ----
}
/*
! * No need to check anything if old and new references are the
! * same on UPDATE.
*/
+ if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
+ {
+ if (ri_KeysEqual(fk_rel, old_row, new_row, &qkey,
+ RI_KEYPAIR_FK_IDX))
+ {
+ heap_close(pk_rel, RowShareLock);
+ return PointerGetDatum(NULL);
+ }
+ }
+
if (SPI_connect() != SPI_OK_CONNECT)
elog(WARNING, "SPI_connect() failed in RI_FKey_check()");
***************
*** 2787,2792 ****
--- 2793,2808 ----
heap_close(fk_rel, RowExclusiveLock);
+ /*
+ * In the case we delete the row who's key is equal to the
+ * default values AND a referencing row in the foreign key
+ * table exists, we would just have updated it to the same
+ * values. We need to do another lookup now and in case a
+ * reference exists, abort the operation. That is already
+ * implemented in the NO ACTION trigger.
+ */
+ RI_FKey_noaction_del(fcinfo);
+
return PointerGetDatum(NULL);
/*
***************
*** 3077,3082 ****
--- 3093,3108 ----
elog(WARNING, "SPI_finish() failed in RI_FKey_setdefault_upd()");
heap_close(fk_rel, RowExclusiveLock);
+
+ /*
+ * In the case we updated the row who's key was equal to the
+ * default values AND a referencing row in the foreign key
+ * table exists, we would just have updated it to the same
+ * values. We need to do another lookup now and in case a
+ * reference exists, abort the operation. That is already
+ * implemented in the NO ACTION trigger.
+ */
+ RI_FKey_noaction_upd(fcinfo);
return PointerGetDatum(NULL);
*** ri_triggers.c.orig Mon Nov 12 01:09:09 2001
--- ri_triggers.c Sun Apr 6 13:36:42 2003
***************
*** 354,366 ****
}
/*
! * Note: We cannot avoid the check on UPDATE, even if old and new key
! * are the same. Otherwise, someone could DELETE the PK that consists
! * of the DEFAULT values, and if there are any references, a ON DELETE
! * SET DEFAULT action would update the references to exactly these
! * values but we wouldn't see that weired case (this is the only place
! * to see it).
*/
if (SPI_connect() != SPI_OK_CONNECT)
elog(NOTICE, "SPI_connect() failed in RI_FKey_check()");
--- 354,372 ----
}
/*
! * No need to check anything if old and new references are the
! * same on UPDATE.
*/
+ if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
+ {
+ if (ri_KeysEqual(fk_rel, old_row, new_row, &qkey,
+ RI_KEYPAIR_FK_IDX))
+ {
+ heap_close(pk_rel, NoLock);
+ return PointerGetDatum(NULL);
+ }
+ }
+
if (SPI_connect() != SPI_OK_CONNECT)
elog(NOTICE, "SPI_connect() failed in RI_FKey_check()");
***************
*** 2447,2452 ****
--- 2453,2468 ----
if (SPI_finish() != SPI_OK_FINISH)
elog(NOTICE, "SPI_finish() failed in RI_FKey_setdefault_del()");
+ /*
+ * In the case we delete the row who's key is equal to the
+ * default values AND a referencing row in the foreign key
+ * table exists, we would just have updated it to the same
+ * values. We need to do another lookup now and in case a
+ * reference exists, abort the operation. That is already
+ * implemented in the NO ACTION trigger.
+ */
+ RI_FKey_noaction_del(fcinfo);
+
return PointerGetDatum(NULL);
/*
***************
*** 2722,2727 ****
--- 2738,2753 ----
if (SPI_finish() != SPI_OK_FINISH)
elog(NOTICE, "SPI_finish() failed in RI_FKey_setdefault_upd()");
+
+ /*
+ * In the case we updated the row who's key was equal to the
+ * default values AND a referencing row in the foreign key
+ * table exists, we would just have updated it to the same
+ * values. We need to do another lookup now and in case a
+ * reference exists, abort the operation. That is already
+ * implemented in the NO ACTION trigger.
+ */
+ RI_FKey_noaction_upd(fcinfo);
return PointerGetDatum(NULL);
*** ri_triggers.c.orig Sat Mar 29 14:33:24 2003
--- ri_triggers.c Sun Apr 6 14:01:27 2003
***************
*** 395,407 ****
}
/*
! * Note: We cannot avoid the check on UPDATE, even if old and new key
! * are the same. Otherwise, someone could DELETE the PK that consists
! * of the DEFAULT values, and if there are any references, a ON DELETE
! * SET DEFAULT action would update the references to exactly these
! * values but we wouldn't see that weird case (this is the only place
! * to see it).
*/
if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "SPI_connect() failed in RI_FKey_check()");
--- 395,413 ----
}
/*
! * No need to check anything if old and new references are the
! * same on UPDATE.
*/
+ if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
+ {
+ if (ri_KeysEqual(fk_rel, old_row, new_row, &qkey,
+ RI_KEYPAIR_FK_IDX))
+ {
+ heap_close(pk_rel, RowShareLock);
+ return PointerGetDatum(NULL);
+ }
+ }
+
if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "SPI_connect() failed in RI_FKey_check()");
***************
*** 2397,2402 ****
--- 2403,2418 ----
heap_close(fk_rel, RowExclusiveLock);
+ /*
+ * In the case we delete the row who's key is equal to the
+ * default values AND a referencing row in the foreign key
+ * table exists, we would just have updated it to the same
+ * values. We need to do another lookup now and in case a
+ * reference exists, abort the operation. That is already
+ * implemented in the NO ACTION trigger.
+ */
+ RI_FKey_noaction_del(fcinfo);
+
return PointerGetDatum(NULL);
/*
***************
*** 2634,2639 ****
--- 2650,2665 ----
elog(ERROR, "SPI_finish() failed in RI_FKey_setdefault_upd()");
heap_close(fk_rel, RowExclusiveLock);
+
+ /*
+ * In the case we updated the row who's key was equal to the
+ * default values AND a referencing row in the foreign key
+ * table exists, we would just have updated it to the same
+ * values. We need to do another lookup now and in case a
+ * reference exists, abort the operation. That is already
+ * implemented in the NO ACTION trigger.
+ */
+ RI_FKey_noaction_upd(fcinfo);
return PointerGetDatum(NULL);
В списке pgsql-hackers по дате отправления: