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 по дате отправления:

Предыдущее
От: Kaare Rasmussen
Дата:
Сообщение: Re: Calling external program from trigger
Следующее
От: greg@turnstep.com
Дата:
Сообщение: Re: Removing width from EXPLAIN