Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3f61999

Browse files
committed
Merge near-duplicate code in RI triggers
Merge ri_setnull and ri_setdefault into one function ri_set. Thesefunctions were to a large part identical.This is a continuation in spirit of4797f9b.Author: Corey Huinker <corey.huinker@gmail.com>Discussion:https://www.postgresql.org/message-id/flat/0ccdd3e1-10b0-dd05-d8a7-183507c11eb1%402ndquadrant.com
1 parentc94fb8e commit3f61999

File tree

1 file changed

+40
-141
lines changed

1 file changed

+40
-141
lines changed

‎src/backend/utils/adt/ri_triggers.c

Lines changed: 40 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,7 @@ static bool ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel,
176176
TupleTableSlot*oldslot,
177177
constRI_ConstraintInfo*riinfo);
178178
staticDatumri_restrict(TriggerData*trigdata,boolis_no_action);
179-
staticDatumri_setnull(TriggerData*trigdata);
180-
staticDatumri_setdefault(TriggerData*trigdata);
179+
staticDatumri_set(TriggerData*trigdata,boolis_set_null);
181180
staticvoidquoteOneName(char*buffer,constchar*name);
182181
staticvoidquoteRelationName(char*buffer,Relationrel);
183182
staticvoidri_GenerateQual(StringInfobuf,
@@ -960,7 +959,7 @@ RI_FKey_setnull_del(PG_FUNCTION_ARGS)
960959
ri_CheckTrigger(fcinfo,"RI_FKey_setnull_del",RI_TRIGTYPE_DELETE);
961960

962961
/* Share code with UPDATE case */
963-
returnri_setnull((TriggerData*)fcinfo->context);
962+
returnri_set((TriggerData*)fcinfo->context, true);
964963
}
965964

966965
/*
@@ -975,119 +974,9 @@ RI_FKey_setnull_upd(PG_FUNCTION_ARGS)
975974
ri_CheckTrigger(fcinfo,"RI_FKey_setnull_upd",RI_TRIGTYPE_UPDATE);
976975

977976
/* Share code with DELETE case */
978-
returnri_setnull((TriggerData*)fcinfo->context);
977+
returnri_set((TriggerData*)fcinfo->context, true);
979978
}
980979

981-
/*
982-
* ri_setnull -
983-
*
984-
* Common code for ON DELETE SET NULL and ON UPDATE SET NULL
985-
*/
986-
staticDatum
987-
ri_setnull(TriggerData*trigdata)
988-
{
989-
constRI_ConstraintInfo*riinfo;
990-
Relationfk_rel;
991-
Relationpk_rel;
992-
TupleTableSlot*oldslot;
993-
RI_QueryKeyqkey;
994-
SPIPlanPtrqplan;
995-
996-
riinfo=ri_FetchConstraintInfo(trigdata->tg_trigger,
997-
trigdata->tg_relation, true);
998-
999-
/*
1000-
* Get the relation descriptors of the FK and PK tables and the old tuple.
1001-
*
1002-
* fk_rel is opened in RowExclusiveLock mode since that's what our
1003-
* eventual UPDATE will get on it.
1004-
*/
1005-
fk_rel=table_open(riinfo->fk_relid,RowExclusiveLock);
1006-
pk_rel=trigdata->tg_relation;
1007-
oldslot=trigdata->tg_trigslot;
1008-
1009-
if (SPI_connect()!=SPI_OK_CONNECT)
1010-
elog(ERROR,"SPI_connect failed");
1011-
1012-
/*
1013-
* Fetch or prepare a saved plan for the set null operation (it's
1014-
* the same query for delete and update cases)
1015-
*/
1016-
ri_BuildQueryKey(&qkey,riinfo,RI_PLAN_SETNULL_DOUPDATE);
1017-
1018-
if ((qplan=ri_FetchPreparedPlan(&qkey))==NULL)
1019-
{
1020-
StringInfoDataquerybuf;
1021-
StringInfoDataqualbuf;
1022-
charfkrelname[MAX_QUOTED_REL_NAME_LEN];
1023-
charattname[MAX_QUOTED_NAME_LEN];
1024-
charparamname[16];
1025-
constchar*querysep;
1026-
constchar*qualsep;
1027-
constchar*fk_only;
1028-
Oidqueryoids[RI_MAX_NUMKEYS];
1029-
1030-
/* ----------
1031-
* The query string built is
1032-
*UPDATE [ONLY] <fktable> SET fkatt1 = NULL [, ...]
1033-
*WHERE $1 = fkatt1 [AND ...]
1034-
* The type id's for the $ parameters are those of the
1035-
* corresponding PK attributes.
1036-
* ----------
1037-
*/
1038-
initStringInfo(&querybuf);
1039-
initStringInfo(&qualbuf);
1040-
fk_only=fk_rel->rd_rel->relkind==RELKIND_PARTITIONED_TABLE ?
1041-
"" :"ONLY ";
1042-
quoteRelationName(fkrelname,fk_rel);
1043-
appendStringInfo(&querybuf,"UPDATE %s%s SET",
1044-
fk_only,fkrelname);
1045-
querysep="";
1046-
qualsep="WHERE";
1047-
for (inti=0;i<riinfo->nkeys;i++)
1048-
{
1049-
Oidpk_type=RIAttType(pk_rel,riinfo->pk_attnums[i]);
1050-
Oidfk_type=RIAttType(fk_rel,riinfo->fk_attnums[i]);
1051-
1052-
quoteOneName(attname,
1053-
RIAttName(fk_rel,riinfo->fk_attnums[i]));
1054-
appendStringInfo(&querybuf,
1055-
"%s %s = NULL",
1056-
querysep,attname);
1057-
sprintf(paramname,"$%d",i+1);
1058-
ri_GenerateQual(&qualbuf,qualsep,
1059-
paramname,pk_type,
1060-
riinfo->pf_eq_oprs[i],
1061-
attname,fk_type);
1062-
querysep=",";
1063-
qualsep="AND";
1064-
queryoids[i]=pk_type;
1065-
}
1066-
appendStringInfoString(&querybuf,qualbuf.data);
1067-
1068-
/* Prepare and save the plan */
1069-
qplan=ri_PlanCheck(querybuf.data,riinfo->nkeys,queryoids,
1070-
&qkey,fk_rel,pk_rel, true);
1071-
}
1072-
1073-
/*
1074-
* We have a plan now. Run it to update the existing references.
1075-
*/
1076-
ri_PerformCheck(riinfo,&qkey,qplan,
1077-
fk_rel,pk_rel,
1078-
oldslot,NULL,
1079-
true,/* must detect new rows */
1080-
SPI_OK_UPDATE);
1081-
1082-
if (SPI_finish()!=SPI_OK_FINISH)
1083-
elog(ERROR,"SPI_finish failed");
1084-
1085-
table_close(fk_rel,RowExclusiveLock);
1086-
1087-
returnPointerGetDatum(NULL);
1088-
}
1089-
1090-
1091980
/*
1092981
* RI_FKey_setdefault_del -
1093982
*
@@ -1100,7 +989,7 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
1100989
ri_CheckTrigger(fcinfo,"RI_FKey_setdefault_del",RI_TRIGTYPE_DELETE);
1101990

1102991
/* Share code with UPDATE case */
1103-
returnri_setdefault((TriggerData*)fcinfo->context);
992+
returnri_set((TriggerData*)fcinfo->context, false);
1104993
}
1105994

1106995
/*
@@ -1115,16 +1004,17 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
11151004
ri_CheckTrigger(fcinfo,"RI_FKey_setdefault_upd",RI_TRIGTYPE_UPDATE);
11161005

11171006
/* Share code with DELETE case */
1118-
returnri_setdefault((TriggerData*)fcinfo->context);
1007+
returnri_set((TriggerData*)fcinfo->context, false);
11191008
}
11201009

11211010
/*
1122-
*ri_setdefault -
1011+
*ri_set -
11231012
*
1124-
* Common code for ON DELETE SET DEFAULT and ON UPDATE SET DEFAULT
1013+
* Common code for ON DELETE SET NULL, ON DELETE SET DEFAULT, ON UPDATE SET
1014+
* NULL, and ON UPDATE SET DEFAULT.
11251015
*/
11261016
staticDatum
1127-
ri_setdefault(TriggerData*trigdata)
1017+
ri_set(TriggerData*trigdata,boolis_set_null)
11281018
{
11291019
constRI_ConstraintInfo*riinfo;
11301020
Relationfk_rel;
@@ -1150,10 +1040,13 @@ ri_setdefault(TriggerData *trigdata)
11501040
elog(ERROR,"SPI_connect failed");
11511041

11521042
/*
1153-
* Fetch or prepare a saved plan for the set default operation
1154-
*(it'sthe same query for delete and update cases)
1043+
* Fetch or prepare a saved plan for the setnull/default operation (it's
1044+
* the same query for delete and update cases)
11551045
*/
1156-
ri_BuildQueryKey(&qkey,riinfo,RI_PLAN_SETDEFAULT_DOUPDATE);
1046+
ri_BuildQueryKey(&qkey,riinfo,
1047+
(is_set_null
1048+
?RI_PLAN_SETNULL_DOUPDATE
1049+
:RI_PLAN_SETDEFAULT_DOUPDATE));
11571050

11581051
if ((qplan=ri_FetchPreparedPlan(&qkey))==NULL)
11591052
{
@@ -1169,17 +1062,17 @@ ri_setdefault(TriggerData *trigdata)
11691062

11701063
/* ----------
11711064
* The query string built is
1172-
*UPDATE [ONLY] <fktable> SET fkatt1 = DEFAULT [, ...]
1065+
*UPDATE [ONLY] <fktable> SET fkatt1 ={NULL|DEFAULT} [, ...]
11731066
*WHERE $1 = fkatt1 [AND ...]
11741067
* The type id's for the $ parameters are those of the
11751068
* corresponding PK attributes.
11761069
* ----------
11771070
*/
11781071
initStringInfo(&querybuf);
11791072
initStringInfo(&qualbuf);
1180-
quoteRelationName(fkrelname,fk_rel);
11811073
fk_only=fk_rel->rd_rel->relkind==RELKIND_PARTITIONED_TABLE ?
11821074
"" :"ONLY ";
1075+
quoteRelationName(fkrelname,fk_rel);
11831076
appendStringInfo(&querybuf,"UPDATE %s%s SET",
11841077
fk_only,fkrelname);
11851078
querysep="";
@@ -1192,8 +1085,9 @@ ri_setdefault(TriggerData *trigdata)
11921085
quoteOneName(attname,
11931086
RIAttName(fk_rel,riinfo->fk_attnums[i]));
11941087
appendStringInfo(&querybuf,
1195-
"%s %s = DEFAULT",
1196-
querysep,attname);
1088+
"%s %s = %s",
1089+
querysep,attname,
1090+
is_set_null ?"NULL" :"DEFAULT");
11971091
sprintf(paramname,"$%d",i+1);
11981092
ri_GenerateQual(&qualbuf,qualsep,
11991093
paramname,pk_type,
@@ -1224,21 +1118,26 @@ ri_setdefault(TriggerData *trigdata)
12241118

12251119
table_close(fk_rel,RowExclusiveLock);
12261120

1227-
/*
1228-
* If we just deleted or updated the PK row whose key was equal to
1229-
* the FK columns' default values, and a referencing row exists in
1230-
* the FK table, we would have updated that row to the same values
1231-
* it already had --- and RI_FKey_fk_upd_check_required would
1232-
* hence believe no check is necessary. So we need to do another
1233-
* lookup now and in case a reference still exists, abort the
1234-
* operation. That is already implemented in the NO ACTION
1235-
* trigger, so just run it. (This recheck is only needed in the
1236-
* SET DEFAULT case, since CASCADE would remove such rows in case
1237-
* of a DELETE operation or would change the FK key values in case
1238-
* of an UPDATE, while SET NULL is certain to result in rows that
1239-
* satisfy the FK constraint.)
1240-
*/
1241-
returnri_restrict(trigdata, true);
1121+
if (is_set_null)
1122+
returnPointerGetDatum(NULL);
1123+
else
1124+
{
1125+
/*
1126+
* If we just deleted or updated the PK row whose key was equal to
1127+
* the FK columns' default values, and a referencing row exists in
1128+
* the FK table, we would have updated that row to the same values
1129+
* it already had --- and RI_FKey_fk_upd_check_required would
1130+
* hence believe no check is necessary. So we need to do another
1131+
* lookup now and in case a reference still exists, abort the
1132+
* operation. That is already implemented in the NO ACTION
1133+
* trigger, so just run it. (This recheck is only needed in the
1134+
* SET DEFAULT case, since CASCADE would remove such rows in case
1135+
* of a DELETE operation or would change the FK key values in case
1136+
* of an UPDATE, while SET NULL is certain to result in rows that
1137+
* satisfy the FK constraint.)
1138+
*/
1139+
returnri_restrict(trigdata, true);
1140+
}
12421141
}
12431142

12441143

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp