LCOV - code coverage report
Current view: top level - src/backend/parser - parse_coerce.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 940 1027 91.5 %
Date: 2025-02-21 18:14:53 Functions: 31 31 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-2025, 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/fmgroids.h"
      30             : #include "utils/lsyscache.h"
      31             : #include "utils/syscache.h"
      32             : #include "utils/typcache.h"
      33             : 
      34             : 
      35             : static Node *coerce_type_typmod(Node *node,
      36             :                                 Oid targetTypeId, int32 targetTypMod,
      37             :                                 CoercionContext ccontext, CoercionForm cformat,
      38             :                                 int location,
      39             :                                 bool hideInputCoercion);
      40             : static void hide_coercion_node(Node *node);
      41             : static Node *build_coercion_expression(Node *node,
      42             :                                        CoercionPathType pathtype,
      43             :                                        Oid funcId,
      44             :                                        Oid targetTypeId, int32 targetTypMod,
      45             :                                        CoercionContext ccontext, CoercionForm cformat,
      46             :                                        int location);
      47             : static Node *coerce_record_to_complex(ParseState *pstate, Node *node,
      48             :                                       Oid targetTypeId,
      49             :                                       CoercionContext ccontext,
      50             :                                       CoercionForm cformat,
      51             :                                       int location);
      52             : static bool is_complex_array(Oid typid);
      53             : static bool typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId);
      54             : 
      55             : 
      56             : /*
      57             :  * coerce_to_target_type()
      58             :  *      Convert an expression to a target type and typmod.
      59             :  *
      60             :  * This is the general-purpose entry point for arbitrary type coercion
      61             :  * operations.  Direct use of the component operations can_coerce_type,
      62             :  * coerce_type, and coerce_type_typmod should be restricted to special
      63             :  * cases (eg, when the conversion is expected to succeed).
      64             :  *
      65             :  * Returns the possibly-transformed expression tree, or NULL if the type
      66             :  * conversion is not possible.  (We do this, rather than ereport'ing directly,
      67             :  * so that callers can generate custom error messages indicating context.)
      68             :  *
      69             :  * pstate - parse state (can be NULL, see coerce_type)
      70             :  * expr - input expression tree (already transformed by transformExpr)
      71             :  * exprtype - result type of expr
      72             :  * targettype - desired result type
      73             :  * targettypmod - desired result typmod
      74             :  * ccontext, cformat - context indicators to control coercions
      75             :  * location - parse location of the coercion request, or -1 if unknown/implicit
      76             :  */
      77             : Node *
      78      801666 : coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype,
      79             :                       Oid targettype, int32 targettypmod,
      80             :                       CoercionContext ccontext,
      81             :                       CoercionForm cformat,
      82             :                       int location)
      83             : {
      84             :     Node       *result;
      85             :     Node       *origexpr;
      86             : 
      87      801666 :     if (!can_coerce_type(1, &exprtype, &targettype, ccontext))
      88         434 :         return NULL;
      89             : 
      90             :     /*
      91             :      * If the input has a CollateExpr at the top, strip it off, perform the
      92             :      * coercion, and put a new one back on.  This is annoying since it
      93             :      * duplicates logic in coerce_type, but if we don't do this then it's too
      94             :      * hard to tell whether coerce_type actually changed anything, and we
      95             :      * *must* know that to avoid possibly calling hide_coercion_node on
      96             :      * something that wasn't generated by coerce_type.  Note that if there are
      97             :      * multiple stacked CollateExprs, we just discard all but the topmost.
      98             :      * Also, if the target type isn't collatable, we discard the CollateExpr.
      99             :      */
     100      801232 :     origexpr = expr;
     101      801274 :     while (expr && IsA(expr, CollateExpr))
     102          42 :         expr = (Node *) ((CollateExpr *) expr)->arg;
     103             : 
     104      801232 :     result = coerce_type(pstate, expr, exprtype,
     105             :                          targettype, targettypmod,
     106             :                          ccontext, cformat, location);
     107             : 
     108             :     /*
     109             :      * If the target is a fixed-length type, it may need a length coercion as
     110             :      * well as a type coercion.  If we find ourselves adding both, force the
     111             :      * inner coercion node to implicit display form.
     112             :      */
     113      796870 :     result = coerce_type_typmod(result,
     114             :                                 targettype, targettypmod,
     115             :                                 ccontext, cformat, location,
     116      796870 :                                 (result != expr && !IsA(result, Const)));
     117             : 
     118      796870 :     if (expr != origexpr && type_is_collatable(targettype))
     119             :     {
     120             :         /* Reinstall top CollateExpr */
     121          36 :         CollateExpr *coll = (CollateExpr *) origexpr;
     122          36 :         CollateExpr *newcoll = makeNode(CollateExpr);
     123             : 
     124          36 :         newcoll->arg = (Expr *) result;
     125          36 :         newcoll->collOid = coll->collOid;
     126          36 :         newcoll->location = coll->location;
     127          36 :         result = (Node *) newcoll;
     128             :     }
     129             : 
     130      796870 :     return result;
     131             : }
     132             : 
     133             : 
     134             : /*
     135             :  * coerce_type()
     136             :  *      Convert an expression to a different type.
     137             :  *
     138             :  * The caller should already have determined that the coercion is possible;
     139             :  * see can_coerce_type.
     140             :  *
     141             :  * Normally, no coercion to a typmod (length) is performed here.  The caller
     142             :  * must call coerce_type_typmod as well, if a typmod constraint is wanted.
     143             :  * (But if the target type is a domain, it may internally contain a
     144             :  * typmod constraint, which will be applied inside coerce_to_domain.)
     145             :  * In some cases pg_cast specifies a type coercion function that also
     146             :  * applies length conversion, and in those cases only, the result will
     147             :  * already be properly coerced to the specified typmod.
     148             :  *
     149             :  * pstate is only used in the case that we are able to resolve the type of
     150             :  * a previously UNKNOWN Param.  It is okay to pass pstate = NULL if the
     151             :  * caller does not want type information updated for Params.
     152             :  *
     153             :  * Note: this function must not modify the given expression tree, only add
     154             :  * decoration on top of it.  See transformSetOperationTree, for example.
     155             :  */
     156             : Node *
     157     1578526 : coerce_type(ParseState *pstate, Node *node,
     158             :             Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod,
     159             :             CoercionContext ccontext, CoercionForm cformat, int location)
     160             : {
     161             :     Node       *result;
     162             :     CoercionPathType pathtype;
     163             :     Oid         funcId;
     164             : 
     165     1578526 :     if (targetTypeId == inputTypeId ||
     166             :         node == NULL)
     167             :     {
     168             :         /* no conversion needed */
     169      360878 :         return node;
     170             :     }
     171     1217648 :     if (targetTypeId == ANYOID ||
     172     1154074 :         targetTypeId == ANYELEMENTOID ||
     173     1138500 :         targetTypeId == ANYNONARRAYOID ||
     174     1138500 :         targetTypeId == ANYCOMPATIBLEOID ||
     175             :         targetTypeId == ANYCOMPATIBLENONARRAYOID)
     176             :     {
     177             :         /*
     178             :          * Assume can_coerce_type verified that implicit coercion is okay.
     179             :          *
     180             :          * Note: by returning the unmodified node here, we are saying that
     181             :          * it's OK to treat an UNKNOWN constant as a valid input for a
     182             :          * function accepting one of these pseudotypes.  This should be all
     183             :          * right, since an UNKNOWN value is still a perfectly valid Datum.
     184             :          *
     185             :          * NB: we do NOT want a RelabelType here: the exposed type of the
     186             :          * function argument must be its actual type, not the polymorphic
     187             :          * pseudotype.
     188             :          */
     189       79148 :         return node;
     190             :     }
     191     1138500 :     if (targetTypeId == ANYARRAYOID ||
     192     1109134 :         targetTypeId == ANYENUMOID ||
     193     1099816 :         targetTypeId == ANYRANGEOID ||
     194     1094134 :         targetTypeId == ANYMULTIRANGEOID ||
     195     1094134 :         targetTypeId == ANYCOMPATIBLEARRAYOID ||
     196     1094134 :         targetTypeId == ANYCOMPATIBLERANGEOID ||
     197             :         targetTypeId == ANYCOMPATIBLEMULTIRANGEOID)
     198             :     {
     199             :         /*
     200             :          * Assume can_coerce_type verified that implicit coercion is okay.
     201             :          *
     202             :          * These cases are unlike the ones above because the exposed type of
     203             :          * the argument must be an actual array, enum, range, or multirange
     204             :          * type.  In particular the argument must *not* be an UNKNOWN
     205             :          * constant.  If it is, we just fall through; below, we'll call the
     206             :          * pseudotype's input function, which will produce an error.  Also, if
     207             :          * what we have is a domain over array, enum, range, or multirange, we
     208             :          * have to relabel it to its base type.
     209             :          *
     210             :          * Note: currently, we can't actually see a domain-over-enum here,
     211             :          * since the other functions in this file will not match such a
     212             :          * parameter to ANYENUM.  But that should get changed eventually.
     213             :          */
     214       44366 :         if (inputTypeId != UNKNOWNOID)
     215             :         {
     216       43364 :             Oid         baseTypeId = getBaseType(inputTypeId);
     217             : 
     218       43364 :             if (baseTypeId != inputTypeId)
     219             :             {
     220          54 :                 RelabelType *r = makeRelabelType((Expr *) node,
     221             :                                                  baseTypeId, -1,
     222             :                                                  InvalidOid,
     223             :                                                  cformat);
     224             : 
     225          54 :                 r->location = location;
     226          54 :                 return (Node *) r;
     227             :             }
     228             :             /* Not a domain type, so return it as-is */
     229       43310 :             return node;
     230             :         }
     231             :     }
     232     1095136 :     if (inputTypeId == UNKNOWNOID && IsA(node, Const))
     233             :     {
     234             :         /*
     235             :          * Input is a string constant with previously undetermined type. Apply
     236             :          * the target type's typinput function to it to produce a constant of
     237             :          * the target type.
     238             :          *
     239             :          * NOTE: this case cannot be folded together with the other
     240             :          * constant-input case, since the typinput function does not
     241             :          * necessarily behave the same as a type conversion function. For
     242             :          * example, int4's typinput function will reject "1.2", whereas
     243             :          * float-to-int type conversion will round to integer.
     244             :          *
     245             :          * XXX if the typinput function is not immutable, we really ought to
     246             :          * postpone evaluation of the function call until runtime. But there
     247             :          * is no way to represent a typinput function call as an expression
     248             :          * tree, because C-string values are not Datums. (XXX This *is*
     249             :          * possible as of 7.3, do we want to do it?)
     250             :          */
     251      776560 :         Const      *con = (Const *) node;
     252      776560 :         Const      *newcon = makeNode(Const);
     253             :         Oid         baseTypeId;
     254             :         int32       baseTypeMod;
     255             :         int32       inputTypeMod;
     256             :         Type        baseType;
     257             :         ParseCallbackState pcbstate;
     258             : 
     259             :         /*
     260             :          * If the target type is a domain, we want to call its base type's
     261             :          * input routine, not domain_in().  This is to avoid premature failure
     262             :          * when the domain applies a typmod: existing input routines follow
     263             :          * implicit-coercion semantics for length checks, which is not always
     264             :          * what we want here.  The needed check will be applied properly
     265             :          * inside coerce_to_domain().
     266             :          */
     267      776560 :         baseTypeMod = targetTypeMod;
     268      776560 :         baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
     269             : 
     270             :         /*
     271             :          * For most types we pass typmod -1 to the input routine, because
     272             :          * existing input routines follow implicit-coercion semantics for
     273             :          * length checks, which is not always what we want here.  Any length
     274             :          * constraint will be applied later by our caller.  An exception
     275             :          * however is the INTERVAL type, for which we *must* pass the typmod
     276             :          * or it won't be able to obey the bizarre SQL-spec input rules. (Ugly
     277             :          * as sin, but so is this part of the spec...)
     278             :          */
     279      776560 :         if (baseTypeId == INTERVALOID)
     280        5136 :             inputTypeMod = baseTypeMod;
     281             :         else
     282      771424 :             inputTypeMod = -1;
     283             : 
     284      776560 :         baseType = typeidType(baseTypeId);
     285             : 
     286      776560 :         newcon->consttype = baseTypeId;
     287      776560 :         newcon->consttypmod = inputTypeMod;
     288      776560 :         newcon->constcollid = typeTypeCollation(baseType);
     289      776560 :         newcon->constlen = typeLen(baseType);
     290      776560 :         newcon->constbyval = typeByVal(baseType);
     291      776560 :         newcon->constisnull = con->constisnull;
     292             : 
     293             :         /*
     294             :          * We use the original literal's location regardless of the position
     295             :          * of the coercion.  This is a change from pre-9.2 behavior, meant to
     296             :          * simplify life for pg_stat_statements.
     297             :          */
     298      776560 :         newcon->location = con->location;
     299             : 
     300             :         /*
     301             :          * Set up to point at the constant's text if the input routine throws
     302             :          * an error.
     303             :          */
     304      776560 :         setup_parser_errposition_callback(&pcbstate, pstate, con->location);
     305             : 
     306             :         /*
     307             :          * We assume here that UNKNOWN's internal representation is the same
     308             :          * as CSTRING.
     309             :          */
     310      776560 :         if (!con->constisnull)
     311      705250 :             newcon->constvalue = stringTypeDatum(baseType,
     312             :                                                  DatumGetCString(con->constvalue),
     313             :                                                  inputTypeMod);
     314             :         else
     315       71310 :             newcon->constvalue = stringTypeDatum(baseType,
     316             :                                                  NULL,
     317             :                                                  inputTypeMod);
     318             : 
     319             :         /*
     320             :          * If it's a varlena value, force it to be in non-expanded
     321             :          * (non-toasted) format; this avoids any possible dependency on
     322             :          * external values and improves consistency of representation.
     323             :          */
     324      771972 :         if (!con->constisnull && newcon->constlen == -1)
     325      328136 :             newcon->constvalue =
     326      328136 :                 PointerGetDatum(PG_DETOAST_DATUM(newcon->constvalue));
     327             : 
     328             : #ifdef RANDOMIZE_ALLOCATED_MEMORY
     329             : 
     330             :         /*
     331             :          * For pass-by-reference data types, repeat the conversion to see if
     332             :          * the input function leaves any uninitialized bytes in the result. We
     333             :          * can only detect that reliably if RANDOMIZE_ALLOCATED_MEMORY is
     334             :          * enabled, so we don't bother testing otherwise.  The reason we don't
     335             :          * want any instability in the input function is that comparison of
     336             :          * Const nodes relies on bytewise comparison of the datums, so if the
     337             :          * input function leaves garbage then subexpressions that should be
     338             :          * identical may not get recognized as such.  See pgsql-hackers
     339             :          * discussion of 2008-04-04.
     340             :          */
     341             :         if (!con->constisnull && !newcon->constbyval)
     342             :         {
     343             :             Datum       val2;
     344             : 
     345             :             val2 = stringTypeDatum(baseType,
     346             :                                    DatumGetCString(con->constvalue),
     347             :                                    inputTypeMod);
     348             :             if (newcon->constlen == -1)
     349             :                 val2 = PointerGetDatum(PG_DETOAST_DATUM(val2));
     350             :             if (!datumIsEqual(newcon->constvalue, val2, false, newcon->constlen))
     351             :                 elog(WARNING, "type %s has unstable input conversion for \"%s\"",
     352             :                      typeTypeName(baseType), DatumGetCString(con->constvalue));
     353             :         }
     354             : #endif
     355             : 
     356      771972 :         cancel_parser_errposition_callback(&pcbstate);
     357             : 
     358      771972 :         result = (Node *) newcon;
     359             : 
     360             :         /* If target is a domain, apply constraints. */
     361      771972 :         if (baseTypeId != targetTypeId)
     362       30444 :             result = coerce_to_domain(result,
     363             :                                       baseTypeId, baseTypeMod,
     364             :                                       targetTypeId,
     365             :                                       ccontext, cformat, location,
     366             :                                       false);
     367             : 
     368      771972 :         ReleaseSysCache(baseType);
     369             : 
     370      771972 :         return result;
     371             :     }
     372      318576 :     if (IsA(node, Param) &&
     373       17634 :         pstate != NULL && pstate->p_coerce_param_hook != NULL)
     374             :     {
     375             :         /*
     376             :          * Allow the CoerceParamHook to decide what happens.  It can return a
     377             :          * transformed node (very possibly the same Param node), or return
     378             :          * NULL to indicate we should proceed with normal coercion.
     379             :          */
     380       12656 :         result = pstate->p_coerce_param_hook(pstate,
     381             :                                              (Param *) node,
     382             :                                              targetTypeId,
     383             :                                              targetTypeMod,
     384             :                                              location);
     385       12656 :         if (result)
     386       12612 :             return result;
     387             :     }
     388      305964 :     if (IsA(node, CollateExpr))
     389             :     {
     390             :         /*
     391             :          * If we have a COLLATE clause, we have to push the coercion
     392             :          * underneath the COLLATE; or discard the COLLATE if the target type
     393             :          * isn't collatable.  This is really ugly, but there is little choice
     394             :          * because the above hacks on Consts and Params wouldn't happen
     395             :          * otherwise.  This kluge has consequences in coerce_to_target_type.
     396             :          */
     397        7566 :         CollateExpr *coll = (CollateExpr *) node;
     398             : 
     399        7566 :         result = coerce_type(pstate, (Node *) coll->arg,
     400             :                              inputTypeId, targetTypeId, targetTypeMod,
     401             :                              ccontext, cformat, location);
     402        7566 :         if (type_is_collatable(targetTypeId))
     403             :         {
     404        7566 :             CollateExpr *newcoll = makeNode(CollateExpr);
     405             : 
     406        7566 :             newcoll->arg = (Expr *) result;
     407        7566 :             newcoll->collOid = coll->collOid;
     408        7566 :             newcoll->location = coll->location;
     409        7566 :             result = (Node *) newcoll;
     410             :         }
     411        7566 :         return result;
     412             :     }
     413      298398 :     pathtype = find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
     414             :                                      &funcId);
     415      298398 :     if (pathtype != COERCION_PATH_NONE)
     416             :     {
     417             :         Oid         baseTypeId;
     418             :         int32       baseTypeMod;
     419             : 
     420      295046 :         baseTypeMod = targetTypeMod;
     421      295046 :         baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
     422             : 
     423      295046 :         if (pathtype != COERCION_PATH_RELABELTYPE)
     424             :         {
     425             :             /*
     426             :              * Generate an expression tree representing run-time application
     427             :              * of the conversion function.  If we are dealing with a domain
     428             :              * target type, the conversion function will yield the base type,
     429             :              * and we need to extract the correct typmod to use from the
     430             :              * domain's typtypmod.
     431             :              */
     432       91188 :             result = build_coercion_expression(node, pathtype, funcId,
     433             :                                                baseTypeId, baseTypeMod,
     434             :                                                ccontext, cformat, location);
     435             : 
     436             :             /*
     437             :              * If domain, coerce to the domain type and relabel with domain
     438             :              * type ID, hiding the previous coercion node.
     439             :              */
     440       91188 :             if (targetTypeId != baseTypeId)
     441        2324 :                 result = coerce_to_domain(result, baseTypeId, baseTypeMod,
     442             :                                           targetTypeId,
     443             :                                           ccontext, cformat, location,
     444             :                                           true);
     445             :         }
     446             :         else
     447             :         {
     448             :             /*
     449             :              * We don't need to do a physical conversion, but we do need to
     450             :              * attach a RelabelType node so that the expression will be seen
     451             :              * to have the intended type when inspected by higher-level code.
     452             :              *
     453             :              * Also, domains may have value restrictions beyond the base type
     454             :              * that must be accounted for.  If the destination is a domain
     455             :              * then we won't need a RelabelType node.
     456             :              */
     457      203858 :             result = coerce_to_domain(node, baseTypeId, baseTypeMod,
     458             :                                       targetTypeId,
     459             :                                       ccontext, cformat, location,
     460             :                                       false);
     461      203858 :             if (result == node)
     462             :             {
     463             :                 /*
     464             :                  * XXX could we label result with exprTypmod(node) instead of
     465             :                  * default -1 typmod, to save a possible length-coercion
     466             :                  * later? Would work if both types have same interpretation of
     467             :                  * typmod, which is likely but not certain.
     468             :                  */
     469      161876 :                 RelabelType *r = makeRelabelType((Expr *) result,
     470             :                                                  targetTypeId, -1,
     471             :                                                  InvalidOid,
     472             :                                                  cformat);
     473             : 
     474      161876 :                 r->location = location;
     475      161876 :                 result = (Node *) r;
     476             :             }
     477             :         }
     478      295046 :         return result;
     479             :     }
     480        5246 :     if (inputTypeId == RECORDOID &&
     481        1894 :         ISCOMPLEX(targetTypeId))
     482             :     {
     483             :         /* Coerce a RECORD to a specific complex type */
     484        1894 :         return coerce_record_to_complex(pstate, node, targetTypeId,
     485             :                                         ccontext, cformat, location);
     486             :     }
     487        2834 :     if (targetTypeId == RECORDOID &&
     488        1376 :         ISCOMPLEX(inputTypeId))
     489             :     {
     490             :         /* Coerce a specific complex type to RECORD */
     491             :         /* NB: we do NOT want a RelabelType here */
     492        1376 :         return node;
     493             :     }
     494             : #ifdef NOT_USED
     495             :     if (inputTypeId == RECORDARRAYOID &&
     496             :         is_complex_array(targetTypeId))
     497             :     {
     498             :         /* Coerce record[] to a specific complex array type */
     499             :         /* not implemented yet ... */
     500             :     }
     501             : #endif
     502          98 :     if (targetTypeId == RECORDARRAYOID &&
     503          16 :         is_complex_array(inputTypeId))
     504             :     {
     505             :         /* Coerce a specific complex array type to record[] */
     506             :         /* NB: we do NOT want a RelabelType here */
     507          16 :         return node;
     508             :     }
     509          66 :     if (typeInheritsFrom(inputTypeId, targetTypeId)
     510           6 :         || typeIsOfTypedTable(inputTypeId, targetTypeId))
     511             :     {
     512             :         /*
     513             :          * Input class type is a subclass of target, so generate an
     514             :          * appropriate runtime conversion (removing unneeded columns and
     515             :          * possibly rearranging the ones that are wanted).
     516             :          *
     517             :          * We will also get here when the input is a domain over a subclass of
     518             :          * the target type.  To keep life simple for the executor, we define
     519             :          * ConvertRowtypeExpr as only working between regular composite types;
     520             :          * therefore, in such cases insert a RelabelType to smash the input
     521             :          * expression down to its base type.
     522             :          */
     523          66 :         Oid         baseTypeId = getBaseType(inputTypeId);
     524          66 :         ConvertRowtypeExpr *r = makeNode(ConvertRowtypeExpr);
     525             : 
     526          66 :         if (baseTypeId != inputTypeId)
     527             :         {
     528           0 :             RelabelType *rt = makeRelabelType((Expr *) node,
     529             :                                               baseTypeId, -1,
     530             :                                               InvalidOid,
     531             :                                               COERCE_IMPLICIT_CAST);
     532             : 
     533           0 :             rt->location = location;
     534           0 :             node = (Node *) rt;
     535             :         }
     536          66 :         r->arg = (Expr *) node;
     537          66 :         r->resulttype = targetTypeId;
     538          66 :         r->convertformat = cformat;
     539          66 :         r->location = location;
     540          66 :         return (Node *) r;
     541             :     }
     542             :     /* If we get here, caller blew it */
     543           0 :     elog(ERROR, "failed to find conversion function from %s to %s",
     544             :          format_type_be(inputTypeId), format_type_be(targetTypeId));
     545             :     return NULL;                /* keep compiler quiet */
     546             : }
     547             : 
     548             : 
     549             : /*
     550             :  * can_coerce_type()
     551             :  *      Can input_typeids be coerced to target_typeids?
     552             :  *
     553             :  * We must be told the context (CAST construct, assignment, implicit coercion)
     554             :  * as this determines the set of available casts.
     555             :  */
     556             : bool
     557     2048332 : can_coerce_type(int nargs, const Oid *input_typeids, const Oid *target_typeids,
     558             :                 CoercionContext ccontext)
     559             : {
     560     2048332 :     bool        have_generics = false;
     561             :     int         i;
     562             : 
     563             :     /* run through argument list... */
     564     3694228 :     for (i = 0; i < nargs; i++)
     565             :     {
     566     2355656 :         Oid         inputTypeId = input_typeids[i];
     567     2355656 :         Oid         targetTypeId = target_typeids[i];
     568             :         CoercionPathType pathtype;
     569             :         Oid         funcId;
     570             : 
     571             :         /* no problem if same type */
     572     2355656 :         if (inputTypeId == targetTypeId)
     573     1645896 :             continue;
     574             : 
     575             :         /* accept if target is ANY */
     576     1865602 :         if (targetTypeId == ANYOID)
     577       58190 :             continue;
     578             : 
     579             :         /* accept if target is polymorphic, for now */
     580     1807412 :         if (IsPolymorphicType(targetTypeId))
     581             :         {
     582      184068 :             have_generics = true;   /* do more checking later */
     583      184068 :             continue;
     584             :         }
     585             : 
     586             :         /*
     587             :          * If input is an untyped string constant, assume we can convert it to
     588             :          * anything.
     589             :          */
     590     1623344 :         if (inputTypeId == UNKNOWNOID)
     591      647854 :             continue;
     592             : 
     593             :         /*
     594             :          * If pg_cast shows that we can coerce, accept.  This test now covers
     595             :          * both binary-compatible and coercion-function cases.
     596             :          */
     597      975490 :         pathtype = find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
     598             :                                          &funcId);
     599      975490 :         if (pathtype != COERCION_PATH_NONE)
     600      262672 :             continue;
     601             : 
     602             :         /*
     603             :          * If input is RECORD and target is a composite type, assume we can
     604             :          * coerce (may need tighter checking here)
     605             :          */
     606      714850 :         if (inputTypeId == RECORDOID &&
     607        2032 :             ISCOMPLEX(targetTypeId))
     608        1894 :             continue;
     609             : 
     610             :         /*
     611             :          * If input is a composite type and target is RECORD, accept
     612             :          */
     613      722732 :         if (targetTypeId == RECORDOID &&
     614       11808 :             ISCOMPLEX(inputTypeId))
     615        1098 :             continue;
     616             : 
     617             : #ifdef NOT_USED                 /* not implemented yet */
     618             : 
     619             :         /*
     620             :          * If input is record[] and target is a composite array type, assume
     621             :          * we can coerce (may need tighter checking here)
     622             :          */
     623             :         if (inputTypeId == RECORDARRAYOID &&
     624             :             is_complex_array(targetTypeId))
     625             :             continue;
     626             : #endif
     627             : 
     628             :         /*
     629             :          * If input is a composite array type and target is record[], accept
     630             :          */
     631      709838 :         if (targetTypeId == RECORDARRAYOID &&
     632          12 :             is_complex_array(inputTypeId))
     633           0 :             continue;
     634             : 
     635             :         /*
     636             :          * If input is a class type that inherits from target, accept
     637             :          */
     638      709826 :         if (typeInheritsFrom(inputTypeId, targetTypeId)
     639      709766 :             || typeIsOfTypedTable(inputTypeId, targetTypeId))
     640          66 :             continue;
     641             : 
     642             :         /*
     643             :          * Else, cannot coerce at this argument position
     644             :          */
     645      709760 :         return false;
     646             :     }
     647             : 
     648             :     /* If we found any generic argument types, cross-check them */
     649     1338572 :     if (have_generics)
     650             :     {
     651      125470 :         if (!check_generic_type_consistency(input_typeids, target_typeids,
     652             :                                             nargs))
     653       71976 :             return false;
     654             :     }
     655             : 
     656     1266596 :     return true;
     657             : }
     658             : 
     659             : 
     660             : /*
     661             :  * Create an expression tree to represent coercion to a domain type.
     662             :  *
     663             :  * 'arg': input expression
     664             :  * 'baseTypeId': base type of domain
     665             :  * 'baseTypeMod': base type typmod of domain
     666             :  * 'typeId': target type to coerce to
     667             :  * 'ccontext': context indicator to control coercions
     668             :  * 'cformat': coercion display format
     669             :  * 'location': coercion request location
     670             :  * 'hideInputCoercion': if true, hide the input coercion under this one.
     671             :  *
     672             :  * If the target type isn't a domain, the given 'arg' is returned as-is.
     673             :  */
     674             : Node *
     675      237290 : coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId,
     676             :                  CoercionContext ccontext, CoercionForm cformat, int location,
     677             :                  bool hideInputCoercion)
     678             : {
     679             :     CoerceToDomain *result;
     680             : 
     681             :     /* We now require the caller to supply correct baseTypeId/baseTypeMod */
     682             :     Assert(OidIsValid(baseTypeId));
     683             : 
     684             :     /* If it isn't a domain, return the node as it was passed in */
     685      237290 :     if (baseTypeId == typeId)
     686      161876 :         return arg;
     687             : 
     688             :     /* Suppress display of nested coercion steps */
     689       75414 :     if (hideInputCoercion)
     690        2324 :         hide_coercion_node(arg);
     691             : 
     692             :     /*
     693             :      * If the domain applies a typmod to its base type, build the appropriate
     694             :      * coercion step.  Mark it implicit for display purposes, because we don't
     695             :      * want it shown separately by ruleutils.c; but the isExplicit flag passed
     696             :      * to the conversion function depends on the manner in which the domain
     697             :      * coercion is invoked, so that the semantics of implicit and explicit
     698             :      * coercion differ.  (Is that really the behavior we want?)
     699             :      *
     700             :      * NOTE: because we apply this as part of the fixed expression structure,
     701             :      * ALTER DOMAIN cannot alter the typtypmod.  But it's unclear that that
     702             :      * would be safe to do anyway, without lots of knowledge about what the
     703             :      * base type thinks the typmod means.
     704             :      */
     705       75414 :     arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod,
     706             :                              ccontext, COERCE_IMPLICIT_CAST, location,
     707             :                              false);
     708             : 
     709             :     /*
     710             :      * Now build the domain coercion node.  This represents run-time checking
     711             :      * of any constraints currently attached to the domain.  This also ensures
     712             :      * that the expression is properly labeled as to result type.
     713             :      */
     714       75414 :     result = makeNode(CoerceToDomain);
     715       75414 :     result->arg = (Expr *) arg;
     716       75414 :     result->resulttype = typeId;
     717       75414 :     result->resulttypmod = -1;   /* currently, always -1 for domains */
     718             :     /* resultcollid will be set by parse_collate.c */
     719       75414 :     result->coercionformat = cformat;
     720       75414 :     result->location = location;
     721             : 
     722       75414 :     return (Node *) result;
     723             : }
     724             : 
     725             : 
     726             : /*
     727             :  * coerce_type_typmod()
     728             :  *      Force a value to a particular typmod, if meaningful and possible.
     729             :  *
     730             :  * This is applied to values that are going to be stored in a relation
     731             :  * (where we have an atttypmod for the column) as well as values being
     732             :  * explicitly CASTed (where the typmod comes from the target type spec).
     733             :  *
     734             :  * The caller must have already ensured that the value is of the correct
     735             :  * type, typically by applying coerce_type.
     736             :  *
     737             :  * ccontext may affect semantics, depending on whether the length coercion
     738             :  * function pays attention to the isExplicit flag it's passed.
     739             :  *
     740             :  * cformat determines the display properties of the generated node (if any).
     741             :  *
     742             :  * If hideInputCoercion is true *and* we generate a node, the input node is
     743             :  * forced to IMPLICIT display form, so that only the typmod coercion node will
     744             :  * be visible when displaying the expression.
     745             :  *
     746             :  * NOTE: this does not need to work on domain types, because any typmod
     747             :  * coercion for a domain is considered to be part of the type coercion
     748             :  * needed to produce the domain value in the first place.  So, no getBaseType.
     749             :  */
     750             : static Node *
     751      872284 : coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod,
     752             :                    CoercionContext ccontext, CoercionForm cformat,
     753             :                    int location,
     754             :                    bool hideInputCoercion)
     755             : {
     756             :     CoercionPathType pathtype;
     757             :     Oid         funcId;
     758             : 
     759             :     /* Skip coercion if already done */
     760      872284 :     if (targetTypMod == exprTypmod(node))
     761      853658 :         return node;
     762             : 
     763             :     /* Suppress display of nested coercion steps */
     764       18626 :     if (hideInputCoercion)
     765         982 :         hide_coercion_node(node);
     766             : 
     767             :     /*
     768             :      * A negative typmod means that no actual coercion is needed, but we still
     769             :      * want a RelabelType to ensure that the expression exposes the intended
     770             :      * typmod.
     771             :      */
     772       18626 :     if (targetTypMod < 0)
     773          30 :         pathtype = COERCION_PATH_NONE;
     774             :     else
     775       18596 :         pathtype = find_typmod_coercion_function(targetTypeId, &funcId);
     776             : 
     777       18626 :     if (pathtype != COERCION_PATH_NONE)
     778             :     {
     779       18584 :         node = build_coercion_expression(node, pathtype, funcId,
     780             :                                          targetTypeId, targetTypMod,
     781             :                                          ccontext, cformat, location);
     782             :     }
     783             :     else
     784             :     {
     785             :         /*
     786             :          * We don't need to perform any actual coercion step, but we should
     787             :          * apply a RelabelType to ensure that the expression exposes the
     788             :          * intended typmod.
     789             :          */
     790          42 :         node = applyRelabelType(node, targetTypeId, targetTypMod,
     791             :                                 exprCollation(node),
     792             :                                 cformat, location, false);
     793             :     }
     794             : 
     795       18626 :     return node;
     796             : }
     797             : 
     798             : /*
     799             :  * Mark a coercion node as IMPLICIT so it will never be displayed by
     800             :  * ruleutils.c.  We use this when we generate a nest of coercion nodes
     801             :  * to implement what is logically one conversion; the inner nodes are
     802             :  * forced to IMPLICIT_CAST format.  This does not change their semantics,
     803             :  * only display behavior.
     804             :  *
     805             :  * It is caller error to call this on something that doesn't have a
     806             :  * CoercionForm field.
     807             :  */
     808             : static void
     809        3306 : hide_coercion_node(Node *node)
     810             : {
     811        3306 :     if (IsA(node, FuncExpr))
     812        1546 :         ((FuncExpr *) node)->funcformat = COERCE_IMPLICIT_CAST;
     813        1760 :     else if (IsA(node, RelabelType))
     814         280 :         ((RelabelType *) node)->relabelformat = COERCE_IMPLICIT_CAST;
     815        1480 :     else if (IsA(node, CoerceViaIO))
     816        1468 :         ((CoerceViaIO *) node)->coerceformat = COERCE_IMPLICIT_CAST;
     817          12 :     else if (IsA(node, ArrayCoerceExpr))
     818          12 :         ((ArrayCoerceExpr *) node)->coerceformat = COERCE_IMPLICIT_CAST;
     819           0 :     else if (IsA(node, ConvertRowtypeExpr))
     820           0 :         ((ConvertRowtypeExpr *) node)->convertformat = COERCE_IMPLICIT_CAST;
     821           0 :     else if (IsA(node, RowExpr))
     822           0 :         ((RowExpr *) node)->row_format = COERCE_IMPLICIT_CAST;
     823           0 :     else if (IsA(node, CoerceToDomain))
     824           0 :         ((CoerceToDomain *) node)->coercionformat = COERCE_IMPLICIT_CAST;
     825             :     else
     826           0 :         elog(ERROR, "unsupported node type: %d", (int) nodeTag(node));
     827        3306 : }
     828             : 
     829             : /*
     830             :  * build_coercion_expression()
     831             :  *      Construct an expression tree for applying a pg_cast entry.
     832             :  *
     833             :  * This is used for both type-coercion and length-coercion operations,
     834             :  * since there is no difference in terms of the calling convention.
     835             :  */
     836             : static Node *
     837      109772 : build_coercion_expression(Node *node,
     838             :                           CoercionPathType pathtype,
     839             :                           Oid funcId,
     840             :                           Oid targetTypeId, int32 targetTypMod,
     841             :                           CoercionContext ccontext, CoercionForm cformat,
     842             :                           int location)
     843             : {
     844      109772 :     int         nargs = 0;
     845             : 
     846      109772 :     if (OidIsValid(funcId))
     847             :     {
     848             :         HeapTuple   tp;
     849             :         Form_pg_proc procstruct;
     850             : 
     851       81734 :         tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcId));
     852       81734 :         if (!HeapTupleIsValid(tp))
     853           0 :             elog(ERROR, "cache lookup failed for function %u", funcId);
     854       81734 :         procstruct = (Form_pg_proc) GETSTRUCT(tp);
     855             : 
     856             :         /*
     857             :          * These Asserts essentially check that function is a legal coercion
     858             :          * function.  We can't make the seemingly obvious tests on prorettype
     859             :          * and proargtypes[0], even in the COERCION_PATH_FUNC case, because of
     860             :          * various binary-compatibility cases.
     861             :          */
     862             :         /* Assert(targetTypeId == procstruct->prorettype); */
     863             :         Assert(!procstruct->proretset);
     864             :         Assert(procstruct->prokind == PROKIND_FUNCTION);
     865       81734 :         nargs = procstruct->pronargs;
     866             :         Assert(nargs >= 1 && nargs <= 3);
     867             :         /* Assert(procstruct->proargtypes.values[0] == exprType(node)); */
     868             :         Assert(nargs < 2 || procstruct->proargtypes.values[1] == INT4OID);
     869             :         Assert(nargs < 3 || procstruct->proargtypes.values[2] == BOOLOID);
     870             : 
     871       81734 :         ReleaseSysCache(tp);
     872             :     }
     873             : 
     874      109772 :     if (pathtype == COERCION_PATH_FUNC)
     875             :     {
     876             :         /* We build an ordinary FuncExpr with special arguments */
     877             :         FuncExpr   *fexpr;
     878             :         List       *args;
     879             :         Const      *cons;
     880             : 
     881             :         Assert(OidIsValid(funcId));
     882             : 
     883       81656 :         args = list_make1(node);
     884             : 
     885       81656 :         if (nargs >= 2)
     886             :         {
     887             :             /* Pass target typmod as an int4 constant */
     888       19778 :             cons = makeConst(INT4OID,
     889             :                              -1,
     890             :                              InvalidOid,
     891             :                              sizeof(int32),
     892             :                              Int32GetDatum(targetTypMod),
     893             :                              false,
     894             :                              true);
     895             : 
     896       19778 :             args = lappend(args, cons);
     897             :         }
     898             : 
     899       81656 :         if (nargs == 3)
     900             :         {
     901             :             /* Pass it a boolean isExplicit parameter, too */
     902       12012 :             cons = makeConst(BOOLOID,
     903             :                              -1,
     904             :                              InvalidOid,
     905             :                              sizeof(bool),
     906             :                              BoolGetDatum(ccontext == COERCION_EXPLICIT),
     907             :                              false,
     908             :                              true);
     909             : 
     910       12012 :             args = lappend(args, cons);
     911             :         }
     912             : 
     913       81656 :         fexpr = makeFuncExpr(funcId, targetTypeId, args,
     914             :                              InvalidOid, InvalidOid, cformat);
     915       81656 :         fexpr->location = location;
     916       81656 :         return (Node *) fexpr;
     917             :     }
     918       28116 :     else if (pathtype == COERCION_PATH_ARRAYCOERCE)
     919             :     {
     920             :         /* We need to build an ArrayCoerceExpr */
     921        5406 :         ArrayCoerceExpr *acoerce = makeNode(ArrayCoerceExpr);
     922        5406 :         CaseTestExpr *ctest = makeNode(CaseTestExpr);
     923             :         Oid         sourceBaseTypeId;
     924             :         int32       sourceBaseTypeMod;
     925             :         Oid         targetElementType;
     926             :         Node       *elemexpr;
     927             : 
     928             :         /*
     929             :          * Look through any domain over the source array type.  Note we don't
     930             :          * expect that the target type is a domain; it must be a plain array.
     931             :          * (To get to a domain target type, we'll do coerce_to_domain later.)
     932             :          */
     933        5406 :         sourceBaseTypeMod = exprTypmod(node);
     934        5406 :         sourceBaseTypeId = getBaseTypeAndTypmod(exprType(node),
     935             :                                                 &sourceBaseTypeMod);
     936             : 
     937             :         /*
     938             :          * Set up a CaseTestExpr representing one element of the source array.
     939             :          * This is an abuse of CaseTestExpr, but it's OK as long as there
     940             :          * can't be any CaseExpr or ArrayCoerceExpr within the completed
     941             :          * elemexpr.
     942             :          */
     943        5406 :         ctest->typeId = get_element_type(sourceBaseTypeId);
     944             :         Assert(OidIsValid(ctest->typeId));
     945        5406 :         ctest->typeMod = sourceBaseTypeMod;
     946        5406 :         ctest->collation = InvalidOid;   /* Assume coercions don't care */
     947             : 
     948             :         /* And coerce it to the target element type */
     949        5406 :         targetElementType = get_element_type(targetTypeId);
     950             :         Assert(OidIsValid(targetElementType));
     951             : 
     952        5406 :         elemexpr = coerce_to_target_type(NULL,
     953             :                                          (Node *) ctest,
     954             :                                          ctest->typeId,
     955             :                                          targetElementType,
     956             :                                          targetTypMod,
     957             :                                          ccontext,
     958             :                                          cformat,
     959             :                                          location);
     960        5406 :         if (elemexpr == NULL)   /* shouldn't happen */
     961           0 :             elog(ERROR, "failed to coerce array element type as expected");
     962             : 
     963        5406 :         acoerce->arg = (Expr *) node;
     964        5406 :         acoerce->elemexpr = (Expr *) elemexpr;
     965        5406 :         acoerce->resulttype = targetTypeId;
     966             : 
     967             :         /*
     968             :          * Label the output as having a particular element typmod only if we
     969             :          * ended up with a per-element expression that is labeled that way.
     970             :          */
     971        5406 :         acoerce->resulttypmod = exprTypmod(elemexpr);
     972             :         /* resultcollid will be set by parse_collate.c */
     973        5406 :         acoerce->coerceformat = cformat;
     974        5406 :         acoerce->location = location;
     975             : 
     976        5406 :         return (Node *) acoerce;
     977             :     }
     978       22710 :     else if (pathtype == COERCION_PATH_COERCEVIAIO)
     979             :     {
     980             :         /* We need to build a CoerceViaIO node */
     981       22710 :         CoerceViaIO *iocoerce = makeNode(CoerceViaIO);
     982             : 
     983             :         Assert(!OidIsValid(funcId));
     984             : 
     985       22710 :         iocoerce->arg = (Expr *) node;
     986       22710 :         iocoerce->resulttype = targetTypeId;
     987             :         /* resultcollid will be set by parse_collate.c */
     988       22710 :         iocoerce->coerceformat = cformat;
     989       22710 :         iocoerce->location = location;
     990             : 
     991       22710 :         return (Node *) iocoerce;
     992             :     }
     993             :     else
     994             :     {
     995           0 :         elog(ERROR, "unsupported pathtype %d in build_coercion_expression",
     996             :              (int) pathtype);
     997             :         return NULL;            /* keep compiler quiet */
     998             :     }
     999             : }
    1000             : 
    1001             : 
    1002             : /*
    1003             :  * coerce_record_to_complex
    1004             :  *      Coerce a RECORD to a specific composite type.
    1005             :  *
    1006             :  * Currently we only support this for inputs that are RowExprs or whole-row
    1007             :  * Vars.
    1008             :  */
    1009             : static Node *
    1010        1894 : coerce_record_to_complex(ParseState *pstate, Node *node,
    1011             :                          Oid targetTypeId,
    1012             :                          CoercionContext ccontext,
    1013             :                          CoercionForm cformat,
    1014             :                          int location)
    1015             : {
    1016             :     RowExpr    *rowexpr;
    1017             :     Oid         baseTypeId;
    1018        1894 :     int32       baseTypeMod = -1;
    1019             :     TupleDesc   tupdesc;
    1020        1894 :     List       *args = NIL;
    1021             :     List       *newargs;
    1022             :     int         i;
    1023             :     int         ucolno;
    1024             :     ListCell   *arg;
    1025             : 
    1026        1894 :     if (node && IsA(node, RowExpr))
    1027             :     {
    1028             :         /*
    1029             :          * Since the RowExpr must be of type RECORD, we needn't worry about it
    1030             :          * containing any dropped columns.
    1031             :          */
    1032        1894 :         args = ((RowExpr *) node)->args;
    1033             :     }
    1034           0 :     else if (node && IsA(node, Var) &&
    1035           0 :              ((Var *) node)->varattno == InvalidAttrNumber)
    1036           0 :     {
    1037           0 :         int         rtindex = ((Var *) node)->varno;
    1038           0 :         int         sublevels_up = ((Var *) node)->varlevelsup;
    1039           0 :         int         vlocation = ((Var *) node)->location;
    1040             :         ParseNamespaceItem *nsitem;
    1041             : 
    1042           0 :         nsitem = GetNSItemByRangeTablePosn(pstate, rtindex, sublevels_up);
    1043           0 :         args = expandNSItemVars(pstate, nsitem, sublevels_up, vlocation, NULL);
    1044             :     }
    1045             :     else
    1046           0 :         ereport(ERROR,
    1047             :                 (errcode(ERRCODE_CANNOT_COERCE),
    1048             :                  errmsg("cannot cast type %s to %s",
    1049             :                         format_type_be(RECORDOID),
    1050             :                         format_type_be(targetTypeId)),
    1051             :                  parser_coercion_errposition(pstate, location, node)));
    1052             : 
    1053             :     /*
    1054             :      * Look up the composite type, accounting for possibility that what we are
    1055             :      * given is a domain over composite.
    1056             :      */
    1057        1894 :     baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
    1058        1894 :     tupdesc = lookup_rowtype_tupdesc(baseTypeId, baseTypeMod);
    1059             : 
    1060             :     /* Process the fields */
    1061        1894 :     newargs = NIL;
    1062        1894 :     ucolno = 1;
    1063        1894 :     arg = list_head(args);
    1064        6270 :     for (i = 0; i < tupdesc->natts; i++)
    1065             :     {
    1066             :         Node       *expr;
    1067             :         Node       *cexpr;
    1068             :         Oid         exprtype;
    1069        4376 :         Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
    1070             : 
    1071             :         /* Fill in NULLs for dropped columns in rowtype */
    1072        4376 :         if (attr->attisdropped)
    1073             :         {
    1074             :             /*
    1075             :              * can't use atttypid here, but it doesn't really matter what type
    1076             :              * the Const claims to be.
    1077             :              */
    1078           6 :             newargs = lappend(newargs,
    1079           6 :                               makeNullConst(INT4OID, -1, InvalidOid));
    1080           6 :             continue;
    1081             :         }
    1082             : 
    1083        4370 :         if (arg == NULL)
    1084           0 :             ereport(ERROR,
    1085             :                     (errcode(ERRCODE_CANNOT_COERCE),
    1086             :                      errmsg("cannot cast type %s to %s",
    1087             :                             format_type_be(RECORDOID),
    1088             :                             format_type_be(targetTypeId)),
    1089             :                      errdetail("Input has too few columns."),
    1090             :                      parser_coercion_errposition(pstate, location, node)));
    1091        4370 :         expr = (Node *) lfirst(arg);
    1092        4370 :         exprtype = exprType(expr);
    1093             : 
    1094        4370 :         cexpr = coerce_to_target_type(pstate,
    1095             :                                       expr, exprtype,
    1096             :                                       attr->atttypid,
    1097             :                                       attr->atttypmod,
    1098             :                                       ccontext,
    1099             :                                       COERCE_IMPLICIT_CAST,
    1100             :                                       -1);
    1101        4370 :         if (cexpr == NULL)
    1102           0 :             ereport(ERROR,
    1103             :                     (errcode(ERRCODE_CANNOT_COERCE),
    1104             :                      errmsg("cannot cast type %s to %s",
    1105             :                             format_type_be(RECORDOID),
    1106             :                             format_type_be(targetTypeId)),
    1107             :                      errdetail("Cannot cast type %s to %s in column %d.",
    1108             :                                format_type_be(exprtype),
    1109             :                                format_type_be(attr->atttypid),
    1110             :                                ucolno),
    1111             :                      parser_coercion_errposition(pstate, location, expr)));
    1112        4370 :         newargs = lappend(newargs, cexpr);
    1113        4370 :         ucolno++;
    1114        4370 :         arg = lnext(args, arg);
    1115             :     }
    1116        1894 :     if (arg != NULL)
    1117           0 :         ereport(ERROR,
    1118             :                 (errcode(ERRCODE_CANNOT_COERCE),
    1119             :                  errmsg("cannot cast type %s to %s",
    1120             :                         format_type_be(RECORDOID),
    1121             :                         format_type_be(targetTypeId)),
    1122             :                  errdetail("Input has too many columns."),
    1123             :                  parser_coercion_errposition(pstate, location, node)));
    1124             : 
    1125        1894 :     ReleaseTupleDesc(tupdesc);
    1126             : 
    1127        1894 :     rowexpr = makeNode(RowExpr);
    1128        1894 :     rowexpr->args = newargs;
    1129        1894 :     rowexpr->row_typeid = baseTypeId;
    1130        1894 :     rowexpr->row_format = cformat;
    1131        1894 :     rowexpr->colnames = NIL; /* not needed for named target type */
    1132        1894 :     rowexpr->location = location;
    1133             : 
    1134             :     /* If target is a domain, apply constraints */
    1135        1894 :     if (baseTypeId != targetTypeId)
    1136             :     {
    1137         154 :         rowexpr->row_format = COERCE_IMPLICIT_CAST;
    1138         154 :         return coerce_to_domain((Node *) rowexpr,
    1139             :                                 baseTypeId, baseTypeMod,
    1140             :                                 targetTypeId,
    1141             :                                 ccontext, cformat, location,
    1142             :                                 false);
    1143             :     }
    1144             : 
    1145        1740 :     return (Node *) rowexpr;
    1146             : }
    1147             : 
    1148             : /*
    1149             :  * coerce_to_boolean()
    1150             :  *      Coerce an argument of a construct that requires boolean input
    1151             :  *      (AND, OR, NOT, etc).  Also check that input is not a set.
    1152             :  *
    1153             :  * Returns the possibly-transformed node tree.
    1154             :  *
    1155             :  * As with coerce_type, pstate may be NULL if no special unknown-Param
    1156             :  * processing is wanted.
    1157             :  */
    1158             : Node *
    1159      905232 : coerce_to_boolean(ParseState *pstate, Node *node,
    1160             :                   const char *constructName)
    1161             : {
    1162      905232 :     Oid         inputTypeId = exprType(node);
    1163             : 
    1164      905232 :     if (inputTypeId != BOOLOID)
    1165             :     {
    1166             :         Node       *newnode;
    1167             : 
    1168          72 :         newnode = coerce_to_target_type(pstate, node, inputTypeId,
    1169             :                                         BOOLOID, -1,
    1170             :                                         COERCION_ASSIGNMENT,
    1171             :                                         COERCE_IMPLICIT_CAST,
    1172             :                                         -1);
    1173          72 :         if (newnode == NULL)
    1174           6 :             ereport(ERROR,
    1175             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    1176             :             /* translator: first %s is name of a SQL construct, eg WHERE */
    1177             :                      errmsg("argument of %s must be type %s, not type %s",
    1178             :                             constructName, "boolean",
    1179             :                             format_type_be(inputTypeId)),
    1180             :                      parser_errposition(pstate, exprLocation(node))));
    1181          66 :         node = newnode;
    1182             :     }
    1183             : 
    1184      905226 :     if (expression_returns_set(node))
    1185           0 :         ereport(ERROR,
    1186             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    1187             :         /* translator: %s is name of a SQL construct, eg WHERE */
    1188             :                  errmsg("argument of %s must not return a set",
    1189             :                         constructName),
    1190             :                  parser_errposition(pstate, exprLocation(node))));
    1191             : 
    1192      905226 :     return node;
    1193             : }
    1194             : 
    1195             : /*
    1196             :  * coerce_to_specific_type_typmod()
    1197             :  *      Coerce an argument of a construct that requires a specific data type,
    1198             :  *      with a specific typmod.  Also check that input is not a set.
    1199             :  *
    1200             :  * Returns the possibly-transformed node tree.
    1201             :  *
    1202             :  * As with coerce_type, pstate may be NULL if no special unknown-Param
    1203             :  * processing is wanted.
    1204             :  */
    1205             : Node *
    1206       16830 : coerce_to_specific_type_typmod(ParseState *pstate, Node *node,
    1207             :                                Oid targetTypeId, int32 targetTypmod,
    1208             :                                const char *constructName)
    1209             : {
    1210       16830 :     Oid         inputTypeId = exprType(node);
    1211             : 
    1212       16830 :     if (inputTypeId != targetTypeId)
    1213             :     {
    1214             :         Node       *newnode;
    1215             : 
    1216       12240 :         newnode = coerce_to_target_type(pstate, node, inputTypeId,
    1217             :                                         targetTypeId, targetTypmod,
    1218             :                                         COERCION_ASSIGNMENT,
    1219             :                                         COERCE_IMPLICIT_CAST,
    1220             :                                         -1);
    1221       12228 :         if (newnode == NULL)
    1222           6 :             ereport(ERROR,
    1223             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    1224             :             /* translator: first %s is name of a SQL construct, eg LIMIT */
    1225             :                      errmsg("argument of %s must be type %s, not type %s",
    1226             :                             constructName,
    1227             :                             format_type_be(targetTypeId),
    1228             :                             format_type_be(inputTypeId)),
    1229             :                      parser_errposition(pstate, exprLocation(node))));
    1230       12222 :         node = newnode;
    1231             :     }
    1232             : 
    1233       16812 :     if (expression_returns_set(node))
    1234           0 :         ereport(ERROR,
    1235             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    1236             :         /* translator: %s is name of a SQL construct, eg LIMIT */
    1237             :                  errmsg("argument of %s must not return a set",
    1238             :                         constructName),
    1239             :                  parser_errposition(pstate, exprLocation(node))));
    1240             : 
    1241       16812 :     return node;
    1242             : }
    1243             : 
    1244             : /*
    1245             :  * coerce_to_specific_type()
    1246             :  *      Coerce an argument of a construct that requires a specific data type.
    1247             :  *      Also check that input is not a set.
    1248             :  *
    1249             :  * Returns the possibly-transformed node tree.
    1250             :  *
    1251             :  * As with coerce_type, pstate may be NULL if no special unknown-Param
    1252             :  * processing is wanted.
    1253             :  */
    1254             : Node *
    1255       16774 : coerce_to_specific_type(ParseState *pstate, Node *node,
    1256             :                         Oid targetTypeId,
    1257             :                         const char *constructName)
    1258             : {
    1259       16774 :     return coerce_to_specific_type_typmod(pstate, node,
    1260             :                                           targetTypeId, -1,
    1261             :                                           constructName);
    1262             : }
    1263             : 
    1264             : /*
    1265             :  * coerce_null_to_domain()
    1266             :  *      Build a NULL constant, then wrap it in CoerceToDomain
    1267             :  *      if the desired type is a domain type.  This allows any
    1268             :  *      NOT NULL domain constraint to be enforced at runtime.
    1269             :  */
    1270             : Node *
    1271       19044 : coerce_null_to_domain(Oid typid, int32 typmod, Oid collation,
    1272             :                       int typlen, bool typbyval)
    1273             : {
    1274             :     Node       *result;
    1275             :     Oid         baseTypeId;
    1276       19044 :     int32       baseTypeMod = typmod;
    1277             : 
    1278             :     /*
    1279             :      * The constant must appear to have the domain's base type/typmod, else
    1280             :      * coerce_to_domain() will apply a length coercion which is useless.
    1281             :      */
    1282       19044 :     baseTypeId = getBaseTypeAndTypmod(typid, &baseTypeMod);
    1283       19044 :     result = (Node *) makeConst(baseTypeId,
    1284             :                                 baseTypeMod,
    1285             :                                 collation,
    1286             :                                 typlen,
    1287             :                                 (Datum) 0,
    1288             :                                 true,   /* isnull */
    1289             :                                 typbyval);
    1290       19044 :     if (typid != baseTypeId)
    1291          78 :         result = coerce_to_domain(result,
    1292             :                                   baseTypeId, baseTypeMod,
    1293             :                                   typid,
    1294             :                                   COERCION_IMPLICIT,
    1295             :                                   COERCE_IMPLICIT_CAST,
    1296             :                                   -1,
    1297             :                                   false);
    1298       19044 :     return result;
    1299             : }
    1300             : 
    1301             : /*
    1302             :  * parser_coercion_errposition - report coercion error location, if possible
    1303             :  *
    1304             :  * We prefer to point at the coercion request (CAST, ::, etc) if possible;
    1305             :  * but there may be no such location in the case of an implicit coercion.
    1306             :  * In that case point at the input expression.
    1307             :  *
    1308             :  * XXX possibly this is more generally useful than coercion errors;
    1309             :  * if so, should rename and place with parser_errposition.
    1310             :  */
    1311             : int
    1312          22 : parser_coercion_errposition(ParseState *pstate,
    1313             :                             int coerce_location,
    1314             :                             Node *input_expr)
    1315             : {
    1316          22 :     if (coerce_location >= 0)
    1317          22 :         return parser_errposition(pstate, coerce_location);
    1318             :     else
    1319           0 :         return parser_errposition(pstate, exprLocation(input_expr));
    1320             : }
    1321             : 
    1322             : 
    1323             : /*
    1324             :  * select_common_type()
    1325             :  *      Determine the common supertype of a list of input expressions.
    1326             :  *      This is used for determining the output type of CASE, UNION,
    1327             :  *      and similar constructs.
    1328             :  *
    1329             :  * 'exprs' is a *nonempty* list of expressions.  Note that earlier items
    1330             :  * in the list will be preferred if there is doubt.
    1331             :  * 'context' is a phrase to use in the error message if we fail to select
    1332             :  * a usable type.  Pass NULL to have the routine return InvalidOid
    1333             :  * rather than throwing an error on failure.
    1334             :  * 'which_expr': if not NULL, receives a pointer to the particular input
    1335             :  * expression from which the result type was taken.
    1336             :  *
    1337             :  * Caution: "failure" just means that there were inputs of different type
    1338             :  * categories.  It is not guaranteed that all the inputs are coercible to the
    1339             :  * selected type; caller must check that (see verify_common_type).
    1340             :  */
    1341             : Oid
    1342      148986 : select_common_type(ParseState *pstate, List *exprs, const char *context,
    1343             :                    Node **which_expr)
    1344             : {
    1345             :     Node       *pexpr;
    1346             :     Oid         ptype;
    1347             :     TYPCATEGORY pcategory;
    1348             :     bool        pispreferred;
    1349             :     ListCell   *lc;
    1350             : 
    1351             :     Assert(exprs != NIL);
    1352      148986 :     pexpr = (Node *) linitial(exprs);
    1353      148986 :     lc = list_second_cell(exprs);
    1354      148986 :     ptype = exprType(pexpr);
    1355             : 
    1356             :     /*
    1357             :      * If all input types are valid and exactly the same, just pick that type.
    1358             :      * This is the only way that we will resolve the result as being a domain
    1359             :      * type; otherwise domains are smashed to their base types for comparison.
    1360             :      */
    1361      148986 :     if (ptype != UNKNOWNOID)
    1362             :     {
    1363      225886 :         for_each_cell(lc, exprs, lc)
    1364             :         {
    1365      147304 :             Node       *nexpr = (Node *) lfirst(lc);
    1366      147304 :             Oid         ntype = exprType(nexpr);
    1367             : 
    1368      147304 :             if (ntype != ptype)
    1369       39930 :                 break;
    1370             :         }
    1371      118512 :         if (lc == NULL)         /* got to the end of the list? */
    1372             :         {
    1373       78582 :             if (which_expr)
    1374       38882 :                 *which_expr = pexpr;
    1375       78582 :             return ptype;
    1376             :         }
    1377             :     }
    1378             : 
    1379             :     /*
    1380             :      * Nope, so set up for the full algorithm.  Note that at this point, lc
    1381             :      * points to the first list item with type different from pexpr's; we need
    1382             :      * not re-examine any items the previous loop advanced over.
    1383             :      */
    1384       70404 :     ptype = getBaseType(ptype);
    1385       70404 :     get_type_category_preferred(ptype, &pcategory, &pispreferred);
    1386             : 
    1387      206172 :     for_each_cell(lc, exprs, lc)
    1388             :     {
    1389      135780 :         Node       *nexpr = (Node *) lfirst(lc);
    1390      135780 :         Oid         ntype = getBaseType(exprType(nexpr));
    1391             : 
    1392             :         /* move on to next one if no new information... */
    1393      135780 :         if (ntype != UNKNOWNOID && ntype != ptype)
    1394             :         {
    1395             :             TYPCATEGORY ncategory;
    1396             :             bool        nispreferred;
    1397             : 
    1398       24146 :             get_type_category_preferred(ntype, &ncategory, &nispreferred);
    1399       24146 :             if (ptype == UNKNOWNOID)
    1400             :             {
    1401             :                 /* so far, only unknowns so take anything... */
    1402       17030 :                 pexpr = nexpr;
    1403       17030 :                 ptype = ntype;
    1404       17030 :                 pcategory = ncategory;
    1405       17030 :                 pispreferred = nispreferred;
    1406             :             }
    1407        7116 :             else if (ncategory != pcategory)
    1408             :             {
    1409             :                 /*
    1410             :                  * both types in different categories? then not much hope...
    1411             :                  */
    1412          12 :                 if (context == NULL)
    1413           0 :                     return InvalidOid;
    1414          12 :                 ereport(ERROR,
    1415             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    1416             :                 /*------
    1417             :                   translator: first %s is name of a SQL construct, eg CASE */
    1418             :                          errmsg("%s types %s and %s cannot be matched",
    1419             :                                 context,
    1420             :                                 format_type_be(ptype),
    1421             :                                 format_type_be(ntype)),
    1422             :                          parser_errposition(pstate, exprLocation(nexpr))));
    1423             :             }
    1424        9294 :             else if (!pispreferred &&
    1425        2190 :                      can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
    1426        1408 :                      !can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
    1427             :             {
    1428             :                 /*
    1429             :                  * take new type if can coerce to it implicitly but not the
    1430             :                  * other way; but if we have a preferred type, stay on it.
    1431             :                  */
    1432        1226 :                 pexpr = nexpr;
    1433        1226 :                 ptype = ntype;
    1434        1226 :                 pcategory = ncategory;
    1435        1226 :                 pispreferred = nispreferred;
    1436             :             }
    1437             :         }
    1438             :     }
    1439             : 
    1440             :     /*
    1441             :      * If all the inputs were UNKNOWN type --- ie, unknown-type literals ---
    1442             :      * then resolve as type TEXT.  This situation comes up with constructs
    1443             :      * like SELECT (CASE WHEN foo THEN 'bar' ELSE 'baz' END); SELECT 'foo'
    1444             :      * UNION SELECT 'bar'; It might seem desirable to leave the construct's
    1445             :      * output type as UNKNOWN, but that really doesn't work, because we'd
    1446             :      * probably end up needing a runtime coercion from UNKNOWN to something
    1447             :      * else, and we usually won't have it.  We need to coerce the unknown
    1448             :      * literals while they are still literals, so a decision has to be made
    1449             :      * now.
    1450             :      */
    1451       70392 :     if (ptype == UNKNOWNOID)
    1452       13444 :         ptype = TEXTOID;
    1453             : 
    1454       70392 :     if (which_expr)
    1455       14824 :         *which_expr = pexpr;
    1456       70392 :     return ptype;
    1457             : }
    1458             : 
    1459             : /*
    1460             :  * select_common_type_from_oids()
    1461             :  *      Determine the common supertype of an array of type OIDs.
    1462             :  *
    1463             :  * This is the same logic as select_common_type(), but working from
    1464             :  * an array of type OIDs not a list of expressions.  As in that function,
    1465             :  * earlier entries in the array have some preference over later ones.
    1466             :  * On failure, return InvalidOid if noerror is true, else throw an error.
    1467             :  *
    1468             :  * Caution: "failure" just means that there were inputs of different type
    1469             :  * categories.  It is not guaranteed that all the inputs are coercible to the
    1470             :  * selected type; caller must check that (see verify_common_type_from_oids).
    1471             :  *
    1472             :  * Note: neither caller will pass any UNKNOWNOID entries, so the tests
    1473             :  * for that in this function are dead code.  However, they don't cost much,
    1474             :  * and it seems better to keep this logic as close to select_common_type()
    1475             :  * as possible.
    1476             :  */
    1477             : static Oid
    1478        7340 : select_common_type_from_oids(int nargs, const Oid *typeids, bool noerror)
    1479             : {
    1480             :     Oid         ptype;
    1481             :     TYPCATEGORY pcategory;
    1482             :     bool        pispreferred;
    1483        7340 :     int         i = 1;
    1484             : 
    1485             :     Assert(nargs > 0);
    1486        7340 :     ptype = typeids[0];
    1487             : 
    1488             :     /* If all input types are valid and exactly the same, pick that type. */
    1489        7340 :     if (ptype != UNKNOWNOID)
    1490             :     {
    1491       10890 :         for (; i < nargs; i++)
    1492             :         {
    1493        4652 :             if (typeids[i] != ptype)
    1494        1102 :                 break;
    1495             :         }
    1496        7340 :         if (i == nargs)
    1497        6238 :             return ptype;
    1498             :     }
    1499             : 
    1500             :     /*
    1501             :      * Nope, so set up for the full algorithm.  Note that at this point, we
    1502             :      * can skip array entries before "i"; they are all equal to ptype.
    1503             :      */
    1504        1102 :     ptype = getBaseType(ptype);
    1505        1102 :     get_type_category_preferred(ptype, &pcategory, &pispreferred);
    1506             : 
    1507        1606 :     for (; i < nargs; i++)
    1508             :     {
    1509        1156 :         Oid         ntype = getBaseType(typeids[i]);
    1510             : 
    1511             :         /* move on to next one if no new information... */
    1512        1156 :         if (ntype != UNKNOWNOID && ntype != ptype)
    1513             :         {
    1514             :             TYPCATEGORY ncategory;
    1515             :             bool        nispreferred;
    1516             : 
    1517        1144 :             get_type_category_preferred(ntype, &ncategory, &nispreferred);
    1518        1144 :             if (ptype == UNKNOWNOID)
    1519             :             {
    1520             :                 /* so far, only unknowns so take anything... */
    1521           0 :                 ptype = ntype;
    1522           0 :                 pcategory = ncategory;
    1523           0 :                 pispreferred = nispreferred;
    1524             :             }
    1525        1144 :             else if (ncategory != pcategory)
    1526             :             {
    1527             :                 /*
    1528             :                  * both types in different categories? then not much hope...
    1529             :                  */
    1530         652 :                 if (noerror)
    1531         652 :                     return InvalidOid;
    1532           0 :                 ereport(ERROR,
    1533             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    1534             :                          errmsg("argument types %s and %s cannot be matched",
    1535             :                                 format_type_be(ptype),
    1536             :                                 format_type_be(ntype))));
    1537             :             }
    1538         912 :             else if (!pispreferred &&
    1539         420 :                      can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
    1540         270 :                      !can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
    1541             :             {
    1542             :                 /*
    1543             :                  * take new type if can coerce to it implicitly but not the
    1544             :                  * other way; but if we have a preferred type, stay on it.
    1545             :                  */
    1546         270 :                 ptype = ntype;
    1547         270 :                 pcategory = ncategory;
    1548         270 :                 pispreferred = nispreferred;
    1549             :             }
    1550             :         }
    1551             :     }
    1552             : 
    1553             :     /* Like select_common_type(), choose TEXT if all inputs were UNKNOWN */
    1554         450 :     if (ptype == UNKNOWNOID)
    1555           0 :         ptype = TEXTOID;
    1556             : 
    1557         450 :     return ptype;
    1558             : }
    1559             : 
    1560             : /*
    1561             :  * coerce_to_common_type()
    1562             :  *      Coerce an expression to the given type.
    1563             :  *
    1564             :  * This is used following select_common_type() to coerce the individual
    1565             :  * expressions to the desired type.  'context' is a phrase to use in the
    1566             :  * error message if we fail to coerce.
    1567             :  *
    1568             :  * As with coerce_type, pstate may be NULL if no special unknown-Param
    1569             :  * processing is wanted.
    1570             :  */
    1571             : Node *
    1572      371090 : coerce_to_common_type(ParseState *pstate, Node *node,
    1573             :                       Oid targetTypeId, const char *context)
    1574             : {
    1575      371090 :     Oid         inputTypeId = exprType(node);
    1576             : 
    1577      371090 :     if (inputTypeId == targetTypeId)
    1578      229878 :         return node;            /* no work */
    1579      141212 :     if (can_coerce_type(1, &inputTypeId, &targetTypeId, COERCION_IMPLICIT))
    1580      141212 :         node = coerce_type(pstate, node, inputTypeId, targetTypeId, -1,
    1581             :                            COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1);
    1582             :     else
    1583           0 :         ereport(ERROR,
    1584             :                 (errcode(ERRCODE_CANNOT_COERCE),
    1585             :         /* translator: first %s is name of a SQL construct, eg CASE */
    1586             :                  errmsg("%s could not convert type %s to %s",
    1587             :                         context,
    1588             :                         format_type_be(inputTypeId),
    1589             :                         format_type_be(targetTypeId)),
    1590             :                  parser_errposition(pstate, exprLocation(node))));
    1591      141206 :     return node;
    1592             : }
    1593             : 
    1594             : /*
    1595             :  * verify_common_type()
    1596             :  *      Verify that all input types can be coerced to a proposed common type.
    1597             :  *      Return true if so, false if not all coercions are possible.
    1598             :  *
    1599             :  * Most callers of select_common_type() don't need to do this explicitly
    1600             :  * because the checks will happen while trying to convert input expressions
    1601             :  * to the right type, e.g. in coerce_to_common_type().  However, if a separate
    1602             :  * check step is needed to validate the applicability of the common type, call
    1603             :  * this.
    1604             :  */
    1605             : bool
    1606       18734 : verify_common_type(Oid common_type, List *exprs)
    1607             : {
    1608             :     ListCell   *lc;
    1609             : 
    1610       91268 :     foreach(lc, exprs)
    1611             :     {
    1612       72540 :         Node       *nexpr = (Node *) lfirst(lc);
    1613       72540 :         Oid         ntype = exprType(nexpr);
    1614             : 
    1615       72540 :         if (!can_coerce_type(1, &ntype, &common_type, COERCION_IMPLICIT))
    1616           6 :             return false;
    1617             :     }
    1618       18728 :     return true;
    1619             : }
    1620             : 
    1621             : /*
    1622             :  * verify_common_type_from_oids()
    1623             :  *      As above, but work from an array of type OIDs.
    1624             :  */
    1625             : static bool
    1626        6688 : verify_common_type_from_oids(Oid common_type, int nargs, const Oid *typeids)
    1627             : {
    1628       17418 :     for (int i = 0; i < nargs; i++)
    1629             :     {
    1630       10742 :         if (!can_coerce_type(1, &typeids[i], &common_type, COERCION_IMPLICIT))
    1631          12 :             return false;
    1632             :     }
    1633        6676 :     return true;
    1634             : }
    1635             : 
    1636             : /*
    1637             :  * select_common_typmod()
    1638             :  *      Determine the common typmod of a list of input expressions.
    1639             :  *
    1640             :  * common_type is the selected common type of the expressions, typically
    1641             :  * computed using select_common_type().
    1642             :  */
    1643             : int32
    1644       64070 : select_common_typmod(ParseState *pstate, List *exprs, Oid common_type)
    1645             : {
    1646             :     ListCell   *lc;
    1647       64070 :     bool        first = true;
    1648       64070 :     int32       result = -1;
    1649             : 
    1650      204788 :     foreach(lc, exprs)
    1651             :     {
    1652      140940 :         Node       *expr = (Node *) lfirst(lc);
    1653             : 
    1654             :         /* Types must match */
    1655      140940 :         if (exprType(expr) != common_type)
    1656         222 :             return -1;
    1657      140760 :         else if (first)
    1658             :         {
    1659       63980 :             result = exprTypmod(expr);
    1660       63980 :             first = false;
    1661             :         }
    1662             :         else
    1663             :         {
    1664             :             /* As soon as we see a non-matching typmod, fall back to -1 */
    1665       76780 :             if (result != exprTypmod(expr))
    1666          42 :                 return -1;
    1667             :         }
    1668             :     }
    1669             : 
    1670       63848 :     return result;
    1671             : }
    1672             : 
    1673             : /*
    1674             :  * check_generic_type_consistency()
    1675             :  *      Are the actual arguments potentially compatible with a
    1676             :  *      polymorphic function?
    1677             :  *
    1678             :  * The argument consistency rules are:
    1679             :  *
    1680             :  * 1) All arguments declared ANYELEMENT must have the same datatype.
    1681             :  * 2) All arguments declared ANYARRAY must have the same datatype,
    1682             :  *    which must be a varlena array type.
    1683             :  * 3) All arguments declared ANYRANGE must be the same range type.
    1684             :  *    Similarly, all arguments declared ANYMULTIRANGE must be the same
    1685             :  *    multirange type; and if both of these appear, the ANYRANGE type
    1686             :  *    must be the element type of the ANYMULTIRANGE type.
    1687             :  * 4) If there are arguments of more than one of these polymorphic types,
    1688             :  *    the array element type and/or range subtype must be the same as each
    1689             :  *    other and the same as the ANYELEMENT type.
    1690             :  * 5) ANYENUM is treated the same as ANYELEMENT except that if it is used
    1691             :  *    (alone or in combination with plain ANYELEMENT), we add the extra
    1692             :  *    condition that the ANYELEMENT type must be an enum.
    1693             :  * 6) ANYNONARRAY is treated the same as ANYELEMENT except that if it is used,
    1694             :  *    we add the extra condition that the ANYELEMENT type must not be an array.
    1695             :  *    (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
    1696             :  *    is an extra restriction if not.)
    1697             :  * 7) All arguments declared ANYCOMPATIBLE must be implicitly castable
    1698             :  *    to a common supertype (chosen as per select_common_type's rules).
    1699             :  *    ANYCOMPATIBLENONARRAY works like ANYCOMPATIBLE but also requires the
    1700             :  *    common supertype to not be an array.  If there are ANYCOMPATIBLEARRAY
    1701             :  *    or ANYCOMPATIBLERANGE or ANYCOMPATIBLEMULTIRANGE arguments, their element
    1702             :  *    types or subtypes are included while making the choice of common supertype.
    1703             :  * 8) The resolved type of ANYCOMPATIBLEARRAY arguments will be the array
    1704             :  *    type over the common supertype (which might not be the same array type
    1705             :  *    as any of the original arrays).
    1706             :  * 9) All ANYCOMPATIBLERANGE arguments must be the exact same range type
    1707             :  *    (after domain flattening), since we have no preference rule that would
    1708             :  *    let us choose one over another.  Furthermore, that range's subtype
    1709             :  *    must exactly match the common supertype chosen by rule 7.
    1710             :  * 10) All ANYCOMPATIBLEMULTIRANGE arguments must be the exact same multirange
    1711             :  *    type (after domain flattening), since we have no preference rule that
    1712             :  *    would let us choose one over another.  Furthermore, if ANYCOMPATIBLERANGE
    1713             :  *    also appears, that range type must be the multirange's element type;
    1714             :  *    otherwise, the multirange's range's subtype must exactly match the
    1715             :  *    common supertype chosen by rule 7.
    1716             :  *
    1717             :  * Domains over arrays match ANYARRAY, and are immediately flattened to their
    1718             :  * base type.  (Thus, for example, we will consider it a match if one ANYARRAY
    1719             :  * argument is a domain over int4[] while another one is just int4[].)  Also
    1720             :  * notice that such a domain does *not* match ANYNONARRAY.  The same goes
    1721             :  * for ANYCOMPATIBLEARRAY and ANYCOMPATIBLENONARRAY.
    1722             :  *
    1723             :  * Similarly, domains over ranges match ANYRANGE or ANYCOMPATIBLERANGE,
    1724             :  * and are immediately flattened to their base type.  Likewise, domains
    1725             :  * over multiranges match ANYMULTIRANGE or ANYCOMPATIBLEMULTIRANGE and are
    1726             :  * immediately flattened to their base type.
    1727             :  *
    1728             :  * Note that domains aren't currently considered to match ANYENUM,
    1729             :  * even if their base type would match.
    1730             :  *
    1731             :  * If we have UNKNOWN input (ie, an untyped literal) for any polymorphic
    1732             :  * argument, assume it is okay.
    1733             :  *
    1734             :  * We do not ereport here, but just return false if a rule is violated.
    1735             :  */
    1736             : bool
    1737      125470 : check_generic_type_consistency(const Oid *actual_arg_types,
    1738             :                                const Oid *declared_arg_types,
    1739             :                                int nargs)
    1740             : {
    1741      125470 :     Oid         elem_typeid = InvalidOid;
    1742      125470 :     Oid         array_typeid = InvalidOid;
    1743      125470 :     Oid         range_typeid = InvalidOid;
    1744      125470 :     Oid         multirange_typeid = InvalidOid;
    1745      125470 :     Oid         anycompatible_range_typeid = InvalidOid;
    1746      125470 :     Oid         anycompatible_range_typelem = InvalidOid;
    1747      125470 :     Oid         anycompatible_multirange_typeid = InvalidOid;
    1748      125470 :     Oid         anycompatible_multirange_typelem = InvalidOid;
    1749      125470 :     Oid         range_typelem = InvalidOid;
    1750      125470 :     bool        have_anynonarray = false;
    1751      125470 :     bool        have_anyenum = false;
    1752      125470 :     bool        have_anycompatible_nonarray = false;
    1753      125470 :     int         n_anycompatible_args = 0;
    1754             :     Oid         anycompatible_actual_types[FUNC_MAX_ARGS];
    1755             : 
    1756             :     /*
    1757             :      * Loop through the arguments to see if we have any that are polymorphic.
    1758             :      * If so, require the actual types to be consistent.
    1759             :      */
    1760             :     Assert(nargs <= FUNC_MAX_ARGS);
    1761      291366 :     for (int j = 0; j < nargs; j++)
    1762             :     {
    1763      200144 :         Oid         decl_type = declared_arg_types[j];
    1764      200144 :         Oid         actual_type = actual_arg_types[j];
    1765             : 
    1766      200144 :         if (decl_type == ANYELEMENTOID ||
    1767      177688 :             decl_type == ANYNONARRAYOID ||
    1768             :             decl_type == ANYENUMOID)
    1769             :         {
    1770       44448 :             if (decl_type == ANYNONARRAYOID)
    1771       16578 :                 have_anynonarray = true;
    1772       27870 :             else if (decl_type == ANYENUMOID)
    1773       21992 :                 have_anyenum = true;
    1774       44448 :             if (actual_type == UNKNOWNOID)
    1775        2572 :                 continue;
    1776       41876 :             if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
    1777        7668 :                 return false;
    1778       34208 :             elem_typeid = actual_type;
    1779             :         }
    1780      155696 :         else if (decl_type == ANYARRAYOID)
    1781             :         {
    1782       59702 :             if (actual_type == UNKNOWNOID)
    1783        2854 :                 continue;
    1784       56848 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1785       56848 :             if (OidIsValid(array_typeid) && actual_type != array_typeid)
    1786        7638 :                 return false;
    1787       49210 :             array_typeid = actual_type;
    1788             :         }
    1789       95994 :         else if (decl_type == ANYRANGEOID)
    1790             :         {
    1791       32068 :             if (actual_type == UNKNOWNOID)
    1792        2138 :                 continue;
    1793       29930 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1794       29930 :             if (OidIsValid(range_typeid) && actual_type != range_typeid)
    1795        8466 :                 return false;
    1796       21464 :             range_typeid = actual_type;
    1797             :         }
    1798       63926 :         else if (decl_type == ANYMULTIRANGEOID)
    1799             :         {
    1800       35862 :             if (actual_type == UNKNOWNOID)
    1801        2156 :                 continue;
    1802       33706 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1803       33706 :             if (OidIsValid(multirange_typeid) && actual_type != multirange_typeid)
    1804        8460 :                 return false;
    1805       25246 :             multirange_typeid = actual_type;
    1806             :         }
    1807       28064 :         else if (decl_type == ANYCOMPATIBLEOID ||
    1808             :                  decl_type == ANYCOMPATIBLENONARRAYOID)
    1809             :         {
    1810        4066 :             if (decl_type == ANYCOMPATIBLENONARRAYOID)
    1811          36 :                 have_anycompatible_nonarray = true;
    1812        4066 :             if (actual_type == UNKNOWNOID)
    1813        1446 :                 continue;
    1814             :             /* collect the actual types of non-unknown COMPATIBLE args */
    1815        2620 :             anycompatible_actual_types[n_anycompatible_args++] = actual_type;
    1816             :         }
    1817       23998 :         else if (decl_type == ANYCOMPATIBLEARRAYOID)
    1818             :         {
    1819             :             Oid         elem_type;
    1820             : 
    1821        5970 :             if (actual_type == UNKNOWNOID)
    1822         952 :                 continue;
    1823        5018 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1824        5018 :             elem_type = get_element_type(actual_type);
    1825        5018 :             if (!OidIsValid(elem_type))
    1826        1992 :                 return false;   /* not an array */
    1827             :             /* collect the element type for common-supertype choice */
    1828        3026 :             anycompatible_actual_types[n_anycompatible_args++] = elem_type;
    1829             :         }
    1830       18028 :         else if (decl_type == ANYCOMPATIBLERANGEOID)
    1831             :         {
    1832         186 :             if (actual_type == UNKNOWNOID)
    1833          12 :                 continue;
    1834         174 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1835         174 :             if (OidIsValid(anycompatible_range_typeid))
    1836             :             {
    1837             :                 /* All ANYCOMPATIBLERANGE arguments must be the same type */
    1838          12 :                 if (anycompatible_range_typeid != actual_type)
    1839           6 :                     return false;
    1840             :             }
    1841             :             else
    1842             :             {
    1843         162 :                 anycompatible_range_typeid = actual_type;
    1844         162 :                 anycompatible_range_typelem = get_range_subtype(actual_type);
    1845         162 :                 if (!OidIsValid(anycompatible_range_typelem))
    1846           6 :                     return false;   /* not a range type */
    1847             :                 /* collect the subtype for common-supertype choice */
    1848         156 :                 anycompatible_actual_types[n_anycompatible_args++] = anycompatible_range_typelem;
    1849             :             }
    1850             :         }
    1851       17842 :         else if (decl_type == ANYCOMPATIBLEMULTIRANGEOID)
    1852             :         {
    1853         138 :             if (actual_type == UNKNOWNOID)
    1854          18 :                 continue;
    1855         120 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1856         120 :             if (OidIsValid(anycompatible_multirange_typeid))
    1857             :             {
    1858             :                 /* All ANYCOMPATIBLEMULTIRANGE arguments must be the same type */
    1859          12 :                 if (anycompatible_multirange_typeid != actual_type)
    1860           6 :                     return false;
    1861             :             }
    1862             :             else
    1863             :             {
    1864         108 :                 anycompatible_multirange_typeid = actual_type;
    1865         108 :                 anycompatible_multirange_typelem = get_multirange_range(actual_type);
    1866         108 :                 if (!OidIsValid(anycompatible_multirange_typelem))
    1867           6 :                     return false;   /* not a multirange type */
    1868             :                 /* we'll consider the subtype below */
    1869             :             }
    1870             :         }
    1871             :     }
    1872             : 
    1873             :     /* Get the element type based on the array type, if we have one */
    1874       91222 :     if (OidIsValid(array_typeid))
    1875             :     {
    1876       39452 :         if (array_typeid == ANYARRAYOID)
    1877             :         {
    1878             :             /*
    1879             :              * Special case for matching ANYARRAY input to an ANYARRAY
    1880             :              * argument: allow it for now.  enforce_generic_type_consistency()
    1881             :              * might complain later, depending on the presence of other
    1882             :              * polymorphic arguments or results, but it will deliver a less
    1883             :              * surprising error message than "function does not exist".
    1884             :              *
    1885             :              * (If you think to change this, note that can_coerce_type will
    1886             :              * consider such a situation as a match, so that we might not even
    1887             :              * get here.)
    1888             :              */
    1889             :         }
    1890             :         else
    1891             :         {
    1892             :             Oid         array_typelem;
    1893             : 
    1894       39452 :             array_typelem = get_element_type(array_typeid);
    1895       39452 :             if (!OidIsValid(array_typelem))
    1896       16388 :                 return false;   /* should be an array, but isn't */
    1897             : 
    1898       23064 :             if (!OidIsValid(elem_typeid))
    1899             :             {
    1900             :                 /*
    1901             :                  * if we don't have an element type yet, use the one we just
    1902             :                  * got
    1903             :                  */
    1904       22932 :                 elem_typeid = array_typelem;
    1905             :             }
    1906         132 :             else if (array_typelem != elem_typeid)
    1907             :             {
    1908             :                 /* otherwise, they better match */
    1909          50 :                 return false;
    1910             :             }
    1911             :         }
    1912             :     }
    1913             : 
    1914             :     /* Deduce range type from multirange type, or check that they agree */
    1915       74784 :     if (OidIsValid(multirange_typeid))
    1916             :     {
    1917             :         Oid         multirange_typelem;
    1918             : 
    1919       14340 :         multirange_typelem = get_multirange_range(multirange_typeid);
    1920       14340 :         if (!OidIsValid(multirange_typelem))
    1921       11998 :             return false;       /* should be a multirange, but isn't */
    1922             : 
    1923        2342 :         if (!OidIsValid(range_typeid))
    1924             :         {
    1925             :             /* If we don't have a range type yet, use the one we just got */
    1926        1802 :             range_typeid = multirange_typelem;
    1927        1802 :             range_typelem = get_range_subtype(multirange_typelem);
    1928        1802 :             if (!OidIsValid(range_typelem))
    1929           0 :                 return false;   /* should be a range, but isn't */
    1930             :         }
    1931         540 :         else if (multirange_typelem != range_typeid)
    1932             :         {
    1933             :             /* otherwise, they better match */
    1934         306 :             return false;
    1935             :         }
    1936             :     }
    1937             : 
    1938             :     /* Get the element type based on the range type, if we have one */
    1939       62480 :     if (OidIsValid(range_typeid))
    1940             :     {
    1941       10370 :         range_typelem = get_range_subtype(range_typeid);
    1942       10370 :         if (!OidIsValid(range_typelem))
    1943        4642 :             return false;       /* should be a range, but isn't */
    1944             : 
    1945        5728 :         if (!OidIsValid(elem_typeid))
    1946             :         {
    1947             :             /*
    1948             :              * If we don't have an element type yet, use the one we just got
    1949             :              */
    1950        5306 :             elem_typeid = range_typelem;
    1951             :         }
    1952         422 :         else if (range_typelem != elem_typeid)
    1953             :         {
    1954             :             /* otherwise, they better match */
    1955         190 :             return false;
    1956             :         }
    1957             :     }
    1958             : 
    1959       57648 :     if (have_anynonarray)
    1960             :     {
    1961             :         /* require the element type to not be an array or domain over array */
    1962       16226 :         if (type_is_array_domain(elem_typeid))
    1963         262 :             return false;
    1964             :     }
    1965             : 
    1966       57386 :     if (have_anyenum)
    1967             :     {
    1968             :         /* require the element type to be an enum */
    1969        3542 :         if (!type_is_enum(elem_typeid))
    1970        3174 :             return false;
    1971             :     }
    1972             : 
    1973             :     /* Deduce range type from multirange type, or check that they agree */
    1974       54212 :     if (OidIsValid(anycompatible_multirange_typeid))
    1975             :     {
    1976          96 :         if (OidIsValid(anycompatible_range_typeid))
    1977             :         {
    1978          12 :             if (anycompatible_multirange_typelem !=
    1979             :                 anycompatible_range_typeid)
    1980           6 :                 return false;
    1981             :         }
    1982             :         else
    1983             :         {
    1984          84 :             anycompatible_range_typeid = anycompatible_multirange_typelem;
    1985          84 :             anycompatible_range_typelem = get_range_subtype(anycompatible_range_typeid);
    1986          84 :             if (!OidIsValid(anycompatible_range_typelem))
    1987           0 :                 return false;   /* not a range type */
    1988             :             /* collect the subtype for common-supertype choice */
    1989          84 :             anycompatible_actual_types[n_anycompatible_args++] =
    1990             :                 anycompatible_range_typelem;
    1991             :         }
    1992             :     }
    1993             : 
    1994             :     /* Check matching of ANYCOMPATIBLE-family arguments, if any */
    1995       54206 :     if (n_anycompatible_args > 0)
    1996             :     {
    1997             :         Oid         anycompatible_typeid;
    1998             : 
    1999             :         anycompatible_typeid =
    2000        3468 :             select_common_type_from_oids(n_anycompatible_args,
    2001             :                                          anycompatible_actual_types,
    2002             :                                          true);
    2003             : 
    2004        3468 :         if (!OidIsValid(anycompatible_typeid))
    2005         652 :             return false;       /* there's definitely no common supertype */
    2006             : 
    2007             :         /* We have to verify that the selected type actually works */
    2008        2816 :         if (!verify_common_type_from_oids(anycompatible_typeid,
    2009             :                                           n_anycompatible_args,
    2010             :                                           anycompatible_actual_types))
    2011          12 :             return false;
    2012             : 
    2013        2804 :         if (have_anycompatible_nonarray)
    2014             :         {
    2015             :             /*
    2016             :              * require the anycompatible type to not be an array or domain
    2017             :              * over array
    2018             :              */
    2019          18 :             if (type_is_array_domain(anycompatible_typeid))
    2020           6 :                 return false;
    2021             :         }
    2022             : 
    2023             :         /*
    2024             :          * The anycompatible type must exactly match the range element type,
    2025             :          * if we were able to identify one. This checks compatibility for
    2026             :          * anycompatiblemultirange too since that also sets
    2027             :          * anycompatible_range_typelem above.
    2028             :          */
    2029        2798 :         if (OidIsValid(anycompatible_range_typelem) &&
    2030             :             anycompatible_range_typelem != anycompatible_typeid)
    2031          42 :             return false;
    2032             :     }
    2033             : 
    2034             :     /* Looks valid */
    2035       53494 :     return true;
    2036             : }
    2037             : 
    2038             : /*
    2039             :  * enforce_generic_type_consistency()
    2040             :  *      Make sure a polymorphic function is legally callable, and
    2041             :  *      deduce actual argument and result types.
    2042             :  *
    2043             :  * If any polymorphic pseudotype is used in a function's arguments or
    2044             :  * return type, we make sure the actual data types are consistent with
    2045             :  * each other.  The argument consistency rules are shown above for
    2046             :  * check_generic_type_consistency().
    2047             :  *
    2048             :  * If we have UNKNOWN input (ie, an untyped literal) for any polymorphic
    2049             :  * argument, we attempt to deduce the actual type it should have.  If
    2050             :  * successful, we alter that position of declared_arg_types[] so that
    2051             :  * make_fn_arguments will coerce the literal to the right thing.
    2052             :  *
    2053             :  * If we have polymorphic arguments of the ANYCOMPATIBLE family,
    2054             :  * we similarly alter declared_arg_types[] entries to show the resolved
    2055             :  * common supertype, so that make_fn_arguments will coerce the actual
    2056             :  * arguments to the proper type.
    2057             :  *
    2058             :  * Rules are applied to the function's return type (possibly altering it)
    2059             :  * if it is declared as a polymorphic type and there is at least one
    2060             :  * polymorphic argument type:
    2061             :  *
    2062             :  * 1) If return type is ANYELEMENT, and any argument is ANYELEMENT, use the
    2063             :  *    argument's actual type as the function's return type.
    2064             :  * 2) If return type is ANYARRAY, and any argument is ANYARRAY, use the
    2065             :  *    argument's actual type as the function's return type.
    2066             :  * 3) Similarly, if return type is ANYRANGE or ANYMULTIRANGE, and any
    2067             :  *    argument is ANYRANGE or ANYMULTIRANGE, use that argument's actual type
    2068             :  *    (or the corresponding range or multirange type) as the function's return
    2069             :  *    type.
    2070             :  * 4) Otherwise, if return type is ANYELEMENT or ANYARRAY, and there is
    2071             :  *    at least one ANYELEMENT, ANYARRAY, ANYRANGE, or ANYMULTIRANGE input,
    2072             :  *    deduce the return type from those inputs, or throw error if we can't.
    2073             :  * 5) Otherwise, if return type is ANYRANGE or ANYMULTIRANGE, throw error.
    2074             :  *    (We have no way to select a specific range type if the arguments don't
    2075             :  *    include ANYRANGE or ANYMULTIRANGE.)
    2076             :  * 6) ANYENUM is treated the same as ANYELEMENT except that if it is used
    2077             :  *    (alone or in combination with plain ANYELEMENT), we add the extra
    2078             :  *    condition that the ANYELEMENT type must be an enum.
    2079             :  * 7) ANYNONARRAY is treated the same as ANYELEMENT except that if it is used,
    2080             :  *    we add the extra condition that the ANYELEMENT type must not be an array.
    2081             :  *    (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
    2082             :  *    is an extra restriction if not.)
    2083             :  * 8) ANYCOMPATIBLE, ANYCOMPATIBLEARRAY, and ANYCOMPATIBLENONARRAY are handled
    2084             :  *    by resolving the common supertype of those arguments (or their element
    2085             :  *    types, for array inputs), and then coercing all those arguments to the
    2086             :  *    common supertype, or the array type over the common supertype for
    2087             :  *    ANYCOMPATIBLEARRAY.
    2088             :  * 9) For ANYCOMPATIBLERANGE and ANYCOMPATIBLEMULTIRANGE, there must be at
    2089             :  *    least one non-UNKNOWN input matching those arguments, and all such
    2090             :  *    inputs must be the same range type (or its multirange type, as
    2091             :  *    appropriate), since we cannot deduce a range type from non-range types.
    2092             :  *    Furthermore, the range type's subtype is included while choosing the
    2093             :  *    common supertype for ANYCOMPATIBLE et al, and it must exactly match
    2094             :  *    that common supertype.
    2095             :  *
    2096             :  * Domains over arrays or ranges match ANYARRAY or ANYRANGE arguments,
    2097             :  * respectively, and are immediately flattened to their base type.  (In
    2098             :  * particular, if the return type is also ANYARRAY or ANYRANGE, we'll set
    2099             :  * it to the base type not the domain type.)  The same is true for
    2100             :  * ANYMULTIRANGE, ANYCOMPATIBLEARRAY, ANYCOMPATIBLERANGE, and
    2101             :  * ANYCOMPATIBLEMULTIRANGE.
    2102             :  *
    2103             :  * When allow_poly is false, we are not expecting any of the actual_arg_types
    2104             :  * to be polymorphic, and we should not return a polymorphic result type
    2105             :  * either.  When allow_poly is true, it is okay to have polymorphic "actual"
    2106             :  * arg types, and we can return a matching polymorphic type as the result.
    2107             :  * (This case is currently used only to check compatibility of an aggregate's
    2108             :  * declaration with the underlying transfn.)
    2109             :  *
    2110             :  * A special case is that we could see ANYARRAY as an actual_arg_type even
    2111             :  * when allow_poly is false (this is possible only because pg_statistic has
    2112             :  * columns shown as anyarray in the catalogs).  We allow this to match a
    2113             :  * declared ANYARRAY argument, but only if there is no other polymorphic
    2114             :  * argument that we would need to match it with, and no need to determine
    2115             :  * the element type to infer the result type.  Note this means that functions
    2116             :  * taking ANYARRAY had better behave sanely if applied to the pg_statistic
    2117             :  * columns; they can't just assume that successive inputs are of the same
    2118             :  * actual element type.  There is no similar logic for ANYCOMPATIBLEARRAY;
    2119             :  * there isn't a need for it since there are no catalog columns of that type,
    2120             :  * so we won't see it as input.  We could consider matching an actual ANYARRAY
    2121             :  * input to an ANYCOMPATIBLEARRAY argument, but at present that seems useless
    2122             :  * as well, since there's no value in using ANYCOMPATIBLEARRAY unless there's
    2123             :  * at least one other ANYCOMPATIBLE-family argument or result.
    2124             :  *
    2125             :  * Also, if there are no arguments declared to be of polymorphic types,
    2126             :  * we'll return the rettype unmodified even if it's polymorphic.  This should
    2127             :  * never occur for user-declared functions, because CREATE FUNCTION prevents
    2128             :  * it.  But it does happen for some built-in functions, such as array_in().
    2129             :  */
    2130             : Oid
    2131     1147516 : enforce_generic_type_consistency(const Oid *actual_arg_types,
    2132             :                                  Oid *declared_arg_types,
    2133             :                                  int nargs,
    2134             :                                  Oid rettype,
    2135             :                                  bool allow_poly)
    2136             : {
    2137     1147516 :     bool        have_poly_anycompatible = false;
    2138     1147516 :     bool        have_poly_unknowns = false;
    2139     1147516 :     Oid         elem_typeid = InvalidOid;
    2140     1147516 :     Oid         array_typeid = InvalidOid;
    2141     1147516 :     Oid         range_typeid = InvalidOid;
    2142     1147516 :     Oid         multirange_typeid = InvalidOid;
    2143     1147516 :     Oid         anycompatible_typeid = InvalidOid;
    2144     1147516 :     Oid         anycompatible_array_typeid = InvalidOid;
    2145     1147516 :     Oid         anycompatible_range_typeid = InvalidOid;
    2146     1147516 :     Oid         anycompatible_range_typelem = InvalidOid;
    2147     1147516 :     Oid         anycompatible_multirange_typeid = InvalidOid;
    2148     1147516 :     Oid         anycompatible_multirange_typelem = InvalidOid;
    2149     1147516 :     bool        have_anynonarray = (rettype == ANYNONARRAYOID);
    2150     1147516 :     bool        have_anyenum = (rettype == ANYENUMOID);
    2151     1147516 :     bool        have_anymultirange = (rettype == ANYMULTIRANGEOID);
    2152     1147516 :     bool        have_anycompatible_nonarray = (rettype == ANYCOMPATIBLENONARRAYOID);
    2153     1147516 :     bool        have_anycompatible_array = (rettype == ANYCOMPATIBLEARRAYOID);
    2154     1147516 :     bool        have_anycompatible_range = (rettype == ANYCOMPATIBLERANGEOID);
    2155     1147516 :     bool        have_anycompatible_multirange = (rettype == ANYCOMPATIBLEMULTIRANGEOID);
    2156     1147516 :     int         n_poly_args = 0;    /* this counts all family-1 arguments */
    2157     1147516 :     int         n_anycompatible_args = 0;   /* this counts only non-unknowns */
    2158             :     Oid         anycompatible_actual_types[FUNC_MAX_ARGS];
    2159             : 
    2160             :     /*
    2161             :      * Loop through the arguments to see if we have any that are polymorphic.
    2162             :      * If so, require the actual types to be consistent.
    2163             :      */
    2164             :     Assert(nargs <= FUNC_MAX_ARGS);
    2165     3332018 :     for (int j = 0; j < nargs; j++)
    2166             :     {
    2167     2184502 :         Oid         decl_type = declared_arg_types[j];
    2168     2184502 :         Oid         actual_type = actual_arg_types[j];
    2169             : 
    2170     2184502 :         if (decl_type == ANYELEMENTOID ||
    2171     2162350 :             decl_type == ANYNONARRAYOID ||
    2172             :             decl_type == ANYENUMOID)
    2173             :         {
    2174       22990 :             n_poly_args++;
    2175       22990 :             if (decl_type == ANYNONARRAYOID)
    2176       15884 :                 have_anynonarray = true;
    2177        7106 :             else if (decl_type == ANYENUMOID)
    2178         838 :                 have_anyenum = true;
    2179       22990 :             if (actual_type == UNKNOWNOID)
    2180             :             {
    2181         756 :                 have_poly_unknowns = true;
    2182         756 :                 continue;
    2183             :             }
    2184       22234 :             if (allow_poly && decl_type == actual_type)
    2185         176 :                 continue;       /* no new information here */
    2186       22058 :             if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
    2187           0 :                 ereport(ERROR,
    2188             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2189             :                          errmsg("arguments declared \"%s\" are not all alike", "anyelement"),
    2190             :                          errdetail("%s versus %s",
    2191             :                                    format_type_be(elem_typeid),
    2192             :                                    format_type_be(actual_type))));
    2193       22058 :             elem_typeid = actual_type;
    2194             :         }
    2195     2161512 :         else if (decl_type == ANYARRAYOID)
    2196             :         {
    2197       32752 :             n_poly_args++;
    2198       32752 :             if (actual_type == UNKNOWNOID)
    2199             :             {
    2200        4392 :                 have_poly_unknowns = true;
    2201        4392 :                 continue;
    2202             :             }
    2203       28360 :             if (allow_poly && decl_type == actual_type)
    2204          98 :                 continue;       /* no new information here */
    2205       28262 :             actual_type = getBaseType(actual_type); /* flatten domains */
    2206       28262 :             if (OidIsValid(array_typeid) && actual_type != array_typeid)
    2207           0 :                 ereport(ERROR,
    2208             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2209             :                          errmsg("arguments declared \"%s\" are not all alike", "anyarray"),
    2210             :                          errdetail("%s versus %s",
    2211             :                                    format_type_be(array_typeid),
    2212             :                                    format_type_be(actual_type))));
    2213       28262 :             array_typeid = actual_type;
    2214             :         }
    2215     2128760 :         else if (decl_type == ANYRANGEOID)
    2216             :         {
    2217        8612 :             n_poly_args++;
    2218        8612 :             if (actual_type == UNKNOWNOID)
    2219             :             {
    2220         996 :                 have_poly_unknowns = true;
    2221         996 :                 continue;
    2222             :             }
    2223        7616 :             if (allow_poly && decl_type == actual_type)
    2224           0 :                 continue;       /* no new information here */
    2225        7616 :             actual_type = getBaseType(actual_type); /* flatten domains */
    2226        7616 :             if (OidIsValid(range_typeid) && actual_type != range_typeid)
    2227           0 :                 ereport(ERROR,
    2228             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2229             :                          errmsg("arguments declared \"%s\" are not all alike", "anyrange"),
    2230             :                          errdetail("%s versus %s",
    2231             :                                    format_type_be(range_typeid),
    2232             :                                    format_type_be(actual_type))));
    2233        7616 :             range_typeid = actual_type;
    2234             :         }
    2235     2120148 :         else if (decl_type == ANYMULTIRANGEOID)
    2236             :         {
    2237        5352 :             n_poly_args++;
    2238        5352 :             have_anymultirange = true;
    2239        5352 :             if (actual_type == UNKNOWNOID)
    2240             :             {
    2241         264 :                 have_poly_unknowns = true;
    2242         264 :                 continue;
    2243             :             }
    2244        5088 :             if (allow_poly && decl_type == actual_type)
    2245           0 :                 continue;       /* no new information here */
    2246        5088 :             actual_type = getBaseType(actual_type); /* flatten domains */
    2247        5088 :             if (OidIsValid(multirange_typeid) && actual_type != multirange_typeid)
    2248           0 :                 ereport(ERROR,
    2249             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2250             :                          errmsg("arguments declared \"%s\" are not all alike", "anymultirange"),
    2251             :                          errdetail("%s versus %s",
    2252             :                                    format_type_be(multirange_typeid),
    2253             :                                    format_type_be(actual_type))));
    2254        5088 :             multirange_typeid = actual_type;
    2255             :         }
    2256     2114796 :         else if (decl_type == ANYCOMPATIBLEOID ||
    2257             :                  decl_type == ANYCOMPATIBLENONARRAYOID)
    2258             :         {
    2259        2184 :             have_poly_anycompatible = true;
    2260        2184 :             if (decl_type == ANYCOMPATIBLENONARRAYOID)
    2261          24 :                 have_anycompatible_nonarray = true;
    2262        2184 :             if (actual_type == UNKNOWNOID)
    2263        1040 :                 continue;
    2264        1144 :             if (allow_poly && decl_type == actual_type)
    2265           8 :                 continue;       /* no new information here */
    2266             :             /* collect the actual types of non-unknown COMPATIBLE args */
    2267        1136 :             anycompatible_actual_types[n_anycompatible_args++] = actual_type;
    2268             :         }
    2269     2112612 :         else if (decl_type == ANYCOMPATIBLEARRAYOID)
    2270             :         {
    2271             :             Oid         anycompatible_elem_type;
    2272             : 
    2273        5348 :             have_poly_anycompatible = true;
    2274        5348 :             have_anycompatible_array = true;
    2275        5348 :             if (actual_type == UNKNOWNOID)
    2276          30 :                 continue;
    2277        5318 :             if (allow_poly && decl_type == actual_type)
    2278           8 :                 continue;       /* no new information here */
    2279        5310 :             actual_type = getBaseType(actual_type); /* flatten domains */
    2280        5310 :             anycompatible_elem_type = get_element_type(actual_type);
    2281        5310 :             if (!OidIsValid(anycompatible_elem_type))
    2282           0 :                 ereport(ERROR,
    2283             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2284             :                          errmsg("argument declared %s is not an array but type %s",
    2285             :                                 "anycompatiblearray",
    2286             :                                 format_type_be(actual_type))));
    2287             :             /* collect the element type for common-supertype choice */
    2288        5310 :             anycompatible_actual_types[n_anycompatible_args++] = anycompatible_elem_type;
    2289             :         }
    2290     2107264 :         else if (decl_type == ANYCOMPATIBLERANGEOID)
    2291             :         {
    2292         138 :             have_poly_anycompatible = true;
    2293         138 :             have_anycompatible_range = true;
    2294         138 :             if (actual_type == UNKNOWNOID)
    2295          12 :                 continue;
    2296         126 :             if (allow_poly && decl_type == actual_type)
    2297           0 :                 continue;       /* no new information here */
    2298         126 :             actual_type = getBaseType(actual_type); /* flatten domains */
    2299         126 :             if (OidIsValid(anycompatible_range_typeid))
    2300             :             {
    2301             :                 /* All ANYCOMPATIBLERANGE arguments must be the same type */
    2302           6 :                 if (anycompatible_range_typeid != actual_type)
    2303           0 :                     ereport(ERROR,
    2304             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2305             :                              errmsg("arguments declared \"%s\" are not all alike", "anycompatiblerange"),
    2306             :                              errdetail("%s versus %s",
    2307             :                                        format_type_be(anycompatible_range_typeid),
    2308             :                                        format_type_be(actual_type))));
    2309             :             }
    2310             :             else
    2311             :             {
    2312         120 :                 anycompatible_range_typeid = actual_type;
    2313         120 :                 anycompatible_range_typelem = get_range_subtype(actual_type);
    2314         120 :                 if (!OidIsValid(anycompatible_range_typelem))
    2315           0 :                     ereport(ERROR,
    2316             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2317             :                              errmsg("argument declared %s is not a range type but type %s",
    2318             :                                     "anycompatiblerange",
    2319             :                                     format_type_be(actual_type))));
    2320             :                 /* collect the subtype for common-supertype choice */
    2321         120 :                 anycompatible_actual_types[n_anycompatible_args++] = anycompatible_range_typelem;
    2322             :             }
    2323             :         }
    2324     2107126 :         else if (decl_type == ANYCOMPATIBLEMULTIRANGEOID)
    2325             :         {
    2326          96 :             have_poly_anycompatible = true;
    2327          96 :             have_anycompatible_multirange = true;
    2328          96 :             if (actual_type == UNKNOWNOID)
    2329          18 :                 continue;
    2330          78 :             if (allow_poly && decl_type == actual_type)
    2331           0 :                 continue;       /* no new information here */
    2332          78 :             actual_type = getBaseType(actual_type); /* flatten domains */
    2333          78 :             if (OidIsValid(anycompatible_multirange_typeid))
    2334             :             {
    2335             :                 /* All ANYCOMPATIBLEMULTIRANGE arguments must be the same type */
    2336           6 :                 if (anycompatible_multirange_typeid != actual_type)
    2337           0 :                     ereport(ERROR,
    2338             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2339             :                              errmsg("arguments declared \"%s\" are not all alike", "anycompatiblemultirange"),
    2340             :                              errdetail("%s versus %s",
    2341             :                                        format_type_be(anycompatible_multirange_typeid),
    2342             :                                        format_type_be(actual_type))));
    2343             :             }
    2344             :             else
    2345             :             {
    2346          72 :                 anycompatible_multirange_typeid = actual_type;
    2347          72 :                 anycompatible_multirange_typelem = get_multirange_range(actual_type);
    2348          72 :                 if (!OidIsValid(anycompatible_multirange_typelem))
    2349           0 :                     ereport(ERROR,
    2350             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2351             :                              errmsg("argument declared %s is not a multirange type but type %s",
    2352             :                                     "anycompatiblemultirange",
    2353             :                                     format_type_be(actual_type))));
    2354             :                 /* we'll consider the subtype below */
    2355             :             }
    2356             :         }
    2357             :     }
    2358             : 
    2359             :     /*
    2360             :      * Fast Track: if none of the arguments are polymorphic, return the
    2361             :      * unmodified rettype.  Not our job to resolve it if it's polymorphic.
    2362             :      */
    2363     1147516 :     if (n_poly_args == 0 && !have_poly_anycompatible)
    2364     1087558 :         return rettype;
    2365             : 
    2366             :     /* Check matching of family-1 polymorphic arguments, if any */
    2367       59958 :     if (n_poly_args)
    2368             :     {
    2369             :         /* Get the element type based on the array type, if we have one */
    2370       56108 :         if (OidIsValid(array_typeid))
    2371             :         {
    2372             :             Oid         array_typelem;
    2373             : 
    2374       26812 :             if (array_typeid == ANYARRAYOID)
    2375             :             {
    2376             :                 /*
    2377             :                  * Special case for matching ANYARRAY input to an ANYARRAY
    2378             :                  * argument: allow it iff no other arguments are family-1
    2379             :                  * polymorphics (otherwise we couldn't be sure whether the
    2380             :                  * array element type matches up) and the result type doesn't
    2381             :                  * require us to infer a specific element type.
    2382             :                  */
    2383          42 :                 if (n_poly_args != 1 ||
    2384          18 :                     (rettype != ANYARRAYOID &&
    2385           6 :                      IsPolymorphicTypeFamily1(rettype)))
    2386          12 :                     ereport(ERROR,
    2387             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2388             :                              errmsg("cannot determine element type of \"anyarray\" argument")));
    2389          30 :                 array_typelem = ANYELEMENTOID;
    2390             :             }
    2391             :             else
    2392             :             {
    2393       26770 :                 array_typelem = get_element_type(array_typeid);
    2394       26770 :                 if (!OidIsValid(array_typelem))
    2395           0 :                     ereport(ERROR,
    2396             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2397             :                              errmsg("argument declared %s is not an array but type %s",
    2398             :                                     "anyarray", format_type_be(array_typeid))));
    2399             :             }
    2400             : 
    2401       26800 :             if (!OidIsValid(elem_typeid))
    2402             :             {
    2403             :                 /*
    2404             :                  * if we don't have an element type yet, use the one we just
    2405             :                  * got
    2406             :                  */
    2407       26718 :                 elem_typeid = array_typelem;
    2408             :             }
    2409          82 :             else if (array_typelem != elem_typeid)
    2410             :             {
    2411             :                 /* otherwise, they better match */
    2412           0 :                 ereport(ERROR,
    2413             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2414             :                          errmsg("argument declared %s is not consistent with argument declared %s",
    2415             :                                 "anyarray", "anyelement"),
    2416             :                          errdetail("%s versus %s",
    2417             :                                    format_type_be(array_typeid),
    2418             :                                    format_type_be(elem_typeid))));
    2419             :             }
    2420             :         }
    2421             : 
    2422             :         /* Deduce range type from multirange type, or vice versa */
    2423       56096 :         if (OidIsValid(multirange_typeid))
    2424             :         {
    2425             :             Oid         multirange_typelem;
    2426             : 
    2427        3732 :             multirange_typelem = get_multirange_range(multirange_typeid);
    2428        3732 :             if (!OidIsValid(multirange_typelem))
    2429           0 :                 ereport(ERROR,
    2430             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2431             :                          errmsg("argument declared %s is not a multirange type but type %s",
    2432             :                                 "anymultirange",
    2433             :                                 format_type_be(multirange_typeid))));
    2434             : 
    2435        3732 :             if (!OidIsValid(range_typeid))
    2436             :             {
    2437             :                 /* if we don't have a range type yet, use the one we just got */
    2438        2418 :                 range_typeid = multirange_typelem;
    2439             :             }
    2440        1314 :             else if (multirange_typelem != range_typeid)
    2441             :             {
    2442             :                 /* otherwise, they better match */
    2443           0 :                 ereport(ERROR,
    2444             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2445             :                          errmsg("argument declared %s is not consistent with argument declared %s",
    2446             :                                 "anymultirange", "anyrange"),
    2447             :                          errdetail("%s versus %s",
    2448             :                                    format_type_be(multirange_typeid),
    2449             :                                    format_type_be(range_typeid))));
    2450             :             }
    2451             :         }
    2452       52364 :         else if (have_anymultirange && OidIsValid(range_typeid))
    2453             :         {
    2454         294 :             multirange_typeid = get_range_multirange(range_typeid);
    2455             :             /* We'll complain below if that didn't work */
    2456             :         }
    2457             : 
    2458             :         /* Get the element type based on the range type, if we have one */
    2459       56096 :         if (OidIsValid(range_typeid))
    2460             :         {
    2461             :             Oid         range_typelem;
    2462             : 
    2463        7984 :             range_typelem = get_range_subtype(range_typeid);
    2464        7984 :             if (!OidIsValid(range_typelem))
    2465           0 :                 ereport(ERROR,
    2466             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2467             :                          errmsg("argument declared %s is not a range type but type %s",
    2468             :                                 "anyrange",
    2469             :                                 format_type_be(range_typeid))));
    2470             : 
    2471        7984 :             if (!OidIsValid(elem_typeid))
    2472             :             {
    2473             :                 /*
    2474             :                  * if we don't have an element type yet, use the one we just
    2475             :                  * got
    2476             :                  */
    2477        7498 :                 elem_typeid = range_typelem;
    2478             :             }
    2479         486 :             else if (range_typelem != elem_typeid)
    2480             :             {
    2481             :                 /* otherwise, they better match */
    2482           0 :                 ereport(ERROR,
    2483             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2484             :                          errmsg("argument declared %s is not consistent with argument declared %s",
    2485             :                                 "anyrange", "anyelement"),
    2486             :                          errdetail("%s versus %s",
    2487             :                                    format_type_be(range_typeid),
    2488             :                                    format_type_be(elem_typeid))));
    2489             :             }
    2490             :         }
    2491             : 
    2492       56096 :         if (!OidIsValid(elem_typeid))
    2493             :         {
    2494         220 :             if (allow_poly)
    2495             :             {
    2496         196 :                 elem_typeid = ANYELEMENTOID;
    2497         196 :                 array_typeid = ANYARRAYOID;
    2498         196 :                 range_typeid = ANYRANGEOID;
    2499         196 :                 multirange_typeid = ANYMULTIRANGEOID;
    2500             :             }
    2501             :             else
    2502             :             {
    2503             :                 /*
    2504             :                  * Only way to get here is if all the family-1 polymorphic
    2505             :                  * arguments have UNKNOWN inputs.
    2506             :                  */
    2507          24 :                 ereport(ERROR,
    2508             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2509             :                          errmsg("could not determine polymorphic type because input has type %s",
    2510             :                                 "unknown")));
    2511             :             }
    2512             :         }
    2513             : 
    2514       56072 :         if (have_anynonarray && elem_typeid != ANYELEMENTOID)
    2515             :         {
    2516             :             /*
    2517             :              * require the element type to not be an array or domain over
    2518             :              * array
    2519             :              */
    2520       15532 :             if (type_is_array_domain(elem_typeid))
    2521           0 :                 ereport(ERROR,
    2522             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2523             :                          errmsg("type matched to anynonarray is an array type: %s",
    2524             :                                 format_type_be(elem_typeid))));
    2525             :         }
    2526             : 
    2527       56072 :         if (have_anyenum && elem_typeid != ANYELEMENTOID)
    2528             :         {
    2529             :             /* require the element type to be an enum */
    2530         572 :             if (!type_is_enum(elem_typeid))
    2531           0 :                 ereport(ERROR,
    2532             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2533             :                          errmsg("type matched to anyenum is not an enum type: %s",
    2534             :                                 format_type_be(elem_typeid))));
    2535             :         }
    2536             :     }
    2537             : 
    2538             :     /* Check matching of family-2 polymorphic arguments, if any */
    2539       59922 :     if (have_poly_anycompatible)
    2540             :     {
    2541             :         /* Deduce range type from multirange type, or vice versa */
    2542        3904 :         if (OidIsValid(anycompatible_multirange_typeid))
    2543             :         {
    2544          72 :             if (OidIsValid(anycompatible_range_typeid))
    2545             :             {
    2546           6 :                 if (anycompatible_multirange_typelem !=
    2547             :                     anycompatible_range_typeid)
    2548           0 :                     ereport(ERROR,
    2549             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2550             :                              errmsg("argument declared %s is not consistent with argument declared %s",
    2551             :                                     "anycompatiblemultirange",
    2552             :                                     "anycompatiblerange"),
    2553             :                              errdetail("%s versus %s",
    2554             :                                        format_type_be(anycompatible_multirange_typeid),
    2555             :                                        format_type_be(anycompatible_range_typeid))));
    2556             :             }
    2557             :             else
    2558             :             {
    2559          66 :                 anycompatible_range_typeid = anycompatible_multirange_typelem;
    2560          66 :                 anycompatible_range_typelem = get_range_subtype(anycompatible_range_typeid);
    2561          66 :                 if (!OidIsValid(anycompatible_range_typelem))
    2562           0 :                     ereport(ERROR,
    2563             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2564             :                              errmsg("argument declared %s is not a multirange type but type %s",
    2565             :                                     "anycompatiblemultirange",
    2566             :                                     format_type_be(anycompatible_multirange_typeid))));
    2567             :                 /* this enables element type matching check below */
    2568          66 :                 have_anycompatible_range = true;
    2569             :                 /* collect the subtype for common-supertype choice */
    2570          66 :                 anycompatible_actual_types[n_anycompatible_args++] =
    2571             :                     anycompatible_range_typelem;
    2572             :             }
    2573             :         }
    2574        3832 :         else if (have_anycompatible_multirange &&
    2575             :                  OidIsValid(anycompatible_range_typeid))
    2576             :         {
    2577           6 :             anycompatible_multirange_typeid = get_range_multirange(anycompatible_range_typeid);
    2578             :             /* We'll complain below if that didn't work */
    2579             :         }
    2580             : 
    2581        3904 :         if (n_anycompatible_args > 0)
    2582             :         {
    2583             :             anycompatible_typeid =
    2584        3872 :                 select_common_type_from_oids(n_anycompatible_args,
    2585             :                                              anycompatible_actual_types,
    2586             :                                              false);
    2587             : 
    2588             :             /* We have to verify that the selected type actually works */
    2589        3872 :             if (!verify_common_type_from_oids(anycompatible_typeid,
    2590             :                                               n_anycompatible_args,
    2591             :                                               anycompatible_actual_types))
    2592           0 :                 ereport(ERROR,
    2593             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2594             :                          errmsg("arguments of anycompatible family cannot be cast to a common type")));
    2595             : 
    2596        3872 :             if (have_anycompatible_array)
    2597             :             {
    2598        3674 :                 anycompatible_array_typeid = get_array_type(anycompatible_typeid);
    2599        3674 :                 if (!OidIsValid(anycompatible_array_typeid))
    2600           0 :                     ereport(ERROR,
    2601             :                             (errcode(ERRCODE_UNDEFINED_OBJECT),
    2602             :                              errmsg("could not find array type for data type %s",
    2603             :                                     format_type_be(anycompatible_typeid))));
    2604             :             }
    2605             : 
    2606        3872 :             if (have_anycompatible_range)
    2607             :             {
    2608             :                 /* we can't infer a range type from the others */
    2609         192 :                 if (!OidIsValid(anycompatible_range_typeid))
    2610           6 :                     ereport(ERROR,
    2611             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2612             :                              errmsg("could not determine polymorphic type %s because input has type %s",
    2613             :                                     "anycompatiblerange", "unknown")));
    2614             : 
    2615             :                 /*
    2616             :                  * the anycompatible type must exactly match the range element
    2617             :                  * type
    2618             :                  */
    2619         186 :                 if (anycompatible_range_typelem != anycompatible_typeid)
    2620           0 :                     ereport(ERROR,
    2621             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2622             :                              errmsg("anycompatiblerange type %s does not match anycompatible type %s",
    2623             :                                     format_type_be(anycompatible_range_typeid),
    2624             :                                     format_type_be(anycompatible_typeid))));
    2625             :             }
    2626             : 
    2627        3866 :             if (have_anycompatible_multirange)
    2628             :             {
    2629             :                 /* we can't infer a multirange type from the others */
    2630          84 :                 if (!OidIsValid(anycompatible_multirange_typeid))
    2631           6 :                     ereport(ERROR,
    2632             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2633             :                              errmsg("could not determine polymorphic type %s because input has type %s",
    2634             :                                     "anycompatiblemultirange", "unknown")));
    2635             : 
    2636             :                 /*
    2637             :                  * the anycompatible type must exactly match the multirange
    2638             :                  * element type
    2639             :                  */
    2640          78 :                 if (anycompatible_range_typelem != anycompatible_typeid)
    2641           0 :                     ereport(ERROR,
    2642             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2643             :                              errmsg("anycompatiblemultirange type %s does not match anycompatible type %s",
    2644             :                                     format_type_be(anycompatible_multirange_typeid),
    2645             :                                     format_type_be(anycompatible_typeid))));
    2646             :             }
    2647             : 
    2648        3860 :             if (have_anycompatible_nonarray)
    2649             :             {
    2650             :                 /*
    2651             :                  * require the element type to not be an array or domain over
    2652             :                  * array
    2653             :                  */
    2654          12 :                 if (type_is_array_domain(anycompatible_typeid))
    2655           0 :                     ereport(ERROR,
    2656             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2657             :                              errmsg("type matched to anycompatiblenonarray is an array type: %s",
    2658             :                                     format_type_be(anycompatible_typeid))));
    2659             :             }
    2660             :         }
    2661             :         else
    2662             :         {
    2663          32 :             if (allow_poly)
    2664             :             {
    2665           8 :                 anycompatible_typeid = ANYCOMPATIBLEOID;
    2666           8 :                 anycompatible_array_typeid = ANYCOMPATIBLEARRAYOID;
    2667           8 :                 anycompatible_range_typeid = ANYCOMPATIBLERANGEOID;
    2668           8 :                 anycompatible_multirange_typeid = ANYCOMPATIBLEMULTIRANGEOID;
    2669             :             }
    2670             :             else
    2671             :             {
    2672             :                 /*
    2673             :                  * Only way to get here is if all the family-2 polymorphic
    2674             :                  * arguments have UNKNOWN inputs.  Resolve to TEXT as
    2675             :                  * select_common_type() would do.  That doesn't license us to
    2676             :                  * use TEXTRANGE or TEXTMULTIRANGE, though.
    2677             :                  */
    2678          24 :                 anycompatible_typeid = TEXTOID;
    2679          24 :                 anycompatible_array_typeid = TEXTARRAYOID;
    2680          24 :                 if (have_anycompatible_range)
    2681          12 :                     ereport(ERROR,
    2682             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2683             :                              errmsg("could not determine polymorphic type %s because input has type %s",
    2684             :                                     "anycompatiblerange", "unknown")));
    2685          12 :                 if (have_anycompatible_multirange)
    2686           6 :                     ereport(ERROR,
    2687             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2688             :                              errmsg("could not determine polymorphic type %s because input has type %s",
    2689             :                                     "anycompatiblemultirange", "unknown")));
    2690             :             }
    2691             :         }
    2692             : 
    2693             :         /* replace family-2 polymorphic types by selected types */
    2694       11736 :         for (int j = 0; j < nargs; j++)
    2695             :         {
    2696        7862 :             Oid         decl_type = declared_arg_types[j];
    2697             : 
    2698        7862 :             if (decl_type == ANYCOMPATIBLEOID ||
    2699             :                 decl_type == ANYCOMPATIBLENONARRAYOID)
    2700        2172 :                 declared_arg_types[j] = anycompatible_typeid;
    2701        5690 :             else if (decl_type == ANYCOMPATIBLEARRAYOID)
    2702        5348 :                 declared_arg_types[j] = anycompatible_array_typeid;
    2703         342 :             else if (decl_type == ANYCOMPATIBLERANGEOID)
    2704         126 :                 declared_arg_types[j] = anycompatible_range_typeid;
    2705         216 :             else if (decl_type == ANYCOMPATIBLEMULTIRANGEOID)
    2706          78 :                 declared_arg_types[j] = anycompatible_multirange_typeid;
    2707             :         }
    2708             :     }
    2709             : 
    2710             :     /*
    2711             :      * If we had any UNKNOWN inputs for family-1 polymorphic arguments,
    2712             :      * re-scan to assign correct types to them.
    2713             :      *
    2714             :      * Note: we don't have to consider unknown inputs that were matched to
    2715             :      * family-2 polymorphic arguments, because we forcibly updated their
    2716             :      * declared_arg_types[] positions just above.
    2717             :      */
    2718       59892 :     if (have_poly_unknowns)
    2719             :     {
    2720       19988 :         for (int j = 0; j < nargs; j++)
    2721             :         {
    2722       13622 :             Oid         decl_type = declared_arg_types[j];
    2723       13622 :             Oid         actual_type = actual_arg_types[j];
    2724             : 
    2725       13622 :             if (actual_type != UNKNOWNOID)
    2726        6594 :                 continue;
    2727             : 
    2728        7028 :             if (decl_type == ANYELEMENTOID ||
    2729        6454 :                 decl_type == ANYNONARRAYOID ||
    2730             :                 decl_type == ANYENUMOID)
    2731         750 :                 declared_arg_types[j] = elem_typeid;
    2732        6278 :             else if (decl_type == ANYARRAYOID)
    2733             :             {
    2734        4392 :                 if (!OidIsValid(array_typeid))
    2735             :                 {
    2736          30 :                     array_typeid = get_array_type(elem_typeid);
    2737          30 :                     if (!OidIsValid(array_typeid))
    2738           0 :                         ereport(ERROR,
    2739             :                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
    2740             :                                  errmsg("could not find array type for data type %s",
    2741             :                                         format_type_be(elem_typeid))));
    2742             :                 }
    2743        4392 :                 declared_arg_types[j] = array_typeid;
    2744             :             }
    2745        1886 :             else if (decl_type == ANYRANGEOID)
    2746             :             {
    2747         990 :                 if (!OidIsValid(range_typeid))
    2748             :                 {
    2749             :                     /* we can't infer a range type from the others */
    2750           0 :                     ereport(ERROR,
    2751             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2752             :                              errmsg("could not determine polymorphic type %s because input has type %s",
    2753             :                                     "anyrange", "unknown")));
    2754             :                 }
    2755         990 :                 declared_arg_types[j] = range_typeid;
    2756             :             }
    2757         896 :             else if (decl_type == ANYMULTIRANGEOID)
    2758             :             {
    2759         252 :                 if (!OidIsValid(multirange_typeid))
    2760             :                 {
    2761             :                     /* we can't infer a multirange type from the others */
    2762           0 :                     ereport(ERROR,
    2763             :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    2764             :                              errmsg("could not determine polymorphic type %s because input has type %s",
    2765             :                                     "anymultirange", "unknown")));
    2766             :                 }
    2767         252 :                 declared_arg_types[j] = multirange_typeid;
    2768             :             }
    2769             :         }
    2770             :     }
    2771             : 
    2772             :     /* if we return ANYELEMENT use the appropriate argument type */
    2773       59892 :     if (rettype == ANYELEMENTOID ||
    2774       49720 :         rettype == ANYNONARRAYOID ||
    2775             :         rettype == ANYENUMOID)
    2776       10400 :         return elem_typeid;
    2777             : 
    2778             :     /* if we return ANYARRAY use the appropriate argument type */
    2779       49492 :     if (rettype == ANYARRAYOID)
    2780             :     {
    2781       15674 :         if (!OidIsValid(array_typeid))
    2782             :         {
    2783       14652 :             array_typeid = get_array_type(elem_typeid);
    2784       14652 :             if (!OidIsValid(array_typeid))
    2785           0 :                 ereport(ERROR,
    2786             :                         (errcode(ERRCODE_UNDEFINED_OBJECT),
    2787             :                          errmsg("could not find array type for data type %s",
    2788             :                                 format_type_be(elem_typeid))));
    2789             :         }
    2790       15674 :         return array_typeid;
    2791             :     }
    2792             : 
    2793             :     /* if we return ANYRANGE use the appropriate argument type */
    2794       33818 :     if (rettype == ANYRANGEOID)
    2795             :     {
    2796             :         /* this error is unreachable if the function signature is valid: */
    2797         400 :         if (!OidIsValid(range_typeid))
    2798           0 :             ereport(ERROR,
    2799             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    2800             :                      errmsg_internal("could not determine polymorphic type %s because input has type %s",
    2801             :                                      "anyrange", "unknown")));
    2802         400 :         return range_typeid;
    2803             :     }
    2804             : 
    2805             :     /* if we return ANYMULTIRANGE use the appropriate argument type */
    2806       33418 :     if (rettype == ANYMULTIRANGEOID)
    2807             :     {
    2808             :         /* this error is unreachable if the function signature is valid: */
    2809         906 :         if (!OidIsValid(multirange_typeid))
    2810           0 :             ereport(ERROR,
    2811             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    2812             :                      errmsg_internal("could not determine polymorphic type %s because input has type %s",
    2813             :                                      "anymultirange", "unknown")));
    2814         906 :         return multirange_typeid;
    2815             :     }
    2816             : 
    2817             :     /* if we return ANYCOMPATIBLE use the appropriate type */
    2818       32512 :     if (rettype == ANYCOMPATIBLEOID ||
    2819             :         rettype == ANYCOMPATIBLENONARRAYOID)
    2820             :     {
    2821             :         /* this error is unreachable if the function signature is valid: */
    2822         158 :         if (!OidIsValid(anycompatible_typeid))
    2823           0 :             ereport(ERROR,
    2824             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    2825             :                      errmsg_internal("could not identify anycompatible type")));
    2826         158 :         return anycompatible_typeid;
    2827             :     }
    2828             : 
    2829             :     /* if we return ANYCOMPATIBLEARRAY use the appropriate type */
    2830       32354 :     if (rettype == ANYCOMPATIBLEARRAYOID)
    2831             :     {
    2832             :         /* this error is unreachable if the function signature is valid: */
    2833        3338 :         if (!OidIsValid(anycompatible_array_typeid))
    2834           0 :             ereport(ERROR,
    2835             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    2836             :                      errmsg_internal("could not identify anycompatiblearray type")));
    2837        3338 :         return anycompatible_array_typeid;
    2838             :     }
    2839             : 
    2840             :     /* if we return ANYCOMPATIBLERANGE use the appropriate argument type */
    2841       29016 :     if (rettype == ANYCOMPATIBLERANGEOID)
    2842             :     {
    2843             :         /* this error is unreachable if the function signature is valid: */
    2844          42 :         if (!OidIsValid(anycompatible_range_typeid))
    2845           0 :             ereport(ERROR,
    2846             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    2847             :                      errmsg_internal("could not identify anycompatiblerange type")));
    2848          42 :         return anycompatible_range_typeid;
    2849             :     }
    2850             : 
    2851             :     /* if we return ANYCOMPATIBLEMULTIRANGE use the appropriate argument type */
    2852       28974 :     if (rettype == ANYCOMPATIBLEMULTIRANGEOID)
    2853             :     {
    2854             :         /* this error is unreachable if the function signature is valid: */
    2855          30 :         if (!OidIsValid(anycompatible_multirange_typeid))
    2856           0 :             ereport(ERROR,
    2857             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    2858             :                      errmsg_internal("could not identify anycompatiblemultirange type")));
    2859          30 :         return anycompatible_multirange_typeid;
    2860             :     }
    2861             : 
    2862             :     /* we don't return a generic type; send back the original return type */
    2863       28944 :     return rettype;
    2864             : }
    2865             : 
    2866             : /*
    2867             :  * check_valid_polymorphic_signature()
    2868             :  *      Is a proposed function signature valid per polymorphism rules?
    2869             :  *
    2870             :  * Returns NULL if the signature is valid (either ret_type is not polymorphic,
    2871             :  * or it can be deduced from the given declared argument types).  Otherwise,
    2872             :  * returns a palloc'd, already translated errdetail string saying why not.
    2873             :  */
    2874             : char *
    2875       37038 : check_valid_polymorphic_signature(Oid ret_type,
    2876             :                                   const Oid *declared_arg_types,
    2877             :                                   int nargs)
    2878             : {
    2879       37038 :     if (ret_type == ANYRANGEOID || ret_type == ANYMULTIRANGEOID)
    2880             :     {
    2881             :         /*
    2882             :          * ANYRANGE and ANYMULTIRANGE require an ANYRANGE or ANYMULTIRANGE
    2883             :          * input, else we can't tell which of several range types with the
    2884             :          * same element type to use.
    2885             :          */
    2886         228 :         for (int i = 0; i < nargs; i++)
    2887             :         {
    2888         156 :             if (declared_arg_types[i] == ANYRANGEOID ||
    2889         118 :                 declared_arg_types[i] == ANYMULTIRANGEOID)
    2890          76 :                 return NULL;    /* OK */
    2891             :         }
    2892          72 :         return psprintf(_("A result of type %s requires at least one input of type anyrange or anymultirange."),
    2893             :                         format_type_be(ret_type));
    2894             :     }
    2895       36890 :     else if (ret_type == ANYCOMPATIBLERANGEOID || ret_type == ANYCOMPATIBLEMULTIRANGEOID)
    2896             :     {
    2897             :         /*
    2898             :          * ANYCOMPATIBLERANGE and ANYCOMPATIBLEMULTIRANGE require an
    2899             :          * ANYCOMPATIBLERANGE or ANYCOMPATIBLEMULTIRANGE input, else we can't
    2900             :          * tell which of several range types with the same element type to
    2901             :          * use.
    2902             :          */
    2903         144 :         for (int i = 0; i < nargs; i++)
    2904             :         {
    2905         102 :             if (declared_arg_types[i] == ANYCOMPATIBLERANGEOID ||
    2906          72 :                 declared_arg_types[i] == ANYCOMPATIBLEMULTIRANGEOID)
    2907          48 :                 return NULL;    /* OK */
    2908             :         }
    2909          42 :         return psprintf(_("A result of type %s requires at least one input of type anycompatiblerange or anycompatiblemultirange."),
    2910             :                         format_type_be(ret_type));
    2911             :     }
    2912       36800 :     else if (IsPolymorphicTypeFamily1(ret_type))
    2913             :     {
    2914             :         /* Otherwise, any family-1 type can be deduced from any other */
    2915        1244 :         for (int i = 0; i < nargs; i++)
    2916             :         {
    2917        1130 :             if (IsPolymorphicTypeFamily1(declared_arg_types[i]))
    2918        1028 :                 return NULL;    /* OK */
    2919             :         }
    2920             :         /* Keep this list in sync with IsPolymorphicTypeFamily1! */
    2921         114 :         return psprintf(_("A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange."),
    2922             :                         format_type_be(ret_type));
    2923             :     }
    2924       35658 :     else if (IsPolymorphicTypeFamily2(ret_type))
    2925             :     {
    2926             :         /* Otherwise, any family-2 type can be deduced from any other */
    2927         236 :         for (int i = 0; i < nargs; i++)
    2928             :         {
    2929         230 :             if (IsPolymorphicTypeFamily2(declared_arg_types[i]))
    2930         188 :                 return NULL;    /* OK */
    2931             :         }
    2932             :         /* Keep this list in sync with IsPolymorphicTypeFamily2! */
    2933           6 :         return psprintf(_("A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, anycompatiblerange, or anycompatiblemultirange."),
    2934             :                         format_type_be(ret_type));
    2935             :     }
    2936             :     else
    2937       35464 :         return NULL;            /* OK, ret_type is not polymorphic */
    2938             : }
    2939             : 
    2940             : /*
    2941             :  * check_valid_internal_signature()
    2942             :  *      Is a proposed function signature valid per INTERNAL safety rules?
    2943             :  *
    2944             :  * Returns NULL if OK, or a suitable error message if ret_type is INTERNAL but
    2945             :  * none of the declared arg types are.  (It's unsafe to create such a function
    2946             :  * since it would allow invocation of INTERNAL-consuming functions directly
    2947             :  * from SQL.)  It's overkill to return the error detail message, since there
    2948             :  * is only one possibility, but we do it like this to keep the API similar to
    2949             :  * check_valid_polymorphic_signature().
    2950             :  */
    2951             : char *
    2952       35982 : check_valid_internal_signature(Oid ret_type,
    2953             :                                const Oid *declared_arg_types,
    2954             :                                int nargs)
    2955             : {
    2956       35982 :     if (ret_type == INTERNALOID)
    2957             :     {
    2958        1086 :         for (int i = 0; i < nargs; i++)
    2959             :         {
    2960        1086 :             if (declared_arg_types[i] == ret_type)
    2961         780 :                 return NULL;    /* OK */
    2962             :         }
    2963           0 :         return pstrdup(_("A result of type internal requires at least one input of type internal."));
    2964             :     }
    2965             :     else
    2966       35202 :         return NULL;            /* OK, ret_type is not INTERNAL */
    2967             : }
    2968             : 
    2969             : 
    2970             : /* TypeCategory()
    2971             :  *      Assign a category to the specified type OID.
    2972             :  *
    2973             :  * NB: this must not return TYPCATEGORY_INVALID.
    2974             :  */
    2975             : TYPCATEGORY
    2976      176904 : TypeCategory(Oid type)
    2977             : {
    2978             :     char        typcategory;
    2979             :     bool        typispreferred;
    2980             : 
    2981      176904 :     get_type_category_preferred(type, &typcategory, &typispreferred);
    2982             :     Assert(typcategory != TYPCATEGORY_INVALID);
    2983      176904 :     return (TYPCATEGORY) typcategory;
    2984             : }
    2985             : 
    2986             : 
    2987             : /* IsPreferredType()
    2988             :  *      Check if this type is a preferred type for the given category.
    2989             :  *
    2990             :  * If category is TYPCATEGORY_INVALID, then we'll return true for preferred
    2991             :  * types of any category; otherwise, only for preferred types of that
    2992             :  * category.
    2993             :  */
    2994             : bool
    2995       29582 : IsPreferredType(TYPCATEGORY category, Oid type)
    2996             : {
    2997             :     char        typcategory;
    2998             :     bool        typispreferred;
    2999             : 
    3000       29582 :     get_type_category_preferred(type, &typcategory, &typispreferred);
    3001       29582 :     if (category == typcategory || category == TYPCATEGORY_INVALID)
    3002       19288 :         return typispreferred;
    3003             :     else
    3004       10294 :         return false;
    3005             : }
    3006             : 
    3007             : 
    3008             : /* IsBinaryCoercible()
    3009             :  *      Check if srctype is binary-coercible to targettype.
    3010             :  *
    3011             :  * This notion allows us to cheat and directly exchange values without
    3012             :  * going through the trouble of calling a conversion function.  Note that
    3013             :  * in general, this should only be an implementation shortcut.  Before 7.4,
    3014             :  * this was also used as a heuristic for resolving overloaded functions and
    3015             :  * operators, but that's basically a bad idea.
    3016             :  *
    3017             :  * As of 7.3, binary coercibility isn't hardwired into the code anymore.
    3018             :  * We consider two types binary-coercible if there is an implicitly
    3019             :  * invokable, no-function-needed pg_cast entry.  Also, a domain is always
    3020             :  * binary-coercible to its base type, though *not* vice versa (in the other
    3021             :  * direction, one must apply domain constraint checks before accepting the
    3022             :  * value as legitimate).  We also need to special-case various polymorphic
    3023             :  * types.
    3024             :  *
    3025             :  * This function replaces IsBinaryCompatible(), which was an inherently
    3026             :  * symmetric test.  Since the pg_cast entries aren't necessarily symmetric,
    3027             :  * the order of the operands is now significant.
    3028             :  */
    3029             : bool
    3030     2291944 : IsBinaryCoercible(Oid srctype, Oid targettype)
    3031             : {
    3032             :     Oid         castoid;
    3033             : 
    3034     2291944 :     return IsBinaryCoercibleWithCast(srctype, targettype, &castoid);
    3035             : }
    3036             : 
    3037             : /* IsBinaryCoercibleWithCast()
    3038             :  *      Check if srctype is binary-coercible to targettype.
    3039             :  *
    3040             :  * This variant also returns the OID of the pg_cast entry if one is involved.
    3041             :  * *castoid is set to InvalidOid if no binary-coercible cast exists, or if
    3042             :  * there is a hard-wired rule for it rather than a pg_cast entry.
    3043             :  */
    3044             : bool
    3045     2292136 : IsBinaryCoercibleWithCast(Oid srctype, Oid targettype,
    3046             :                           Oid *castoid)
    3047             : {
    3048             :     HeapTuple   tuple;
    3049             :     Form_pg_cast castForm;
    3050             :     bool        result;
    3051             : 
    3052     2292136 :     *castoid = InvalidOid;
    3053             : 
    3054             :     /* Fast path if same type */
    3055     2292136 :     if (srctype == targettype)
    3056      472456 :         return true;
    3057             : 
    3058             :     /* Anything is coercible to ANY or ANYELEMENT or ANYCOMPATIBLE */
    3059     1819680 :     if (targettype == ANYOID || targettype == ANYELEMENTOID ||
    3060             :         targettype == ANYCOMPATIBLEOID)
    3061         188 :         return true;
    3062             : 
    3063             :     /* If srctype is a domain, reduce to its base type */
    3064     1819492 :     if (OidIsValid(srctype))
    3065     1819492 :         srctype = getBaseType(srctype);
    3066             : 
    3067             :     /* Somewhat-fast path for domain -> base type case */
    3068     1819492 :     if (srctype == targettype)
    3069          12 :         return true;
    3070             : 
    3071             :     /* Also accept any array type as coercible to ANY[COMPATIBLE]ARRAY */
    3072     1819480 :     if (targettype == ANYARRAYOID || targettype == ANYCOMPATIBLEARRAYOID)
    3073       98936 :         if (type_is_array(srctype))
    3074        4354 :             return true;
    3075             : 
    3076             :     /* Also accept any non-array type as coercible to ANY[COMPATIBLE]NONARRAY */
    3077     1815126 :     if (targettype == ANYNONARRAYOID || targettype == ANYCOMPATIBLENONARRAYOID)
    3078           0 :         if (!type_is_array(srctype))
    3079           0 :             return true;
    3080             : 
    3081             :     /* Also accept any enum type as coercible to ANYENUM */
    3082     1815126 :     if (targettype == ANYENUMOID)
    3083       89556 :         if (type_is_enum(srctype))
    3084         160 :             return true;
    3085             : 
    3086             :     /* Also accept any range type as coercible to ANY[COMPATIBLE]RANGE */
    3087     1814966 :     if (targettype == ANYRANGEOID || targettype == ANYCOMPATIBLERANGEOID)
    3088       23144 :         if (type_is_range(srctype))
    3089        3326 :             return true;
    3090             : 
    3091             :     /* Also, any multirange type is coercible to ANY[COMPATIBLE]MULTIRANGE */
    3092     1811640 :     if (targettype == ANYMULTIRANGEOID || targettype == ANYCOMPATIBLEMULTIRANGEOID)
    3093       50752 :         if (type_is_multirange(srctype))
    3094         384 :             return true;
    3095             : 
    3096             :     /* Also accept any composite type as coercible to RECORD */
    3097     1811256 :     if (targettype == RECORDOID)
    3098       19460 :         if (ISCOMPLEX(srctype))
    3099         814 :             return true;
    3100             : 
    3101             :     /* Also accept any composite array type as coercible to RECORD[] */
    3102     1810442 :     if (targettype == RECORDARRAYOID)
    3103           0 :         if (is_complex_array(srctype))
    3104           0 :             return true;
    3105             : 
    3106             :     /* Else look in pg_cast */
    3107     1810442 :     tuple = SearchSysCache2(CASTSOURCETARGET,
    3108             :                             ObjectIdGetDatum(srctype),
    3109             :                             ObjectIdGetDatum(targettype));
    3110     1810442 :     if (!HeapTupleIsValid(tuple))
    3111     1488808 :         return false;           /* no cast */
    3112      321634 :     castForm = (Form_pg_cast) GETSTRUCT(tuple);
    3113             : 
    3114      356736 :     result = (castForm->castmethod == COERCION_METHOD_BINARY &&
    3115       35102 :               castForm->castcontext == COERCION_CODE_IMPLICIT);
    3116             : 
    3117      321634 :     if (result)
    3118       13900 :         *castoid = castForm->oid;
    3119             : 
    3120      321634 :     ReleaseSysCache(tuple);
    3121             : 
    3122      321634 :     return result;
    3123             : }
    3124             : 
    3125             : 
    3126             : /*
    3127             :  * find_coercion_pathway
    3128             :  *      Look for a coercion pathway between two types.
    3129             :  *
    3130             :  * Currently, this deals only with scalar-type cases; it does not consider
    3131             :  * polymorphic types nor casts between composite types.  (Perhaps fold
    3132             :  * those in someday?)
    3133             :  *
    3134             :  * ccontext determines the set of available casts.
    3135             :  *
    3136             :  * The possible result codes are:
    3137             :  *  COERCION_PATH_NONE: failed to find any coercion pathway
    3138             :  *              *funcid is set to InvalidOid
    3139             :  *  COERCION_PATH_FUNC: apply the coercion function returned in *funcid
    3140             :  *  COERCION_PATH_RELABELTYPE: binary-compatible cast, no function needed
    3141             :  *              *funcid is set to InvalidOid
    3142             :  *  COERCION_PATH_ARRAYCOERCE: need an ArrayCoerceExpr node
    3143             :  *              *funcid is set to InvalidOid
    3144             :  *  COERCION_PATH_COERCEVIAIO: need a CoerceViaIO node
    3145             :  *              *funcid is set to InvalidOid
    3146             :  *
    3147             :  * Note: COERCION_PATH_RELABELTYPE does not necessarily mean that no work is
    3148             :  * needed to do the coercion; if the target is a domain then we may need to
    3149             :  * apply domain constraint checking.  If you want to check for a zero-effort
    3150             :  * conversion then use IsBinaryCoercible().
    3151             :  */
    3152             : CoercionPathType
    3153     1283980 : find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
    3154             :                       CoercionContext ccontext,
    3155             :                       Oid *funcid)
    3156             : {
    3157     1283980 :     CoercionPathType result = COERCION_PATH_NONE;
    3158             :     HeapTuple   tuple;
    3159             : 
    3160     1283980 :     *funcid = InvalidOid;
    3161             : 
    3162             :     /* Perhaps the types are domains; if so, look at their base types */
    3163     1283980 :     if (OidIsValid(sourceTypeId))
    3164     1283980 :         sourceTypeId = getBaseType(sourceTypeId);
    3165     1283980 :     if (OidIsValid(targetTypeId))
    3166     1283980 :         targetTypeId = getBaseType(targetTypeId);
    3167             : 
    3168             :     /* Domains are always coercible to and from their base type */
    3169     1283980 :     if (sourceTypeId == targetTypeId)
    3170       83388 :         return COERCION_PATH_RELABELTYPE;
    3171             : 
    3172             :     /* Look in pg_cast */
    3173     1200592 :     tuple = SearchSysCache2(CASTSOURCETARGET,
    3174             :                             ObjectIdGetDatum(sourceTypeId),
    3175             :                             ObjectIdGetDatum(targetTypeId));
    3176             : 
    3177     1200592 :     if (HeapTupleIsValid(tuple))
    3178             :     {
    3179      501154 :         Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
    3180             :         CoercionContext castcontext;
    3181             : 
    3182             :         /* convert char value for castcontext to CoercionContext enum */
    3183      501154 :         switch (castForm->castcontext)
    3184             :         {
    3185      409934 :             case COERCION_CODE_IMPLICIT:
    3186      409934 :                 castcontext = COERCION_IMPLICIT;
    3187      409934 :                 break;
    3188       82960 :             case COERCION_CODE_ASSIGNMENT:
    3189       82960 :                 castcontext = COERCION_ASSIGNMENT;
    3190       82960 :                 break;
    3191        8260 :             case COERCION_CODE_EXPLICIT:
    3192        8260 :                 castcontext = COERCION_EXPLICIT;
    3193        8260 :                 break;
    3194           0 :             default:
    3195           0 :                 elog(ERROR, "unrecognized castcontext: %d",
    3196             :                      (int) castForm->castcontext);
    3197             :                 castcontext = 0;    /* keep compiler quiet */
    3198             :                 break;
    3199             :         }
    3200             : 
    3201             :         /* Rely on ordering of enum for correct behavior here */
    3202      501154 :         if (ccontext >= castcontext)
    3203             :         {
    3204      429504 :             switch (castForm->castmethod)
    3205             :             {
    3206      147034 :                 case COERCION_METHOD_FUNCTION:
    3207      147034 :                     result = COERCION_PATH_FUNC;
    3208      147034 :                     *funcid = castForm->castfunc;
    3209      147034 :                     break;
    3210         604 :                 case COERCION_METHOD_INOUT:
    3211         604 :                     result = COERCION_PATH_COERCEVIAIO;
    3212         604 :                     break;
    3213      281866 :                 case COERCION_METHOD_BINARY:
    3214      281866 :                     result = COERCION_PATH_RELABELTYPE;
    3215      281866 :                     break;
    3216           0 :                 default:
    3217           0 :                     elog(ERROR, "unrecognized castmethod: %d",
    3218             :                          (int) castForm->castmethod);
    3219             :                     break;
    3220             :             }
    3221       71650 :         }
    3222             : 
    3223      501154 :         ReleaseSysCache(tuple);
    3224             :     }
    3225             :     else
    3226             :     {
    3227             :         /*
    3228             :          * If there's no pg_cast entry, perhaps we are dealing with a pair of
    3229             :          * array types.  If so, and if their element types have a conversion
    3230             :          * pathway, report that we can coerce with an ArrayCoerceExpr.
    3231             :          *
    3232             :          * Hack: disallow coercions to oidvector and int2vector, which
    3233             :          * otherwise tend to capture coercions that should go to "real" array
    3234             :          * types.  We want those types to be considered "real" arrays for many
    3235             :          * purposes, but not this one.  (Also, ArrayCoerceExpr isn't
    3236             :          * guaranteed to produce an output that meets the restrictions of
    3237             :          * these datatypes, such as being 1-dimensional.)
    3238             :          */
    3239      699438 :         if (targetTypeId != OIDVECTOROID && targetTypeId != INT2VECTOROID)
    3240             :         {
    3241             :             Oid         targetElem;
    3242             :             Oid         sourceElem;
    3243             : 
    3244      699662 :             if ((targetElem = get_element_type(targetTypeId)) != InvalidOid &&
    3245       10892 :                 (sourceElem = get_element_type(sourceTypeId)) != InvalidOid)
    3246             :             {
    3247             :                 CoercionPathType elempathtype;
    3248             :                 Oid         elemfuncid;
    3249             : 
    3250        9804 :                 elempathtype = find_coercion_pathway(targetElem,
    3251             :                                                      sourceElem,
    3252             :                                                      ccontext,
    3253             :                                                      &elemfuncid);
    3254        9804 :                 if (elempathtype != COERCION_PATH_NONE)
    3255             :                 {
    3256        9662 :                     result = COERCION_PATH_ARRAYCOERCE;
    3257             :                 }
    3258             :             }
    3259             :         }
    3260             : 
    3261             :         /*
    3262             :          * If we still haven't found a possibility, consider automatic casting
    3263             :          * using I/O functions.  We allow assignment casts to string types and
    3264             :          * explicit casts from string types to be handled this way. (The
    3265             :          * CoerceViaIO mechanism is a lot more general than that, but this is
    3266             :          * all we want to allow in the absence of a pg_cast entry.) It would
    3267             :          * probably be better to insist on explicit casts in both directions,
    3268             :          * but this is a compromise to preserve something of the pre-8.3
    3269             :          * behavior that many types had implicit (yipes!) casts to text.
    3270             :          */
    3271      699438 :         if (result == COERCION_PATH_NONE)
    3272             :         {
    3273      738940 :             if (ccontext >= COERCION_ASSIGNMENT &&
    3274       49164 :                 TypeCategory(targetTypeId) == TYPCATEGORY_STRING)
    3275       39502 :                 result = COERCION_PATH_COERCEVIAIO;
    3276      658908 :             else if (ccontext >= COERCION_EXPLICIT &&
    3277        8634 :                      TypeCategory(sourceTypeId) == TYPCATEGORY_STRING)
    3278        5336 :                 result = COERCION_PATH_COERCEVIAIO;
    3279             :         }
    3280             :     }
    3281             : 
    3282             :     /*
    3283             :      * When parsing PL/pgSQL assignments, allow an I/O cast to be used
    3284             :      * whenever no normal coercion is available.
    3285             :      */
    3286     1200592 :     if (result == COERCION_PATH_NONE &&
    3287             :         ccontext == COERCION_PLPGSQL)
    3288         224 :         result = COERCION_PATH_COERCEVIAIO;
    3289             : 
    3290     1200592 :     return result;
    3291             : }
    3292             : 
    3293             : 
    3294             : /*
    3295             :  * find_typmod_coercion_function -- does the given type need length coercion?
    3296             :  *
    3297             :  * If the target type possesses a pg_cast function from itself to itself,
    3298             :  * it must need length coercion.
    3299             :  *
    3300             :  * "bpchar" (ie, char(N)) and "numeric" are examples of such types.
    3301             :  *
    3302             :  * If the given type is a varlena array type, we do not look for a coercion
    3303             :  * function associated directly with the array type, but instead look for
    3304             :  * one associated with the element type.  An ArrayCoerceExpr node must be
    3305             :  * used to apply such a function.  (Note: currently, it's pointless to
    3306             :  * return the funcid in this case, because it'll just get looked up again
    3307             :  * in the recursive construction of the ArrayCoerceExpr's elemexpr.)
    3308             :  *
    3309             :  * We use the same result enum as find_coercion_pathway, but the only possible
    3310             :  * result codes are:
    3311             :  *  COERCION_PATH_NONE: no length coercion needed
    3312             :  *  COERCION_PATH_FUNC: apply the function returned in *funcid
    3313             :  *  COERCION_PATH_ARRAYCOERCE: apply the function using ArrayCoerceExpr
    3314             :  */
    3315             : CoercionPathType
    3316       18596 : find_typmod_coercion_function(Oid typeId,
    3317             :                               Oid *funcid)
    3318             : {
    3319             :     CoercionPathType result;
    3320             :     Type        targetType;
    3321             :     Form_pg_type typeForm;
    3322             :     HeapTuple   tuple;
    3323             : 
    3324       18596 :     *funcid = InvalidOid;
    3325       18596 :     result = COERCION_PATH_FUNC;
    3326             : 
    3327       18596 :     targetType = typeidType(typeId);
    3328       18596 :     typeForm = (Form_pg_type) GETSTRUCT(targetType);
    3329             : 
    3330             :     /* Check for a "true" array type */
    3331       18596 :     if (IsTrueArrayType(typeForm))
    3332             :     {
    3333             :         /* Yes, switch our attention to the element type */
    3334          78 :         typeId = typeForm->typelem;
    3335          78 :         result = COERCION_PATH_ARRAYCOERCE;
    3336             :     }
    3337       18596 :     ReleaseSysCache(targetType);
    3338             : 
    3339             :     /* Look in pg_cast */
    3340       18596 :     tuple = SearchSysCache2(CASTSOURCETARGET,
    3341             :                             ObjectIdGetDatum(typeId),
    3342             :                             ObjectIdGetDatum(typeId));
    3343             : 
    3344       18596 :     if (HeapTupleIsValid(tuple))
    3345             :     {
    3346       18584 :         Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
    3347             : 
    3348       18584 :         *funcid = castForm->castfunc;
    3349       18584 :         ReleaseSysCache(tuple);
    3350             :     }
    3351             : 
    3352       18596 :     if (!OidIsValid(*funcid))
    3353          12 :         result = COERCION_PATH_NONE;
    3354             : 
    3355       18596 :     return result;
    3356             : }
    3357             : 
    3358             : /*
    3359             :  * is_complex_array
    3360             :  *      Is this type an array of composite?
    3361             :  *
    3362             :  * Note: this will not return true for record[]; check for RECORDARRAYOID
    3363             :  * separately if needed.
    3364             :  */
    3365             : static bool
    3366          28 : is_complex_array(Oid typid)
    3367             : {
    3368          28 :     Oid         elemtype = get_element_type(typid);
    3369             : 
    3370          28 :     return (OidIsValid(elemtype) && ISCOMPLEX(elemtype));
    3371             : }
    3372             : 
    3373             : 
    3374             : /*
    3375             :  * Check whether reltypeId is the row type of a typed table of type
    3376             :  * reloftypeId, or is a domain over such a row type.  (This is conceptually
    3377             :  * similar to the subtype relationship checked by typeInheritsFrom().)
    3378             :  */
    3379             : static bool
    3380      709772 : typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId)
    3381             : {
    3382      709772 :     Oid         relid = typeOrDomainTypeRelid(reltypeId);
    3383      709772 :     bool        result = false;
    3384             : 
    3385      709772 :     if (relid)
    3386             :     {
    3387             :         HeapTuple   tp;
    3388             :         Form_pg_class reltup;
    3389             : 
    3390       13448 :         tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
    3391       13448 :         if (!HeapTupleIsValid(tp))
    3392           0 :             elog(ERROR, "cache lookup failed for relation %u", relid);
    3393             : 
    3394       13448 :         reltup = (Form_pg_class) GETSTRUCT(tp);
    3395       13448 :         if (reltup->reloftype == reloftypeId)
    3396          12 :             result = true;
    3397             : 
    3398       13448 :         ReleaseSysCache(tp);
    3399             :     }
    3400             : 
    3401      709772 :     return result;
    3402             : }

Generated by: LCOV version 1.14