@@ -303,60 +303,6 @@ RI_FKey_check(TriggerData *trigdata)
303303 fk_rel = trigdata -> tg_relation ;
304304 pk_rel = heap_open (riinfo -> pk_relid , RowShareLock );
305305
306- /* ----------
307- * SQL:2008 4.17.3 <Table constraints>
308- * If Rf and Rt are empty (no columns to compare given)
309- * constraint is true if 0 < (SELECT COUNT(*) FROM T)
310- *
311- * Note: The special case that no columns are given cannot
312- * occur at present in Postgres (and is disallowed by the
313- * standard too); it's just there for future enhancements.
314- * ----------
315- */
316- if (riinfo -> nkeys == 0 )
317- {
318- if (SPI_connect () != SPI_OK_CONNECT )
319- elog (ERROR , "SPI_connect failed" );
320-
321- ri_BuildQueryKey (& qkey , riinfo , RI_PLAN_CHECK_LOOKUPPK );
322-
323- if ((qplan = ri_FetchPreparedPlan (& qkey )) == NULL )
324- {
325- char querystr [MAX_QUOTED_REL_NAME_LEN + 100 ];
326- char pkrelname [MAX_QUOTED_REL_NAME_LEN ];
327-
328- /* ---------
329- * The query string built is
330- * SELECT 1 FROM ONLY <pktable>
331- * ----------
332- */
333- quoteRelationName (pkrelname , pk_rel );
334- snprintf (querystr , sizeof (querystr ),
335- "SELECT 1 FROM ONLY %s x FOR SHARE OF x" ,
336- pkrelname );
337-
338- /* Prepare and save the plan */
339- qplan = ri_PlanCheck (querystr , 0 , NULL ,
340- & qkey , fk_rel , pk_rel , true);
341- }
342-
343- /*
344- * Execute the plan
345- */
346- ri_PerformCheck (riinfo , & qkey , qplan ,
347- fk_rel , pk_rel ,
348- NULL , NULL ,
349- false,
350- SPI_OK_SELECT );
351-
352- if (SPI_finish () != SPI_OK_FINISH )
353- elog (ERROR , "SPI_finish failed" );
354-
355- heap_close (pk_rel , RowShareLock );
356-
357- return PointerGetDatum (NULL );
358- }
359-
360306 if (riinfo -> confmatchtype == FKCONSTR_MATCH_PARTIAL )
361307 ereport (ERROR ,
362308 (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
@@ -704,12 +650,6 @@ ri_restrict_del(TriggerData *trigdata, bool is_no_action)
704650 riinfo = ri_FetchConstraintInfo (trigdata -> tg_trigger ,
705651 trigdata -> tg_relation , true);
706652
707- /*
708- * Nothing to do if no column names to compare given
709- */
710- if (riinfo -> nkeys == 0 )
711- return PointerGetDatum (NULL );
712-
713653 /*
714654 * Get the relation descriptors of the FK and PK tables and the old tuple.
715655 *
@@ -922,12 +862,6 @@ ri_restrict_upd(TriggerData *trigdata, bool is_no_action)
922862 riinfo = ri_FetchConstraintInfo (trigdata -> tg_trigger ,
923863 trigdata -> tg_relation , true);
924864
925- /*
926- * Nothing to do if no column names to compare given
927- */
928- if (riinfo -> nkeys == 0 )
929- return PointerGetDatum (NULL );
930-
931865 /*
932866 * Get the relation descriptors of the FK and PK tables and the new and
933867 * old tuple.
@@ -1109,12 +1043,6 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS)
11091043 riinfo = ri_FetchConstraintInfo (trigdata -> tg_trigger ,
11101044 trigdata -> tg_relation , true);
11111045
1112- /*
1113- * Nothing to do if no column names to compare given
1114- */
1115- if (riinfo -> nkeys == 0 )
1116- return PointerGetDatum (NULL );
1117-
11181046 /*
11191047 * Get the relation descriptors of the FK and PK tables and the old tuple.
11201048 *
@@ -1273,12 +1201,6 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
12731201 riinfo = ri_FetchConstraintInfo (trigdata -> tg_trigger ,
12741202 trigdata -> tg_relation , true);
12751203
1276- /*
1277- * Nothing to do if no column names to compare given
1278- */
1279- if (riinfo -> nkeys == 0 )
1280- return PointerGetDatum (NULL );
1281-
12821204 /*
12831205 * Get the relation descriptors of the FK and PK tables and the new and
12841206 * old tuple.
@@ -1458,12 +1380,6 @@ RI_FKey_setnull_del(PG_FUNCTION_ARGS)
14581380 riinfo = ri_FetchConstraintInfo (trigdata -> tg_trigger ,
14591381 trigdata -> tg_relation , true);
14601382
1461- /*
1462- * Nothing to do if no column names to compare given
1463- */
1464- if (riinfo -> nkeys == 0 )
1465- return PointerGetDatum (NULL );
1466-
14671383 /*
14681384 * Get the relation descriptors of the FK and PK tables and the old tuple.
14691385 *
@@ -1630,12 +1546,6 @@ RI_FKey_setnull_upd(PG_FUNCTION_ARGS)
16301546 riinfo = ri_FetchConstraintInfo (trigdata -> tg_trigger ,
16311547 trigdata -> tg_relation , true);
16321548
1633- /*
1634- * Nothing to do if no column names to compare given
1635- */
1636- if (riinfo -> nkeys == 0 )
1637- return PointerGetDatum (NULL );
1638-
16391549 /*
16401550 * Get the relation descriptors of the FK and PK tables and the old tuple.
16411551 *
@@ -1810,12 +1720,6 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
18101720 riinfo = ri_FetchConstraintInfo (trigdata -> tg_trigger ,
18111721 trigdata -> tg_relation , true);
18121722
1813- /*
1814- * Nothing to do if no column names to compare given
1815- */
1816- if (riinfo -> nkeys == 0 )
1817- return PointerGetDatum (NULL );
1818-
18191723 /*
18201724 * Get the relation descriptors of the FK and PK tables and the old tuple.
18211725 *
@@ -1997,12 +1901,6 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
19971901 riinfo = ri_FetchConstraintInfo (trigdata -> tg_trigger ,
19981902 trigdata -> tg_relation , true);
19991903
2000- /*
2001- * Nothing to do if no column names to compare given
2002- */
2003- if (riinfo -> nkeys == 0 )
2004- return PointerGetDatum (NULL );
2005-
20061904 /*
20071905 * Get the relation descriptors of the FK and PK tables and the old tuple.
20081906 *
@@ -2186,13 +2084,6 @@ RI_FKey_pk_upd_check_required(Trigger *trigger, Relation pk_rel,
21862084 */
21872085 riinfo = ri_FetchConstraintInfo (trigger , pk_rel , true);
21882086
2189- /*
2190- * Nothing to do if no columns (satisfaction of such a constraint only
2191- * requires existence of a PK row, and this update won't change that).
2192- */
2193- if (riinfo -> nkeys == 0 )
2194- return false;
2195-
21962087 switch (riinfo -> confmatchtype )
21972088 {
21982089 case FKCONSTR_MATCH_SIMPLE :
@@ -2250,13 +2141,6 @@ RI_FKey_fk_upd_check_required(Trigger *trigger, Relation fk_rel,
22502141 */
22512142 riinfo = ri_FetchConstraintInfo (trigger , fk_rel , false);
22522143
2253- /*
2254- * Nothing to do if no columns (satisfaction of such a constraint only
2255- * requires existence of a PK row, and this update won't change that).
2256- */
2257- if (riinfo -> nkeys == 0 )
2258- return false;
2259-
22602144 switch (riinfo -> confmatchtype )
22612145 {
22622146 case FKCONSTR_MATCH_SIMPLE :
@@ -2945,13 +2829,13 @@ ri_LoadConstraintInfo(Oid constraintOid)
29452829 if (isNull )
29462830 elog (ERROR , "null conkey for constraint %u" , constraintOid );
29472831 arr = DatumGetArrayTypeP (adatum ); /* ensure not toasted */
2948- numkeys = ARR_DIMS (arr )[0 ];
29492832 if (ARR_NDIM (arr ) != 1 ||
2950- numkeys < 0 ||
2951- numkeys > RI_MAX_NUMKEYS ||
29522833 ARR_HASNULL (arr ) ||
29532834 ARR_ELEMTYPE (arr ) != INT2OID )
29542835 elog (ERROR , "conkey is not a 1-D smallint array" );
2836+ numkeys = ARR_DIMS (arr )[0 ];
2837+ if (numkeys <= 0 || numkeys > RI_MAX_NUMKEYS )
2838+ elog (ERROR , "foreign key constraint cannot have %d columns" , numkeys );
29552839 riinfo -> nkeys = numkeys ;
29562840 memcpy (riinfo -> fk_attnums , ARR_DATA_PTR (arr ), numkeys * sizeof (int16 ));
29572841 if ((Pointer ) arr != DatumGetPointer (adatum ))
@@ -2962,10 +2846,8 @@ ri_LoadConstraintInfo(Oid constraintOid)
29622846 if (isNull )
29632847 elog (ERROR , "null confkey for constraint %u" , constraintOid );
29642848 arr = DatumGetArrayTypeP (adatum ); /* ensure not toasted */
2965- numkeys = ARR_DIMS (arr )[0 ];
29662849 if (ARR_NDIM (arr ) != 1 ||
2967- numkeys != riinfo -> nkeys ||
2968- numkeys > RI_MAX_NUMKEYS ||
2850+ ARR_DIMS (arr )[0 ] != numkeys ||
29692851 ARR_HASNULL (arr ) ||
29702852 ARR_ELEMTYPE (arr ) != INT2OID )
29712853 elog (ERROR , "confkey is not a 1-D smallint array" );
@@ -2978,11 +2860,9 @@ ri_LoadConstraintInfo(Oid constraintOid)
29782860 if (isNull )
29792861 elog (ERROR , "null conpfeqop for constraint %u" , constraintOid );
29802862 arr = DatumGetArrayTypeP (adatum ); /* ensure not toasted */
2981- numkeys = ARR_DIMS (arr )[0 ];
29822863 /* see TryReuseForeignKey if you change the test below */
29832864 if (ARR_NDIM (arr ) != 1 ||
2984- numkeys != riinfo -> nkeys ||
2985- numkeys > RI_MAX_NUMKEYS ||
2865+ ARR_DIMS (arr )[0 ] != numkeys ||
29862866 ARR_HASNULL (arr ) ||
29872867 ARR_ELEMTYPE (arr ) != OIDOID )
29882868 elog (ERROR , "conpfeqop is not a 1-D Oid array" );
@@ -2995,10 +2875,8 @@ ri_LoadConstraintInfo(Oid constraintOid)
29952875 if (isNull )
29962876 elog (ERROR , "null conppeqop for constraint %u" , constraintOid );
29972877 arr = DatumGetArrayTypeP (adatum ); /* ensure not toasted */
2998- numkeys = ARR_DIMS (arr )[0 ];
29992878 if (ARR_NDIM (arr ) != 1 ||
3000- numkeys != riinfo -> nkeys ||
3001- numkeys > RI_MAX_NUMKEYS ||
2879+ ARR_DIMS (arr )[0 ] != numkeys ||
30022880 ARR_HASNULL (arr ) ||
30032881 ARR_ELEMTYPE (arr ) != OIDOID )
30042882 elog (ERROR , "conppeqop is not a 1-D Oid array" );
@@ -3011,10 +2889,8 @@ ri_LoadConstraintInfo(Oid constraintOid)
30112889 if (isNull )
30122890 elog (ERROR , "null conffeqop for constraint %u" , constraintOid );
30132891 arr = DatumGetArrayTypeP (adatum ); /* ensure not toasted */
3014- numkeys = ARR_DIMS (arr )[0 ];
30152892 if (ARR_NDIM (arr ) != 1 ||
3016- numkeys != riinfo -> nkeys ||
3017- numkeys > RI_MAX_NUMKEYS ||
2893+ ARR_DIMS (arr )[0 ] != numkeys ||
30182894 ARR_HASNULL (arr ) ||
30192895 ARR_ELEMTYPE (arr ) != OIDOID )
30202896 elog (ERROR , "conffeqop is not a 1-D Oid array" );
@@ -3311,22 +3187,6 @@ ri_ReportViolation(const RI_ConstraintInfo *riinfo,
33113187 tupdesc = pk_rel -> rd_att ;
33123188 }
33133189
3314- /*
3315- * Special case - if there are no keys at all, this is a 'no column'
3316- * constraint - no need to try to extract the values, and the message in
3317- * this case looks different.
3318- */
3319- if (riinfo -> nkeys == 0 )
3320- {
3321- ereport (ERROR ,
3322- (errcode (ERRCODE_FOREIGN_KEY_VIOLATION ),
3323- errmsg ("insert or update on table \"%s\" violates foreign key constraint \"%s\"" ,
3324- RelationGetRelationName (fk_rel ),
3325- NameStr (riinfo -> conname )),
3326- errdetail ("No rows were found in \"%s\"." ,
3327- RelationGetRelationName (pk_rel ))));
3328- }
3329-
33303190 /* Get printable versions of the keys involved */
33313191 initStringInfo (& key_names );
33323192 initStringInfo (& key_values );
0 commit comments