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:
@ -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>
|
||||||
|
|
||||||
|
@ -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(
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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:
|
||||||
|
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 201206141
|
#define CATALOG_VERSION_NO 201206171
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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 */
|
||||||
|
@ -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"
|
||||||
|
@ -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) );
|
||||||
|
Reference in New Issue
Block a user