1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-30 21:42:05 +03:00

Refer to the default foreign key match style as MATCH SIMPLE internally.

Previously we followed the SQL92 wording, "MATCH <unspecified>", but since
SQL99 there's been a less awkward way to refer to the default style.

In addition to the code changes, pg_constraint.confmatchtype now stores
this match style as 's' (SIMPLE) rather than 'u' (UNSPECIFIED).  This
doesn't affect pg_dump or psql because they use pg_get_constraintdef()
to reconstruct foreign key definitions.  But other client-side code might
examine that column directly, so this change will have to be marked as
an incompatibility in the 9.3 release notes.
This commit is contained in:
Tom Lane
2012-06-17 20:16:07 -04:00
parent bb7520cc26
commit f5297bdfe4
10 changed files with 134 additions and 98 deletions

View File

@ -2010,7 +2010,7 @@
<entry>Foreign key match type: <entry>Foreign key match type:
<literal>f</> = full, <literal>f</> = full,
<literal>p</> = partial, <literal>p</> = partial,
<literal>u</> = simple (unspecified) <literal>s</> = simple
</entry> </entry>
</row> </row>

View File

@ -1160,7 +1160,7 @@ CREATE VIEW referential_constraints AS
CAST( CAST(
CASE con.confmatchtype WHEN 'f' THEN 'FULL' CASE con.confmatchtype WHEN 'f' THEN 'FULL'
WHEN 'p' THEN 'PARTIAL' WHEN 'p' THEN 'PARTIAL'
WHEN 'u' THEN 'NONE' END WHEN 's' THEN 'NONE' END
AS character_data) AS match_option, AS character_data) AS match_option,
CAST( CAST(

View File

@ -805,7 +805,7 @@ ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid)
char *constr_name; char *constr_name;
char *fk_table_name; char *fk_table_name;
char *pk_table_name; char *pk_table_name;
char fk_matchtype = FKCONSTR_MATCH_UNSPECIFIED; char fk_matchtype = FKCONSTR_MATCH_SIMPLE;
List *fk_attrs = NIL; List *fk_attrs = NIL;
List *pk_attrs = NIL; List *pk_attrs = NIL;
StringInfoData buf; StringInfoData buf;
@ -831,7 +831,7 @@ ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid)
if (strcmp(strVal(arg), "FULL") == 0) if (strcmp(strVal(arg), "FULL") == 0)
fk_matchtype = FKCONSTR_MATCH_FULL; fk_matchtype = FKCONSTR_MATCH_FULL;
else else
fk_matchtype = FKCONSTR_MATCH_UNSPECIFIED; fk_matchtype = FKCONSTR_MATCH_SIMPLE;
continue; continue;
} }
if (i % 2) if (i % 2)

View File

@ -2972,11 +2972,11 @@ key_match: MATCH FULL
} }
| MATCH SIMPLE | MATCH SIMPLE
{ {
$$ = FKCONSTR_MATCH_UNSPECIFIED; $$ = FKCONSTR_MATCH_SIMPLE;
} }
| /*EMPTY*/ | /*EMPTY*/
{ {
$$ = FKCONSTR_MATCH_UNSPECIFIED; $$ = FKCONSTR_MATCH_SIMPLE;
} }
; ;

View File

@ -384,8 +384,7 @@ RI_FKey_check(PG_FUNCTION_ARGS)
* No check - if NULLs are allowed at all is already checked by * No check - if NULLs are allowed at all is already checked by
* NOT NULL constraint. * NOT NULL constraint.
* *
* This is true for MATCH FULL, MATCH PARTIAL, and MATCH * This is true for MATCH FULL, MATCH PARTIAL, and MATCH SIMPLE.
* <unspecified>
*/ */
heap_close(pk_rel, RowShareLock); heap_close(pk_rel, RowShareLock);
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
@ -413,11 +412,10 @@ RI_FKey_check(PG_FUNCTION_ARGS)
heap_close(pk_rel, RowShareLock); heap_close(pk_rel, RowShareLock);
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
/* /*
* MATCH <unspecified> - if ANY column is null, we have a * MATCH SIMPLE - if ANY column is null, we have a match.
* match.
*/ */
heap_close(pk_rel, RowShareLock); heap_close(pk_rel, RowShareLock);
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
@ -435,6 +433,11 @@ RI_FKey_check(PG_FUNCTION_ARGS)
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
heap_close(pk_rel, RowShareLock); heap_close(pk_rel, RowShareLock);
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
default:
elog(ERROR, "unrecognized confmatchtype: %d",
riinfo.confmatchtype);
break;
} }
case RI_KEYS_NONE_NULL: case RI_KEYS_NONE_NULL:
@ -577,10 +580,10 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel,
switch (riinfo->confmatchtype) switch (riinfo->confmatchtype)
{ {
case FKCONSTR_MATCH_FULL: case FKCONSTR_MATCH_FULL:
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
/* /*
* MATCH <unspecified>/FULL - if ANY column is null, we * MATCH SIMPLE/FULL - if ANY column is null, we
* can't be matching to this row already. * can't be matching to this row already.
*/ */
return true; return true;
@ -597,6 +600,11 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
break; break;
default:
elog(ERROR, "unrecognized confmatchtype: %d",
riinfo->confmatchtype);
break;
} }
case RI_KEYS_NONE_NULL: case RI_KEYS_NONE_NULL:
@ -732,12 +740,12 @@ RI_FKey_noaction_del(PG_FUNCTION_ARGS)
{ {
/* ---------- /* ----------
* SQL3 11.9 <referential constraint definition> * SQL3 11.9 <referential constraint definition>
* Gereral rules 6) a) iv): * General rules 6) a) iv):
* MATCH <unspecified> or MATCH FULL * MATCH SIMPLE/FULL
* ... ON DELETE CASCADE * ... ON DELETE CASCADE
* ---------- * ----------
*/ */
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
case FKCONSTR_MATCH_FULL: case FKCONSTR_MATCH_FULL:
ri_BuildQueryKeyFull(&qkey, &riinfo, ri_BuildQueryKeyFull(&qkey, &riinfo,
RI_PLAN_NOACTION_DEL_CHECKREF); RI_PLAN_NOACTION_DEL_CHECKREF);
@ -837,12 +845,14 @@ RI_FKey_noaction_del(PG_FUNCTION_ARGS)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
default:
elog(ERROR, "unrecognized confmatchtype: %d",
riinfo.confmatchtype);
break;
} }
/* /* Never reached */
* Never reached
*/
elog(ERROR, "invalid confmatchtype");
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
} }
@ -901,12 +911,12 @@ RI_FKey_noaction_upd(PG_FUNCTION_ARGS)
{ {
/* ---------- /* ----------
* SQL3 11.9 <referential constraint definition> * SQL3 11.9 <referential constraint definition>
* Gereral rules 6) a) iv): * General rules 6) a) iv):
* MATCH <unspecified> or MATCH FULL * MATCH SIMPLE/FULL
* ... ON DELETE CASCADE * ... ON DELETE CASCADE
* ---------- * ----------
*/ */
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
case FKCONSTR_MATCH_FULL: case FKCONSTR_MATCH_FULL:
ri_BuildQueryKeyFull(&qkey, &riinfo, ri_BuildQueryKeyFull(&qkey, &riinfo,
RI_PLAN_NOACTION_UPD_CHECKREF); RI_PLAN_NOACTION_UPD_CHECKREF);
@ -1025,12 +1035,14 @@ RI_FKey_noaction_upd(PG_FUNCTION_ARGS)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
default:
elog(ERROR, "unrecognized confmatchtype: %d",
riinfo.confmatchtype);
break;
} }
/* /* Never reached */
* Never reached
*/
elog(ERROR, "invalid confmatchtype");
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
} }
@ -1084,12 +1096,12 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS)
{ {
/* ---------- /* ----------
* SQL3 11.9 <referential constraint definition> * SQL3 11.9 <referential constraint definition>
* Gereral rules 6) a) i): * General rules 6) a) i):
* MATCH <unspecified> or MATCH FULL * MATCH SIMPLE/FULL
* ... ON DELETE CASCADE * ... ON DELETE CASCADE
* ---------- * ----------
*/ */
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
case FKCONSTR_MATCH_FULL: case FKCONSTR_MATCH_FULL:
ri_BuildQueryKeyFull(&qkey, &riinfo, ri_BuildQueryKeyFull(&qkey, &riinfo,
RI_PLAN_CASCADE_DEL_DODELETE); RI_PLAN_CASCADE_DEL_DODELETE);
@ -1187,12 +1199,14 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
default:
elog(ERROR, "unrecognized confmatchtype: %d",
riinfo.confmatchtype);
break;
} }
/* /* Never reached */
* Never reached
*/
elog(ERROR, "invalid confmatchtype");
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
} }
@ -1250,12 +1264,12 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
{ {
/* ---------- /* ----------
* SQL3 11.9 <referential constraint definition> * SQL3 11.9 <referential constraint definition>
* Gereral rules 7) a) i): * General rules 7) a) i):
* MATCH <unspecified> or MATCH FULL * MATCH SIMPLE/FULL
* ... ON UPDATE CASCADE * ... ON UPDATE CASCADE
* ---------- * ----------
*/ */
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
case FKCONSTR_MATCH_FULL: case FKCONSTR_MATCH_FULL:
ri_BuildQueryKeyFull(&qkey, &riinfo, ri_BuildQueryKeyFull(&qkey, &riinfo,
RI_PLAN_CASCADE_UPD_DOUPDATE); RI_PLAN_CASCADE_UPD_DOUPDATE);
@ -1375,12 +1389,14 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
default:
elog(ERROR, "unrecognized confmatchtype: %d",
riinfo.confmatchtype);
break;
} }
/* /* Never reached */
* Never reached
*/
elog(ERROR, "invalid confmatchtype");
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
} }
@ -1441,12 +1457,12 @@ RI_FKey_restrict_del(PG_FUNCTION_ARGS)
{ {
/* ---------- /* ----------
* SQL3 11.9 <referential constraint definition> * SQL3 11.9 <referential constraint definition>
* Gereral rules 6) a) iv): * General rules 6) a) iv):
* MATCH <unspecified> or MATCH FULL * MATCH SIMPLE/FULL
* ... ON DELETE CASCADE * ... ON DELETE CASCADE
* ---------- * ----------
*/ */
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
case FKCONSTR_MATCH_FULL: case FKCONSTR_MATCH_FULL:
ri_BuildQueryKeyFull(&qkey, &riinfo, ri_BuildQueryKeyFull(&qkey, &riinfo,
RI_PLAN_RESTRICT_DEL_CHECKREF); RI_PLAN_RESTRICT_DEL_CHECKREF);
@ -1546,12 +1562,14 @@ RI_FKey_restrict_del(PG_FUNCTION_ARGS)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
default:
elog(ERROR, "unrecognized confmatchtype: %d",
riinfo.confmatchtype);
break;
} }
/* /* Never reached */
* Never reached
*/
elog(ERROR, "invalid confmatchtype");
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
} }
@ -1615,12 +1633,12 @@ RI_FKey_restrict_upd(PG_FUNCTION_ARGS)
{ {
/* ---------- /* ----------
* SQL3 11.9 <referential constraint definition> * SQL3 11.9 <referential constraint definition>
* Gereral rules 6) a) iv): * General rules 6) a) iv):
* MATCH <unspecified> or MATCH FULL * MATCH SIMPLE/FULL
* ... ON DELETE CASCADE * ... ON DELETE CASCADE
* ---------- * ----------
*/ */
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
case FKCONSTR_MATCH_FULL: case FKCONSTR_MATCH_FULL:
ri_BuildQueryKeyFull(&qkey, &riinfo, ri_BuildQueryKeyFull(&qkey, &riinfo,
RI_PLAN_RESTRICT_UPD_CHECKREF); RI_PLAN_RESTRICT_UPD_CHECKREF);
@ -1729,12 +1747,14 @@ RI_FKey_restrict_upd(PG_FUNCTION_ARGS)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
default:
elog(ERROR, "unrecognized confmatchtype: %d",
riinfo.confmatchtype);
break;
} }
/* /* Never reached */
* Never reached
*/
elog(ERROR, "invalid confmatchtype");
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
} }
@ -1788,12 +1808,12 @@ RI_FKey_setnull_del(PG_FUNCTION_ARGS)
{ {
/* ---------- /* ----------
* SQL3 11.9 <referential constraint definition> * SQL3 11.9 <referential constraint definition>
* Gereral rules 6) a) ii): * General rules 6) a) ii):
* MATCH <UNSPECIFIED> or MATCH FULL * MATCH SIMPLE/FULL
* ... ON DELETE SET NULL * ... ON DELETE SET NULL
* ---------- * ----------
*/ */
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
case FKCONSTR_MATCH_FULL: case FKCONSTR_MATCH_FULL:
ri_BuildQueryKeyFull(&qkey, &riinfo, ri_BuildQueryKeyFull(&qkey, &riinfo,
RI_PLAN_SETNULL_DEL_DOUPDATE); RI_PLAN_SETNULL_DEL_DOUPDATE);
@ -1900,12 +1920,14 @@ RI_FKey_setnull_del(PG_FUNCTION_ARGS)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
default:
elog(ERROR, "unrecognized confmatchtype: %d",
riinfo.confmatchtype);
break;
} }
/* /* Never reached */
* Never reached
*/
elog(ERROR, "invalid confmatchtype");
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
} }
@ -1962,12 +1984,12 @@ RI_FKey_setnull_upd(PG_FUNCTION_ARGS)
{ {
/* ---------- /* ----------
* SQL3 11.9 <referential constraint definition> * SQL3 11.9 <referential constraint definition>
* Gereral rules 7) a) ii) 2): * General rules 7) a) ii) 2):
* MATCH FULL * MATCH FULL
* ... ON UPDATE SET NULL * ... ON UPDATE SET NULL
* ---------- * ----------
*/ */
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
case FKCONSTR_MATCH_FULL: case FKCONSTR_MATCH_FULL:
ri_BuildQueryKeyFull(&qkey, &riinfo, ri_BuildQueryKeyFull(&qkey, &riinfo,
RI_PLAN_SETNULL_UPD_DOUPDATE); RI_PLAN_SETNULL_UPD_DOUPDATE);
@ -2005,7 +2027,7 @@ RI_FKey_setnull_upd(PG_FUNCTION_ARGS)
elog(ERROR, "SPI_connect failed"); elog(ERROR, "SPI_connect failed");
/* /*
* "MATCH <unspecified>" only changes columns corresponding to the * "MATCH SIMPLE" only changes columns corresponding to the
* referenced columns that have changed in pk_rel. This means the * referenced columns that have changed in pk_rel. This means the
* "SET attrn=NULL [, attrn=NULL]" string will be change as well. * "SET attrn=NULL [, attrn=NULL]" string will be change as well.
* In this case, we need to build a temporary plan rather than use * In this case, we need to build a temporary plan rather than use
@ -2060,7 +2082,7 @@ RI_FKey_setnull_upd(PG_FUNCTION_ARGS)
RIAttName(fk_rel, riinfo.fk_attnums[i])); RIAttName(fk_rel, riinfo.fk_attnums[i]));
/* /*
* MATCH <unspecified> - only change columns corresponding * MATCH SIMPLE - only change columns corresponding
* to changed columns in pk_rel's key * to changed columns in pk_rel's key
*/ */
if (riinfo.confmatchtype == FKCONSTR_MATCH_FULL || if (riinfo.confmatchtype == FKCONSTR_MATCH_FULL ||
@ -2116,12 +2138,14 @@ RI_FKey_setnull_upd(PG_FUNCTION_ARGS)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
default:
elog(ERROR, "unrecognized confmatchtype: %d",
riinfo.confmatchtype);
break;
} }
/* /* Never reached */
* Never reached
*/
elog(ERROR, "invalid confmatchtype");
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
} }
@ -2174,12 +2198,12 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
{ {
/* ---------- /* ----------
* SQL3 11.9 <referential constraint definition> * SQL3 11.9 <referential constraint definition>
* Gereral rules 6) a) iii): * General rules 6) a) iii):
* MATCH <UNSPECIFIED> or MATCH FULL * MATCH SIMPLE/FULL
* ... ON DELETE SET DEFAULT * ... ON DELETE SET DEFAULT
* ---------- * ----------
*/ */
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
case FKCONSTR_MATCH_FULL: case FKCONSTR_MATCH_FULL:
ri_BuildQueryKeyFull(&qkey, &riinfo, ri_BuildQueryKeyFull(&qkey, &riinfo,
RI_PLAN_SETNULL_DEL_DOUPDATE); RI_PLAN_SETNULL_DEL_DOUPDATE);
@ -2298,12 +2322,14 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
default:
elog(ERROR, "unrecognized confmatchtype: %d",
riinfo.confmatchtype);
break;
} }
/* /* Never reached */
* Never reached
*/
elog(ERROR, "invalid confmatchtype");
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
} }
@ -2358,12 +2384,12 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
{ {
/* ---------- /* ----------
* SQL3 11.9 <referential constraint definition> * SQL3 11.9 <referential constraint definition>
* Gereral rules 7) a) iii): * General rules 7) a) iii):
* MATCH <UNSPECIFIED> or MATCH FULL * MATCH SIMPLE/FULL
* ... ON UPDATE SET DEFAULT * ... ON UPDATE SET DEFAULT
* ---------- * ----------
*/ */
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
case FKCONSTR_MATCH_FULL: case FKCONSTR_MATCH_FULL:
ri_BuildQueryKeyFull(&qkey, &riinfo, ri_BuildQueryKeyFull(&qkey, &riinfo,
RI_PLAN_SETNULL_DEL_DOUPDATE); RI_PLAN_SETNULL_DEL_DOUPDATE);
@ -2439,7 +2465,7 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
RIAttName(fk_rel, riinfo.fk_attnums[i])); RIAttName(fk_rel, riinfo.fk_attnums[i]));
/* /*
* MATCH <unspecified> - only change columns corresponding * MATCH SIMPLE - only change columns corresponding
* to changed columns in pk_rel's key * to changed columns in pk_rel's key
*/ */
if (riinfo.confmatchtype == FKCONSTR_MATCH_FULL || if (riinfo.confmatchtype == FKCONSTR_MATCH_FULL ||
@ -2501,12 +2527,14 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
default:
elog(ERROR, "unrecognized confmatchtype: %d",
riinfo.confmatchtype);
break;
} }
/* /* Never reached */
* Never reached
*/
elog(ERROR, "invalid confmatchtype");
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
} }
@ -2538,7 +2566,7 @@ RI_FKey_keyequal_upd_pk(Trigger *trigger, Relation pk_rel,
switch (riinfo.confmatchtype) switch (riinfo.confmatchtype)
{ {
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
case FKCONSTR_MATCH_FULL: case FKCONSTR_MATCH_FULL:
/* Return true if keys are equal */ /* Return true if keys are equal */
return ri_KeysEqual(pk_rel, old_row, new_row, &riinfo, true); return ri_KeysEqual(pk_rel, old_row, new_row, &riinfo, true);
@ -2549,10 +2577,14 @@ RI_FKey_keyequal_upd_pk(Trigger *trigger, Relation pk_rel,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
break; break;
default:
elog(ERROR, "unrecognized confmatchtype: %d",
riinfo.confmatchtype);
break;
} }
/* Never reached */ /* Never reached */
elog(ERROR, "invalid confmatchtype");
return false; return false;
} }
@ -2583,7 +2615,7 @@ RI_FKey_keyequal_upd_fk(Trigger *trigger, Relation fk_rel,
switch (riinfo.confmatchtype) switch (riinfo.confmatchtype)
{ {
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
case FKCONSTR_MATCH_FULL: case FKCONSTR_MATCH_FULL:
/* Return true if keys are equal */ /* Return true if keys are equal */
return ri_KeysEqual(fk_rel, old_row, new_row, &riinfo, false); return ri_KeysEqual(fk_rel, old_row, new_row, &riinfo, false);
@ -2594,10 +2626,14 @@ RI_FKey_keyequal_upd_fk(Trigger *trigger, Relation fk_rel,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
break; break;
default:
elog(ERROR, "unrecognized confmatchtype: %d",
riinfo.confmatchtype);
break;
} }
/* Never reached */ /* Never reached */
elog(ERROR, "invalid confmatchtype");
return false; return false;
} }
@ -2680,7 +2716,7 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
* LEFT OUTER JOIN ONLY pkrelname pk * LEFT OUTER JOIN ONLY pkrelname pk
* ON (pk.pkkeycol1=fk.keycol1 [AND ...]) * ON (pk.pkkeycol1=fk.keycol1 [AND ...])
* WHERE pk.pkkeycol1 IS NULL AND * WHERE pk.pkkeycol1 IS NULL AND
* For MATCH unspecified: * For MATCH SIMPLE:
* (fk.keycol1 IS NOT NULL [AND ...]) * (fk.keycol1 IS NOT NULL [AND ...])
* For MATCH FULL: * For MATCH FULL:
* (fk.keycol1 IS NOT NULL [OR ...]) * (fk.keycol1 IS NOT NULL [OR ...])
@ -2745,7 +2781,7 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
sep, fkattname); sep, fkattname);
switch (riinfo.confmatchtype) switch (riinfo.confmatchtype)
{ {
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
sep = " AND "; sep = " AND ";
break; break;
case FKCONSTR_MATCH_FULL: case FKCONSTR_MATCH_FULL:
@ -2757,7 +2793,7 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
errmsg("MATCH PARTIAL not yet implemented"))); errmsg("MATCH PARTIAL not yet implemented")));
break; break;
default: default:
elog(ERROR, "unrecognized match type: %d", elog(ERROR, "unrecognized confmatchtype: %d",
riinfo.confmatchtype); riinfo.confmatchtype);
break; break;
} }

View File

@ -1184,7 +1184,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
case FKCONSTR_MATCH_PARTIAL: case FKCONSTR_MATCH_PARTIAL:
string = " MATCH PARTIAL"; string = " MATCH PARTIAL";
break; break;
case FKCONSTR_MATCH_UNSPECIFIED: case FKCONSTR_MATCH_SIMPLE:
string = ""; string = "";
break; break;
default: default:

View File

@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 201206141 #define CATALOG_VERSION_NO 201206171
#endif #endif

View File

@ -1514,7 +1514,7 @@ typedef enum ConstrType /* types of constraints */
/* Foreign key matchtype codes */ /* Foreign key matchtype codes */
#define FKCONSTR_MATCH_FULL 'f' #define FKCONSTR_MATCH_FULL 'f'
#define FKCONSTR_MATCH_PARTIAL 'p' #define FKCONSTR_MATCH_PARTIAL 'p'
#define FKCONSTR_MATCH_UNSPECIFIED 'u' #define FKCONSTR_MATCH_SIMPLE 's'
typedef struct Constraint typedef struct Constraint
{ {
@ -1550,7 +1550,7 @@ typedef struct Constraint
RangeVar *pktable; /* Primary key table */ RangeVar *pktable; /* Primary key table */
List *fk_attrs; /* Attributes of foreign key */ List *fk_attrs; /* Attributes of foreign key */
List *pk_attrs; /* Corresponding attrs in PK table */ List *pk_attrs; /* Corresponding attrs in PK table */
char fk_matchtype; /* FULL, PARTIAL, UNSPECIFIED */ char fk_matchtype; /* FULL, PARTIAL, SIMPLE */
char fk_upd_action; /* ON UPDATE action */ char fk_upd_action; /* ON UPDATE action */
char fk_del_action; /* ON DELETE action */ char fk_del_action; /* ON DELETE action */
List *old_conpfeqop; /* pg_constraint.conpfeqop of my former self */ List *old_conpfeqop; /* pg_constraint.conpfeqop of my former self */

View File

@ -339,7 +339,7 @@ SELECT * FROM PKTABLE;
DROP TABLE FKTABLE; DROP TABLE FKTABLE;
DROP TABLE PKTABLE; DROP TABLE PKTABLE;
-- MATCH unspecified -- MATCH SIMPLE
-- Base test restricting update/delete -- Base test restricting update/delete
CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ); CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) );
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable" NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable"

View File

@ -214,7 +214,7 @@ DROP TABLE FKTABLE;
DROP TABLE PKTABLE; DROP TABLE PKTABLE;
-- MATCH unspecified -- MATCH SIMPLE
-- Base test restricting update/delete -- Base test restricting update/delete
CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ); CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) );