|
15 | 15 | #include "postgres.h"
|
16 | 16 |
|
17 | 17 | #include "catalog/pg_cast.h"
|
| 18 | +#include "catalog/pg_class.h" |
18 | 19 | #include "catalog/pg_inherits_fn.h"
|
19 | 20 | #include "catalog/pg_proc.h"
|
20 | 21 | #include "catalog/pg_type.h"
|
@@ -48,6 +49,7 @@ static Node *coerce_record_to_complex(ParseState *pstate, Node *node,
|
48 | 49 | CoercionForm cformat,
|
49 | 50 | int location);
|
50 | 51 | static bool is_complex_array(Oid typid);
|
| 52 | +static bool typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId); |
51 | 53 |
|
52 | 54 |
|
53 | 55 | /*
|
@@ -371,7 +373,8 @@ coerce_type(ParseState *pstate, Node *node,
|
371 | 373 | /* NB: we do NOT want a RelabelType here */
|
372 | 374 | return node;
|
373 | 375 | }
|
374 |
| - if (typeInheritsFrom(inputTypeId, targetTypeId)) |
| 376 | + if (typeInheritsFrom(inputTypeId, targetTypeId) |
| 377 | + || typeIsOfTypedTable(inputTypeId, targetTypeId)) |
375 | 378 | {
|
376 | 379 | /*
|
377 | 380 | * Input class type is a subclass of target, so generate an
|
@@ -482,7 +485,8 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *target_typeids,
|
482 | 485 | /*
|
483 | 486 | * If input is a class type that inherits from target, accept
|
484 | 487 | */
|
485 |
| - if (typeInheritsFrom(inputTypeId, targetTypeId)) |
| 488 | + if (typeInheritsFrom(inputTypeId, targetTypeId) |
| 489 | + || typeIsOfTypedTable(inputTypeId, targetTypeId)) |
486 | 490 | continue;
|
487 | 491 |
|
488 | 492 | /*
|
@@ -2046,3 +2050,34 @@ is_complex_array(Oid typid)
|
2046 | 2050 |
|
2047 | 2051 | return (OidIsValid(elemtype) && ISCOMPLEX(elemtype));
|
2048 | 2052 | }
|
| 2053 | + |
| 2054 | + |
| 2055 | +/* |
| 2056 | + * Check whether reltypeId is the row type of a typed table of type |
| 2057 | + * reloftypeId. (This is conceptually similar to the subtype |
| 2058 | + * relationship checked by typeInheritsFrom().) |
| 2059 | + */ |
| 2060 | +static bool |
| 2061 | +typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId) |
| 2062 | +{ |
| 2063 | + Oid relid = typeidTypeRelid(reltypeId); |
| 2064 | + bool result = false; |
| 2065 | + |
| 2066 | + if (relid) |
| 2067 | + { |
| 2068 | + HeapTuple tp; |
| 2069 | + Form_pg_class reltup; |
| 2070 | + |
| 2071 | + tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); |
| 2072 | + if (!HeapTupleIsValid(tp)) |
| 2073 | + elog(ERROR, "cache lookup failed for relation %u", relid); |
| 2074 | + |
| 2075 | + reltup = (Form_pg_class) GETSTRUCT(tp); |
| 2076 | + if (reltup->reloftype == reloftypeId) |
| 2077 | + result = true; |
| 2078 | + |
| 2079 | + ReleaseSysCache(tp); |
| 2080 | + } |
| 2081 | + |
| 2082 | + return result; |
| 2083 | +} |
0 commit comments