@@ -532,7 +532,7 @@ static ObjectAddress ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *
532
532
Relation rel, Constraint *fkconstraint,
533
533
bool recurse, bool recursing,
534
534
LOCKMODE lockmode);
535
- static void validateFkOnDeleteSetColumns(int numfks, const int16 *fkattnums,
535
+ static void validateFkOnDeleteSetColumns(int numfks, const int16 *fkattnums, const int16 fkperiodattnum,
536
536
int numfksetcols, const int16 *fksetcolsattnums,
537
537
List *fksetcols);
538
538
static ObjectAddress addFkConstraint(addFkConstraintSides fkside,
@@ -9870,6 +9870,7 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
9870
9870
int16 fkdelsetcols[INDEX_MAX_KEYS] = {0};
9871
9871
bool with_period;
9872
9872
bool pk_has_without_overlaps;
9873
+ int16 fkperiodattnum = InvalidAttrNumber;
9873
9874
int i;
9874
9875
int numfks,
9875
9876
numpks,
@@ -9955,15 +9956,19 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
9955
9956
fkconstraint->fk_attrs,
9956
9957
fkattnum, fktypoid, fkcolloid);
9957
9958
with_period = fkconstraint->fk_with_period || fkconstraint->pk_with_period;
9958
- if (with_period && !fkconstraint->fk_with_period)
9959
- ereport(ERROR,
9960
- errcode(ERRCODE_INVALID_FOREIGN_KEY),
9961
- errmsg("foreign key uses PERIOD on the referenced table but not the referencing table"));
9959
+ if (with_period)
9960
+ {
9961
+ if (!fkconstraint->fk_with_period)
9962
+ ereport(ERROR,
9963
+ (errcode(ERRCODE_INVALID_FOREIGN_KEY),
9964
+ errmsg("foreign key uses PERIOD on the referenced table but not the referencing table")));
9965
+ fkperiodattnum = fkattnum[numfks - 1];
9966
+ }
9962
9967
9963
9968
numfkdelsetcols = transformColumnNameList(RelationGetRelid(rel),
9964
9969
fkconstraint->fk_del_set_cols,
9965
9970
fkdelsetcols, NULL, NULL);
9966
- validateFkOnDeleteSetColumns(numfks, fkattnum,
9971
+ validateFkOnDeleteSetColumns(numfks, fkattnum, fkperiodattnum,
9967
9972
numfkdelsetcols, fkdelsetcols,
9968
9973
fkconstraint->fk_del_set_cols);
9969
9974
@@ -10064,19 +10069,13 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
10064
10069
*/
10065
10070
if (fkconstraint->fk_with_period)
10066
10071
{
10067
- if (fkconstraint->fk_upd_action == FKCONSTR_ACTION_RESTRICT ||
10068
- fkconstraint->fk_upd_action == FKCONSTR_ACTION_CASCADE ||
10069
- fkconstraint->fk_upd_action == FKCONSTR_ACTION_SETNULL ||
10070
- fkconstraint->fk_upd_action == FKCONSTR_ACTION_SETDEFAULT)
10072
+ if (fkconstraint->fk_upd_action == FKCONSTR_ACTION_RESTRICT)
10071
10073
ereport(ERROR,
10072
10074
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
10073
10075
errmsg("unsupported %s action for foreign key constraint using PERIOD",
10074
10076
"ON UPDATE"));
10075
10077
10076
- if (fkconstraint->fk_del_action == FKCONSTR_ACTION_RESTRICT ||
10077
- fkconstraint->fk_del_action == FKCONSTR_ACTION_CASCADE ||
10078
- fkconstraint->fk_del_action == FKCONSTR_ACTION_SETNULL ||
10079
- fkconstraint->fk_del_action == FKCONSTR_ACTION_SETDEFAULT)
10078
+ if (fkconstraint->fk_del_action == FKCONSTR_ACTION_RESTRICT)
10080
10079
ereport(ERROR,
10081
10080
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
10082
10081
errmsg("unsupported %s action for foreign key constraint using PERIOD",
@@ -10431,6 +10430,7 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
10431
10430
*/
10432
10431
void
10433
10432
validateFkOnDeleteSetColumns(int numfks, const int16 *fkattnums,
10433
+ const int16 fkperiodattnum,
10434
10434
int numfksetcols, const int16 *fksetcolsattnums,
10435
10435
List *fksetcols)
10436
10436
{
@@ -10441,6 +10441,13 @@ validateFkOnDeleteSetColumns(int numfks, const int16 *fkattnums,
10441
10441
10442
10442
for (int j = 0; j < numfks; j++)
10443
10443
{
10444
+ if (fkperiodattnum == setcol_attnum)
10445
+ {
10446
+ char *col = strVal(list_nth(fksetcols, i));
10447
+ ereport(ERROR,
10448
+ (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
10449
+ errmsg("column \"%s\" referenced in ON DELETE SET action cannot be PERIOD", col)));
10450
+ }
10444
10451
if (fkattnums[j] == setcol_attnum)
10445
10452
{
10446
10453
seen = true;
@@ -13192,17 +13199,26 @@ createForeignKeyActionTriggers(Relation rel, Oid refRelOid, Constraint *fkconstr
13192
13199
case FKCONSTR_ACTION_CASCADE:
13193
13200
fk_trigger->deferrable = false;
13194
13201
fk_trigger->initdeferred = false;
13195
- fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_del");
13202
+ if (fkconstraint->fk_with_period)
13203
+ fk_trigger->funcname = SystemFuncName("RI_FKey_period_cascade_del");
13204
+ else
13205
+ fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_del");
13196
13206
break;
13197
13207
case FKCONSTR_ACTION_SETNULL:
13198
13208
fk_trigger->deferrable = false;
13199
13209
fk_trigger->initdeferred = false;
13200
- fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_del");
13210
+ if (fkconstraint->fk_with_period)
13211
+ fk_trigger->funcname = SystemFuncName("RI_FKey_period_setnull_del");
13212
+ else
13213
+ fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_del");
13201
13214
break;
13202
13215
case FKCONSTR_ACTION_SETDEFAULT:
13203
13216
fk_trigger->deferrable = false;
13204
13217
fk_trigger->initdeferred = false;
13205
- fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_del");
13218
+ if (fkconstraint->fk_with_period)
13219
+ fk_trigger->funcname = SystemFuncName("RI_FKey_period_setdefault_del");
13220
+ else
13221
+ fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_del");
13206
13222
break;
13207
13223
default:
13208
13224
elog(ERROR, "unrecognized FK action type: %d",
@@ -13253,17 +13269,26 @@ createForeignKeyActionTriggers(Relation rel, Oid refRelOid, Constraint *fkconstr
13253
13269
case FKCONSTR_ACTION_CASCADE:
13254
13270
fk_trigger->deferrable = false;
13255
13271
fk_trigger->initdeferred = false;
13256
- fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_upd");
13272
+ if (fkconstraint->fk_with_period)
13273
+ fk_trigger->funcname = SystemFuncName("RI_FKey_period_cascade_upd");
13274
+ else
13275
+ fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_upd");
13257
13276
break;
13258
13277
case FKCONSTR_ACTION_SETNULL:
13259
13278
fk_trigger->deferrable = false;
13260
13279
fk_trigger->initdeferred = false;
13261
- fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_upd");
13280
+ if (fkconstraint->fk_with_period)
13281
+ fk_trigger->funcname = SystemFuncName("RI_FKey_period_setnull_upd");
13282
+ else
13283
+ fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_upd");
13262
13284
break;
13263
13285
case FKCONSTR_ACTION_SETDEFAULT:
13264
13286
fk_trigger->deferrable = false;
13265
13287
fk_trigger->initdeferred = false;
13266
- fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_upd");
13288
+ if (fkconstraint->fk_with_period)
13289
+ fk_trigger->funcname = SystemFuncName("RI_FKey_period_setdefault_upd");
13290
+ else
13291
+ fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_upd");
13267
13292
break;
13268
13293
default:
13269
13294
elog(ERROR, "unrecognized FK action type: %d",
0 commit comments