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

Generated by: LCOV version 1.16