LCOV - code coverage report
Current view: top level - src/backend/parser - parse_coerce.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13beta1 Lines: 774 851 91.0 %
Date: 2020-06-05 20:07:15 Functions: 26 26 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * parse_coerce.c
       4             :  *      handle type coercions/conversions for parser
       5             :  *
       6             :  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/parser/parse_coerce.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : #include "postgres.h"
      16             : 
      17             : #include "catalog/pg_cast.h"
      18             : #include "catalog/pg_class.h"
      19             : #include "catalog/pg_inherits.h"
      20             : #include "catalog/pg_proc.h"
      21             : #include "catalog/pg_type.h"
      22             : #include "nodes/makefuncs.h"
      23             : #include "nodes/nodeFuncs.h"
      24             : #include "parser/parse_coerce.h"
      25             : #include "parser/parse_relation.h"
      26             : #include "parser/parse_type.h"
      27             : #include "utils/builtins.h"
      28             : #include "utils/datum.h"      /* needed for datumIsEqual() */
      29             : #include "utils/lsyscache.h"
      30             : #include "utils/syscache.h"
      31             : #include "utils/typcache.h"
      32             : 
      33             : 
      34             : static Node *coerce_type_typmod(Node *node,
      35             :                                 Oid targetTypeId, int32 targetTypMod,
      36             :                                 CoercionContext ccontext, CoercionForm cformat,
      37             :                                 int location,
      38             :                                 bool hideInputCoercion);
      39             : static void hide_coercion_node(Node *node);
      40             : static Node *build_coercion_expression(Node *node,
      41             :                                        CoercionPathType pathtype,
      42             :                                        Oid funcId,
      43             :                                        Oid targetTypeId, int32 targetTypMod,
      44             :                                        CoercionContext ccontext, CoercionForm cformat,
      45             :                                        int location);
      46             : static Node *coerce_record_to_complex(ParseState *pstate, Node *node,
      47             :                                       Oid targetTypeId,
      48             :                                       CoercionContext ccontext,
      49             :                                       CoercionForm cformat,
      50             :                                       int location);
      51             : static bool is_complex_array(Oid typid);
      52             : static bool typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId);
      53             : 
      54             : 
      55             : /*
      56             :  * coerce_to_target_type()
      57             :  *      Convert an expression to a target type and typmod.
      58             :  *
      59             :  * This is the general-purpose entry point for arbitrary type coercion
      60             :  * operations.  Direct use of the component operations can_coerce_type,
      61             :  * coerce_type, and coerce_type_typmod should be restricted to special
      62             :  * cases (eg, when the conversion is expected to succeed).
      63             :  *
      64             :  * Returns the possibly-transformed expression tree, or NULL if the type
      65             :  * conversion is not possible.  (We do this, rather than ereport'ing directly,
      66             :  * so that callers can generate custom error messages indicating context.)
      67             :  *
      68             :  * pstate - parse state (can be NULL, see coerce_type)
      69             :  * expr - input expression tree (already transformed by transformExpr)
      70             :  * exprtype - result type of expr
      71             :  * targettype - desired result type
      72             :  * targettypmod - desired result typmod
      73             :  * ccontext, cformat - context indicators to control coercions
      74             :  * location - parse location of the coercion request, or -1 if unknown/implicit
      75             :  */
      76             : Node *
      77      713148 : coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype,
      78             :                       Oid targettype, int32 targettypmod,
      79             :                       CoercionContext ccontext,
      80             :                       CoercionForm cformat,
      81             :                       int location)
      82             : {
      83             :     Node       *result;
      84             :     Node       *origexpr;
      85             : 
      86      713148 :     if (!can_coerce_type(1, &exprtype, &targettype, ccontext))
      87         280 :         return NULL;
      88             : 
      89             :     /*
      90             :      * If the input has a CollateExpr at the top, strip it off, perform the
      91             :      * coercion, and put a new one back on.  This is annoying since it
      92             :      * duplicates logic in coerce_type, but if we don't do this then it's too
      93             :      * hard to tell whether coerce_type actually changed anything, and we
      94             :      * *must* know that to avoid possibly calling hide_coercion_node on
      95             :      * something that wasn't generated by coerce_type.  Note that if there are
      96             :      * multiple stacked CollateExprs, we just discard all but the topmost.
      97             :      */
      98      712868 :     origexpr = expr;
      99      712880 :     while (expr && IsA(expr, CollateExpr))
     100          12 :         expr = (Node *) ((CollateExpr *) expr)->arg;
     101             : 
     102      712868 :     result = coerce_type(pstate, expr, exprtype,
     103             :                          targettype, targettypmod,
     104             :                          ccontext, cformat, location);
     105             : 
     106             :     /*
     107             :      * If the target is a fixed-length type, it may need a length coercion as
     108             :      * well as a type coercion.  If we find ourselves adding both, force the
     109             :      * inner coercion node to implicit display form.
     110             :      */
     111      711050 :     result = coerce_type_typmod(result,
     112             :                                 targettype, targettypmod,
     113             :                                 ccontext, cformat, location,
     114      711050 :                                 (result != expr && !IsA(result, Const)));
     115             : 
     116      711050 :     if (expr != origexpr)
     117             :     {
     118             :         /* Reinstall top CollateExpr */
     119          12 :         CollateExpr *coll = (CollateExpr *) origexpr;
     120          12 :         CollateExpr *newcoll = makeNode(CollateExpr);
     121             : 
     122          12 :         newcoll->arg = (Expr *) result;
     123          12 :         newcoll->collOid = coll->collOid;
     124          12 :         newcoll->location = coll->location;
     125          12 :         result = (Node *) newcoll;
     126             :     }
     127             : 
     128      711050 :     return result;
     129             : }
     130             : 
     131             : 
     132             : /*
     133             :  * coerce_type()
     134             :  *      Convert an expression to a different type.
     135             :  *
     136             :  * The caller should already have determined that the coercion is possible;
     137             :  * see can_coerce_type.
     138             :  *
     139             :  * Normally, no coercion to a typmod (length) is performed here.  The caller
     140             :  * must call coerce_type_typmod as well, if a typmod constraint is wanted.
     141             :  * (But if the target type is a domain, it may internally contain a
     142             :  * typmod constraint, which will be applied inside coerce_to_domain.)
     143             :  * In some cases pg_cast specifies a type coercion function that also
     144             :  * applies length conversion, and in those cases only, the result will
     145             :  * already be properly coerced to the specified typmod.
     146             :  *
     147             :  * pstate is only used in the case that we are able to resolve the type of
     148             :  * a previously UNKNOWN Param.  It is okay to pass pstate = NULL if the
     149             :  * caller does not want type information updated for Params.
     150             :  *
     151             :  * Note: this function must not modify the given expression tree, only add
     152             :  * decoration on top of it.  See transformSetOperationTree, for example.
     153             :  */
     154             : Node *
     155     1373458 : coerce_type(ParseState *pstate, Node *node,
     156             :             Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod,
     157             :             CoercionContext ccontext, CoercionForm cformat, int location)
     158             : {
     159             :     Node       *result;
     160             :     CoercionPathType pathtype;
     161             :     Oid         funcId;
     162             : 
     163     1373458 :     if (targetTypeId == inputTypeId ||
     164             :         node == NULL)
     165             :     {
     166             :         /* no conversion needed */
     167      160750 :         return node;
     168             :     }
     169     1212708 :     if (targetTypeId == ANYOID ||
     170     1204738 :         targetTypeId == ANYELEMENTOID ||
     171     1189282 :         targetTypeId == ANYNONARRAYOID ||
     172     1189282 :         targetTypeId == ANYCOMPATIBLEOID ||
     173             :         targetTypeId == ANYCOMPATIBLENONARRAYOID)
     174             :     {
     175             :         /*
     176             :          * Assume can_coerce_type verified that implicit coercion is okay.
     177             :          *
     178             :          * Note: by returning the unmodified node here, we are saying that
     179             :          * it's OK to treat an UNKNOWN constant as a valid input for a
     180             :          * function accepting one of these pseudotypes.  This should be all
     181             :          * right, since an UNKNOWN value is still a perfectly valid Datum.
     182             :          *
     183             :          * NB: we do NOT want a RelabelType here: the exposed type of the
     184             :          * function argument must be its actual type, not the polymorphic
     185             :          * pseudotype.
     186             :          */
     187       23426 :         return node;
     188             :     }
     189     1189282 :     if (targetTypeId == ANYARRAYOID ||
     190     1131392 :         targetTypeId == ANYENUMOID ||
     191     1129454 :         targetTypeId == ANYRANGEOID ||
     192     1129454 :         targetTypeId == ANYCOMPATIBLEARRAYOID ||
     193             :         targetTypeId == ANYCOMPATIBLERANGEOID)
     194             :     {
     195             :         /*
     196             :          * Assume can_coerce_type verified that implicit coercion is okay.
     197             :          *
     198             :          * These cases are unlike the ones above because the exposed type of
     199             :          * the argument must be an actual array, enum, or range type.  In
     200             :          * particular the argument must *not* be an UNKNOWN constant.  If it
     201             :          * is, we just fall through; below, we'll call the pseudotype's input
     202             :          * function, which will produce an error.  Also, if what we have is a
     203             :          * domain over array, enum, or range, we have to relabel it to its
     204             :          * base type.
     205             :          *
     206             :          * Note: currently, we can't actually see a domain-over-enum here,
     207             :          * since the other functions in this file will not match such a
     208             :          * parameter to ANYENUM.  But that should get changed eventually.
     209             :          */
     210       59828 :         if (inputTypeId != UNKNOWNOID)
     211             :         {
     212       53614 :             Oid         baseTypeId = getBaseType(inputTypeId);
     213             : 
     214       53614 :             if (baseTypeId != inputTypeId)
     215             :             {
     216          40 :                 RelabelType *r = makeRelabelType((Expr *) node,
     217             :                                                  baseTypeId, -1,
     218             :                                                  InvalidOid,
     219             :                                                  cformat);
     220             : 
     221          40 :                 r->location = location;
     222          40 :                 return (Node *) r;
     223             :             }
     224             :             /* Not a domain type, so return it as-is */
     225       53574 :             return node;
     226             :         }
     227             :     }
     228     1135668 :     if (inputTypeId == UNKNOWNOID && IsA(node, Const))
     229             :     {
     230             :         /*
     231             :          * Input is a string constant with previously undetermined type. Apply
     232             :          * the target type's typinput function to it to produce a constant of
     233             :          * the target type.
     234             :          *
     235             :          * NOTE: this case cannot be folded together with the other
     236             :          * constant-input case, since the typinput function does not
     237             :          * necessarily behave the same as a type conversion function. For
     238             :          * example, int4's typinput function will reject "1.2", whereas
     239             :          * float-to-int type conversion will round to integer.
     240             :          *
     241             :          * XXX if the typinput function is not immutable, we really ought to
     242             :          * postpone evaluation of the function call until runtime. But there
     243             :          * is no way to represent a typinput function call as an expression
     244             :          * tree, because C-string values are not Datums. (XXX This *is*
     245             :          * possible as of 7.3, do we want to do it?)
     246             :          */
     247      765598 :         Const      *con = (Const *) node;
     248      765598 :         Const      *newcon = makeNode(Const);
     249             :         Oid         baseTypeId;
     250             :         int32       baseTypeMod;
     251             :         int32       inputTypeMod;
     252             :         Type        baseType;
     253             :         ParseCallbackState pcbstate;
     254             : 
     255             :         /*
     256             :          * If the target type is a domain, we want to call its base type's
     257             :          * input routine, not domain_in().  This is to avoid premature failure
     258             :          * when the domain applies a typmod: existing input routines follow
     259             :          * implicit-coercion semantics for length checks, which is not always
     260             :          * what we want here.  The needed check will be applied properly
     261             :          * inside coerce_to_domain().
     262             :          */
     263      765598 :         baseTypeMod = targetTypeMod;
     264      765598 :         baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
     265             : 
     266             :         /*
     267             :          * For most types we pass typmod -1 to the input routine, because
     268             :          * existing input routines follow implicit-coercion semantics for
     269             :          * length checks, which is not always what we want here.  Any length
     270             :          * constraint will be applied later by our caller.  An exception
     271             :          * however is the INTERVAL type, for which we *must* pass the typmod
     272             :          * or it won't be able to obey the bizarre SQL-spec input rules. (Ugly
     273             :          * as sin, but so is this part of the spec...)
     274             :          */
     275      765598 :         if (baseTypeId == INTERVALOID)
     276        1362 :             inputTypeMod = baseTypeMod;
     277             :         else
     278      764236 :             inputTypeMod = -1;
     279             : 
     280      765598 :         baseType = typeidType(baseTypeId);
     281             : 
     282      765598 :         newcon->consttype = baseTypeId;
     283      765598 :         newcon->consttypmod = inputTypeMod;
     284      765598 :         newcon->constcollid = typeTypeCollation(baseType);
     285      765598 :         newcon->constlen = typeLen(baseType);
     286      765598 :         newcon->constbyval = typeByVal(baseType);
     287      765598 :         newcon->constisnull = con->constisnull;
     288             : 
     289             :         /*
     290             :          * We use the original literal's location regardless of the position
     291             :          * of the coercion.  This is a change from pre-9.2 behavior, meant to
     292             :          * simplify life for pg_stat_statements.
     293             :          */
     294      765598 :         newcon->location = con->location;
     295             : 
     296             :         /*
     297             :          * Set up to point at the constant's text if the input routine throws
     298             :          * an error.
     299             :          */
     300      765598 :         setup_parser_errposition_callback(&pcbstate, pstate, con->location);
     301             : 
     302             :         /*
     303             :          * We assume here that UNKNOWN's internal representation is the same
     304             :          * as CSTRING.
     305             :          */
     306      765598 :         if (!con->constisnull)
     307      630922 :             newcon->constvalue = stringTypeDatum(baseType,
     308      632852 :                                                  DatumGetCString(con->constvalue),
     309             :                                                  inputTypeMod);
     310             :         else
     311      132746 :             newcon->constvalue = stringTypeDatum(baseType,
     312             :                                                  NULL,
     313             :                                                  inputTypeMod);
     314             : 
     315             :         /*
     316             :          * If it's a varlena value, force it to be in non-expanded
     317             :          * (non-toasted) format; this avoids any possible dependency on
     318             :          * external values and improves consistency of representation.
     319             :          */
     320      763668 :         if (!con->constisnull && newcon->constlen == -1)
     321      326194 :             newcon->constvalue =
     322      326194 :                 PointerGetDatum(PG_DETOAST_DATUM(newcon->constvalue));
     323             : 
     324             : #ifdef RANDOMIZE_ALLOCATED_MEMORY
     325             : 
     326             :         /*
     327             :          * For pass-by-reference data types, repeat the conversion to see if
     328             :          * the input function leaves any uninitialized bytes in the result. We
     329             :          * can only detect that reliably if RANDOMIZE_ALLOCATED_MEMORY is
     330             :          * enabled, so we don't bother testing otherwise.  The reason we don't
     331             :          * want any instability in the input function is that comparison of
     332             :          * Const nodes relies on bytewise comparison of the datums, so if the
     333             :          * input function leaves garbage then subexpressions that should be
     334             :          * identical may not get recognized as such.  See pgsql-hackers
     335             :          * discussion of 2008-04-04.
     336             :          */
     337             :         if (!con->constisnull && !newcon->constbyval)
     338             :         {
     339             :             Datum       val2;
     340             : 
     341             :             val2 = stringTypeDatum(baseType,
     342             :                                    DatumGetCString(con->constvalue),
     343             :                                    inputTypeMod);
     344             :             if (newcon->constlen == -1)
     345             :                 val2 = PointerGetDatum(PG_DETOAST_DATUM(val2));
     346             :             if (!datumIsEqual(newcon->constvalue, val2, false, newcon->constlen))
     347             :                 elog(WARNING, "type %s has unstable input conversion for \"%s\"",
     348             :                      typeTypeName(baseType), DatumGetCString(con->constvalue));
     349             :         }
     350             : #endif
     351             : 
     352      763668 :         cancel_parser_errposition_callback(&pcbstate);
     353             : 
     354      763668 :         result = (Node *) newcon;
     355             : 
     356             :         /* If target is a domain, apply constraints. */
     357      763668 :         if (baseTypeId != targetTypeId)
     358      123984 :             result = coerce_to_domain(result,
     359             :                                       baseTypeId, baseTypeMod,
     360             :                                       targetTypeId,
     361             :                                       ccontext, cformat, location,
     362             :                                       false);
     363             : 
     364      763668 :         ReleaseSysCache(baseType);
     365             : 
     366      763668 :         return result;
     367             :     }
     368      370070 :     if (IsA(node, Param) &&
     369       19396 :         pstate != NULL && pstate->p_coerce_param_hook != NULL)
     370             :     {
     371             :         /*
     372             :          * Allow the CoerceParamHook to decide what happens.  It can return a
     373             :          * transformed node (very possibly the same Param node), or return
     374             :          * NULL to indicate we should proceed with normal coercion.
     375             :          */
     376       10378 :         result = pstate->p_coerce_param_hook(pstate,
     377             :                                              (Param *) node,
     378             :                                              targetTypeId,
     379             :                                              targetTypeMod,
     380             :                                              location);
     381       10378 :         if (result)
     382       10366 :             return result;
     383             :     }
     384      359704 :     if (IsA(node, CollateExpr))
     385             :     {
     386             :         /*
     387             :          * If we have a COLLATE clause, we have to push the coercion
     388             :          * underneath the COLLATE.  This is really ugly, but there is little
     389             :          * choice because the above hacks on Consts and Params wouldn't happen
     390             :          * otherwise.  This kluge has consequences in coerce_to_target_type.
     391             :          */
     392        2488 :         CollateExpr *coll = (CollateExpr *) node;
     393        2488 :         CollateExpr *newcoll = makeNode(CollateExpr);
     394             : 
     395        2488 :         newcoll->arg = (Expr *)
     396        2488 :             coerce_type(pstate, (Node *) coll->arg,
     397             :                         inputTypeId, targetTypeId, targetTypeMod,
     398             :                         ccontext, cformat, location);
     399        2488 :         newcoll->collOid = coll->collOid;
     400        2488 :         newcoll->location = coll->location;
     401        2488 :         return (Node *) newcoll;
     402             :     }
     403      357216 :     pathtype = find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
     404             :                                      &funcId);
     405      357216 :     if (pathtype != COERCION_PATH_NONE)
     406             :     {
     407      355190 :         if (pathtype != COERCION_PATH_RELABELTYPE)
     408             :         {
     409             :             /*
     410             :              * Generate an expression tree representing run-time application
     411             :              * of the conversion function.  If we are dealing with a domain
     412             :              * target type, the conversion function will yield the base type,
     413             :              * and we need to extract the correct typmod to use from the
     414             :              * domain's typtypmod.
     415             :              */
     416             :             Oid         baseTypeId;
     417             :             int32       baseTypeMod;
     418             : 
     419       79392 :             baseTypeMod = targetTypeMod;
     420       79392 :             baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
     421             : 
     422       79392 :             result = build_coercion_expression(node, pathtype, funcId,
     423             :                                                baseTypeId, baseTypeMod,
     424             :                                                ccontext, cformat, location);
     425             : 
     426             :             /*
     427             :              * If domain, coerce to the domain type and relabel with domain
     428             :              * type ID, hiding the previous coercion node.
     429             :              */
     430       79392 :             if (targetTypeId != baseTypeId)
     431       10046 :                 result = coerce_to_domain(result, baseTypeId, baseTypeMod,
     432             :                                           targetTypeId,
     433             :                                           ccontext, cformat, location,
     434             :                                           true);
     435             :         }
     436             :         else
     437             :         {
     438             :             /*
     439             :              * We don't need to do a physical conversion, but we do need to
     440             :              * attach a RelabelType node so that the expression will be seen
     441             :              * to have the intended type when inspected by higher-level code.
     442             :              *
     443             :              * Also, domains may have value restrictions beyond the base type
     444             :              * that must be accounted for.  If the destination is a domain
     445             :              * then we won't need a RelabelType node.
     446             :              */
     447      275798 :             result = coerce_to_domain(node, InvalidOid, -1, targetTypeId,
     448             :                                       ccontext, cformat, location,
     449             :                                       false);
     450      275798 :             if (result == node)
     451             :             {
     452             :                 /*
     453             :                  * XXX could we label result with exprTypmod(node) instead of
     454             :                  * default -1 typmod, to save a possible length-coercion
     455             :                  * later? Would work if both types have same interpretation of
     456             :                  * typmod, which is likely but not certain.
     457             :                  */
     458      116860 :                 RelabelType *r = makeRelabelType((Expr *) result,
     459             :                                                  targetTypeId, -1,
     460             :                                                  InvalidOid,
     461             :                                                  cformat);
     462             : 
     463      116860 :                 r->location = location;
     464      116860 :                 result = (Node *) r;
     465             :             }
     466             :         }
     467      355190 :         return result;
     468             :     }
     469        3230 :     if (inputTypeId == RECORDOID &&
     470        1204 :         ISCOMPLEX(targetTypeId))
     471             :     {
     472             :         /* Coerce a RECORD to a specific complex type */
     473        1204 :         return coerce_record_to_complex(pstate, node, targetTypeId,
     474             :                                         ccontext, cformat, location);
     475             :     }
     476        1592 :     if (targetTypeId == RECORDOID &&
     477         770 :         ISCOMPLEX(inputTypeId))
     478             :     {
     479             :         /* Coerce a specific complex type to RECORD */
     480             :         /* NB: we do NOT want a RelabelType here */
     481         770 :         return node;
     482             :     }
     483             : #ifdef NOT_USED
     484             :     if (inputTypeId == RECORDARRAYOID &&
     485             :         is_complex_array(targetTypeId))
     486             :     {
     487             :         /* Coerce record[] to a specific complex array type */
     488             :         /* not implemented yet ... */
     489             :     }
     490             : #endif
     491          64 :     if (targetTypeId == RECORDARRAYOID &&
     492          12 :         is_complex_array(inputTypeId))
     493             :     {
     494             :         /* Coerce a specific complex array type to record[] */
     495             :         /* NB: we do NOT want a RelabelType here */
     496          12 :         return node;
     497             :     }
     498          40 :     if (typeInheritsFrom(inputTypeId, targetTypeId)
     499           4 :         || typeIsOfTypedTable(inputTypeId, targetTypeId))
     500             :     {
     501             :         /*
     502             :          * Input class type is a subclass of target, so generate an
     503             :          * appropriate runtime conversion (removing unneeded columns and
     504             :          * possibly rearranging the ones that are wanted).
     505             :          *
     506             :          * We will also get here when the input is a domain over a subclass of
     507             :          * the target type.  To keep life simple for the executor, we define
     508             :          * ConvertRowtypeExpr as only working between regular composite types;
     509             :          * therefore, in such cases insert a RelabelType to smash the input
     510             :          * expression down to its base type.
     511             :          */
     512          40 :         Oid         baseTypeId = getBaseType(inputTypeId);
     513          40 :         ConvertRowtypeExpr *r = makeNode(ConvertRowtypeExpr);
     514             : 
     515          40 :         if (baseTypeId != inputTypeId)
     516             :         {
     517           0 :             RelabelType *rt = makeRelabelType((Expr *) node,
     518             :                                               baseTypeId, -1,
     519             :                                               InvalidOid,
     520             :                                               COERCE_IMPLICIT_CAST);
     521             : 
     522           0 :             rt->location = location;
     523           0 :             node = (Node *) rt;
     524             :         }
     525          40 :         r->arg = (Expr *) node;
     526          40 :         r->resulttype = targetTypeId;
     527          40 :         r->convertformat = cformat;
     528          40 :         r->location = location;
     529          40 :         return (Node *) r;
     530             :     }
     531             :     /* If we get here, caller blew it */
     532           0 :     elog(ERROR, "failed to find conversion function from %s to %s",
     533             :          format_type_be(inputTypeId), format_type_be(targetTypeId));
     534             :     return NULL;                /* keep compiler quiet */
     535             : }
     536             : 
     537             : 
     538             : /*
     539             :  * can_coerce_type()
     540             :  *      Can input_typeids be coerced to target_typeids?
     541             :  *
     542             :  * We must be told the context (CAST construct, assignment, implicit coercion)
     543             :  * as this determines the set of available casts.
     544             :  */
     545             : bool
     546     1885110 : can_coerce_type(int nargs, const Oid *input_typeids, const Oid *target_typeids,
     547             :                 CoercionContext ccontext)
     548             : {
     549     1885110 :     bool        have_generics = false;
     550             :     int         i;
     551             : 
     552             :     /* run through argument list... */
     553     3292046 :     for (i = 0; i < nargs; i++)
     554             :     {
     555     2102358 :         Oid         inputTypeId = input_typeids[i];
     556     2102358 :         Oid         targetTypeId = target_typeids[i];
     557             :         CoercionPathType pathtype;
     558             :         Oid         funcId;
     559             : 
     560             :         /* no problem if same type */
     561     2102358 :         if (inputTypeId == targetTypeId)
     562     1406936 :             continue;
     563             : 
     564             :         /* accept if target is ANY */
     565     1841322 :         if (targetTypeId == ANYOID)
     566        4646 :             continue;
     567             : 
     568             :         /* accept if target is polymorphic, for now */
     569     1836676 :         if (IsPolymorphicType(targetTypeId))
     570             :         {
     571      159742 :             have_generics = true;   /* do more checking later */
     572      159742 :             continue;
     573             :         }
     574             : 
     575             :         /*
     576             :          * If input is an untyped string constant, assume we can convert it to
     577             :          * anything.
     578             :          */
     579     1676934 :         if (inputTypeId == UNKNOWNOID)
     580      635234 :             continue;
     581             : 
     582             :         /*
     583             :          * If pg_cast shows that we can coerce, accept.  This test now covers
     584             :          * both binary-compatible and coercion-function cases.
     585             :          */
     586     1041700 :         pathtype = find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
     587             :                                          &funcId);
     588     1041700 :         if (pathtype != COERCION_PATH_NONE)
     589      344448 :             continue;
     590             : 
     591             :         /*
     592             :          * If input is RECORD and target is a composite type, assume we can
     593             :          * coerce (may need tighter checking here)
     594             :          */
     595      698512 :         if (inputTypeId == RECORDOID &&
     596        1260 :             ISCOMPLEX(targetTypeId))
     597        1204 :             continue;
     598             : 
     599             :         /*
     600             :          * If input is a composite type and target is RECORD, accept
     601             :          */
     602      706822 :         if (targetTypeId == RECORDOID &&
     603       10774 :             ISCOMPLEX(inputTypeId))
     604         586 :             continue;
     605             : 
     606             : #ifdef NOT_USED                 /* not implemented yet */
     607             : 
     608             :         /*
     609             :          * If input is record[] and target is a composite array type, assume
     610             :          * we can coerce (may need tighter checking here)
     611             :          */
     612             :         if (inputTypeId == RECORDARRAYOID &&
     613             :             is_complex_array(targetTypeId))
     614             :             continue;
     615             : #endif
     616             : 
     617             :         /*
     618             :          * If input is a composite array type and target is record[], accept
     619             :          */
     620      695462 :         if (targetTypeId == RECORDARRAYOID &&
     621           0 :             is_complex_array(inputTypeId))
     622           0 :             continue;
     623             : 
     624             :         /*
     625             :          * If input is a class type that inherits from target, accept
     626             :          */
     627      695462 :         if (typeInheritsFrom(inputTypeId, targetTypeId)
     628      695426 :             || typeIsOfTypedTable(inputTypeId, targetTypeId))
     629          40 :             continue;
     630             : 
     631             :         /*
     632             :          * Else, cannot coerce at this argument position
     633             :          */
     634      695422 :         return false;
     635             :     }
     636             : 
     637             :     /* If we found any generic argument types, cross-check them */
     638     1189688 :     if (have_generics)
     639             :     {
     640      120868 :         if (!check_generic_type_consistency(input_typeids, target_typeids,
     641             :                                             nargs))
     642       50430 :             return false;
     643             :     }
     644             : 
     645     1139258 :     return true;
     646             : }
     647             : 
     648             : 
     649             : /*
     650             :  * Create an expression tree to represent coercion to a domain type.
     651             :  *
     652             :  * 'arg': input expression
     653             :  * 'baseTypeId': base type of domain, if known (pass InvalidOid if caller
     654             :  *      has not bothered to look this up)
     655             :  * 'baseTypeMod': base type typmod of domain, if known (pass -1 if caller
     656             :  *      has not bothered to look this up)
     657             :  * 'typeId': target type to coerce to
     658             :  * 'ccontext': context indicator to control coercions
     659             :  * 'cformat': coercion display format
     660             :  * 'location': coercion request location
     661             :  * 'hideInputCoercion': if true, hide the input coercion under this one.
     662             :  *
     663             :  * If the target type isn't a domain, the given 'arg' is returned as-is.
     664             :  */
     665             : Node *
     666      423966 : coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId,
     667             :                  CoercionContext ccontext, CoercionForm cformat, int location,
     668             :                  bool hideInputCoercion)
     669             : {
     670             :     CoerceToDomain *result;
     671             : 
     672             :     /* Get the base type if it hasn't been supplied */
     673      423966 :     if (baseTypeId == InvalidOid)
     674      289804 :         baseTypeId = getBaseTypeAndTypmod(typeId, &baseTypeMod);
     675             : 
     676             :     /* If it isn't a domain, return the node as it was passed in */
     677      423966 :     if (baseTypeId == typeId)
     678      130822 :         return arg;
     679             : 
     680             :     /* Suppress display of nested coercion steps */
     681      293144 :     if (hideInputCoercion)
     682       10046 :         hide_coercion_node(arg);
     683             : 
     684             :     /*
     685             :      * If the domain applies a typmod to its base type, build the appropriate
     686             :      * coercion step.  Mark it implicit for display purposes, because we don't
     687             :      * want it shown separately by ruleutils.c; but the isExplicit flag passed
     688             :      * to the conversion function depends on the manner in which the domain
     689             :      * coercion is invoked, so that the semantics of implicit and explicit
     690             :      * coercion differ.  (Is that really the behavior we want?)
     691             :      *
     692             :      * NOTE: because we apply this as part of the fixed expression structure,
     693             :      * ALTER DOMAIN cannot alter the typtypmod.  But it's unclear that that
     694             :      * would be safe to do anyway, without lots of knowledge about what the
     695             :      * base type thinks the typmod means.
     696             :      */
     697      293144 :     arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod,
     698             :                              ccontext, COERCE_IMPLICIT_CAST, location,
     699             :                              false);
     700             : 
     701             :     /*
     702             :      * Now build the domain coercion node.  This represents run-time checking
     703             :      * of any constraints currently attached to the domain.  This also ensures
     704             :      * that the expression is properly labeled as to result type.
     705             :      */
     706      293144 :     result = makeNode(CoerceToDomain);
     707      293144 :     result->arg = (Expr *) arg;
     708      293144 :     result->resulttype = typeId;
     709      293144 :     result->resulttypmod = -1;   /* currently, always -1 for domains */
     710             :     /* resultcollid will be set by parse_collate.c */
     711      293144 :     result->coercionformat = cformat;
     712      293144 :     result->location = location;
     713             : 
     714      293144 :     return (Node *) result;
     715             : }
     716             : 
     717             : 
     718             : /*
     719             :  * coerce_type_typmod()
     720             :  *      Force a value to a particular typmod, if meaningful and possible.
     721             :  *
     722             :  * This is applied to values that are going to be stored in a relation
     723             :  * (where we have an atttypmod for the column) as well as values being
     724             :  * explicitly CASTed (where the typmod comes from the target type spec).
     725             :  *
     726             :  * The caller must have already ensured that the value is of the correct
     727             :  * type, typically by applying coerce_type.
     728             :  *
     729             :  * ccontext may affect semantics, depending on whether the length coercion
     730             :  * function pays attention to the isExplicit flag it's passed.
     731             :  *
     732             :  * cformat determines the display properties of the generated node (if any).
     733             :  *
     734             :  * If hideInputCoercion is true *and* we generate a node, the input node is
     735             :  * forced to IMPLICIT display form, so that only the typmod coercion node will
     736             :  * be visible when displaying the expression.
     737             :  *
     738             :  * NOTE: this does not need to work on domain types, because any typmod
     739             :  * coercion for a domain is considered to be part of the type coercion
     740             :  * needed to produce the domain value in the first place.  So, no getBaseType.
     741             :  */
     742             : static Node *
     743     1004194 : coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod,
     744             :                    CoercionContext ccontext, CoercionForm cformat,
     745             :                    int location,
     746             :                    bool hideInputCoercion)
     747             : {
     748             :     CoercionPathType pathtype;
     749             :     Oid         funcId;
     750             : 
     751             :     /*
     752             :      * A negative typmod is assumed to mean that no coercion is wanted. Also,
     753             :      * skip coercion if already done.
     754             :      */
     755     1004194 :     if (targetTypMod < 0 || targetTypMod == exprTypmod(node))
     756      973508 :         return node;
     757             : 
     758       30686 :     pathtype = find_typmod_coercion_function(targetTypeId, &funcId);
     759             : 
     760       30686 :     if (pathtype != COERCION_PATH_NONE)
     761             :     {
     762             :         /* Suppress display of nested coercion steps */
     763       30674 :         if (hideInputCoercion)
     764         562 :             hide_coercion_node(node);
     765             : 
     766       30674 :         node = build_coercion_expression(node, pathtype, funcId,
     767             :                                          targetTypeId, targetTypMod,
     768             :                                          ccontext, cformat, location);
     769             :     }
     770             : 
     771       30686 :     return node;
     772             : }
     773             : 
     774             : /*
     775             :  * Mark a coercion node as IMPLICIT so it will never be displayed by
     776             :  * ruleutils.c.  We use this when we generate a nest of coercion nodes
     777             :  * to implement what is logically one conversion; the inner nodes are
     778             :  * forced to IMPLICIT_CAST format.  This does not change their semantics,
     779             :  * only display behavior.
     780             :  *
     781             :  * It is caller error to call this on something that doesn't have a
     782             :  * CoercionForm field.
     783             :  */
     784             : static void
     785       10608 : hide_coercion_node(Node *node)
     786             : {
     787       10608 :     if (IsA(node, FuncExpr))
     788        5012 :         ((FuncExpr *) node)->funcformat = COERCE_IMPLICIT_CAST;
     789        5596 :     else if (IsA(node, RelabelType))
     790         150 :         ((RelabelType *) node)->relabelformat = COERCE_IMPLICIT_CAST;
     791        5446 :     else if (IsA(node, CoerceViaIO))
     792        5438 :         ((CoerceViaIO *) node)->coerceformat = COERCE_IMPLICIT_CAST;
     793           8 :     else if (IsA(node, ArrayCoerceExpr))
     794           8 :         ((ArrayCoerceExpr *) node)->coerceformat = COERCE_IMPLICIT_CAST;
     795           0 :     else if (IsA(node, ConvertRowtypeExpr))
     796           0 :         ((ConvertRowtypeExpr *) node)->convertformat = COERCE_IMPLICIT_CAST;
     797           0 :     else if (IsA(node, RowExpr))
     798           0 :         ((RowExpr *) node)->row_format = COERCE_IMPLICIT_CAST;
     799           0 :     else if (IsA(node, CoerceToDomain))
     800           0 :         ((CoerceToDomain *) node)->coercionformat = COERCE_IMPLICIT_CAST;
     801             :     else
     802           0 :         elog(ERROR, "unsupported node type: %d", (int) nodeTag(node));
     803       10608 : }
     804             : 
     805             : /*
     806             :  * build_coercion_expression()
     807             :  *      Construct an expression tree for applying a pg_cast entry.
     808             :  *
     809             :  * This is used for both type-coercion and length-coercion operations,
     810             :  * since there is no difference in terms of the calling convention.
     811             :  */
     812             : static Node *
     813      110066 : build_coercion_expression(Node *node,
     814             :                           CoercionPathType pathtype,
     815             :                           Oid funcId,
     816             :                           Oid targetTypeId, int32 targetTypMod,
     817             :                           CoercionContext ccontext, CoercionForm cformat,
     818             :                           int location)
     819             : {
     820      110066 :     int         nargs = 0;
     821             : 
     822      110066 :     if (OidIsValid(funcId))
     823             :     {
     824             :         HeapTuple   tp;
     825             :         Form_pg_proc procstruct;
     826             : 
     827       93406 :         tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcId));
     828       93406 :         if (!HeapTupleIsValid(tp))
     829           0 :             elog(ERROR, "cache lookup failed for function %u", funcId);
     830       93406 :         procstruct = (Form_pg_proc) GETSTRUCT(tp);
     831             : 
     832             :         /*
     833             :          * These Asserts essentially check that function is a legal coercion
     834             :          * function.  We can't make the seemingly obvious tests on prorettype
     835             :          * and proargtypes[0], even in the COERCION_PATH_FUNC case, because of
     836             :          * various binary-compatibility cases.
     837             :          */
     838             :         /* Assert(targetTypeId == procstruct->prorettype); */
     839             :         Assert(!procstruct->proretset);
     840             :         Assert(procstruct->prokind == PROKIND_FUNCTION);
     841       93406 :         nargs = procstruct->pronargs;
     842             :         Assert(nargs >= 1 && nargs <= 3);
     843             :         /* Assert(procstruct->proargtypes.values[0] == exprType(node)); */
     844             :         Assert(nargs < 2 || procstruct->proargtypes.values[1] == INT4OID);
     845             :         Assert(nargs < 3 || procstruct->proargtypes.values[2] == BOOLOID);
     846             : 
     847       93406 :         ReleaseSysCache(tp);
     848             :     }
     849             : 
     850      110066 :     if (pathtype == COERCION_PATH_FUNC)
     851             :     {
     852             :         /* We build an ordinary FuncExpr with special arguments */
     853             :         FuncExpr   *fexpr;
     854             :         List       *args;
     855             :         Const      *cons;
     856             : 
     857             :         Assert(OidIsValid(funcId));
     858             : 
     859       93350 :         args = list_make1(node);
     860             : 
     861       93350 :         if (nargs >= 2)
     862             :         {
     863             :             /* Pass target typmod as an int4 constant */
     864       31390 :             cons = makeConst(INT4OID,
     865             :                              -1,
     866             :                              InvalidOid,
     867             :                              sizeof(int32),
     868             :                              Int32GetDatum(targetTypMod),
     869             :                              false,
     870             :                              true);
     871             : 
     872       31390 :             args = lappend(args, cons);
     873             :         }
     874             : 
     875       93350 :         if (nargs == 3)
     876             :         {
     877             :             /* Pass it a boolean isExplicit parameter, too */
     878       25146 :             cons = makeConst(BOOLOID,
     879             :                              -1,
     880             :                              InvalidOid,
     881             :                              sizeof(bool),
     882             :                              BoolGetDatum(ccontext == COERCION_EXPLICIT),
     883             :                              false,
     884             :                              true);
     885             : 
     886       25146 :             args = lappend(args, cons);
     887             :         }
     888             : 
     889       93350 :         fexpr = makeFuncExpr(funcId, targetTypeId, args,
     890             :                              InvalidOid, InvalidOid, cformat);
     891       93350 :         fexpr->location = location;
     892       93350 :         return (Node *) fexpr;
     893             :     }
     894       16716 :     else if (pathtype == COERCION_PATH_ARRAYCOERCE)
     895             :     {
     896             :         /* We need to build an ArrayCoerceExpr */
     897        1968 :         ArrayCoerceExpr *acoerce = makeNode(ArrayCoerceExpr);
     898        1968 :         CaseTestExpr *ctest = makeNode(CaseTestExpr);
     899             :         Oid         sourceBaseTypeId;
     900             :         int32       sourceBaseTypeMod;
     901             :         Oid         targetElementType;
     902             :         Node       *elemexpr;
     903             : 
     904             :         /*
     905             :          * Look through any domain over the source array type.  Note we don't
     906             :          * expect that the target type is a domain; it must be a plain array.
     907             :          * (To get to a domain target type, we'll do coerce_to_domain later.)
     908             :          */
     909        1968 :         sourceBaseTypeMod = exprTypmod(node);
     910        1968 :         sourceBaseTypeId = getBaseTypeAndTypmod(exprType(node),
     911             :                                                 &sourceBaseTypeMod);
     912             : 
     913             :         /*
     914             :          * Set up a CaseTestExpr representing one element of the source array.
     915             :          * This is an abuse of CaseTestExpr, but it's OK as long as there
     916             :          * can't be any CaseExpr or ArrayCoerceExpr within the completed
     917             :          * elemexpr.
     918             :          */
     919        1968 :         ctest->typeId = get_element_type(sourceBaseTypeId);
     920             :         Assert(OidIsValid(ctest->typeId));
     921        1968 :         ctest->typeMod = sourceBaseTypeMod;
     922        1968 :         ctest->collation = InvalidOid;   /* Assume coercions don't care */
     923             : 
     924             :         /* And coerce it to the target element type */
     925        1968 :         targetElementType = get_element_type(targetTypeId);
     926             :         Assert(OidIsValid(targetElementType));
     927             : 
     928        1968 :         elemexpr = coerce_to_target_type(NULL,
     929             :                                          (Node *) ctest,
     930             :                                          ctest->typeId,
     931             :                                          targetElementType,
     932             :                                          targetTypMod,
     933             :                                          ccontext,
     934             :                                          cformat,
     935             :                                          location);
     936        1968 :         if (elemexpr == NULL)   /* shouldn't happen */
     937           0 :             elog(ERROR, "failed to coerce array element type as expected");
     938             : 
     939        1968 :         acoerce->arg = (Expr *) node;
     940        1968 :         acoerce->elemexpr = (Expr *) elemexpr;
     941        1968 :         acoerce->resulttype = targetTypeId;
     942             : 
     943             :         /*
     944             :          * Label the output as having a particular element typmod only if we
     945             :          * ended up with a per-element expression that is labeled that way.
     946             :          */
     947        1968 :         acoerce->resulttypmod = exprTypmod(elemexpr);
     948             :         /* resultcollid will be set by parse_collate.c */
     949        1968 :         acoerce->coerceformat = cformat;
     950        1968 :         acoerce->location = location;
     951             : 
     952        1968 :         return (Node *) acoerce;
     953             :     }
     954       14748 :     else if (pathtype == COERCION_PATH_COERCEVIAIO)
     955             :     {
     956             :         /* We need to build a CoerceViaIO node */
     957       14748 :         CoerceViaIO *iocoerce = makeNode(CoerceViaIO);
     958             : 
     959             :         Assert(!OidIsValid(funcId));
     960             : 
     961       14748 :         iocoerce->arg = (Expr *) node;
     962       14748 :         iocoerce->resulttype = targetTypeId;
     963             :         /* resultcollid will be set by parse_collate.c */
     964       14748 :         iocoerce->coerceformat = cformat;
     965       14748 :         iocoerce->location = location;
     966             : 
     967       14748 :         return (Node *) iocoerce;
     968             :     }
     969             :     else
     970             :     {
     971           0 :         elog(ERROR, "unsupported pathtype %d in build_coercion_expression",
     972             :              (int) pathtype);
     973             :         return NULL;            /* keep compiler quiet */
     974             :     }
     975             : }
     976             : 
     977             : 
     978             : /*
     979             :  * coerce_record_to_complex
     980             :  *      Coerce a RECORD to a specific composite type.
     981             :  *
     982             :  * Currently we only support this for inputs that are RowExprs or whole-row
     983             :  * Vars.
     984             :  */
     985             : static Node *
     986        1204 : coerce_record_to_complex(ParseState *pstate, Node *node,
     987             :                          Oid targetTypeId,
     988             :                          CoercionContext ccontext,
     989             :                          CoercionForm cformat,
     990             :                          int location)
     991             : {
     992             :     RowExpr    *rowexpr;
     993             :     Oid         baseTypeId;
     994        1204 :     int32       baseTypeMod = -1;
     995             :     TupleDesc   tupdesc;
     996        1204 :     List       *args = NIL;
     997             :     List       *newargs;
     998             :     int         i;
     999             :     int         ucolno;
    1000             :     ListCell   *arg;
    1001             : 
    1002        1204 :     if (node && IsA(node, RowExpr))
    1003             :     {
    1004             :         /*
    1005             :          * Since the RowExpr must be of type RECORD, we needn't worry about it
    1006             :          * containing any dropped columns.
    1007             :          */
    1008        1204 :         args = ((RowExpr *) node)->args;
    1009             :     }
    1010           0 :     else if (node && IsA(node, Var) &&
    1011           0 :              ((Var *) node)->varattno == InvalidAttrNumber)
    1012           0 :     {
    1013           0 :         int         rtindex = ((Var *) node)->varno;
    1014           0 :         int         sublevels_up = ((Var *) node)->varlevelsup;
    1015           0 :         int         vlocation = ((Var *) node)->location;
    1016             :         ParseNamespaceItem *nsitem;
    1017             : 
    1018           0 :         nsitem = GetNSItemByRangeTablePosn(pstate, rtindex, sublevels_up);
    1019           0 :         args = expandNSItemVars(nsitem, sublevels_up, vlocation, NULL);
    1020             :     }
    1021             :     else
    1022           0 :         ereport(ERROR,
    1023             :                 (errcode(ERRCODE_CANNOT_COERCE),
    1024             :                  errmsg("cannot cast type %s to %s",
    1025             :                         format_type_be(RECORDOID),
    1026             :                         format_type_be(targetTypeId)),
    1027             :                  parser_coercion_errposition(pstate, location, node)));
    1028             : 
    1029             :     /*
    1030             :      * Look up the composite type, accounting for possibility that what we are
    1031             :      * given is a domain over composite.
    1032             :      */
    1033        1204 :     baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
    1034        1204 :     tupdesc = lookup_rowtype_tupdesc(baseTypeId, baseTypeMod);
    1035             : 
    1036             :     /* Process the fields */
    1037        1204 :     newargs = NIL;
    1038        1204 :     ucolno = 1;
    1039        1204 :     arg = list_head(args);
    1040        4054 :     for (i = 0; i < tupdesc->natts; i++)
    1041             :     {
    1042             :         Node       *expr;
    1043             :         Node       *cexpr;
    1044             :         Oid         exprtype;
    1045        2850 :         Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
    1046             : 
    1047             :         /* Fill in NULLs for dropped columns in rowtype */
    1048        2850 :         if (attr->attisdropped)
    1049             :         {
    1050             :             /*
    1051             :              * can't use atttypid here, but it doesn't really matter what type
    1052             :              * the Const claims to be.
    1053             :              */
    1054           6 :             newargs = lappend(newargs,
    1055           6 :                               makeNullConst(INT4OID, -1, InvalidOid));
    1056           6 :             continue;
    1057             :         }
    1058             : 
    1059        2844 :         if (arg == NULL)
    1060           0 :             ereport(ERROR,
    1061             :                     (errcode(ERRCODE_CANNOT_COERCE),
    1062             :                      errmsg("cannot cast type %s to %s",
    1063             :                             format_type_be(RECORDOID),
    1064             :                             format_type_be(targetTypeId)),
    1065             :                      errdetail("Input has too few columns."),
    1066             :                      parser_coercion_errposition(pstate, location, node)));
    1067        2844 :         expr = (Node *) lfirst(arg);
    1068        2844 :         exprtype = exprType(expr);
    1069             : 
    1070        2844 :         cexpr = coerce_to_target_type(pstate,
    1071             :                                       expr, exprtype,
    1072             :                                       attr->atttypid,
    1073             :                                       attr->atttypmod,
    1074             :                                       ccontext,
    1075             :                                       COERCE_IMPLICIT_CAST,
    1076             :                                       -1);
    1077        2844 :         if (cexpr == NULL)
    1078           0 :             ereport(ERROR,
    1079             :                     (errcode(ERRCODE_CANNOT_COERCE),
    1080             :                      errmsg("cannot cast type %s to %s",
    1081             :                             format_type_be(RECORDOID),
    1082             :                             format_type_be(targetTypeId)),
    1083             :                      errdetail("Cannot cast type %s to %s in column %d.",
    1084             :                                format_type_be(exprtype),
    1085             :                                format_type_be(attr->atttypid),
    1086             :                                ucolno),
    1087             :                      parser_coercion_errposition(pstate, location, expr)));
    1088        2844 :         newargs = lappend(newargs, cexpr);
    1089        2844 :         ucolno++;
    1090        2844 :         arg = lnext(args, arg);
    1091             :     }
    1092        1204 :     if (arg != NULL)
    1093           0 :         ereport(ERROR,
    1094             :                 (errcode(ERRCODE_CANNOT_COERCE),
    1095             :                  errmsg("cannot cast type %s to %s",
    1096             :                         format_type_be(RECORDOID),
    1097             :                         format_type_be(targetTypeId)),
    1098             :                  errdetail("Input has too many columns."),
    1099             :                  parser_coercion_errposition(pstate, location, node)));
    1100             : 
    1101        1204 :     ReleaseTupleDesc(tupdesc);
    1102             : 
    1103        1204 :     rowexpr = makeNode(RowExpr);
    1104        1204 :     rowexpr->args = newargs;
    1105        1204 :     rowexpr->row_typeid = baseTypeId;
    1106        1204 :     rowexpr->row_format = cformat;
    1107        1204 :     rowexpr->colnames = NIL; /* not needed for named target type */
    1108        1204 :     rowexpr->location = location;
    1109             : 
    1110             :     /* If target is a domain, apply constraints */
    1111        1204 :     if (baseTypeId != targetTypeId)
    1112             :     {
    1113          76 :         rowexpr->row_format = COERCE_IMPLICIT_CAST;
    1114          76 :         return coerce_to_domain((Node *) rowexpr,
    1115             :                                 baseTypeId, baseTypeMod,
    1116             :                                 targetTypeId,
    1117             :                                 ccontext, cformat, location,
    1118             :                                 false);
    1119             :     }
    1120             : 
    1121        1128 :     return (Node *) rowexpr;
    1122             : }
    1123             : 
    1124             : /*
    1125             :  * coerce_to_boolean()
    1126             :  *      Coerce an argument of a construct that requires boolean input
    1127             :  *      (AND, OR, NOT, etc).  Also check that input is not a set.
    1128             :  *
    1129             :  * Returns the possibly-transformed node tree.
    1130             :  *
    1131             :  * As with coerce_type, pstate may be NULL if no special unknown-Param
    1132             :  * processing is wanted.
    1133             :  */
    1134             : Node *
    1135      803922 : coerce_to_boolean(ParseState *pstate, Node *node,
    1136             :                   const char *constructName)
    1137             : {
    1138      803922 :     Oid         inputTypeId = exprType(node);
    1139             : 
    1140      803922 :     if (inputTypeId != BOOLOID)
    1141             :     {
    1142             :         Node       *newnode;
    1143             : 
    1144           0 :         newnode = coerce_to_target_type(pstate, node, inputTypeId,
    1145             :                                         BOOLOID, -1,
    1146             :                                         COERCION_ASSIGNMENT,
    1147             :                                         COERCE_IMPLICIT_CAST,
    1148             :                                         -1);
    1149           0 :         if (newnode == NULL)
    1150           0 :             ereport(ERROR,
    1151             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    1152             :             /* translator: first %s is name of a SQL construct, eg WHERE */
    1153             :                      errmsg("argument of %s must be type %s, not type %s",
    1154             :                             constructName, "boolean",
    1155             :                             format_type_be(inputTypeId)),
    1156             :                      parser_errposition(pstate, exprLocation(node))));
    1157           0 :         node = newnode;
    1158             :     }
    1159             : 
    1160      803922 :     if (expression_returns_set(node))
    1161           0 :         ereport(ERROR,
    1162             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    1163             :         /* translator: %s is name of a SQL construct, eg WHERE */
    1164             :                  errmsg("argument of %s must not return a set",
    1165             :                         constructName),
    1166             :                  parser_errposition(pstate, exprLocation(node))));
    1167             : 
    1168      803922 :     return node;
    1169             : }
    1170             : 
    1171             : /*
    1172             :  * coerce_to_specific_type_typmod()
    1173             :  *      Coerce an argument of a construct that requires a specific data type,
    1174             :  *      with a specific typmod.  Also check that input is not a set.
    1175             :  *
    1176             :  * Returns the possibly-transformed node tree.
    1177             :  *
    1178             :  * As with coerce_type, pstate may be NULL if no special unknown-Param
    1179             :  * processing is wanted.
    1180             :  */
    1181             : Node *
    1182       24040 : coerce_to_specific_type_typmod(ParseState *pstate, Node *node,
    1183             :                                Oid targetTypeId, int32 targetTypmod,
    1184             :                                const char *constructName)
    1185             : {
    1186       24040 :     Oid         inputTypeId = exprType(node);
    1187             : 
    1188       24040 :     if (inputTypeId != targetTypeId)
    1189             :     {
    1190             :         Node       *newnode;
    1191             : 
    1192       12366 :         newnode = coerce_to_target_type(pstate, node, inputTypeId,
    1193             :                                         targetTypeId, targetTypmod,
    1194             :                                         COERCION_ASSIGNMENT,
    1195             :                                         COERCE_IMPLICIT_CAST,
    1196             :                                         -1);
    1197       12358 :         if (newnode == NULL)
    1198           4 :             ereport(ERROR,
    1199             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    1200             :             /* translator: first %s is name of a SQL construct, eg LIMIT */
    1201             :                      errmsg("argument of %s must be type %s, not type %s",
    1202             :                             constructName,
    1203             :                             format_type_be(targetTypeId),
    1204             :                             format_type_be(inputTypeId)),
    1205             :                      parser_errposition(pstate, exprLocation(node))));
    1206       12354 :         node = newnode;
    1207             :     }
    1208             : 
    1209       24028 :     if (expression_returns_set(node))
    1210           0 :         ereport(ERROR,
    1211             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    1212             :         /* translator: %s is name of a SQL construct, eg LIMIT */
    1213             :                  errmsg("argument of %s must not return a set",
    1214             :                         constructName),
    1215             :                  parser_errposition(pstate, exprLocation(node))));
    1216             : 
    1217       24028 :     return node;
    1218             : }
    1219             : 
    1220             : /*
    1221             :  * coerce_to_specific_type()
    1222             :  *      Coerce an argument of a construct that requires a specific data type.
    1223             :  *      Also check that input is not a set.
    1224             :  *
    1225             :  * Returns the possibly-transformed node tree.
    1226             :  *
    1227             :  * As with coerce_type, pstate may be NULL if no special unknown-Param
    1228             :  * processing is wanted.
    1229             :  */
    1230             : Node *
    1231       24002 : coerce_to_specific_type(ParseState *pstate, Node *node,
    1232             :                         Oid targetTypeId,
    1233             :                         const char *constructName)
    1234             : {
    1235       24002 :     return coerce_to_specific_type_typmod(pstate, node,
    1236             :                                           targetTypeId, -1,
    1237             :                                           constructName);
    1238             : }
    1239             : 
    1240             : /*
    1241             :  * parser_coercion_errposition - report coercion error location, if possible
    1242             :  *
    1243             :  * We prefer to point at the coercion request (CAST, ::, etc) if possible;
    1244             :  * but there may be no such location in the case of an implicit coercion.
    1245             :  * In that case point at the input expression.
    1246             :  *
    1247             :  * XXX possibly this is more generally useful than coercion errors;
    1248             :  * if so, should rename and place with parser_errposition.
    1249             :  */
    1250             : int
    1251          16 : parser_coercion_errposition(ParseState *pstate,
    1252             :                             int coerce_location,
    1253             :                             Node *input_expr)
    1254             : {
    1255          16 :     if (coerce_location >= 0)
    1256          16 :         return parser_errposition(pstate, coerce_location);
    1257             :     else
    1258           0 :         return parser_errposition(pstate, exprLocation(input_expr));
    1259             : }
    1260             : 
    1261             : 
    1262             : /*
    1263             :  * select_common_type()
    1264             :  *      Determine the common supertype of a list of input expressions.
    1265             :  *      This is used for determining the output type of CASE, UNION,
    1266             :  *      and similar constructs.
    1267             :  *
    1268             :  * 'exprs' is a *nonempty* list of expressions.  Note that earlier items
    1269             :  * in the list will be preferred if there is doubt.
    1270             :  * 'context' is a phrase to use in the error message if we fail to select
    1271             :  * a usable type.  Pass NULL to have the routine return InvalidOid
    1272             :  * rather than throwing an error on failure.
    1273             :  * 'which_expr': if not NULL, receives a pointer to the particular input
    1274             :  * expression from which the result type was taken.
    1275             :  */
    1276             : Oid
    1277      206872 : select_common_type(ParseState *pstate, List *exprs, const char *context,
    1278             :                    Node **which_expr)
    1279             : {
    1280             :     Node       *pexpr;
    1281             :     Oid         ptype;
    1282             :     TYPCATEGORY pcategory;
    1283             :     bool        pispreferred;
    1284             :     ListCell   *lc;
    1285             : 
    1286             :     Assert(exprs != NIL);
    1287      206872 :     pexpr = (Node *) linitial(exprs);
    1288      206872 :     lc = list_second_cell(exprs);
    1289      206872 :     ptype = exprType(pexpr);
    1290             : 
    1291             :     /*
    1292             :      * If all input types are valid and exactly the same, just pick that type.
    1293             :      * This is the only way that we will resolve the result as being a domain
    1294             :      * type; otherwise domains are smashed to their base types for comparison.
    1295             :      */
    1296      206872 :     if (ptype != UNKNOWNOID)
    1297             :     {
    1298      277222 :         for_each_cell(lc, exprs, lc)
    1299             :         {
    1300      168356 :             Node       *nexpr = (Node *) lfirst(lc);
    1301      168356 :             Oid         ntype = exprType(nexpr);
    1302             : 
    1303      168356 :             if (ntype != ptype)
    1304       51390 :                 break;
    1305             :         }
    1306      160256 :         if (lc == NULL)         /* got to the end of the list? */
    1307             :         {
    1308      108866 :             if (which_expr)
    1309       78770 :                 *which_expr = pexpr;
    1310      108866 :             return ptype;
    1311             :         }
    1312             :     }
    1313             : 
    1314             :     /*
    1315             :      * Nope, so set up for the full algorithm.  Note that at this point, lc
    1316             :      * points to the first list item with type different from pexpr's; we need
    1317             :      * not re-examine any items the previous loop advanced over.
    1318             :      */
    1319       98006 :     ptype = getBaseType(ptype);
    1320       98006 :     get_type_category_preferred(ptype, &pcategory, &pispreferred);
    1321             : 
    1322      295220 :     for_each_cell(lc, exprs, lc)
    1323             :     {
    1324      197218 :         Node       *nexpr = (Node *) lfirst(lc);
    1325      197218 :         Oid         ntype = getBaseType(exprType(nexpr));
    1326             : 
    1327             :         /* move on to next one if no new information... */
    1328      197218 :         if (ntype != UNKNOWNOID && ntype != ptype)
    1329             :         {
    1330             :             TYPCATEGORY ncategory;
    1331             :             bool        nispreferred;
    1332             : 
    1333       39242 :             get_type_category_preferred(ntype, &ncategory, &nispreferred);
    1334       39242 :             if (ptype == UNKNOWNOID)
    1335             :             {
    1336             :                 /* so far, only unknowns so take anything... */
    1337       23440 :                 pexpr = nexpr;
    1338       23440 :                 ptype = ntype;
    1339       23440 :                 pcategory = ncategory;
    1340       23440 :                 pispreferred = nispreferred;
    1341             :             }
    1342       15802 :             else if (ncategory != pcategory)
    1343             :             {
    1344             :                 /*
    1345             :                  * both types in different categories? then not much hope...
    1346             :                  */
    1347           4 :                 if (context == NULL)
    1348           0 :                     return InvalidOid;
    1349           4 :                 ereport(ERROR,
    1350             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    1351             :                 /*------
    1352             :                   translator: first %s is name of a SQL construct, eg CASE */
    1353             :                          errmsg("%s types %s and %s cannot be matched",
    1354             :                                 context,
    1355             :                                 format_type_be(ptype),
    1356             :                                 format_type_be(ntype)),
    1357             :                          parser_errposition(pstate, exprLocation(nexpr))));
    1358             :             }
    1359       22950 :             else if (!pispreferred &&
    1360        7152 :                      can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
    1361        6826 :                      !can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
    1362             :             {
    1363             :                 /*
    1364             :                  * take new type if can coerce to it implicitly but not the
    1365             :                  * other way; but if we have a preferred type, stay on it.
    1366             :                  */
    1367        6456 :                 pexpr = nexpr;
    1368        6456 :                 ptype = ntype;
    1369        6456 :                 pcategory = ncategory;
    1370        6456 :                 pispreferred = nispreferred;
    1371             :             }
    1372             :         }
    1373             :     }
    1374             : 
    1375             :     /*
    1376             :      * If all the inputs were UNKNOWN type --- ie, unknown-type literals ---
    1377             :      * then resolve as type TEXT.  This situation comes up with constructs
    1378             :      * like SELECT (CASE WHEN foo THEN 'bar' ELSE 'baz' END); SELECT 'foo'
    1379             :      * UNION SELECT 'bar'; It might seem desirable to leave the construct's
    1380             :      * output type as UNKNOWN, but that really doesn't work, because we'd
    1381             :      * probably end up needing a runtime coercion from UNKNOWN to something
    1382             :      * else, and we usually won't have it.  We need to coerce the unknown
    1383             :      * literals while they are still literals, so a decision has to be made
    1384             :      * now.
    1385             :      */
    1386       98002 :     if (ptype == UNKNOWNOID)
    1387       23176 :         ptype = TEXTOID;
    1388             : 
    1389       98002 :     if (which_expr)
    1390        5260 :         *which_expr = pexpr;
    1391       98002 :     return ptype;
    1392             : }
    1393             : 
    1394             : /*
    1395             :  * select_common_type_from_oids()
    1396             :  *      Determine the common supertype of an array of type OIDs.
    1397             :  *
    1398             :  * This is the same logic as select_common_type(), but working from
    1399             :  * an array of type OIDs not a list of expressions.  As in that function,
    1400             :  * earlier entries in the array have some preference over later ones.
    1401             :  * On failure, return InvalidOid if noerror is true, else throw an error.
    1402             :  *
    1403             :  * Note: neither caller will pass any UNKNOWNOID entries, so the tests
    1404             :  * for that in this function are dead code.  However, they don't cost much,
    1405             :  * and it seems better to keep this logic as close to select_common_type()
    1406             :  * as possible.
    1407             :  */
    1408             : static Oid
    1409         512 : select_common_type_from_oids(int nargs, const Oid *typeids, bool noerror)
    1410             : {
    1411             :     Oid         ptype;
    1412             :     TYPCATEGORY pcategory;
    1413             :     bool        pispreferred;
    1414         512 :     int         i = 1;
    1415             : 
    1416             :     Assert(nargs > 0);
    1417         512 :     ptype = typeids[0];
    1418             : 
    1419             :     /* If all input types are valid and exactly the same, pick that type. */
    1420         512 :     if (ptype != UNKNOWNOID)
    1421             :     {
    1422         676 :         for (; i < nargs; i++)
    1423             :         {
    1424         384 :             if (typeids[i] != ptype)
    1425         220 :                 break;
    1426             :         }
    1427         512 :         if (i == nargs)
    1428         292 :             return ptype;
    1429             :     }
    1430             : 
    1431             :     /*
    1432             :      * Nope, so set up for the full algorithm.  Note that at this point, we
    1433             :      * can skip array entries before "i"; they are all equal to ptype.
    1434             :      */
    1435         220 :     ptype = getBaseType(ptype);
    1436         220 :     get_type_category_preferred(ptype, &pcategory, &pispreferred);
    1437             : 
    1438         444 :     for (; i < nargs; i++)
    1439             :     {
    1440         236 :         Oid         ntype = getBaseType(typeids[i]);
    1441             : 
    1442             :         /* move on to next one if no new information... */
    1443         236 :         if (ntype != UNKNOWNOID && ntype != ptype)
    1444             :         {
    1445             :             TYPCATEGORY ncategory;
    1446             :             bool        nispreferred;
    1447             : 
    1448         236 :             get_type_category_preferred(ntype, &ncategory, &nispreferred);
    1449         236 :             if (ptype == UNKNOWNOID)
    1450             :             {
    1451             :                 /* so far, only unknowns so take anything... */
    1452           0 :                 ptype = ntype;
    1453           0 :                 pcategory = ncategory;
    1454           0 :                 pispreferred = nispreferred;
    1455             :             }
    1456         236 :             else if (ncategory != pcategory)
    1457             :             {
    1458             :                 /*
    1459             :                  * both types in different categories? then not much hope...
    1460             :                  */
    1461          12 :                 if (noerror)
    1462          12 :                     return InvalidOid;
    1463           0 :                 ereport(ERROR,
    1464             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    1465             :                          errmsg("argument types %s and %s cannot be matched",
    1466             :                                 format_type_be(ptype),
    1467             :                                 format_type_be(ntype))));
    1468             :             }
    1469         400 :             else if (!pispreferred &&
    1470         176 :                      can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
    1471         120 :                      !can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
    1472             :             {
    1473             :                 /*
    1474             :                  * take new type if can coerce to it implicitly but not the
    1475             :                  * other way; but if we have a preferred type, stay on it.
    1476             :                  */
    1477         120 :                 ptype = ntype;
    1478         120 :                 pcategory = ncategory;
    1479         120 :                 pispreferred = nispreferred;
    1480             :             }
    1481             :         }
    1482             :     }
    1483             : 
    1484             :     /* Like select_common_type(), choose TEXT if all inputs were UNKNOWN */
    1485         208 :     if (ptype == UNKNOWNOID)
    1486           0 :         ptype = TEXTOID;
    1487             : 
    1488         208 :     return ptype;
    1489             : }
    1490             : 
    1491             : /*
    1492             :  * coerce_to_common_type()
    1493             :  *      Coerce an expression to the given type.
    1494             :  *
    1495             :  * This is used following select_common_type() to coerce the individual
    1496             :  * expressions to the desired type.  'context' is a phrase to use in the
    1497             :  * error message if we fail to coerce.
    1498             :  *
    1499             :  * As with coerce_type, pstate may be NULL if no special unknown-Param
    1500             :  * processing is wanted.
    1501             :  */
    1502             : Node *
    1503      493162 : coerce_to_common_type(ParseState *pstate, Node *node,
    1504             :                       Oid targetTypeId, const char *context)
    1505             : {
    1506      493162 :     Oid         inputTypeId = exprType(node);
    1507             : 
    1508      493162 :     if (inputTypeId == targetTypeId)
    1509      289482 :         return node;            /* no work */
    1510      203680 :     if (can_coerce_type(1, &inputTypeId, &targetTypeId, COERCION_IMPLICIT))
    1511      203680 :         node = coerce_type(pstate, node, inputTypeId, targetTypeId, -1,
    1512             :                            COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1);
    1513             :     else
    1514           0 :         ereport(ERROR,
    1515             :                 (errcode(ERRCODE_CANNOT_COERCE),
    1516             :         /* translator: first %s is name of a SQL construct, eg CASE */
    1517             :                  errmsg("%s could not convert type %s to %s",
    1518             :                         context,
    1519             :                         format_type_be(inputTypeId),
    1520             :                         format_type_be(targetTypeId)),
    1521             :                  parser_errposition(pstate, exprLocation(node))));
    1522      203676 :     return node;
    1523             : }
    1524             : 
    1525             : /*
    1526             :  * check_generic_type_consistency()
    1527             :  *      Are the actual arguments potentially compatible with a
    1528             :  *      polymorphic function?
    1529             :  *
    1530             :  * The argument consistency rules are:
    1531             :  *
    1532             :  * 1) All arguments declared ANYELEMENT must have the same datatype.
    1533             :  * 2) All arguments declared ANYARRAY must have the same datatype,
    1534             :  *    which must be a varlena array type.
    1535             :  * 3) All arguments declared ANYRANGE must have the same datatype,
    1536             :  *    which must be a range type.
    1537             :  * 4) If there are arguments of more than one of these polymorphic types,
    1538             :  *    the array element type and/or range subtype must be the same as each
    1539             :  *    other and the same as the ANYELEMENT type.
    1540             :  * 5) ANYENUM is treated the same as ANYELEMENT except that if it is used
    1541             :  *    (alone or in combination with plain ANYELEMENT), we add the extra
    1542             :  *    condition that the ANYELEMENT type must be an enum.
    1543             :  * 6) ANYNONARRAY is treated the same as ANYELEMENT except that if it is used,
    1544             :  *    we add the extra condition that the ANYELEMENT type must not be an array.
    1545             :  *    (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
    1546             :  *    is an extra restriction if not.)
    1547             :  * 7) All arguments declared ANYCOMPATIBLE must be implicitly castable
    1548             :  *    to a common supertype (chosen as per select_common_type's rules).
    1549             :  *    ANYCOMPATIBLENONARRAY works like ANYCOMPATIBLE but also requires the
    1550             :  *    common supertype to not be an array.  If there are ANYCOMPATIBLEARRAY
    1551             :  *    or ANYCOMPATIBLERANGE arguments, their element types or subtypes are
    1552             :  *    included while making the choice of common supertype.
    1553             :  * 8) The resolved type of ANYCOMPATIBLEARRAY arguments will be the array
    1554             :  *    type over the common supertype (which might not be the same array type
    1555             :  *    as any of the original arrays).
    1556             :  * 9) All ANYCOMPATIBLERANGE arguments must be the exact same range type
    1557             :  *    (after domain flattening), since we have no preference rule that would
    1558             :  *    let us choose one over another.  Furthermore, that range's subtype
    1559             :  *    must exactly match the common supertype chosen by rule 7.
    1560             :  *
    1561             :  * Domains over arrays match ANYARRAY, and are immediately flattened to their
    1562             :  * base type.  (Thus, for example, we will consider it a match if one ANYARRAY
    1563             :  * argument is a domain over int4[] while another one is just int4[].)  Also
    1564             :  * notice that such a domain does *not* match ANYNONARRAY.  The same goes
    1565             :  * for ANYCOMPATIBLEARRAY and ANYCOMPATIBLENONARRAY.
    1566             :  *
    1567             :  * Similarly, domains over ranges match ANYRANGE or ANYCOMPATIBLERANGE,
    1568             :  * and are immediately flattened to their base type.
    1569             :  *
    1570             :  * Note that domains aren't currently considered to match ANYENUM,
    1571             :  * even if their base type would match.
    1572             :  *
    1573             :  * If we have UNKNOWN input (ie, an untyped literal) for any polymorphic
    1574             :  * argument, assume it is okay.
    1575             :  *
    1576             :  * We do not ereport here, but just return false if a rule is violated.
    1577             :  */
    1578             : bool
    1579      120868 : check_generic_type_consistency(const Oid *actual_arg_types,
    1580             :                                const Oid *declared_arg_types,
    1581             :                                int nargs)
    1582             : {
    1583      120868 :     Oid         elem_typeid = InvalidOid;
    1584      120868 :     Oid         array_typeid = InvalidOid;
    1585      120868 :     Oid         range_typeid = InvalidOid;
    1586      120868 :     Oid         anycompatible_range_typeid = InvalidOid;
    1587      120868 :     Oid         anycompatible_range_typelem = InvalidOid;
    1588      120868 :     bool        have_anynonarray = false;
    1589      120868 :     bool        have_anyenum = false;
    1590      120868 :     bool        have_anycompatible_nonarray = false;
    1591      120868 :     int         n_anycompatible_args = 0;
    1592             :     Oid         anycompatible_actual_types[FUNC_MAX_ARGS];
    1593             : 
    1594             :     /*
    1595             :      * Loop through the arguments to see if we have any that are polymorphic.
    1596             :      * If so, require the actual types to be consistent.
    1597             :      */
    1598             :     Assert(nargs <= FUNC_MAX_ARGS);
    1599      285076 :     for (int j = 0; j < nargs; j++)
    1600             :     {
    1601      185350 :         Oid         decl_type = declared_arg_types[j];
    1602      185350 :         Oid         actual_type = actual_arg_types[j];
    1603             : 
    1604      185350 :         if (decl_type == ANYELEMENTOID ||
    1605      159960 :             decl_type == ANYNONARRAYOID ||
    1606             :             decl_type == ANYENUMOID)
    1607             :         {
    1608       46380 :             if (decl_type == ANYNONARRAYOID)
    1609       18744 :                 have_anynonarray = true;
    1610       27636 :             else if (decl_type == ANYENUMOID)
    1611       20990 :                 have_anyenum = true;
    1612       46380 :             if (actual_type == UNKNOWNOID)
    1613        4232 :                 continue;
    1614       42148 :             if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
    1615        7486 :                 return false;
    1616       34662 :             elem_typeid = actual_type;
    1617             :         }
    1618      138970 :         else if (decl_type == ANYARRAYOID)
    1619             :         {
    1620       89358 :             if (actual_type == UNKNOWNOID)
    1621        9800 :                 continue;
    1622       79558 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1623       79558 :             if (OidIsValid(array_typeid) && actual_type != array_typeid)
    1624        6902 :                 return false;
    1625       72656 :             array_typeid = actual_type;
    1626             :         }
    1627       49612 :         else if (decl_type == ANYRANGEOID)
    1628             :         {
    1629       23102 :             if (actual_type == UNKNOWNOID)
    1630        1730 :                 continue;
    1631       21372 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1632       21372 :             if (OidIsValid(range_typeid) && actual_type != range_typeid)
    1633        6742 :                 return false;
    1634       14630 :             range_typeid = actual_type;
    1635             :         }
    1636       26510 :         else if (decl_type == ANYCOMPATIBLEOID ||
    1637             :                  decl_type == ANYCOMPATIBLENONARRAYOID)
    1638             :         {
    1639         380 :             if (decl_type == ANYCOMPATIBLENONARRAYOID)
    1640          24 :                 have_anycompatible_nonarray = true;
    1641         380 :             if (actual_type == UNKNOWNOID)
    1642          28 :                 continue;
    1643             :             /* collect the actual types of non-unknown COMPATIBLE args */
    1644         352 :             anycompatible_actual_types[n_anycompatible_args++] = actual_type;
    1645             :         }
    1646       26130 :         else if (decl_type == ANYCOMPATIBLEARRAYOID)
    1647             :         {
    1648             :             Oid         elem_type;
    1649             : 
    1650          84 :             if (actual_type == UNKNOWNOID)
    1651           4 :                 continue;
    1652          80 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1653          80 :             elem_type = get_element_type(actual_type);
    1654          80 :             if (!OidIsValid(elem_type))
    1655           4 :                 return false;   /* not an array */
    1656             :             /* collect the element type for common-supertype choice */
    1657          76 :             anycompatible_actual_types[n_anycompatible_args++] = elem_type;
    1658             :         }
    1659       26046 :         else if (decl_type == ANYCOMPATIBLERANGEOID)
    1660             :         {
    1661         108 :             if (actual_type == UNKNOWNOID)
    1662           4 :                 continue;
    1663         104 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1664         104 :             if (OidIsValid(anycompatible_range_typeid))
    1665             :             {
    1666             :                 /* All ANYCOMPATIBLERANGE arguments must be the same type */
    1667           8 :                 if (anycompatible_range_typeid != actual_type)
    1668           4 :                     return false;
    1669             :             }
    1670             :             else
    1671             :             {
    1672          96 :                 anycompatible_range_typeid = actual_type;
    1673          96 :                 anycompatible_range_typelem = get_range_subtype(actual_type);
    1674          96 :                 if (!OidIsValid(anycompatible_range_typelem))
    1675           4 :                     return false;   /* not a range type */
    1676             :                 /* collect the subtype for common-supertype choice */
    1677          92 :                 anycompatible_actual_types[n_anycompatible_args++] = anycompatible_range_typelem;
    1678             :             }
    1679             :         }
    1680             :     }
    1681             : 
    1682             :     /* Get the element type based on the array type, if we have one */
    1683       99726 :     if (OidIsValid(array_typeid))
    1684             :     {
    1685       63084 :         if (array_typeid == ANYARRAYOID)
    1686             :         {
    1687             :             /*
    1688             :              * Special case for matching ANYARRAY input to an ANYARRAY
    1689             :              * argument: allow it for now.  enforce_generic_type_consistency()
    1690             :              * might complain later, depending on the presence of other
    1691             :              * polymorphic arguments or results, but it will deliver a less
    1692             :              * surprising error message than "function does not exist".
    1693             :              *
    1694             :              * (If you think to change this, note that can_coerce_type will
    1695             :              * consider such a situation as a match, so that we might not even
    1696             :              * get here.)
    1697             :              */
    1698             :         }
    1699             :         else
    1700             :         {
    1701             :             Oid         array_typelem;
    1702             : 
    1703       63084 :             array_typelem = get_element_type(array_typeid);
    1704       63084 :             if (!OidIsValid(array_typelem))
    1705       20616 :                 return false;   /* should be an array, but isn't */
    1706             : 
    1707       42468 :             if (!OidIsValid(elem_typeid))
    1708             :             {
    1709             :                 /*
    1710             :                  * if we don't have an element type yet, use the one we just
    1711             :                  * got
    1712             :                  */
    1713       41766 :                 elem_typeid = array_typelem;
    1714             :             }
    1715         702 :             else if (array_typelem != elem_typeid)
    1716             :             {
    1717             :                 /* otherwise, they better match */
    1718         324 :                 return false;
    1719             :             }
    1720             :         }
    1721             :     }
    1722             : 
    1723             :     /* Get the element type based on the range type, if we have one */
    1724       78786 :     if (OidIsValid(range_typeid))
    1725             :     {
    1726             :         Oid         range_typelem;
    1727             : 
    1728        5258 :         range_typelem = get_range_subtype(range_typeid);
    1729        5258 :         if (!OidIsValid(range_typelem))
    1730        4598 :             return false;       /* should be a range, but isn't */
    1731             : 
    1732         660 :         if (!OidIsValid(elem_typeid))
    1733             :         {
    1734             :             /*
    1735             :              * if we don't have an element type yet, use the one we just got
    1736             :              */
    1737         572 :             elem_typeid = range_typelem;
    1738             :         }
    1739          88 :         else if (range_typelem != elem_typeid)
    1740             :         {
    1741             :             /* otherwise, they better match */
    1742          36 :             return false;
    1743             :         }
    1744             :     }
    1745             : 
    1746       74152 :     if (have_anynonarray)
    1747             :     {
    1748             :         /* require the element type to not be an array or domain over array */
    1749       18392 :         if (type_is_array_domain(elem_typeid))
    1750         764 :             return false;
    1751             :     }
    1752             : 
    1753       73388 :     if (have_anyenum)
    1754             :     {
    1755             :         /* require the element type to be an enum */
    1756        3154 :         if (!type_is_enum(elem_typeid))
    1757        2918 :             return false;
    1758             :     }
    1759             : 
    1760             :     /* Check matching of ANYCOMPATIBLE-family arguments, if any */
    1761       70470 :     if (n_anycompatible_args > 0)
    1762             :     {
    1763             :         Oid         anycompatible_typeid;
    1764             : 
    1765             :         anycompatible_typeid =
    1766         264 :             select_common_type_from_oids(n_anycompatible_args,
    1767             :                                          anycompatible_actual_types,
    1768             :                                          true);
    1769             : 
    1770         264 :         if (!OidIsValid(anycompatible_typeid))
    1771          12 :             return false;       /* there's no common supertype */
    1772             : 
    1773         252 :         if (have_anycompatible_nonarray)
    1774             :         {
    1775             :             /*
    1776             :              * require the anycompatible type to not be an array or domain
    1777             :              * over array
    1778             :              */
    1779          12 :             if (type_is_array_domain(anycompatible_typeid))
    1780           4 :                 return false;
    1781             :         }
    1782             : 
    1783             :         /*
    1784             :          * the anycompatible type must exactly match the range element type,
    1785             :          * if we were able to identify one
    1786             :          */
    1787         248 :         if (OidIsValid(anycompatible_range_typelem) &&
    1788             :             anycompatible_range_typelem != anycompatible_typeid)
    1789          16 :             return false;
    1790             :     }
    1791             : 
    1792             :     /* Looks valid */
    1793       70438 :     return true;
    1794             : }
    1795             : 
    1796             : /*
    1797             :  * enforce_generic_type_consistency()
    1798             :  *      Make sure a polymorphic function is legally callable, and
    1799             :  *      deduce actual argument and result types.
    1800             :  *
    1801             :  * If any polymorphic pseudotype is used in a function's arguments or
    1802             :  * return type, we make sure the actual data types are consistent with
    1803             :  * each other.  The argument consistency rules are shown above for
    1804             :  * check_generic_type_consistency().
    1805             :  *
    1806             :  * If we have UNKNOWN input (ie, an untyped literal) for any polymorphic
    1807             :  * argument, we attempt to deduce the actual type it should have.  If
    1808             :  * successful, we alter that position of declared_arg_types[] so that
    1809             :  * make_fn_arguments will coerce the literal to the right thing.
    1810             :  *
    1811             :  * If we have polymorphic arguments of the ANYCOMPATIBLE family,
    1812             :  * we similarly alter declared_arg_types[] entries to show the resolved
    1813             :  * common supertype, so that make_fn_arguments will coerce the actual
    1814             :  * arguments to the proper type.
    1815             :  *
    1816             :  * Rules are applied to the function's return type (possibly altering it)
    1817             :  * if it is declared as a polymorphic type and there is at least one
    1818             :  * polymorphic argument type:
    1819             :  *
    1820             :  * 1) If return type is ANYELEMENT, and any argument is ANYELEMENT, use the
    1821             :  *    argument's actual type as the function's return type.
    1822             :  * 2) If return type is ANYARRAY, and any argument is ANYARRAY, use the
    1823             :  *    argument's actual type as the function's return type.
    1824             :  * 3) Similarly, if return type is ANYRANGE, and any argument is ANYRANGE,
    1825             :  *    use the argument's actual type as the function's return type.
    1826             :  * 4) Otherwise, if return type is ANYELEMENT or ANYARRAY, and there is
    1827             :  *    at least one ANYELEMENT, ANYARRAY, or ANYRANGE input, deduce the
    1828             :  *    return type from those inputs, or throw error if we can't.
    1829             :  * 5) Otherwise, if return type is ANYRANGE, throw error.  (We have no way to
    1830             :  *    select a specific range type if the arguments don't include ANYRANGE.)
    1831             :  * 6) ANYENUM is treated the same as ANYELEMENT except that if it is used
    1832             :  *    (alone or in combination with plain ANYELEMENT), we add the extra
    1833             :  *    condition that the ANYELEMENT type must be an enum.
    1834             :  * 7) ANYNONARRAY is treated the same as ANYELEMENT except that if it is used,
    1835             :  *    we add the extra condition that the ANYELEMENT type must not be an array.
    1836             :  *    (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
    1837             :  *    is an extra restriction if not.)
    1838             :  * 8) ANYCOMPATIBLE, ANYCOMPATIBLEARRAY, ANYCOMPATIBLENONARRAY, and
    1839             :  *    ANYCOMPATIBLERANGE are handled by resolving the common supertype
    1840             :  *    of those arguments (or their element types/subtypes, for array and range
    1841             :  *    inputs), and then coercing all those arguments to the common supertype,
    1842             :  *    or the array type over the common supertype for ANYCOMPATIBLEARRAY.
    1843             :  *    For ANYCOMPATIBLERANGE, there must be at least one non-UNKNOWN input,
    1844             :  *    all such inputs must be the same range type, and that type's subtype
    1845             :  *    must equal the common supertype.
    1846             :  *
    1847             :  * Domains over arrays or ranges match ANYARRAY or ANYRANGE arguments,
    1848             :  * respectively, and are immediately flattened to their base type.  (In
    1849             :  * particular, if the return type is also ANYARRAY or ANYRANGE, we'll set
    1850             :  * it to the base type not the domain type.)  The same is true for
    1851             :  * ANYCOMPATIBLEARRAY and ANYCOMPATIBLERANGE.
    1852             :  *
    1853             :  * When allow_poly is false, we are not expecting any of the actual_arg_types
    1854             :  * to be polymorphic, and we should not return a polymorphic result type
    1855             :  * either.  When allow_poly is true, it is okay to have polymorphic "actual"
    1856             :  * arg types, and we can return a matching polymorphic type as the result.
    1857             :  * (This case is currently used only to check compatibility of an aggregate's
    1858             :  * declaration with the underlying transfn.)
    1859             :  *
    1860             :  * A special case is that we could see ANYARRAY as an actual_arg_type even
    1861             :  * when allow_poly is false (this is possible only because pg_statistic has
    1862             :  * columns shown as anyarray in the catalogs).  We allow this to match a
    1863             :  * declared ANYARRAY argument, but only if there is no other polymorphic
    1864             :  * argument that we would need to match it with, and no need to determine
    1865             :  * the element type to infer the result type.  Note this means that functions
    1866             :  * taking ANYARRAY had better behave sanely if applied to the pg_statistic
    1867             :  * columns; they can't just assume that successive inputs are of the same
    1868             :  * actual element type.  There is no similar logic for ANYCOMPATIBLEARRAY;
    1869             :  * there isn't a need for it since there are no catalog columns of that type,
    1870             :  * so we won't see it as input.  We could consider matching an actual ANYARRAY
    1871             :  * input to an ANYCOMPATIBLEARRAY argument, but at present that seems useless
    1872             :  * as well, since there's no value in using ANYCOMPATIBLEARRAY unless there's
    1873             :  * at least one other ANYCOMPATIBLE-family argument or result.
    1874             :  *
    1875             :  * Also, if there are no arguments declared to be of polymorphic types,
    1876             :  * we'll return the rettype unmodified even if it's polymorphic.  This should
    1877             :  * never occur for user-declared functions, because CREATE FUNCTION prevents
    1878             :  * it.  But it does happen for some built-in functions, such as array_in().
    1879             :  */
    1880             : Oid
    1881     1023314 : enforce_generic_type_consistency(const Oid *actual_arg_types,
    1882             :                                  Oid *declared_arg_types,
    1883             :                                  int nargs,
    1884             :                                  Oid rettype,
    1885             :                                  bool allow_poly)
    1886             : {
    1887     1023314 :     bool        have_poly_anycompatible = false;
    1888     1023314 :     bool        have_poly_unknowns = false;
    1889     1023314 :     Oid         elem_typeid = InvalidOid;
    1890     1023314 :     Oid         array_typeid = InvalidOid;
    1891     1023314 :     Oid         range_typeid = InvalidOid;
    1892     1023314 :     Oid         anycompatible_typeid = InvalidOid;
    1893     1023314 :     Oid         anycompatible_array_typeid = InvalidOid;
    1894     1023314 :     Oid         anycompatible_range_typeid = InvalidOid;
    1895     1023314 :     Oid         anycompatible_range_typelem = InvalidOid;
    1896     1023314 :     bool        have_anynonarray = (rettype == ANYNONARRAYOID);
    1897     1023314 :     bool        have_anyenum = (rettype == ANYENUMOID);
    1898     1023314 :     bool        have_anycompatible_nonarray = (rettype == ANYCOMPATIBLENONARRAYOID);
    1899     1023314 :     bool        have_anycompatible_array = (rettype == ANYCOMPATIBLEARRAYOID);
    1900     1023314 :     bool        have_anycompatible_range = (rettype == ANYCOMPATIBLERANGEOID);
    1901     1023314 :     int         n_poly_args = 0;    /* this counts all family-1 arguments */
    1902     1023314 :     int         n_anycompatible_args = 0;   /* this counts only non-unknowns */
    1903             :     Oid         anycompatible_actual_types[FUNC_MAX_ARGS];
    1904             : 
    1905             :     /*
    1906             :      * Loop through the arguments to see if we have any that are polymorphic.
    1907             :      * If so, require the actual types to be consistent.
    1908             :      */
    1909             :     Assert(nargs <= FUNC_MAX_ARGS);
    1910     2778454 :     for (int j = 0; j < nargs; j++)
    1911             :     {
    1912     1755140 :         Oid         decl_type = declared_arg_types[j];
    1913     1755140 :         Oid         actual_type = actual_arg_types[j];
    1914             : 
    1915     1755140 :         if (decl_type == ANYELEMENTOID ||
    1916     1735054 :             decl_type == ANYNONARRAYOID ||
    1917             :             decl_type == ANYENUMOID)
    1918             :         {
    1919       20666 :             n_poly_args++;
    1920       20666 :             if (decl_type == ANYNONARRAYOID)
    1921       15766 :                 have_anynonarray = true;
    1922        4900 :             else if (decl_type == ANYENUMOID)
    1923         580 :                 have_anyenum = true;
    1924       20666 :             if (actual_type == UNKNOWNOID)
    1925             :             {
    1926         992 :                 have_poly_unknowns = true;
    1927         992 :                 continue;
    1928             :             }
    1929       19674 :             if (allow_poly && decl_type == actual_type)
    1930         132 :                 continue;       /* no new information here */
    1931       19542 :             if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
    1932           0 :                 ereport(ERROR,
    1933             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    1934             :                          errmsg("arguments declared \"anyelement\" are not all alike"),
    1935             :                          errdetail("%s versus %s",
    1936             :                                    format_type_be(elem_typeid),
    1937             :                                    format_type_be(actual_type))));
    1938       19542 :             elem_typeid = actual_type;
    1939             :         }
    1940     1734474 :         else if (decl_type == ANYARRAYOID)
    1941             :         {
    1942       59438 :             n_poly_args++;
    1943       59438 :             if (actual_type == UNKNOWNOID)
    1944             :             {
    1945        7782 :                 have_poly_unknowns = true;
    1946        7782 :                 continue;
    1947             :             }
    1948       51656 :             if (allow_poly && decl_type == actual_type)
    1949          60 :                 continue;       /* no new information here */
    1950       51596 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1951       51596 :             if (OidIsValid(array_typeid) && actual_type != array_typeid)
    1952           0 :                 ereport(ERROR,
    1953             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    1954             :                          errmsg("arguments declared \"anyarray\" are not all alike"),
    1955             :                          errdetail("%s versus %s",
    1956             :                                    format_type_be(array_typeid),
    1957             :                                    format_type_be(actual_type))));
    1958       51596 :             array_typeid = actual_type;
    1959             :         }
    1960     1675036 :         else if (decl_type == ANYRANGEOID)
    1961             :         {
    1962        1984 :             n_poly_args++;
    1963        1984 :             if (actual_type == UNKNOWNOID)
    1964             :             {
    1965          46 :                 have_poly_unknowns = true;
    1966          46 :                 continue;
    1967             :             }
    1968        1938 :             if (allow_poly && decl_type == actual_type)
    1969           0 :                 continue;       /* no new information here */
    1970        1938 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1971        1938 :             if (OidIsValid(range_typeid) && actual_type != range_typeid)
    1972           0 :                 ereport(ERROR,
    1973             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    1974             :                          errmsg("arguments declared \"anyrange\" are not all alike"),
    1975             :                          errdetail("%s versus %s",
    1976             :                                    format_type_be(range_typeid),
    1977             :                                    format_type_be(actual_type))));
    1978        1938 :             range_typeid = actual_type;
    1979             :         }
    1980     1673052 :         else if (decl_type == ANYCOMPATIBLEOID ||
    1981             :                  decl_type == ANYCOMPATIBLENONARRAYOID)
    1982             :         {
    1983         306 :             have_poly_anycompatible = true;
    1984         306 :             if (decl_type == ANYCOMPATIBLENONARRAYOID)
    1985          16 :                 have_anycompatible_nonarray = true;
    1986         306 :             if (actual_type == UNKNOWNOID)
    1987          28 :                 continue;
    1988         278 :             if (allow_poly && decl_type == actual_type)
    1989           6 :                 continue;       /* no new information here */
    1990             :             /* collect the actual types of non-unknown COMPATIBLE args */
    1991         272 :             anycompatible_actual_types[n_anycompatible_args++] = actual_type;
    1992             :         }
    1993     1672746 :         else if (decl_type == ANYCOMPATIBLEARRAYOID)
    1994             :         {
    1995             :             Oid         anycompatible_elem_type;
    1996             : 
    1997          94 :             have_poly_anycompatible = true;
    1998          94 :             have_anycompatible_array = true;
    1999          94 :             if (actual_type == UNKNOWNOID)
    2000           4 :                 continue;
    2001          90 :             if (allow_poly && decl_type == actual_type)
    2002           6 :                 continue;       /* no new information here */
    2003          84 :             actual_type = getBaseType(actual_type); /* flatten domains */
    2004          84 :             anycompatible_elem_type = get_element_type(actual_type);
    2005          84 :             if (!OidIsValid(anycompatible_elem_type))
    2006           0 :                 ereport(ERROR,
    2007             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2008             :                          errmsg("argument declared %s is not an array but type %s",
    2009             :                                 "anycompatiblearray",
    2010             :                                 format_type_be(actual_type))));
    2011             :             /* collect the element type for common-supertype choice */
    2012          84 :             anycompatible_actual_types[n_anycompatible_args++] = anycompatible_elem_type;
    2013             :         }
    2014     1672652 :         else if (decl_type == ANYCOMPATIBLERANGEOID)
    2015             :         {
    2016          80 :             have_poly_anycompatible = true;
    2017          80 :             have_anycompatible_range = true;
    2018          80 :             if (actual_type == UNKNOWNOID)
    2019           4 :                 continue;
    2020          76 :             if (allow_poly && decl_type == actual_type)
    2021           0 :                 continue;       /* no new information here */
    2022          76 :             actual_type = getBaseType(actual_type); /* flatten domains */
    2023          76 :             if (OidIsValid(anycompatible_range_typeid))
    2024             :             {
    2025             :                 /* All ANYCOMPATIBLERANGE arguments must be the same type */
    2026           4 :                 if (anycompatible_range_typeid != actual_type)
    2027           0 :                     ereport(ERROR,
    2028             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2029             :                              errmsg("arguments declared \"anycompatiblerange\" are not all alike"),
    2030             :                              errdetail("%s versus %s",
    2031             :                                        format_type_be(anycompatible_range_typeid),
    2032             :                                        format_type_be(actual_type))));
    2033             :             }
    2034             :             else
    2035             :             {
    2036          72 :                 anycompatible_range_typeid = actual_type;
    2037          72 :                 anycompatible_range_typelem = get_range_subtype(actual_type);
    2038          72 :                 if (!OidIsValid(anycompatible_range_typelem))
    2039           0 :                     ereport(ERROR,
    2040             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2041             :                              errmsg("argument declared %s is not a range type but type %s",
    2042             :                                     "anycompatiblerange",
    2043             :                                     format_type_be(actual_type))));
    2044             :                 /* collect the subtype for common-supertype choice */
    2045          72 :                 anycompatible_actual_types[n_anycompatible_args++] = anycompatible_range_typelem;
    2046             :             }
    2047             :         }
    2048             :     }
    2049             : 
    2050             :     /*
    2051             :      * Fast Track: if none of the arguments are polymorphic, return the
    2052             :      * unmodified rettype.  Not our job to resolve it if it's polymorphic.
    2053             :      */
    2054     1023314 :     if (n_poly_args == 0 && !have_poly_anycompatible)
    2055      952824 :         return rettype;
    2056             : 
    2057             :     /* Check matching of family-1 polymorphic arguments, if any */
    2058       70490 :     if (n_poly_args)
    2059             :     {
    2060             :         /* Get the element type based on the array type, if we have one */
    2061       70268 :         if (OidIsValid(array_typeid))
    2062             :         {
    2063             :             Oid         array_typelem;
    2064             : 
    2065       50218 :             if (array_typeid == ANYARRAYOID)
    2066             :             {
    2067             :                 /*
    2068             :                  * Special case for matching ANYARRAY input to an ANYARRAY
    2069             :                  * argument: allow it iff no other arguments are family-1
    2070             :                  * polymorphics (otherwise we couldn't be sure whether the
    2071             :                  * array element type matches up) and the result type doesn't
    2072             :                  * require us to infer a specific element type.
    2073             :                  */
    2074          28 :                 if (n_poly_args != 1 ||
    2075          12 :                     (rettype != ANYARRAYOID &&
    2076           4 :                      IsPolymorphicTypeFamily1(rettype)))
    2077           8 :                     ereport(ERROR,
    2078             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2079             :                              errmsg("cannot determine element type of \"anyarray\" argument")));
    2080          20 :                 array_typelem = ANYELEMENTOID;
    2081             :             }
    2082             :             else
    2083             :             {
    2084       50190 :                 array_typelem = get_element_type(array_typeid);
    2085       50190 :                 if (!OidIsValid(array_typelem))
    2086           0 :                     ereport(ERROR,
    2087             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2088             :                              errmsg("argument declared %s is not an array but type %s",
    2089             :                                     "anyarray", format_type_be(array_typeid))));
    2090             :             }
    2091             : 
    2092       50210 :             if (!OidIsValid(elem_typeid))
    2093             :             {
    2094             :                 /*
    2095             :                  * if we don't have an element type yet, use the one we just
    2096             :                  * got
    2097             :                  */
    2098       49768 :                 elem_typeid = array_typelem;
    2099             :             }
    2100         442 :             else if (array_typelem != elem_typeid)
    2101             :             {
    2102             :                 /* otherwise, they better match */
    2103           0 :                 ereport(ERROR,
    2104             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2105             :                          errmsg("argument declared %s is not consistent with argument declared %s",
    2106             :                                 "anyarray", "anyelement"),
    2107             :                          errdetail("%s versus %s",
    2108             :                                    format_type_be(array_typeid),
    2109             :                                    format_type_be(elem_typeid))));
    2110             :             }
    2111             :         }
    2112             : 
    2113             :         /* Get the element type based on the range type, if we have one */
    2114       70260 :         if (OidIsValid(range_typeid))
    2115             :         {
    2116             :             Oid         range_typelem;
    2117             : 
    2118        1200 :             range_typelem = get_range_subtype(range_typeid);
    2119        1200 :             if (!OidIsValid(range_typelem))
    2120           0 :                 ereport(ERROR,
    2121             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2122             :                          errmsg("argument declared %s is not a range type but type %s",
    2123             :                                 "anyrange",
    2124             :                                 format_type_be(range_typeid))));
    2125             : 
    2126        1200 :             if (!OidIsValid(elem_typeid))
    2127             :             {
    2128             :                 /*
    2129             :                  * if we don't have an element type yet, use the one we just
    2130             :                  * got
    2131             :                  */
    2132        1108 :                 elem_typeid = range_typelem;
    2133             :             }
    2134          92 :             else if (range_typelem != elem_typeid)
    2135             :             {
    2136             :                 /* otherwise, they better match */
    2137           0 :                 ereport(ERROR,
    2138             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2139             :                          errmsg("argument declared %s is not consistent with argument declared %s",
    2140             :                                 "anyrange", "anyelement"),
    2141             :                          errdetail("%s versus %s",
    2142             :                                    format_type_be(range_typeid),
    2143             :                                    format_type_be(elem_typeid))));
    2144             :             }
    2145             :         }
    2146             : 
    2147       70260 :         if (!OidIsValid(elem_typeid))
    2148             :         {
    2149         142 :             if (allow_poly)
    2150             :             {
    2151         138 :                 elem_typeid = ANYELEMENTOID;
    2152         138 :                 array_typeid = ANYARRAYOID;
    2153         138 :                 range_typeid = ANYRANGEOID;
    2154             :             }
    2155             :             else
    2156             :             {
    2157             :                 /*
    2158             :                  * Only way to get here is if all the polymorphic args have
    2159             :                  * UNKNOWN inputs
    2160             :                  */
    2161           4 :                 ereport(ERROR,
    2162             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2163             :                          errmsg("could not determine polymorphic type because input has type %s",
    2164             :                                 "unknown")));
    2165             :             }
    2166             :         }
    2167             : 
    2168       70256 :         if (have_anynonarray && elem_typeid != ANYELEMENTOID)
    2169             :         {
    2170             :             /*
    2171             :              * require the element type to not be an array or domain over
    2172             :              * array
    2173             :              */
    2174       15414 :             if (type_is_array_domain(elem_typeid))
    2175           0 :                 ereport(ERROR,
    2176             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2177             :                          errmsg("type matched to anynonarray is an array type: %s",
    2178             :                                 format_type_be(elem_typeid))));
    2179             :         }
    2180             : 
    2181       70256 :         if (have_anyenum && elem_typeid != ANYELEMENTOID)
    2182             :         {
    2183             :             /* require the element type to be an enum */
    2184         392 :             if (!type_is_enum(elem_typeid))
    2185           0 :                 ereport(ERROR,
    2186             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2187             :                          errmsg("type matched to anyenum is not an enum type: %s",
    2188             :                                 format_type_be(elem_typeid))));
    2189             :         }
    2190             :     }
    2191             : 
    2192             :     /* Check matching of family-2 polymorphic arguments, if any */
    2193       70478 :     if (have_poly_anycompatible)
    2194             :     {
    2195         258 :         if (n_anycompatible_args > 0)
    2196             :         {
    2197             :             anycompatible_typeid =
    2198         248 :                 select_common_type_from_oids(n_anycompatible_args,
    2199             :                                              anycompatible_actual_types,
    2200             :                                              false);
    2201             : 
    2202         248 :             if (have_anycompatible_array)
    2203             :             {
    2204         164 :                 anycompatible_array_typeid = get_array_type(anycompatible_typeid);
    2205         164 :                 if (!OidIsValid(anycompatible_array_typeid))
    2206           0 :                     ereport(ERROR,
    2207             :                             (errcode(ERRCODE_UNDEFINED_OBJECT),
    2208             :                              errmsg("could not find array type for data type %s",
    2209             :                                     format_type_be(anycompatible_typeid))));
    2210             :             }
    2211             : 
    2212         248 :             if (have_anycompatible_range)
    2213             :             {
    2214             :                 /* we can't infer a range type from the others */
    2215          76 :                 if (!OidIsValid(anycompatible_range_typeid))
    2216           4 :                     ereport(ERROR,
    2217             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2218             :                              errmsg("could not determine polymorphic type %s because input has type %s",
    2219             :                                     "anycompatiblerange", "unknown")));
    2220             : 
    2221             :                 /*
    2222             :                  * the anycompatible type must exactly match the range element
    2223             :                  * type
    2224             :                  */
    2225          72 :                 if (anycompatible_range_typelem != anycompatible_typeid)
    2226           0 :                     ereport(ERROR,
    2227             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2228             :                              errmsg("anycompatiblerange type %s does not match anycompatible type %s",
    2229             :                                     format_type_be(anycompatible_range_typeid),
    2230             :                                     format_type_be(anycompatible_typeid))));
    2231             :             }
    2232             : 
    2233         244 :             if (have_anycompatible_nonarray)
    2234             :             {
    2235             :                 /*
    2236             :                  * require the element type to not be an array or domain over
    2237             :                  * array
    2238             :                  */
    2239           8 :                 if (type_is_array_domain(anycompatible_typeid))
    2240           0 :                     ereport(ERROR,
    2241             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2242             :                              errmsg("type matched to anycompatiblenonarray is an array type: %s",
    2243             :                                     format_type_be(anycompatible_typeid))));
    2244             :             }
    2245             :         }
    2246             :         else
    2247             :         {
    2248          10 :             if (allow_poly)
    2249             :             {
    2250           6 :                 anycompatible_typeid = ANYCOMPATIBLEOID;
    2251           6 :                 anycompatible_array_typeid = ANYCOMPATIBLEARRAYOID;
    2252           6 :                 anycompatible_range_typeid = ANYCOMPATIBLERANGEOID;
    2253             :             }
    2254             :             else
    2255             :             {
    2256             :                 /*
    2257             :                  * Only way to get here is if all the ANYCOMPATIBLE args have
    2258             :                  * UNKNOWN inputs.  Resolve to TEXT as select_common_type()
    2259             :                  * would do.  That doesn't license us to use TEXTRANGE,
    2260             :                  * though.
    2261             :                  */
    2262           4 :                 anycompatible_typeid = TEXTOID;
    2263           4 :                 anycompatible_array_typeid = TEXTARRAYOID;
    2264           4 :                 if (have_anycompatible_range)
    2265           0 :                     ereport(ERROR,
    2266             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2267             :                              errmsg("could not determine polymorphic type %s because input has type %s",
    2268             :                                     "anycompatiblerange", "unknown")));
    2269             :             }
    2270             :         }
    2271             : 
    2272             :         /* replace polymorphic types by selected types */
    2273         798 :         for (int j = 0; j < nargs; j++)
    2274             :         {
    2275         544 :             Oid         decl_type = declared_arg_types[j];
    2276             : 
    2277         544 :             if (decl_type == ANYCOMPATIBLEOID ||
    2278             :                 decl_type == ANYCOMPATIBLENONARRAYOID)
    2279         302 :                 declared_arg_types[j] = anycompatible_typeid;
    2280         242 :             else if (decl_type == ANYCOMPATIBLEARRAYOID)
    2281          94 :                 declared_arg_types[j] = anycompatible_array_typeid;
    2282         148 :             else if (decl_type == ANYCOMPATIBLERANGEOID)
    2283          76 :                 declared_arg_types[j] = anycompatible_range_typeid;
    2284             :         }
    2285             :     }
    2286             : 
    2287             :     /*
    2288             :      * If we had any UNKNOWN inputs for polymorphic arguments, re-scan to
    2289             :      * assign correct types to them.
    2290             :      *
    2291             :      * Note: we don't have to consider unknown inputs that were matched to
    2292             :      * ANYCOMPATIBLE-family arguments, because we forcibly updated their
    2293             :      * declared_arg_types[] positions just above.
    2294             :      */
    2295       70474 :     if (have_poly_unknowns)
    2296             :     {
    2297       27212 :         for (int j = 0; j < nargs; j++)
    2298             :         {
    2299       18412 :             Oid         decl_type = declared_arg_types[j];
    2300       18412 :             Oid         actual_type = actual_arg_types[j];
    2301             : 
    2302       18412 :             if (actual_type != UNKNOWNOID)
    2303        8960 :                 continue;
    2304             : 
    2305        9452 :             if (decl_type == ANYELEMENTOID ||
    2306        8582 :                 decl_type == ANYNONARRAYOID ||
    2307             :                 decl_type == ANYENUMOID)
    2308         988 :                 declared_arg_types[j] = elem_typeid;
    2309        8464 :             else if (decl_type == ANYARRAYOID)
    2310             :             {
    2311        7782 :                 if (!OidIsValid(array_typeid))
    2312             :                 {
    2313          28 :                     array_typeid = get_array_type(elem_typeid);
    2314          28 :                     if (!OidIsValid(array_typeid))
    2315           0 :                         ereport(ERROR,
    2316             :                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
    2317             :                                  errmsg("could not find array type for data type %s",
    2318             :                                         format_type_be(elem_typeid))));
    2319             :                 }
    2320        7782 :                 declared_arg_types[j] = array_typeid;
    2321             :             }
    2322         682 :             else if (decl_type == ANYRANGEOID)
    2323             :             {
    2324          46 :                 if (!OidIsValid(range_typeid))
    2325             :                 {
    2326             :                     /* we can't infer a range type from the others */
    2327           0 :                     ereport(ERROR,
    2328             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2329             :                              errmsg("could not determine polymorphic type %s because input has type %s",
    2330             :                                     "anyrange", "unknown")));
    2331             :                 }
    2332          46 :                 declared_arg_types[j] = range_typeid;
    2333             :             }
    2334             :         }
    2335             :     }
    2336             : 
    2337             :     /* if we return ANYELEMENT use the appropriate argument type */
    2338       70474 :     if (rettype == ANYELEMENTOID ||
    2339       52152 :         rettype == ANYNONARRAYOID ||
    2340             :         rettype == ANYENUMOID)
    2341       18474 :         return elem_typeid;
    2342             : 
    2343             :     /* if we return ANYARRAY use the appropriate argument type */
    2344       52000 :     if (rettype == ANYARRAYOID)
    2345             :     {
    2346       17502 :         if (!OidIsValid(array_typeid))
    2347             :         {
    2348       14910 :             array_typeid = get_array_type(elem_typeid);
    2349       14910 :             if (!OidIsValid(array_typeid))
    2350           0 :                 ereport(ERROR,
    2351             :                         (errcode(ERRCODE_UNDEFINED_OBJECT),
    2352             :                          errmsg("could not find array type for data type %s",
    2353             :                                 format_type_be(elem_typeid))));
    2354             :         }
    2355       17502 :         return array_typeid;
    2356             :     }
    2357             : 
    2358             :     /* if we return ANYRANGE use the appropriate argument type */
    2359       34498 :     if (rettype == ANYRANGEOID)
    2360             :     {
    2361             :         /* this error is unreachable if the function signature is valid: */
    2362          56 :         if (!OidIsValid(range_typeid))
    2363           0 :             ereport(ERROR,
    2364             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    2365             :                      errmsg("could not determine polymorphic type %s because input has type %s",
    2366             :                             "anyrange", "unknown")));
    2367          56 :         return range_typeid;
    2368             :     }
    2369             : 
    2370             :     /* if we return ANYCOMPATIBLE use the appropriate type */
    2371       34442 :     if (rettype == ANYCOMPATIBLEOID ||
    2372             :         rettype == ANYCOMPATIBLENONARRAYOID)
    2373             :     {
    2374             :         /* this error is unreachable if the function signature is valid: */
    2375          70 :         if (!OidIsValid(anycompatible_typeid))
    2376           0 :             ereport(ERROR,
    2377             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    2378             :                      errmsg_internal("could not identify anycompatible type")));
    2379          70 :         return anycompatible_typeid;
    2380             :     }
    2381             : 
    2382             :     /* if we return ANYCOMPATIBLEARRAY use the appropriate type */
    2383       34372 :     if (rettype == ANYCOMPATIBLEARRAYOID)
    2384             :     {
    2385             :         /* this error is unreachable if the function signature is valid: */
    2386         100 :         if (!OidIsValid(anycompatible_array_typeid))
    2387           0 :             ereport(ERROR,
    2388             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    2389             :                      errmsg_internal("could not identify anycompatiblearray type")));
    2390         100 :         return anycompatible_array_typeid;
    2391             :     }
    2392             : 
    2393             :     /* if we return ANYCOMPATIBLERANGE use the appropriate argument type */
    2394       34272 :     if (rettype == ANYCOMPATIBLERANGEOID)
    2395             :     {
    2396             :         /* this error is unreachable if the function signature is valid: */
    2397          24 :         if (!OidIsValid(anycompatible_range_typeid))
    2398           0 :             ereport(ERROR,
    2399             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    2400             :                      errmsg_internal("could not identify anycompatiblerange type")));
    2401          24 :         return anycompatible_range_typeid;
    2402             :     }
    2403             : 
    2404             :     /* we don't return a generic type; send back the original return type */
    2405       34248 :     return rettype;
    2406             : }
    2407             : 
    2408             : /*
    2409             :  * check_valid_polymorphic_signature()
    2410             :  *      Is a proposed function signature valid per polymorphism rules?
    2411             :  *
    2412             :  * Returns NULL if the signature is valid (either ret_type is not polymorphic,
    2413             :  * or it can be deduced from the given declared argument types).  Otherwise,
    2414             :  * returns a palloc'd, already translated errdetail string saying why not.
    2415             :  */
    2416             : char *
    2417       40916 : check_valid_polymorphic_signature(Oid ret_type,
    2418             :                                   const Oid *declared_arg_types,
    2419             :                                   int nargs)
    2420             : {
    2421       40916 :     if (ret_type == ANYRANGEOID || ret_type == ANYCOMPATIBLERANGEOID)
    2422             :     {
    2423             :         /*
    2424             :          * ANYRANGE requires an ANYRANGE input, else we can't tell which of
    2425             :          * several range types with the same element type to use.  Likewise
    2426             :          * for ANYCOMPATIBLERANGE.
    2427             :          */
    2428         120 :         for (int i = 0; i < nargs; i++)
    2429             :         {
    2430          76 :             if (declared_arg_types[i] == ret_type)
    2431          28 :                 return NULL;    /* OK */
    2432             :         }
    2433          44 :         return psprintf(_("A result of type %s requires at least one input of type %s."),
    2434             :                         format_type_be(ret_type), format_type_be(ret_type));
    2435             :     }
    2436       40844 :     else if (IsPolymorphicTypeFamily1(ret_type))
    2437             :     {
    2438             :         /* Otherwise, any family-1 type can be deduced from any other */
    2439        1648 :         for (int i = 0; i < nargs; i++)
    2440             :         {
    2441        1572 :             if (IsPolymorphicTypeFamily1(declared_arg_types[i]))
    2442        1502 :                 return NULL;    /* OK */
    2443             :         }
    2444             :         /* Keep this list in sync with IsPolymorphicTypeFamily1! */
    2445          76 :         return psprintf(_("A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange."),
    2446             :                         format_type_be(ret_type));
    2447             :     }
    2448       39266 :     else if (IsPolymorphicTypeFamily2(ret_type))
    2449             :     {
    2450             :         /* Otherwise, any family-2 type can be deduced from any other */
    2451         140 :         for (int i = 0; i < nargs; i++)
    2452             :         {
    2453         136 :             if (IsPolymorphicTypeFamily2(declared_arg_types[i]))
    2454         108 :                 return NULL;    /* OK */
    2455             :         }
    2456             :         /* Keep this list in sync with IsPolymorphicTypeFamily2! */
    2457           4 :         return psprintf(_("A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, or anycompatiblerange."),
    2458             :                         format_type_be(ret_type));
    2459             :     }
    2460             :     else
    2461       39154 :         return NULL;            /* OK, ret_type is not polymorphic */
    2462             : }
    2463             : 
    2464             : /*
    2465             :  * check_valid_internal_signature()
    2466             :  *      Is a proposed function signature valid per INTERNAL safety rules?
    2467             :  *
    2468             :  * Returns NULL if OK, or a suitable error message if ret_type is INTERNAL but
    2469             :  * none of the declared arg types are.  (It's unsafe to create such a function
    2470             :  * since it would allow invocation of INTERNAL-consuming functions directly
    2471             :  * from SQL.)  It's overkill to return the error detail message, since there
    2472             :  * is only one possibility, but we do it like this to keep the API similar to
    2473             :  * check_valid_polymorphic_signature().
    2474             :  */
    2475             : char *
    2476       40204 : check_valid_internal_signature(Oid ret_type,
    2477             :                                const Oid *declared_arg_types,
    2478             :                                int nargs)
    2479             : {
    2480       40204 :     if (ret_type == INTERNALOID)
    2481             :     {
    2482        1592 :         for (int i = 0; i < nargs; i++)
    2483             :         {
    2484        1592 :             if (declared_arg_types[i] == ret_type)
    2485        1294 :                 return NULL;    /* OK */
    2486             :         }
    2487           0 :         return pstrdup(_("A result of type internal requires at least one input of type internal."));
    2488             :     }
    2489             :     else
    2490       38910 :         return NULL;            /* OK, ret_type is not INTERNAL */
    2491             : }
    2492             : 
    2493             : 
    2494             : /* TypeCategory()
    2495             :  *      Assign a category to the specified type OID.
    2496             :  *
    2497             :  * NB: this must not return TYPCATEGORY_INVALID.
    2498             :  */
    2499             : TYPCATEGORY
    2500       97372 : TypeCategory(Oid type)
    2501             : {
    2502             :     char        typcategory;
    2503             :     bool        typispreferred;
    2504             : 
    2505       97372 :     get_type_category_preferred(type, &typcategory, &typispreferred);
    2506             :     Assert(typcategory != TYPCATEGORY_INVALID);
    2507       97372 :     return (TYPCATEGORY) typcategory;
    2508             : }
    2509             : 
    2510             : 
    2511             : /* IsPreferredType()
    2512             :  *      Check if this type is a preferred type for the given category.
    2513             :  *
    2514             :  * If category is TYPCATEGORY_INVALID, then we'll return true for preferred
    2515             :  * types of any category; otherwise, only for preferred types of that
    2516             :  * category.
    2517             :  */
    2518             : bool
    2519       30060 : IsPreferredType(TYPCATEGORY category, Oid type)
    2520             : {
    2521             :     char        typcategory;
    2522             :     bool        typispreferred;
    2523             : 
    2524       30060 :     get_type_category_preferred(type, &typcategory, &typispreferred);
    2525       30060 :     if (category == typcategory || category == TYPCATEGORY_INVALID)
    2526       22512 :         return typispreferred;
    2527             :     else
    2528        7548 :         return false;
    2529             : }
    2530             : 
    2531             : 
    2532             : /* IsBinaryCoercible()
    2533             :  *      Check if srctype is binary-coercible to targettype.
    2534             :  *
    2535             :  * This notion allows us to cheat and directly exchange values without
    2536             :  * going through the trouble of calling a conversion function.  Note that
    2537             :  * in general, this should only be an implementation shortcut.  Before 7.4,
    2538             :  * this was also used as a heuristic for resolving overloaded functions and
    2539             :  * operators, but that's basically a bad idea.
    2540             :  *
    2541             :  * As of 7.3, binary coercibility isn't hardwired into the code anymore.
    2542             :  * We consider two types binary-coercible if there is an implicitly
    2543             :  * invokable, no-function-needed pg_cast entry.  Also, a domain is always
    2544             :  * binary-coercible to its base type, though *not* vice versa (in the other
    2545             :  * direction, one must apply domain constraint checks before accepting the
    2546             :  * value as legitimate).  We also need to special-case various polymorphic
    2547             :  * types.
    2548             :  *
    2549             :  * This function replaces IsBinaryCompatible(), which was an inherently
    2550             :  * symmetric test.  Since the pg_cast entries aren't necessarily symmetric,
    2551             :  * the order of the operands is now significant.
    2552             :  */
    2553             : bool
    2554     1604422 : IsBinaryCoercible(Oid srctype, Oid targettype)
    2555             : {
    2556             :     HeapTuple   tuple;
    2557             :     Form_pg_cast castForm;
    2558             :     bool        result;
    2559             : 
    2560             :     /* Fast path if same type */
    2561     1604422 :     if (srctype == targettype)
    2562      730124 :         return true;
    2563             : 
    2564             :     /* Anything is coercible to ANY or ANYELEMENT or ANYCOMPATIBLE */
    2565      874298 :     if (targettype == ANYOID || targettype == ANYELEMENTOID ||
    2566             :         targettype == ANYCOMPATIBLEOID)
    2567         130 :         return true;
    2568             : 
    2569             :     /* If srctype is a domain, reduce to its base type */
    2570      874168 :     if (OidIsValid(srctype))
    2571      874168 :         srctype = getBaseType(srctype);
    2572             : 
    2573             :     /* Somewhat-fast path for domain -> base type case */
    2574      874168 :     if (srctype == targettype)
    2575           8 :         return true;
    2576             : 
    2577             :     /* Also accept any array type as coercible to ANY[COMPATIBLE]ARRAY */
    2578      874160 :     if (targettype == ANYARRAYOID || targettype == ANYCOMPATIBLEARRAYOID)
    2579       45734 :         if (type_is_array(srctype))
    2580        3668 :             return true;
    2581             : 
    2582             :     /* Also accept any non-array type as coercible to ANY[COMPATIBLE]NONARRAY */
    2583      870492 :     if (targettype == ANYNONARRAYOID || targettype == ANYCOMPATIBLENONARRAYOID)
    2584           0 :         if (!type_is_array(srctype))
    2585           0 :             return true;
    2586             : 
    2587             :     /* Also accept any enum type as coercible to ANYENUM */
    2588      870492 :     if (targettype == ANYENUMOID)
    2589       41412 :         if (type_is_enum(srctype))
    2590          82 :             return true;
    2591             : 
    2592             :     /* Also accept any range type as coercible to ANY[COMPATIBLE]RANGE */
    2593      870410 :     if (targettype == ANYRANGEOID || targettype == ANYCOMPATIBLERANGEOID)
    2594       15050 :         if (type_is_range(srctype))
    2595         236 :             return true;
    2596             : 
    2597             :     /* Also accept any composite type as coercible to RECORD */
    2598      870174 :     if (targettype == RECORDOID)
    2599       12178 :         if (ISCOMPLEX(srctype))
    2600         158 :             return true;
    2601             : 
    2602             :     /* Also accept any composite array type as coercible to RECORD[] */
    2603      870016 :     if (targettype == RECORDARRAYOID)
    2604           0 :         if (is_complex_array(srctype))
    2605           0 :             return true;
    2606             : 
    2607             :     /* Else look in pg_cast */
    2608      870016 :     tuple = SearchSysCache2(CASTSOURCETARGET,
    2609             :                             ObjectIdGetDatum(srctype),
    2610             :                             ObjectIdGetDatum(targettype));
    2611      870016 :     if (!HeapTupleIsValid(tuple))
    2612      724130 :         return false;           /* no cast */
    2613      145886 :     castForm = (Form_pg_cast) GETSTRUCT(tuple);
    2614             : 
    2615      159262 :     result = (castForm->castmethod == COERCION_METHOD_BINARY &&
    2616       13376 :               castForm->castcontext == COERCION_CODE_IMPLICIT);
    2617             : 
    2618      145886 :     ReleaseSysCache(tuple);
    2619             : 
    2620      145886 :     return result;
    2621             : }
    2622             : 
    2623             : 
    2624             : /*
    2625             :  * find_coercion_pathway
    2626             :  *      Look for a coercion pathway between two types.
    2627             :  *
    2628             :  * Currently, this deals only with scalar-type cases; it does not consider
    2629             :  * polymorphic types nor casts between composite types.  (Perhaps fold
    2630             :  * those in someday?)
    2631             :  *
    2632             :  * ccontext determines the set of available casts.
    2633             :  *
    2634             :  * The possible result codes are:
    2635             :  *  COERCION_PATH_NONE: failed to find any coercion pathway
    2636             :  *              *funcid is set to InvalidOid
    2637             :  *  COERCION_PATH_FUNC: apply the coercion function returned in *funcid
    2638             :  *  COERCION_PATH_RELABELTYPE: binary-compatible cast, no function needed
    2639             :  *              *funcid is set to InvalidOid
    2640             :  *  COERCION_PATH_ARRAYCOERCE: need an ArrayCoerceExpr node
    2641             :  *              *funcid is set to InvalidOid
    2642             :  *  COERCION_PATH_COERCEVIAIO: need a CoerceViaIO node
    2643             :  *              *funcid is set to InvalidOid
    2644             :  *
    2645             :  * Note: COERCION_PATH_RELABELTYPE does not necessarily mean that no work is
    2646             :  * needed to do the coercion; if the target is a domain then we may need to
    2647             :  * apply domain constraint checking.  If you want to check for a zero-effort
    2648             :  * conversion then use IsBinaryCoercible().
    2649             :  */
    2650             : CoercionPathType
    2651     1403084 : find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
    2652             :                       CoercionContext ccontext,
    2653             :                       Oid *funcid)
    2654             : {
    2655     1403084 :     CoercionPathType result = COERCION_PATH_NONE;
    2656             :     HeapTuple   tuple;
    2657             : 
    2658     1403084 :     *funcid = InvalidOid;
    2659             : 
    2660             :     /* Perhaps the types are domains; if so, look at their base types */
    2661     1403084 :     if (OidIsValid(sourceTypeId))
    2662     1403084 :         sourceTypeId = getBaseType(sourceTypeId);
    2663     1403084 :     if (OidIsValid(targetTypeId))
    2664     1403084 :         targetTypeId = getBaseType(targetTypeId);
    2665             : 
    2666             :     /* Domains are always coercible to and from their base type */
    2667     1403084 :     if (sourceTypeId == targetTypeId)
    2668      278928 :         return COERCION_PATH_RELABELTYPE;
    2669             : 
    2670             :     /* Look in pg_cast */
    2671     1124156 :     tuple = SearchSysCache2(CASTSOURCETARGET,
    2672             :                             ObjectIdGetDatum(sourceTypeId),
    2673             :                             ObjectIdGetDatum(targetTypeId));
    2674             : 
    2675     1124156 :     if (HeapTupleIsValid(tuple))
    2676             :     {
    2677      451978 :         Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
    2678             :         CoercionContext castcontext;
    2679             : 
    2680             :         /* convert char value for castcontext to CoercionContext enum */
    2681      451978 :         switch (castForm->castcontext)
    2682             :         {
    2683      364318 :             case COERCION_CODE_IMPLICIT:
    2684      364318 :                 castcontext = COERCION_IMPLICIT;
    2685      364318 :                 break;
    2686       83236 :             case COERCION_CODE_ASSIGNMENT:
    2687       83236 :                 castcontext = COERCION_ASSIGNMENT;
    2688       83236 :                 break;
    2689        4424 :             case COERCION_CODE_EXPLICIT:
    2690        4424 :                 castcontext = COERCION_EXPLICIT;
    2691        4424 :                 break;
    2692           0 :             default:
    2693           0 :                 elog(ERROR, "unrecognized castcontext: %d",
    2694             :                      (int) castForm->castcontext);
    2695             :                 castcontext = 0;    /* keep compiler quiet */
    2696             :                 break;
    2697             :         }
    2698             : 
    2699             :         /* Rely on ordering of enum for correct behavior here */
    2700      451978 :         if (ccontext >= castcontext)
    2701             :         {
    2702      391202 :             switch (castForm->castmethod)
    2703             :             {
    2704      149096 :                 case COERCION_METHOD_FUNCTION:
    2705      149096 :                     result = COERCION_PATH_FUNC;
    2706      149096 :                     *funcid = castForm->castfunc;
    2707      149096 :                     break;
    2708          20 :                 case COERCION_METHOD_INOUT:
    2709          20 :                     result = COERCION_PATH_COERCEVIAIO;
    2710          20 :                     break;
    2711      242086 :                 case COERCION_METHOD_BINARY:
    2712      242086 :                     result = COERCION_PATH_RELABELTYPE;
    2713      242086 :                     break;
    2714           0 :                 default:
    2715           0 :                     elog(ERROR, "unrecognized castmethod: %d",
    2716             :                          (int) castForm->castmethod);
    2717             :                     break;
    2718             :             }
    2719       60776 :         }
    2720             : 
    2721      451978 :         ReleaseSysCache(tuple);
    2722             :     }
    2723             :     else
    2724             :     {
    2725             :         /*
    2726             :          * If there's no pg_cast entry, perhaps we are dealing with a pair of
    2727             :          * array types.  If so, and if their element types have a conversion
    2728             :          * pathway, report that we can coerce with an ArrayCoerceExpr.
    2729             :          *
    2730             :          * Hack: disallow coercions to oidvector and int2vector, which
    2731             :          * otherwise tend to capture coercions that should go to "real" array
    2732             :          * types.  We want those types to be considered "real" arrays for many
    2733             :          * purposes, but not this one.  (Also, ArrayCoerceExpr isn't
    2734             :          * guaranteed to produce an output that meets the restrictions of
    2735             :          * these datatypes, such as being 1-dimensional.)
    2736             :          */
    2737      672178 :         if (targetTypeId != OIDVECTOROID && targetTypeId != INT2VECTOROID)
    2738             :         {
    2739             :             Oid         targetElem;
    2740             :             Oid         sourceElem;
    2741             : 
    2742      667102 :             if ((targetElem = get_element_type(targetTypeId)) != InvalidOid &&
    2743        5232 :                 (sourceElem = get_element_type(sourceTypeId)) != InvalidOid)
    2744             :             {
    2745             :                 CoercionPathType elempathtype;
    2746             :                 Oid         elemfuncid;
    2747             : 
    2748        4018 :                 elempathtype = find_coercion_pathway(targetElem,
    2749             :                                                      sourceElem,
    2750             :                                                      ccontext,
    2751             :                                                      &elemfuncid);
    2752        4018 :                 if (elempathtype != COERCION_PATH_NONE)
    2753             :                 {
    2754        3914 :                     result = COERCION_PATH_ARRAYCOERCE;
    2755             :                 }
    2756             :             }
    2757             :         }
    2758             : 
    2759             :         /*
    2760             :          * If we still haven't found a possibility, consider automatic casting
    2761             :          * using I/O functions.  We allow assignment casts to string types and
    2762             :          * explicit casts from string types to be handled this way. (The
    2763             :          * CoerceViaIO mechanism is a lot more general than that, but this is
    2764             :          * all we want to allow in the absence of a pg_cast entry.) It would
    2765             :          * probably be better to insist on explicit casts in both directions,
    2766             :          * but this is a compromise to preserve something of the pre-8.3
    2767             :          * behavior that many types had implicit (yipes!) casts to text.
    2768             :          */
    2769      672178 :         if (result == COERCION_PATH_NONE)
    2770             :         {
    2771      700516 :             if (ccontext >= COERCION_ASSIGNMENT &&
    2772       32252 :                 TypeCategory(targetTypeId) == TYPCATEGORY_STRING)
    2773       28360 :                 result = COERCION_PATH_COERCEVIAIO;
    2774      643266 :             else if (ccontext >= COERCION_EXPLICIT &&
    2775        3362 :                      TypeCategory(sourceTypeId) == TYPCATEGORY_STRING)
    2776        1272 :                 result = COERCION_PATH_COERCEVIAIO;
    2777             :         }
    2778             :     }
    2779             : 
    2780     1124156 :     return result;
    2781             : }
    2782             : 
    2783             : 
    2784             : /*
    2785             :  * find_typmod_coercion_function -- does the given type need length coercion?
    2786             :  *
    2787             :  * If the target type possesses a pg_cast function from itself to itself,
    2788             :  * it must need length coercion.
    2789             :  *
    2790             :  * "bpchar" (ie, char(N)) and "numeric" are examples of such types.
    2791             :  *
    2792             :  * If the given type is a varlena array type, we do not look for a coercion
    2793             :  * function associated directly with the array type, but instead look for
    2794             :  * one associated with the element type.  An ArrayCoerceExpr node must be
    2795             :  * used to apply such a function.  (Note: currently, it's pointless to
    2796             :  * return the funcid in this case, because it'll just get looked up again
    2797             :  * in the recursive construction of the ArrayCoerceExpr's elemexpr.)
    2798             :  *
    2799             :  * We use the same result enum as find_coercion_pathway, but the only possible
    2800             :  * result codes are:
    2801             :  *  COERCION_PATH_NONE: no length coercion needed
    2802             :  *  COERCION_PATH_FUNC: apply the function returned in *funcid
    2803             :  *  COERCION_PATH_ARRAYCOERCE: apply the function using ArrayCoerceExpr
    2804             :  */
    2805             : CoercionPathType
    2806       30686 : find_typmod_coercion_function(Oid typeId,
    2807             :                               Oid *funcid)
    2808             : {
    2809             :     CoercionPathType result;
    2810             :     Type        targetType;
    2811             :     Form_pg_type typeForm;
    2812             :     HeapTuple   tuple;
    2813             : 
    2814       30686 :     *funcid = InvalidOid;
    2815       30686 :     result = COERCION_PATH_FUNC;
    2816             : 
    2817       30686 :     targetType = typeidType(typeId);
    2818       30686 :     typeForm = (Form_pg_type) GETSTRUCT(targetType);
    2819             : 
    2820             :     /* Check for a varlena array type */
    2821       30686 :     if (typeForm->typelem != InvalidOid && typeForm->typlen == -1)
    2822             :     {
    2823             :         /* Yes, switch our attention to the element type */
    2824          56 :         typeId = typeForm->typelem;
    2825          56 :         result = COERCION_PATH_ARRAYCOERCE;
    2826             :     }
    2827       30686 :     ReleaseSysCache(targetType);
    2828             : 
    2829             :     /* Look in pg_cast */
    2830       30686 :     tuple = SearchSysCache2(CASTSOURCETARGET,
    2831             :                             ObjectIdGetDatum(typeId),
    2832             :                             ObjectIdGetDatum(typeId));
    2833             : 
    2834       30686 :     if (HeapTupleIsValid(tuple))
    2835             :     {
    2836       30674 :         Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
    2837             : 
    2838       30674 :         *funcid = castForm->castfunc;
    2839       30674 :         ReleaseSysCache(tuple);
    2840             :     }
    2841             : 
    2842       30686 :     if (!OidIsValid(*funcid))
    2843          12 :         result = COERCION_PATH_NONE;
    2844             : 
    2845       30686 :     return result;
    2846             : }
    2847             : 
    2848             : /*
    2849             :  * is_complex_array
    2850             :  *      Is this type an array of composite?
    2851             :  *
    2852             :  * Note: this will not return true for record[]; check for RECORDARRAYOID
    2853             :  * separately if needed.
    2854             :  */
    2855             : static bool
    2856          12 : is_complex_array(Oid typid)
    2857             : {
    2858          12 :     Oid         elemtype = get_element_type(typid);
    2859             : 
    2860          12 :     return (OidIsValid(elemtype) && ISCOMPLEX(elemtype));
    2861             : }
    2862             : 
    2863             : 
    2864             : /*
    2865             :  * Check whether reltypeId is the row type of a typed table of type
    2866             :  * reloftypeId, or is a domain over such a row type.  (This is conceptually
    2867             :  * similar to the subtype relationship checked by typeInheritsFrom().)
    2868             :  */
    2869             : static bool
    2870      695430 : typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId)
    2871             : {
    2872      695430 :     Oid         relid = typeOrDomainTypeRelid(reltypeId);
    2873      695430 :     bool        result = false;
    2874             : 
    2875      695430 :     if (relid)
    2876             :     {
    2877             :         HeapTuple   tp;
    2878             :         Form_pg_class reltup;
    2879             : 
    2880        7302 :         tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
    2881        7302 :         if (!HeapTupleIsValid(tp))
    2882           0 :             elog(ERROR, "cache lookup failed for relation %u", relid);
    2883             : 
    2884        7302 :         reltup = (Form_pg_class) GETSTRUCT(tp);
    2885        7302 :         if (reltup->reloftype == reloftypeId)
    2886           8 :             result = true;
    2887             : 
    2888        7302 :         ReleaseSysCache(tp);
    2889             :     }
    2890             : 
    2891      695430 :     return result;
    2892             : }

Generated by: LCOV version 1.13