mirror of
https://github.com/postgres/postgres.git
synced 2025-07-17 06:41:09 +03:00
Record dependencies of a cast on other casts that it requires.
When creating a cast that uses a conversion function, we've historically allowed the input and result types to be binary-compatible with the function's input and result types, rather than necessarily being identical. This means that the new cast is logically dependent on the binary-compatible cast or casts that it references: if those are defined by pg_cast entries, and you try to restore the new cast without having defined them, it'll fail. Hence, we should make pg_depend entries to record these dependencies so that pg_dump knows that there is an ordering requirement. This is not the only place where we allow such shortcuts; aggregate functions for example are similarly lax, and in principle should gain similar dependencies. However, for now it seems sufficient to fix the cast-versus-cast case, as pg_dump's other ordering heuristics should keep it out of trouble for other object types. Per report from David Turoň; thanks also to Robert Haas for preliminary investigation. I considered back-patching, but seeing that this issue has existed for many years without previous reports, it's not clear it's worth the trouble. Moreover, back-patching wouldn't be enough to ensure that the new pg_depend entries exist in existing databases anyway. Discussion: https://postgr.es/m/OF0A160F3E.578B15D1-ONC12588DA.003E4857-C12588DA.0045A428@notes.linuxbox.cz
This commit is contained in:
@ -2993,11 +2993,29 @@ IsPreferredType(TYPCATEGORY category, Oid type)
|
||||
*/
|
||||
bool
|
||||
IsBinaryCoercible(Oid srctype, Oid targettype)
|
||||
{
|
||||
Oid castoid;
|
||||
|
||||
return IsBinaryCoercibleWithCast(srctype, targettype, &castoid);
|
||||
}
|
||||
|
||||
/* IsBinaryCoercibleWithCast()
|
||||
* Check if srctype is binary-coercible to targettype.
|
||||
*
|
||||
* This variant also returns the OID of the pg_cast entry if one is involved.
|
||||
* *castoid is set to InvalidOid if no binary-coercible cast exists, or if
|
||||
* there is a hard-wired rule for it rather than a pg_cast entry.
|
||||
*/
|
||||
bool
|
||||
IsBinaryCoercibleWithCast(Oid srctype, Oid targettype,
|
||||
Oid *castoid)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
Form_pg_cast castForm;
|
||||
bool result;
|
||||
|
||||
*castoid = InvalidOid;
|
||||
|
||||
/* Fast path if same type */
|
||||
if (srctype == targettype)
|
||||
return true;
|
||||
@ -3061,6 +3079,9 @@ IsBinaryCoercible(Oid srctype, Oid targettype)
|
||||
result = (castForm->castmethod == COERCION_METHOD_BINARY &&
|
||||
castForm->castcontext == COERCION_CODE_IMPLICIT);
|
||||
|
||||
if (result)
|
||||
*castoid = castForm->oid;
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
return result;
|
||||
|
Reference in New Issue
Block a user