1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

Fix ALTER TABLE code to update domain constraints when needed.

It's possible for dropping a column, or altering its type, to require
changes in domain CHECK constraint expressions; but the code was
previously only expecting to find dependent table CHECK constraints.
Make the necessary adjustments.

This is a fairly old oversight, but it's a lot easier to encounter
the problem in the context of domains over composite types than it
was before.  Given the lack of field complaints, I'm not going to
bother with a back-patch, though I'd be willing to reconsider that
decision if someone does complain.

Patch by me, reviewed by Michael Paquier

Discussion: https://postgr.es/m/30656.1509128130@sss.pgh.pa.us
This commit is contained in:
Tom Lane
2017-11-01 13:32:23 -04:00
parent 387ec70322
commit af20e2d728
5 changed files with 186 additions and 25 deletions

View File

@ -460,6 +460,7 @@ static char *generate_function_name(Oid funcid, int nargs,
bool has_variadic, bool *use_variadic_p,
ParseExprKind special_exprkind);
static char *generate_operator_name(Oid operid, Oid arg1, Oid arg2);
static char *generate_qualified_type_name(Oid typid);
static text *string_to_text(char *str);
static char *flatten_reloptions(Oid relid);
@ -1867,15 +1868,27 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
if (fullCommand)
{
/*
* Currently, callers want ALTER TABLE (without ONLY) for CHECK
* constraints, and other types of constraints don't inherit anyway so
* it doesn't matter whether we say ONLY or not. Someday we might
* need to let callers specify whether to put ONLY in the command.
*/
appendStringInfo(&buf, "ALTER TABLE %s ADD CONSTRAINT %s ",
generate_qualified_relation_name(conForm->conrelid),
quote_identifier(NameStr(conForm->conname)));
if (OidIsValid(conForm->conrelid))
{
/*
* Currently, callers want ALTER TABLE (without ONLY) for CHECK
* constraints, and other types of constraints don't inherit
* anyway so it doesn't matter whether we say ONLY or not. Someday
* we might need to let callers specify whether to put ONLY in the
* command.
*/
appendStringInfo(&buf, "ALTER TABLE %s ADD CONSTRAINT %s ",
generate_qualified_relation_name(conForm->conrelid),
quote_identifier(NameStr(conForm->conname)));
}
else
{
/* Must be a domain constraint */
Assert(OidIsValid(conForm->contypid));
appendStringInfo(&buf, "ALTER DOMAIN %s ADD CONSTRAINT %s ",
generate_qualified_type_name(conForm->contypid),
quote_identifier(NameStr(conForm->conname)));
}
}
switch (conForm->contype)
@ -10778,6 +10791,42 @@ generate_operator_name(Oid operid, Oid arg1, Oid arg2)
return buf.data;
}
/*
* generate_qualified_type_name
* Compute the name to display for a type specified by OID
*
* This is different from format_type_be() in that we unconditionally
* schema-qualify the name. That also means no special syntax for
* SQL-standard type names ... although in current usage, this should
* only get used for domains, so such cases wouldn't occur anyway.
*/
static char *
generate_qualified_type_name(Oid typid)
{
HeapTuple tp;
Form_pg_type typtup;
char *typname;
char *nspname;
char *result;
tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for type %u", typid);
typtup = (Form_pg_type) GETSTRUCT(tp);
typname = NameStr(typtup->typname);
nspname = get_namespace_name(typtup->typnamespace);
if (!nspname)
elog(ERROR, "cache lookup failed for namespace %u",
typtup->typnamespace);
result = quote_qualified_identifier(nspname, typname);
ReleaseSysCache(tp);
return result;
}
/*
* generate_collation_name
* Compute the name to display for a collation specified by OID