LCOV - code coverage report
Current view: top level - src/backend/parser - parse_coerce.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 613 692 88.6 %
Date: 2019-11-21 15:06:52 Functions: 24 24 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-2019, 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"
      30             : #include "utils/lsyscache.h"
      31             : #include "utils/syscache.h"
      32             : #include "utils/typcache.h"
      33             : 
      34             : 
      35             : static Node *coerce_type_typmod(Node *node,
      36             :                                 Oid targetTypeId, int32 targetTypMod,
      37             :                                 CoercionContext ccontext, CoercionForm cformat,
      38             :                                 int location,
      39             :                                 bool hideInputCoercion);
      40             : static void hide_coercion_node(Node *node);
      41             : static Node *build_coercion_expression(Node *node,
      42             :                                        CoercionPathType pathtype,
      43             :                                        Oid funcId,
      44             :                                        Oid targetTypeId, int32 targetTypMod,
      45             :                                        CoercionContext ccontext, CoercionForm cformat,
      46             :                                        int location);
      47             : static Node *coerce_record_to_complex(ParseState *pstate, Node *node,
      48             :                                       Oid targetTypeId,
      49             :                                       CoercionContext ccontext,
      50             :                                       CoercionForm cformat,
      51             :                                       int location);
      52             : static bool is_complex_array(Oid typid);
      53             : static bool typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId);
      54             : 
      55             : 
      56             : /*
      57             :  * coerce_to_target_type()
      58             :  *      Convert an expression to a target type and typmod.
      59             :  *
      60             :  * This is the general-purpose entry point for arbitrary type coercion
      61             :  * operations.  Direct use of the component operations can_coerce_type,
      62             :  * coerce_type, and coerce_type_typmod should be restricted to special
      63             :  * cases (eg, when the conversion is expected to succeed).
      64             :  *
      65             :  * Returns the possibly-transformed expression tree, or NULL if the type
      66             :  * conversion is not possible.  (We do this, rather than ereport'ing directly,
      67             :  * so that callers can generate custom error messages indicating context.)
      68             :  *
      69             :  * pstate - parse state (can be NULL, see coerce_type)
      70             :  * expr - input expression tree (already transformed by transformExpr)
      71             :  * exprtype - result type of expr
      72             :  * targettype - desired result type
      73             :  * targettypmod - desired result typmod
      74             :  * ccontext, cformat - context indicators to control coercions
      75             :  * location - parse location of the coercion request, or -1 if unknown/implicit
      76             :  */
      77             : Node *
      78      627114 : coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype,
      79             :                       Oid targettype, int32 targettypmod,
      80             :                       CoercionContext ccontext,
      81             :                       CoercionForm cformat,
      82             :                       int location)
      83             : {
      84             :     Node       *result;
      85             :     Node       *origexpr;
      86             : 
      87      627114 :     if (!can_coerce_type(1, &exprtype, &targettype, ccontext))
      88         254 :         return NULL;
      89             : 
      90             :     /*
      91             :      * If the input has a CollateExpr at the top, strip it off, perform the
      92             :      * coercion, and put a new one back on.  This is annoying since it
      93             :      * duplicates logic in coerce_type, but if we don't do this then it's too
      94             :      * hard to tell whether coerce_type actually changed anything, and we
      95             :      * *must* know that to avoid possibly calling hide_coercion_node on
      96             :      * something that wasn't generated by coerce_type.  Note that if there are
      97             :      * multiple stacked CollateExprs, we just discard all but the topmost.
      98             :      */
      99      626860 :     origexpr = expr;
     100     1253732 :     while (expr && IsA(expr, CollateExpr))
     101          12 :         expr = (Node *) ((CollateExpr *) expr)->arg;
     102             : 
     103      626860 :     result = coerce_type(pstate, expr, exprtype,
     104             :                          targettype, targettypmod,
     105             :                          ccontext, cformat, location);
     106             : 
     107             :     /*
     108             :      * If the target is a fixed-length type, it may need a length coercion as
     109             :      * well as a type coercion.  If we find ourselves adding both, force the
     110             :      * inner coercion node to implicit display form.
     111             :      */
     112      625124 :     result = coerce_type_typmod(result,
     113             :                                 targettype, targettypmod,
     114             :                                 ccontext, cformat, location,
     115      625124 :                                 (result != expr && !IsA(result, Const)));
     116             : 
     117      625124 :     if (expr != origexpr)
     118             :     {
     119             :         /* Reinstall top CollateExpr */
     120          12 :         CollateExpr *coll = (CollateExpr *) origexpr;
     121          12 :         CollateExpr *newcoll = makeNode(CollateExpr);
     122             : 
     123          12 :         newcoll->arg = (Expr *) result;
     124          12 :         newcoll->collOid = coll->collOid;
     125          12 :         newcoll->location = coll->location;
     126          12 :         result = (Node *) newcoll;
     127             :     }
     128             : 
     129      625124 :     return result;
     130             : }
     131             : 
     132             : 
     133             : /*
     134             :  * coerce_type()
     135             :  *      Convert an expression to a different type.
     136             :  *
     137             :  * The caller should already have determined that the coercion is possible;
     138             :  * see can_coerce_type.
     139             :  *
     140             :  * Normally, no coercion to a typmod (length) is performed here.  The caller
     141             :  * must call coerce_type_typmod as well, if a typmod constraint is wanted.
     142             :  * (But if the target type is a domain, it may internally contain a
     143             :  * typmod constraint, which will be applied inside coerce_to_domain.)
     144             :  * In some cases pg_cast specifies a type coercion function that also
     145             :  * applies length conversion, and in those cases only, the result will
     146             :  * already be properly coerced to the specified typmod.
     147             :  *
     148             :  * pstate is only used in the case that we are able to resolve the type of
     149             :  * a previously UNKNOWN Param.  It is okay to pass pstate = NULL if the
     150             :  * caller does not want type information updated for Params.
     151             :  *
     152             :  * Note: this function must not modify the given expression tree, only add
     153             :  * decoration on top of it.  See transformSetOperationTree, for example.
     154             :  */
     155             : Node *
     156     1228892 : coerce_type(ParseState *pstate, Node *node,
     157             :             Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod,
     158             :             CoercionContext ccontext, CoercionForm cformat, int location)
     159             : {
     160             :     Node       *result;
     161             :     CoercionPathType pathtype;
     162             :     Oid         funcId;
     163             : 
     164     1228892 :     if (targetTypeId == inputTypeId ||
     165             :         node == NULL)
     166             :     {
     167             :         /* no conversion needed */
     168      124336 :         return node;
     169             :     }
     170     1104556 :     if (targetTypeId == ANYOID ||
     171     1096930 :         targetTypeId == ANYELEMENTOID ||
     172             :         targetTypeId == ANYNONARRAYOID)
     173             :     {
     174             :         /*
     175             :          * Assume can_coerce_type verified that implicit coercion is okay.
     176             :          *
     177             :          * Note: by returning the unmodified node here, we are saying that
     178             :          * it's OK to treat an UNKNOWN constant as a valid input for a
     179             :          * function accepting ANY, ANYELEMENT, or ANYNONARRAY.  This should be
     180             :          * all right, since an UNKNOWN value is still a perfectly valid Datum.
     181             :          *
     182             :          * NB: we do NOT want a RelabelType here: the exposed type of the
     183             :          * function argument must be its actual type, not the polymorphic
     184             :          * pseudotype.
     185             :          */
     186       22666 :         return node;
     187             :     }
     188     1081890 :     if (targetTypeId == ANYARRAYOID ||
     189     1027108 :         targetTypeId == ANYENUMOID ||
     190             :         targetTypeId == ANYRANGEOID)
     191             :     {
     192             :         /*
     193             :          * Assume can_coerce_type verified that implicit coercion is okay.
     194             :          *
     195             :          * These cases are unlike the ones above because the exposed type of
     196             :          * the argument must be an actual array, enum, or range type.  In
     197             :          * particular the argument must *not* be an UNKNOWN constant.  If it
     198             :          * is, we just fall through; below, we'll call anyarray_in,
     199             :          * anyenum_in, or anyrange_in, which will produce an error.  Also, if
     200             :          * what we have is a domain over array, enum, or range, we have to
     201             :          * relabel it to its base type.
     202             :          *
     203             :          * Note: currently, we can't actually see a domain-over-enum here,
     204             :          * since the other functions in this file will not match such a
     205             :          * parameter to ANYENUM.  But that should get changed eventually.
     206             :          */
     207       56464 :         if (inputTypeId != UNKNOWNOID)
     208             :         {
     209       50620 :             Oid         baseTypeId = getBaseType(inputTypeId);
     210             : 
     211       50620 :             if (baseTypeId != inputTypeId)
     212             :             {
     213          40 :                 RelabelType *r = makeRelabelType((Expr *) node,
     214             :                                                  baseTypeId, -1,
     215             :                                                  InvalidOid,
     216             :                                                  cformat);
     217             : 
     218          40 :                 r->location = location;
     219          40 :                 return (Node *) r;
     220             :             }
     221             :             /* Not a domain type, so return it as-is */
     222       50580 :             return node;
     223             :         }
     224             :     }
     225     1031270 :     if (inputTypeId == UNKNOWNOID && IsA(node, Const))
     226             :     {
     227             :         /*
     228             :          * Input is a string constant with previously undetermined type. Apply
     229             :          * the target type's typinput function to it to produce a constant of
     230             :          * the target type.
     231             :          *
     232             :          * NOTE: this case cannot be folded together with the other
     233             :          * constant-input case, since the typinput function does not
     234             :          * necessarily behave the same as a type conversion function. For
     235             :          * example, int4's typinput function will reject "1.2", whereas
     236             :          * float-to-int type conversion will round to integer.
     237             :          *
     238             :          * XXX if the typinput function is not immutable, we really ought to
     239             :          * postpone evaluation of the function call until runtime. But there
     240             :          * is no way to represent a typinput function call as an expression
     241             :          * tree, because C-string values are not Datums. (XXX This *is*
     242             :          * possible as of 7.3, do we want to do it?)
     243             :          */
     244      694524 :         Const      *con = (Const *) node;
     245      694524 :         Const      *newcon = makeNode(Const);
     246             :         Oid         baseTypeId;
     247             :         int32       baseTypeMod;
     248             :         int32       inputTypeMod;
     249             :         Type        baseType;
     250             :         ParseCallbackState pcbstate;
     251             : 
     252             :         /*
     253             :          * If the target type is a domain, we want to call its base type's
     254             :          * input routine, not domain_in().  This is to avoid premature failure
     255             :          * when the domain applies a typmod: existing input routines follow
     256             :          * implicit-coercion semantics for length checks, which is not always
     257             :          * what we want here.  The needed check will be applied properly
     258             :          * inside coerce_to_domain().
     259             :          */
     260      694524 :         baseTypeMod = targetTypeMod;
     261      694524 :         baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
     262             : 
     263             :         /*
     264             :          * For most types we pass typmod -1 to the input routine, because
     265             :          * existing input routines follow implicit-coercion semantics for
     266             :          * length checks, which is not always what we want here.  Any length
     267             :          * constraint will be applied later by our caller.  An exception
     268             :          * however is the INTERVAL type, for which we *must* pass the typmod
     269             :          * or it won't be able to obey the bizarre SQL-spec input rules. (Ugly
     270             :          * as sin, but so is this part of the spec...)
     271             :          */
     272      694524 :         if (baseTypeId == INTERVALOID)
     273        1362 :             inputTypeMod = baseTypeMod;
     274             :         else
     275      693162 :             inputTypeMod = -1;
     276             : 
     277      694524 :         baseType = typeidType(baseTypeId);
     278             : 
     279      694524 :         newcon->consttype = baseTypeId;
     280      694524 :         newcon->consttypmod = inputTypeMod;
     281      694524 :         newcon->constcollid = typeTypeCollation(baseType);
     282      694524 :         newcon->constlen = typeLen(baseType);
     283      694524 :         newcon->constbyval = typeByVal(baseType);
     284      694524 :         newcon->constisnull = con->constisnull;
     285             : 
     286             :         /*
     287             :          * We use the original literal's location regardless of the position
     288             :          * of the coercion.  This is a change from pre-9.2 behavior, meant to
     289             :          * simplify life for pg_stat_statements.
     290             :          */
     291      694524 :         newcon->location = con->location;
     292             : 
     293             :         /*
     294             :          * Set up to point at the constant's text if the input routine throws
     295             :          * an error.
     296             :          */
     297      694524 :         setup_parser_errposition_callback(&pcbstate, pstate, con->location);
     298             : 
     299             :         /*
     300             :          * We assume here that UNKNOWN's internal representation is the same
     301             :          * as CSTRING.
     302             :          */
     303      694524 :         if (!con->constisnull)
     304      574844 :             newcon->constvalue = stringTypeDatum(baseType,
     305      574844 :                                                  DatumGetCString(con->constvalue),
     306             :                                                  inputTypeMod);
     307             :         else
     308      119680 :             newcon->constvalue = stringTypeDatum(baseType,
     309             :                                                  NULL,
     310             :                                                  inputTypeMod);
     311             : 
     312             :         /*
     313             :          * If it's a varlena value, force it to be in non-expanded
     314             :          * (non-toasted) format; this avoids any possible dependency on
     315             :          * external values and improves consistency of representation.
     316             :          */
     317      692684 :         if (!con->constisnull && newcon->constlen == -1)
     318      292374 :             newcon->constvalue =
     319      292374 :                 PointerGetDatum(PG_DETOAST_DATUM(newcon->constvalue));
     320             : 
     321             : #ifdef RANDOMIZE_ALLOCATED_MEMORY
     322             : 
     323             :         /*
     324             :          * For pass-by-reference data types, repeat the conversion to see if
     325             :          * the input function leaves any uninitialized bytes in the result. We
     326             :          * can only detect that reliably if RANDOMIZE_ALLOCATED_MEMORY is
     327             :          * enabled, so we don't bother testing otherwise.  The reason we don't
     328             :          * want any instability in the input function is that comparison of
     329             :          * Const nodes relies on bytewise comparison of the datums, so if the
     330             :          * input function leaves garbage then subexpressions that should be
     331             :          * identical may not get recognized as such.  See pgsql-hackers
     332             :          * discussion of 2008-04-04.
     333             :          */
     334             :         if (!con->constisnull && !newcon->constbyval)
     335             :         {
     336             :             Datum       val2;
     337             : 
     338             :             val2 = stringTypeDatum(baseType,
     339             :                                    DatumGetCString(con->constvalue),
     340             :                                    inputTypeMod);
     341             :             if (newcon->constlen == -1)
     342             :                 val2 = PointerGetDatum(PG_DETOAST_DATUM(val2));
     343             :             if (!datumIsEqual(newcon->constvalue, val2, false, newcon->constlen))
     344             :                 elog(WARNING, "type %s has unstable input conversion for \"%s\"",
     345             :                      typeTypeName(baseType), DatumGetCString(con->constvalue));
     346             :         }
     347             : #endif
     348             : 
     349      692684 :         cancel_parser_errposition_callback(&pcbstate);
     350             : 
     351      692684 :         result = (Node *) newcon;
     352             : 
     353             :         /* If target is a domain, apply constraints. */
     354      692684 :         if (baseTypeId != targetTypeId)
     355      109954 :             result = coerce_to_domain(result,
     356             :                                       baseTypeId, baseTypeMod,
     357             :                                       targetTypeId,
     358             :                                       ccontext, cformat, location,
     359             :                                       false);
     360             : 
     361      692684 :         ReleaseSysCache(baseType);
     362             : 
     363      692684 :         return result;
     364             :     }
     365      336746 :     if (IsA(node, Param) &&
     366       18576 :         pstate != NULL && pstate->p_coerce_param_hook != NULL)
     367             :     {
     368             :         /*
     369             :          * Allow the CoerceParamHook to decide what happens.  It can return a
     370             :          * transformed node (very possibly the same Param node), or return
     371             :          * NULL to indicate we should proceed with normal coercion.
     372             :          */
     373       10322 :         result = pstate->p_coerce_param_hook(pstate,
     374             :                                              (Param *) node,
     375             :                                              targetTypeId,
     376             :                                              targetTypeMod,
     377             :                                              location);
     378       10322 :         if (result)
     379       10310 :             return result;
     380             :     }
     381      326436 :     if (IsA(node, CollateExpr))
     382             :     {
     383             :         /*
     384             :          * If we have a COLLATE clause, we have to push the coercion
     385             :          * underneath the COLLATE.  This is really ugly, but there is little
     386             :          * choice because the above hacks on Consts and Params wouldn't happen
     387             :          * otherwise.  This kluge has consequences in coerce_to_target_type.
     388             :          */
     389        2212 :         CollateExpr *coll = (CollateExpr *) node;
     390        2212 :         CollateExpr *newcoll = makeNode(CollateExpr);
     391             : 
     392        2212 :         newcoll->arg = (Expr *)
     393        2212 :             coerce_type(pstate, (Node *) coll->arg,
     394             :                         inputTypeId, targetTypeId, targetTypeMod,
     395             :                         ccontext, cformat, location);
     396        2212 :         newcoll->collOid = coll->collOid;
     397        2212 :         newcoll->location = coll->location;
     398        2212 :         return (Node *) newcoll;
     399             :     }
     400      324224 :     pathtype = find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
     401             :                                      &funcId);
     402      324224 :     if (pathtype != COERCION_PATH_NONE)
     403             :     {
     404      322224 :         if (pathtype != COERCION_PATH_RELABELTYPE)
     405             :         {
     406             :             /*
     407             :              * Generate an expression tree representing run-time application
     408             :              * of the conversion function.  If we are dealing with a domain
     409             :              * target type, the conversion function will yield the base type,
     410             :              * and we need to extract the correct typmod to use from the
     411             :              * domain's typtypmod.
     412             :              */
     413             :             Oid         baseTypeId;
     414             :             int32       baseTypeMod;
     415             : 
     416       73458 :             baseTypeMod = targetTypeMod;
     417       73458 :             baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
     418             : 
     419       73458 :             result = build_coercion_expression(node, pathtype, funcId,
     420             :                                                baseTypeId, baseTypeMod,
     421             :                                                ccontext, cformat, location);
     422             : 
     423             :             /*
     424             :              * If domain, coerce to the domain type and relabel with domain
     425             :              * type ID, hiding the previous coercion node.
     426             :              */
     427       73458 :             if (targetTypeId != baseTypeId)
     428        9038 :                 result = coerce_to_domain(result, baseTypeId, baseTypeMod,
     429             :                                           targetTypeId,
     430             :                                           ccontext, cformat, location,
     431             :                                           true);
     432             :         }
     433             :         else
     434             :         {
     435             :             /*
     436             :              * We don't need to do a physical conversion, but we do need to
     437             :              * attach a RelabelType node so that the expression will be seen
     438             :              * to have the intended type when inspected by higher-level code.
     439             :              *
     440             :              * Also, domains may have value restrictions beyond the base type
     441             :              * that must be accounted for.  If the destination is a domain
     442             :              * then we won't need a RelabelType node.
     443             :              */
     444      248766 :             result = coerce_to_domain(node, InvalidOid, -1, targetTypeId,
     445             :                                       ccontext, cformat, location,
     446             :                                       false);
     447      248766 :             if (result == node)
     448             :             {
     449             :                 /*
     450             :                  * XXX could we label result with exprTypmod(node) instead of
     451             :                  * default -1 typmod, to save a possible length-coercion
     452             :                  * later? Would work if both types have same interpretation of
     453             :                  * typmod, which is likely but not certain.
     454             :                  */
     455      106352 :                 RelabelType *r = makeRelabelType((Expr *) result,
     456             :                                                  targetTypeId, -1,
     457             :                                                  InvalidOid,
     458             :                                                  cformat);
     459             : 
     460      106352 :                 r->location = location;
     461      106352 :                 result = (Node *) r;
     462             :             }
     463             :         }
     464      322224 :         return result;
     465             :     }
     466        3196 :     if (inputTypeId == RECORDOID &&
     467        1196 :         ISCOMPLEX(targetTypeId))
     468             :     {
     469             :         /* Coerce a RECORD to a specific complex type */
     470        1196 :         return coerce_record_to_complex(pstate, node, targetTypeId,
     471             :                                         ccontext, cformat, location);
     472             :     }
     473        1556 :     if (targetTypeId == RECORDOID &&
     474         752 :         ISCOMPLEX(inputTypeId))
     475             :     {
     476             :         /* Coerce a specific complex type to RECORD */
     477             :         /* NB: we do NOT want a RelabelType here */
     478         752 :         return node;
     479             :     }
     480             : #ifdef NOT_USED
     481             :     if (inputTypeId == RECORDARRAYOID &&
     482             :         is_complex_array(targetTypeId))
     483             :     {
     484             :         /* Coerce record[] to a specific complex array type */
     485             :         /* not implemented yet ... */
     486             :     }
     487             : #endif
     488          64 :     if (targetTypeId == RECORDARRAYOID &&
     489          12 :         is_complex_array(inputTypeId))
     490             :     {
     491             :         /* Coerce a specific complex array type to record[] */
     492             :         /* NB: we do NOT want a RelabelType here */
     493          12 :         return node;
     494             :     }
     495          40 :     if (typeInheritsFrom(inputTypeId, targetTypeId)
     496           4 :         || typeIsOfTypedTable(inputTypeId, targetTypeId))
     497             :     {
     498             :         /*
     499             :          * Input class type is a subclass of target, so generate an
     500             :          * appropriate runtime conversion (removing unneeded columns and
     501             :          * possibly rearranging the ones that are wanted).
     502             :          *
     503             :          * We will also get here when the input is a domain over a subclass of
     504             :          * the target type.  To keep life simple for the executor, we define
     505             :          * ConvertRowtypeExpr as only working between regular composite types;
     506             :          * therefore, in such cases insert a RelabelType to smash the input
     507             :          * expression down to its base type.
     508             :          */
     509          40 :         Oid         baseTypeId = getBaseType(inputTypeId);
     510          40 :         ConvertRowtypeExpr *r = makeNode(ConvertRowtypeExpr);
     511             : 
     512          40 :         if (baseTypeId != inputTypeId)
     513             :         {
     514           0 :             RelabelType *rt = makeRelabelType((Expr *) node,
     515             :                                               baseTypeId, -1,
     516             :                                               InvalidOid,
     517             :                                               COERCE_IMPLICIT_CAST);
     518             : 
     519           0 :             rt->location = location;
     520           0 :             node = (Node *) rt;
     521             :         }
     522          40 :         r->arg = (Expr *) node;
     523          40 :         r->resulttype = targetTypeId;
     524          40 :         r->convertformat = cformat;
     525          40 :         r->location = location;
     526          40 :         return (Node *) r;
     527             :     }
     528             :     /* If we get here, caller blew it */
     529           0 :     elog(ERROR, "failed to find conversion function from %s to %s",
     530             :          format_type_be(inputTypeId), format_type_be(targetTypeId));
     531             :     return NULL;                /* keep compiler quiet */
     532             : }
     533             : 
     534             : 
     535             : /*
     536             :  * can_coerce_type()
     537             :  *      Can input_typeids be coerced to target_typeids?
     538             :  *
     539             :  * We must be told the context (CAST construct, assignment, implicit coercion)
     540             :  * as this determines the set of available casts.
     541             :  */
     542             : bool
     543     1686018 : can_coerce_type(int nargs, const Oid *input_typeids, const Oid *target_typeids,
     544             :                 CoercionContext ccontext)
     545             : {
     546     1686018 :     bool        have_generics = false;
     547             :     int         i;
     548             : 
     549             :     /* run through argument list... */
     550     2944656 :     for (i = 0; i < nargs; i++)
     551             :     {
     552     1885620 :         Oid         inputTypeId = input_typeids[i];
     553     1885620 :         Oid         targetTypeId = target_typeids[i];
     554             :         CoercionPathType pathtype;
     555             :         Oid         funcId;
     556             : 
     557             :         /* no problem if same type */
     558     1885620 :         if (inputTypeId == targetTypeId)
     559     1475074 :             continue;
     560             : 
     561             :         /* accept if target is ANY */
     562     1669184 :         if (targetTypeId == ANYOID)
     563        4406 :             continue;
     564             : 
     565             :         /* accept if target is polymorphic, for now */
     566     1664778 :         if (IsPolymorphicType(targetTypeId))
     567             :         {
     568      149194 :             have_generics = true;   /* do more checking later */
     569      149194 :             continue;
     570             :         }
     571             : 
     572             :         /*
     573             :          * If input is an untyped string constant, assume we can convert it to
     574             :          * anything.
     575             :          */
     576     1515584 :         if (inputTypeId == UNKNOWNOID)
     577      574738 :             continue;
     578             : 
     579             :         /*
     580             :          * If pg_cast shows that we can coerce, accept.  This test now covers
     581             :          * both binary-compatible and coercion-function cases.
     582             :          */
     583      940846 :         pathtype = find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
     584             :                                          &funcId);
     585      940846 :         if (pathtype != COERCION_PATH_NONE)
     586      312056 :             continue;
     587             : 
     588             :         /*
     589             :          * If input is RECORD and target is a composite type, assume we can
     590             :          * coerce (may need tighter checking here)
     591             :          */
     592      630042 :         if (inputTypeId == RECORDOID &&
     593        1252 :             ISCOMPLEX(targetTypeId))
     594        1196 :             continue;
     595             : 
     596             :         /*
     597             :          * If input is a composite type and target is RECORD, accept
     598             :          */
     599      637482 :         if (targetTypeId == RECORDOID &&
     600        9888 :             ISCOMPLEX(inputTypeId))
     601         572 :             continue;
     602             : 
     603             : #ifdef NOT_USED                 /* not implemented yet */
     604             : 
     605             :         /*
     606             :          * If input is record[] and target is a composite array type, assume
     607             :          * we can coerce (may need tighter checking here)
     608             :          */
     609             :         if (inputTypeId == RECORDARRAYOID &&
     610             :             is_complex_array(targetTypeId))
     611             :             continue;
     612             : #endif
     613             : 
     614             :         /*
     615             :          * If input is a composite array type and target is record[], accept
     616             :          */
     617      627022 :         if (targetTypeId == RECORDARRAYOID &&
     618           0 :             is_complex_array(inputTypeId))
     619           0 :             continue;
     620             : 
     621             :         /*
     622             :          * If input is a class type that inherits from target, accept
     623             :          */
     624      627022 :         if (typeInheritsFrom(inputTypeId, targetTypeId)
     625      626986 :             || typeIsOfTypedTable(inputTypeId, targetTypeId))
     626          40 :             continue;
     627             : 
     628             :         /*
     629             :          * Else, cannot coerce at this argument position
     630             :          */
     631      626982 :         return false;
     632             :     }
     633             : 
     634             :     /* If we found any generic argument types, cross-check them */
     635     1059036 :     if (have_generics)
     636             :     {
     637      113814 :         if (!check_generic_type_consistency(input_typeids, target_typeids,
     638             :                                             nargs))
     639       46938 :             return false;
     640             :     }
     641             : 
     642     1012098 :     return true;
     643             : }
     644             : 
     645             : 
     646             : /*
     647             :  * Create an expression tree to represent coercion to a domain type.
     648             :  *
     649             :  * 'arg': input expression
     650             :  * 'baseTypeId': base type of domain, if known (pass InvalidOid if caller
     651             :  *      has not bothered to look this up)
     652             :  * 'baseTypeMod': base type typmod of domain, if known (pass -1 if caller
     653             :  *      has not bothered to look this up)
     654             :  * 'typeId': target type to coerce to
     655             :  * 'ccontext': context indicator to control coercions
     656             :  * 'cformat': coercion display format
     657             :  * 'location': coercion request location
     658             :  * 'hideInputCoercion': if true, hide the input coercion under this one.
     659             :  *
     660             :  * If the target type isn't a domain, the given 'arg' is returned as-is.
     661             :  */
     662             : Node *
     663      381796 : coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId,
     664             :                  CoercionContext ccontext, CoercionForm cformat, int location,
     665             :                  bool hideInputCoercion)
     666             : {
     667             :     CoerceToDomain *result;
     668             : 
     669             :     /* Get the base type if it hasn't been supplied */
     670      381796 :     if (baseTypeId == InvalidOid)
     671      262672 :         baseTypeId = getBaseTypeAndTypmod(typeId, &baseTypeMod);
     672             : 
     673             :     /* If it isn't a domain, return the node as it was passed in */
     674      381796 :     if (baseTypeId == typeId)
     675      120214 :         return arg;
     676             : 
     677             :     /* Suppress display of nested coercion steps */
     678      261582 :     if (hideInputCoercion)
     679        9038 :         hide_coercion_node(arg);
     680             : 
     681             :     /*
     682             :      * If the domain applies a typmod to its base type, build the appropriate
     683             :      * coercion step.  Mark it implicit for display purposes, because we don't
     684             :      * want it shown separately by ruleutils.c; but the isExplicit flag passed
     685             :      * to the conversion function depends on the manner in which the domain
     686             :      * coercion is invoked, so that the semantics of implicit and explicit
     687             :      * coercion differ.  (Is that really the behavior we want?)
     688             :      *
     689             :      * NOTE: because we apply this as part of the fixed expression structure,
     690             :      * ALTER DOMAIN cannot alter the typtypmod.  But it's unclear that that
     691             :      * would be safe to do anyway, without lots of knowledge about what the
     692             :      * base type thinks the typmod means.
     693             :      */
     694      261582 :     arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod,
     695             :                              ccontext, COERCE_IMPLICIT_CAST, location,
     696             :                              false);
     697             : 
     698             :     /*
     699             :      * Now build the domain coercion node.  This represents run-time checking
     700             :      * of any constraints currently attached to the domain.  This also ensures
     701             :      * that the expression is properly labeled as to result type.
     702             :      */
     703      261582 :     result = makeNode(CoerceToDomain);
     704      261582 :     result->arg = (Expr *) arg;
     705      261582 :     result->resulttype = typeId;
     706      261582 :     result->resulttypmod = -1;   /* currently, always -1 for domains */
     707             :     /* resultcollid will be set by parse_collate.c */
     708      261582 :     result->coercionformat = cformat;
     709      261582 :     result->location = location;
     710             : 
     711      261582 :     return (Node *) result;
     712             : }
     713             : 
     714             : 
     715             : /*
     716             :  * coerce_type_typmod()
     717             :  *      Force a value to a particular typmod, if meaningful and possible.
     718             :  *
     719             :  * This is applied to values that are going to be stored in a relation
     720             :  * (where we have an atttypmod for the column) as well as values being
     721             :  * explicitly CASTed (where the typmod comes from the target type spec).
     722             :  *
     723             :  * The caller must have already ensured that the value is of the correct
     724             :  * type, typically by applying coerce_type.
     725             :  *
     726             :  * ccontext may affect semantics, depending on whether the length coercion
     727             :  * function pays attention to the isExplicit flag it's passed.
     728             :  *
     729             :  * cformat determines the display properties of the generated node (if any).
     730             :  *
     731             :  * If hideInputCoercion is true *and* we generate a node, the input node is
     732             :  * forced to IMPLICIT display form, so that only the typmod coercion node will
     733             :  * be visible when displaying the expression.
     734             :  *
     735             :  * NOTE: this does not need to work on domain types, because any typmod
     736             :  * coercion for a domain is considered to be part of the type coercion
     737             :  * needed to produce the domain value in the first place.  So, no getBaseType.
     738             :  */
     739             : static Node *
     740      886706 : coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod,
     741             :                    CoercionContext ccontext, CoercionForm cformat,
     742             :                    int location,
     743             :                    bool hideInputCoercion)
     744             : {
     745             :     CoercionPathType pathtype;
     746             :     Oid         funcId;
     747             : 
     748             :     /*
     749             :      * A negative typmod is assumed to mean that no coercion is wanted. Also,
     750             :      * skip coercion if already done.
     751             :      */
     752      886706 :     if (targetTypMod < 0 || targetTypMod == exprTypmod(node))
     753      858652 :         return node;
     754             : 
     755       28054 :     pathtype = find_typmod_coercion_function(targetTypeId, &funcId);
     756             : 
     757       28054 :     if (pathtype != COERCION_PATH_NONE)
     758             :     {
     759             :         /* Suppress display of nested coercion steps */
     760       28042 :         if (hideInputCoercion)
     761         540 :             hide_coercion_node(node);
     762             : 
     763       28042 :         node = build_coercion_expression(node, pathtype, funcId,
     764             :                                          targetTypeId, targetTypMod,
     765             :                                          ccontext, cformat, location);
     766             :     }
     767             : 
     768       28054 :     return node;
     769             : }
     770             : 
     771             : /*
     772             :  * Mark a coercion node as IMPLICIT so it will never be displayed by
     773             :  * ruleutils.c.  We use this when we generate a nest of coercion nodes
     774             :  * to implement what is logically one conversion; the inner nodes are
     775             :  * forced to IMPLICIT_CAST format.  This does not change their semantics,
     776             :  * only display behavior.
     777             :  *
     778             :  * It is caller error to call this on something that doesn't have a
     779             :  * CoercionForm field.
     780             :  */
     781             : static void
     782        9578 : hide_coercion_node(Node *node)
     783             : {
     784        9578 :     if (IsA(node, FuncExpr))
     785        4532 :         ((FuncExpr *) node)->funcformat = COERCE_IMPLICIT_CAST;
     786        5046 :     else if (IsA(node, RelabelType))
     787         140 :         ((RelabelType *) node)->relabelformat = COERCE_IMPLICIT_CAST;
     788        4906 :     else if (IsA(node, CoerceViaIO))
     789        4898 :         ((CoerceViaIO *) node)->coerceformat = COERCE_IMPLICIT_CAST;
     790           8 :     else if (IsA(node, ArrayCoerceExpr))
     791           8 :         ((ArrayCoerceExpr *) node)->coerceformat = COERCE_IMPLICIT_CAST;
     792           0 :     else if (IsA(node, ConvertRowtypeExpr))
     793           0 :         ((ConvertRowtypeExpr *) node)->convertformat = COERCE_IMPLICIT_CAST;
     794           0 :     else if (IsA(node, RowExpr))
     795           0 :         ((RowExpr *) node)->row_format = COERCE_IMPLICIT_CAST;
     796           0 :     else if (IsA(node, CoerceToDomain))
     797           0 :         ((CoerceToDomain *) node)->coercionformat = COERCE_IMPLICIT_CAST;
     798             :     else
     799           0 :         elog(ERROR, "unsupported node type: %d", (int) nodeTag(node));
     800        9578 : }
     801             : 
     802             : /*
     803             :  * build_coercion_expression()
     804             :  *      Construct an expression tree for applying a pg_cast entry.
     805             :  *
     806             :  * This is used for both type-coercion and length-coercion operations,
     807             :  * since there is no difference in terms of the calling convention.
     808             :  */
     809             : static Node *
     810      101500 : build_coercion_expression(Node *node,
     811             :                           CoercionPathType pathtype,
     812             :                           Oid funcId,
     813             :                           Oid targetTypeId, int32 targetTypMod,
     814             :                           CoercionContext ccontext, CoercionForm cformat,
     815             :                           int location)
     816             : {
     817      101500 :     int         nargs = 0;
     818             : 
     819      101500 :     if (OidIsValid(funcId))
     820             :     {
     821             :         HeapTuple   tp;
     822             :         Form_pg_proc procstruct;
     823             : 
     824       86534 :         tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcId));
     825       86534 :         if (!HeapTupleIsValid(tp))
     826           0 :             elog(ERROR, "cache lookup failed for function %u", funcId);
     827       86534 :         procstruct = (Form_pg_proc) GETSTRUCT(tp);
     828             : 
     829             :         /*
     830             :          * These Asserts essentially check that function is a legal coercion
     831             :          * function.  We can't make the seemingly obvious tests on prorettype
     832             :          * and proargtypes[0], even in the COERCION_PATH_FUNC case, because of
     833             :          * various binary-compatibility cases.
     834             :          */
     835             :         /* Assert(targetTypeId == procstruct->prorettype); */
     836             :         Assert(!procstruct->proretset);
     837             :         Assert(procstruct->prokind == PROKIND_FUNCTION);
     838       86534 :         nargs = procstruct->pronargs;
     839             :         Assert(nargs >= 1 && nargs <= 3);
     840             :         /* Assert(procstruct->proargtypes.values[0] == exprType(node)); */
     841             :         Assert(nargs < 2 || procstruct->proargtypes.values[1] == INT4OID);
     842             :         Assert(nargs < 3 || procstruct->proargtypes.values[2] == BOOLOID);
     843             : 
     844       86534 :         ReleaseSysCache(tp);
     845             :     }
     846             : 
     847      101500 :     if (pathtype == COERCION_PATH_FUNC)
     848             :     {
     849             :         /* We build an ordinary FuncExpr with special arguments */
     850             :         FuncExpr   *fexpr;
     851             :         List       *args;
     852             :         Const      *cons;
     853             : 
     854             :         Assert(OidIsValid(funcId));
     855             : 
     856       86478 :         args = list_make1(node);
     857             : 
     858       86478 :         if (nargs >= 2)
     859             :         {
     860             :             /* Pass target typmod as an int4 constant */
     861       28758 :             cons = makeConst(INT4OID,
     862             :                              -1,
     863             :                              InvalidOid,
     864             :                              sizeof(int32),
     865             :                              Int32GetDatum(targetTypMod),
     866             :                              false,
     867             :                              true);
     868             : 
     869       28758 :             args = lappend(args, cons);
     870             :         }
     871             : 
     872       86478 :         if (nargs == 3)
     873             :         {
     874             :             /* Pass it a boolean isExplicit parameter, too */
     875       22738 :             cons = makeConst(BOOLOID,
     876             :                              -1,
     877             :                              InvalidOid,
     878             :                              sizeof(bool),
     879             :                              BoolGetDatum(ccontext == COERCION_EXPLICIT),
     880             :                              false,
     881             :                              true);
     882             : 
     883       22738 :             args = lappend(args, cons);
     884             :         }
     885             : 
     886       86478 :         fexpr = makeFuncExpr(funcId, targetTypeId, args,
     887             :                              InvalidOid, InvalidOid, cformat);
     888       86478 :         fexpr->location = location;
     889       86478 :         return (Node *) fexpr;
     890             :     }
     891       15022 :     else if (pathtype == COERCION_PATH_ARRAYCOERCE)
     892             :     {
     893             :         /* We need to build an ArrayCoerceExpr */
     894        1696 :         ArrayCoerceExpr *acoerce = makeNode(ArrayCoerceExpr);
     895        1696 :         CaseTestExpr *ctest = makeNode(CaseTestExpr);
     896             :         Oid         sourceBaseTypeId;
     897             :         int32       sourceBaseTypeMod;
     898             :         Oid         targetElementType;
     899             :         Node       *elemexpr;
     900             : 
     901             :         /*
     902             :          * Look through any domain over the source array type.  Note we don't
     903             :          * expect that the target type is a domain; it must be a plain array.
     904             :          * (To get to a domain target type, we'll do coerce_to_domain later.)
     905             :          */
     906        1696 :         sourceBaseTypeMod = exprTypmod(node);
     907        1696 :         sourceBaseTypeId = getBaseTypeAndTypmod(exprType(node),
     908             :                                                 &sourceBaseTypeMod);
     909             : 
     910             :         /*
     911             :          * Set up a CaseTestExpr representing one element of the source array.
     912             :          * This is an abuse of CaseTestExpr, but it's OK as long as there
     913             :          * can't be any CaseExpr or ArrayCoerceExpr within the completed
     914             :          * elemexpr.
     915             :          */
     916        1696 :         ctest->typeId = get_element_type(sourceBaseTypeId);
     917             :         Assert(OidIsValid(ctest->typeId));
     918        1696 :         ctest->typeMod = sourceBaseTypeMod;
     919        1696 :         ctest->collation = InvalidOid;   /* Assume coercions don't care */
     920             : 
     921             :         /* And coerce it to the target element type */
     922        1696 :         targetElementType = get_element_type(targetTypeId);
     923             :         Assert(OidIsValid(targetElementType));
     924             : 
     925        1696 :         elemexpr = coerce_to_target_type(NULL,
     926             :                                          (Node *) ctest,
     927             :                                          ctest->typeId,
     928             :                                          targetElementType,
     929             :                                          targetTypMod,
     930             :                                          ccontext,
     931             :                                          cformat,
     932             :                                          location);
     933        1696 :         if (elemexpr == NULL)   /* shouldn't happen */
     934           0 :             elog(ERROR, "failed to coerce array element type as expected");
     935             : 
     936        1696 :         acoerce->arg = (Expr *) node;
     937        1696 :         acoerce->elemexpr = (Expr *) elemexpr;
     938        1696 :         acoerce->resulttype = targetTypeId;
     939             : 
     940             :         /*
     941             :          * Label the output as having a particular element typmod only if we
     942             :          * ended up with a per-element expression that is labeled that way.
     943             :          */
     944        1696 :         acoerce->resulttypmod = exprTypmod(elemexpr);
     945             :         /* resultcollid will be set by parse_collate.c */
     946        1696 :         acoerce->coerceformat = cformat;
     947        1696 :         acoerce->location = location;
     948             : 
     949        1696 :         return (Node *) acoerce;
     950             :     }
     951       13326 :     else if (pathtype == COERCION_PATH_COERCEVIAIO)
     952             :     {
     953             :         /* We need to build a CoerceViaIO node */
     954       13326 :         CoerceViaIO *iocoerce = makeNode(CoerceViaIO);
     955             : 
     956             :         Assert(!OidIsValid(funcId));
     957             : 
     958       13326 :         iocoerce->arg = (Expr *) node;
     959       13326 :         iocoerce->resulttype = targetTypeId;
     960             :         /* resultcollid will be set by parse_collate.c */
     961       13326 :         iocoerce->coerceformat = cformat;
     962       13326 :         iocoerce->location = location;
     963             : 
     964       13326 :         return (Node *) iocoerce;
     965             :     }
     966             :     else
     967             :     {
     968           0 :         elog(ERROR, "unsupported pathtype %d in build_coercion_expression",
     969             :              (int) pathtype);
     970             :         return NULL;            /* keep compiler quiet */
     971             :     }
     972             : }
     973             : 
     974             : 
     975             : /*
     976             :  * coerce_record_to_complex
     977             :  *      Coerce a RECORD to a specific composite type.
     978             :  *
     979             :  * Currently we only support this for inputs that are RowExprs or whole-row
     980             :  * Vars.
     981             :  */
     982             : static Node *
     983        1196 : coerce_record_to_complex(ParseState *pstate, Node *node,
     984             :                          Oid targetTypeId,
     985             :                          CoercionContext ccontext,
     986             :                          CoercionForm cformat,
     987             :                          int location)
     988             : {
     989             :     RowExpr    *rowexpr;
     990             :     Oid         baseTypeId;
     991        1196 :     int32       baseTypeMod = -1;
     992             :     TupleDesc   tupdesc;
     993        1196 :     List       *args = NIL;
     994             :     List       *newargs;
     995             :     int         i;
     996             :     int         ucolno;
     997             :     ListCell   *arg;
     998             : 
     999        1196 :     if (node && IsA(node, RowExpr))
    1000             :     {
    1001             :         /*
    1002             :          * Since the RowExpr must be of type RECORD, we needn't worry about it
    1003             :          * containing any dropped columns.
    1004             :          */
    1005        1196 :         args = ((RowExpr *) node)->args;
    1006             :     }
    1007           0 :     else if (node && IsA(node, Var) &&
    1008           0 :              ((Var *) node)->varattno == InvalidAttrNumber)
    1009           0 :     {
    1010           0 :         int         rtindex = ((Var *) node)->varno;
    1011           0 :         int         sublevels_up = ((Var *) node)->varlevelsup;
    1012           0 :         int         vlocation = ((Var *) node)->location;
    1013             :         RangeTblEntry *rte;
    1014             : 
    1015           0 :         rte = GetRTEByRangeTablePosn(pstate, rtindex, sublevels_up);
    1016           0 :         expandRTE(rte, rtindex, sublevels_up, vlocation, false,
    1017             :                   NULL, &args);
    1018             :     }
    1019             :     else
    1020           0 :         ereport(ERROR,
    1021             :                 (errcode(ERRCODE_CANNOT_COERCE),
    1022             :                  errmsg("cannot cast type %s to %s",
    1023             :                         format_type_be(RECORDOID),
    1024             :                         format_type_be(targetTypeId)),
    1025             :                  parser_coercion_errposition(pstate, location, node)));
    1026             : 
    1027             :     /*
    1028             :      * Look up the composite type, accounting for possibility that what we are
    1029             :      * given is a domain over composite.
    1030             :      */
    1031        1196 :     baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
    1032        1196 :     tupdesc = lookup_rowtype_tupdesc(baseTypeId, baseTypeMod);
    1033             : 
    1034             :     /* Process the fields */
    1035        1196 :     newargs = NIL;
    1036        1196 :     ucolno = 1;
    1037        1196 :     arg = list_head(args);
    1038        4030 :     for (i = 0; i < tupdesc->natts; i++)
    1039             :     {
    1040             :         Node       *expr;
    1041             :         Node       *cexpr;
    1042             :         Oid         exprtype;
    1043        2834 :         Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
    1044             : 
    1045             :         /* Fill in NULLs for dropped columns in rowtype */
    1046        2834 :         if (attr->attisdropped)
    1047             :         {
    1048             :             /*
    1049             :              * can't use atttypid here, but it doesn't really matter what type
    1050             :              * the Const claims to be.
    1051             :              */
    1052           6 :             newargs = lappend(newargs,
    1053           6 :                               makeNullConst(INT4OID, -1, InvalidOid));
    1054           6 :             continue;
    1055             :         }
    1056             : 
    1057        2828 :         if (arg == NULL)
    1058           0 :             ereport(ERROR,
    1059             :                     (errcode(ERRCODE_CANNOT_COERCE),
    1060             :                      errmsg("cannot cast type %s to %s",
    1061             :                             format_type_be(RECORDOID),
    1062             :                             format_type_be(targetTypeId)),
    1063             :                      errdetail("Input has too few columns."),
    1064             :                      parser_coercion_errposition(pstate, location, node)));
    1065        2828 :         expr = (Node *) lfirst(arg);
    1066        2828 :         exprtype = exprType(expr);
    1067             : 
    1068        2828 :         cexpr = coerce_to_target_type(pstate,
    1069             :                                       expr, exprtype,
    1070             :                                       attr->atttypid,
    1071             :                                       attr->atttypmod,
    1072             :                                       ccontext,
    1073             :                                       COERCE_IMPLICIT_CAST,
    1074             :                                       -1);
    1075        2828 :         if (cexpr == NULL)
    1076           0 :             ereport(ERROR,
    1077             :                     (errcode(ERRCODE_CANNOT_COERCE),
    1078             :                      errmsg("cannot cast type %s to %s",
    1079             :                             format_type_be(RECORDOID),
    1080             :                             format_type_be(targetTypeId)),
    1081             :                      errdetail("Cannot cast type %s to %s in column %d.",
    1082             :                                format_type_be(exprtype),
    1083             :                                format_type_be(attr->atttypid),
    1084             :                                ucolno),
    1085             :                      parser_coercion_errposition(pstate, location, expr)));
    1086        2828 :         newargs = lappend(newargs, cexpr);
    1087        2828 :         ucolno++;
    1088        2828 :         arg = lnext(args, arg);
    1089             :     }
    1090        1196 :     if (arg != NULL)
    1091           0 :         ereport(ERROR,
    1092             :                 (errcode(ERRCODE_CANNOT_COERCE),
    1093             :                  errmsg("cannot cast type %s to %s",
    1094             :                         format_type_be(RECORDOID),
    1095             :                         format_type_be(targetTypeId)),
    1096             :                  errdetail("Input has too many columns."),
    1097             :                  parser_coercion_errposition(pstate, location, node)));
    1098             : 
    1099        1196 :     ReleaseTupleDesc(tupdesc);
    1100             : 
    1101        1196 :     rowexpr = makeNode(RowExpr);
    1102        1196 :     rowexpr->args = newargs;
    1103        1196 :     rowexpr->row_typeid = baseTypeId;
    1104        1196 :     rowexpr->row_format = cformat;
    1105        1196 :     rowexpr->colnames = NIL; /* not needed for named target type */
    1106        1196 :     rowexpr->location = location;
    1107             : 
    1108             :     /* If target is a domain, apply constraints */
    1109        1196 :     if (baseTypeId != targetTypeId)
    1110             :     {
    1111          76 :         rowexpr->row_format = COERCE_IMPLICIT_CAST;
    1112          76 :         return coerce_to_domain((Node *) rowexpr,
    1113             :                                 baseTypeId, baseTypeMod,
    1114             :                                 targetTypeId,
    1115             :                                 ccontext, cformat, location,
    1116             :                                 false);
    1117             :     }
    1118             : 
    1119        1120 :     return (Node *) rowexpr;
    1120             : }
    1121             : 
    1122             : /*
    1123             :  * coerce_to_boolean()
    1124             :  *      Coerce an argument of a construct that requires boolean input
    1125             :  *      (AND, OR, NOT, etc).  Also check that input is not a set.
    1126             :  *
    1127             :  * Returns the possibly-transformed node tree.
    1128             :  *
    1129             :  * As with coerce_type, pstate may be NULL if no special unknown-Param
    1130             :  * processing is wanted.
    1131             :  */
    1132             : Node *
    1133      731026 : coerce_to_boolean(ParseState *pstate, Node *node,
    1134             :                   const char *constructName)
    1135             : {
    1136      731026 :     Oid         inputTypeId = exprType(node);
    1137             : 
    1138      731026 :     if (inputTypeId != BOOLOID)
    1139             :     {
    1140             :         Node       *newnode;
    1141             : 
    1142           0 :         newnode = coerce_to_target_type(pstate, node, inputTypeId,
    1143             :                                         BOOLOID, -1,
    1144             :                                         COERCION_ASSIGNMENT,
    1145             :                                         COERCE_IMPLICIT_CAST,
    1146             :                                         -1);
    1147           0 :         if (newnode == NULL)
    1148           0 :             ereport(ERROR,
    1149             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    1150             :             /* translator: first %s is name of a SQL construct, eg WHERE */
    1151             :                      errmsg("argument of %s must be type %s, not type %s",
    1152             :                             constructName, "boolean",
    1153             :                             format_type_be(inputTypeId)),
    1154             :                      parser_errposition(pstate, exprLocation(node))));
    1155           0 :         node = newnode;
    1156             :     }
    1157             : 
    1158      731026 :     if (expression_returns_set(node))
    1159           0 :         ereport(ERROR,
    1160             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    1161             :         /* translator: %s is name of a SQL construct, eg WHERE */
    1162             :                  errmsg("argument of %s must not return a set",
    1163             :                         constructName),
    1164             :                  parser_errposition(pstate, exprLocation(node))));
    1165             : 
    1166      731026 :     return node;
    1167             : }
    1168             : 
    1169             : /*
    1170             :  * coerce_to_specific_type_typmod()
    1171             :  *      Coerce an argument of a construct that requires a specific data type,
    1172             :  *      with a specific typmod.  Also check that input is not a set.
    1173             :  *
    1174             :  * Returns the possibly-transformed node tree.
    1175             :  *
    1176             :  * As with coerce_type, pstate may be NULL if no special unknown-Param
    1177             :  * processing is wanted.
    1178             :  */
    1179             : Node *
    1180       20608 : coerce_to_specific_type_typmod(ParseState *pstate, Node *node,
    1181             :                                Oid targetTypeId, int32 targetTypmod,
    1182             :                                const char *constructName)
    1183             : {
    1184       20608 :     Oid         inputTypeId = exprType(node);
    1185             : 
    1186       20608 :     if (inputTypeId != targetTypeId)
    1187             :     {
    1188             :         Node       *newnode;
    1189             : 
    1190       10344 :         newnode = coerce_to_target_type(pstate, node, inputTypeId,
    1191             :                                         targetTypeId, targetTypmod,
    1192             :                                         COERCION_ASSIGNMENT,
    1193             :                                         COERCE_IMPLICIT_CAST,
    1194             :                                         -1);
    1195       10336 :         if (newnode == NULL)
    1196           4 :             ereport(ERROR,
    1197             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    1198             :             /* translator: first %s is name of a SQL construct, eg LIMIT */
    1199             :                      errmsg("argument of %s must be type %s, not type %s",
    1200             :                             constructName,
    1201             :                             format_type_be(targetTypeId),
    1202             :                             format_type_be(inputTypeId)),
    1203             :                      parser_errposition(pstate, exprLocation(node))));
    1204       10332 :         node = newnode;
    1205             :     }
    1206             : 
    1207       20596 :     if (expression_returns_set(node))
    1208           0 :         ereport(ERROR,
    1209             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    1210             :         /* translator: %s is name of a SQL construct, eg LIMIT */
    1211             :                  errmsg("argument of %s must not return a set",
    1212             :                         constructName),
    1213             :                  parser_errposition(pstate, exprLocation(node))));
    1214             : 
    1215       20596 :     return node;
    1216             : }
    1217             : 
    1218             : /*
    1219             :  * coerce_to_specific_type()
    1220             :  *      Coerce an argument of a construct that requires a specific data type.
    1221             :  *      Also check that input is not a set.
    1222             :  *
    1223             :  * Returns the possibly-transformed node tree.
    1224             :  *
    1225             :  * As with coerce_type, pstate may be NULL if no special unknown-Param
    1226             :  * processing is wanted.
    1227             :  */
    1228             : Node *
    1229       20570 : coerce_to_specific_type(ParseState *pstate, Node *node,
    1230             :                         Oid targetTypeId,
    1231             :                         const char *constructName)
    1232             : {
    1233       20570 :     return coerce_to_specific_type_typmod(pstate, node,
    1234             :                                           targetTypeId, -1,
    1235             :                                           constructName);
    1236             : }
    1237             : 
    1238             : /*
    1239             :  * parser_coercion_errposition - report coercion error location, if possible
    1240             :  *
    1241             :  * We prefer to point at the coercion request (CAST, ::, etc) if possible;
    1242             :  * but there may be no such location in the case of an implicit coercion.
    1243             :  * In that case point at the input expression.
    1244             :  *
    1245             :  * XXX possibly this is more generally useful than coercion errors;
    1246             :  * if so, should rename and place with parser_errposition.
    1247             :  */
    1248             : int
    1249          16 : parser_coercion_errposition(ParseState *pstate,
    1250             :                             int coerce_location,
    1251             :                             Node *input_expr)
    1252             : {
    1253          16 :     if (coerce_location >= 0)
    1254          16 :         return parser_errposition(pstate, coerce_location);
    1255             :     else
    1256           0 :         return parser_errposition(pstate, exprLocation(input_expr));
    1257             : }
    1258             : 
    1259             : 
    1260             : /*
    1261             :  * select_common_type()
    1262             :  *      Determine the common supertype of a list of input expressions.
    1263             :  *      This is used for determining the output type of CASE, UNION,
    1264             :  *      and similar constructs.
    1265             :  *
    1266             :  * 'exprs' is a *nonempty* list of expressions.  Note that earlier items
    1267             :  * in the list will be preferred if there is doubt.
    1268             :  * 'context' is a phrase to use in the error message if we fail to select
    1269             :  * a usable type.  Pass NULL to have the routine return InvalidOid
    1270             :  * rather than throwing an error on failure.
    1271             :  * 'which_expr': if not NULL, receives a pointer to the particular input
    1272             :  * expression from which the result type was taken.
    1273             :  */
    1274             : Oid
    1275      186802 : select_common_type(ParseState *pstate, List *exprs, const char *context,
    1276             :                    Node **which_expr)
    1277             : {
    1278             :     Node       *pexpr;
    1279             :     Oid         ptype;
    1280             :     TYPCATEGORY pcategory;
    1281             :     bool        pispreferred;
    1282             :     ListCell   *lc;
    1283             : 
    1284             :     Assert(exprs != NIL);
    1285      186802 :     pexpr = (Node *) linitial(exprs);
    1286      186802 :     lc = list_second_cell(exprs);
    1287      186802 :     ptype = exprType(pexpr);
    1288             : 
    1289             :     /*
    1290             :      * If all input types are valid and exactly the same, just pick that type.
    1291             :      * This is the only way that we will resolve the result as being a domain
    1292             :      * type; otherwise domains are smashed to their base types for comparison.
    1293             :      */
    1294      186802 :     if (ptype != UNKNOWNOID)
    1295             :     {
    1296      250596 :         for_each_cell(lc, exprs, lc)
    1297             :         {
    1298      152134 :             Node       *nexpr = (Node *) lfirst(lc);
    1299      152134 :             Oid         ntype = exprType(nexpr);
    1300             : 
    1301      152134 :             if (ntype != ptype)
    1302       46604 :                 break;
    1303             :         }
    1304      145066 :         if (lc == NULL)         /* got to the end of the list? */
    1305             :         {
    1306       98462 :             if (which_expr)
    1307       70830 :                 *which_expr = pexpr;
    1308       98462 :             return ptype;
    1309             :         }
    1310             :     }
    1311             : 
    1312             :     /*
    1313             :      * Nope, so set up for the full algorithm.  Note that at this point, lc
    1314             :      * points to the first list item with type different from pexpr's; we need
    1315             :      * not re-examine any items the previous loop advanced over.
    1316             :      */
    1317       88340 :     ptype = getBaseType(ptype);
    1318       88340 :     get_type_category_preferred(ptype, &pcategory, &pispreferred);
    1319             : 
    1320      263094 :     for_each_cell(lc, exprs, lc)
    1321             :     {
    1322      174758 :         Node       *nexpr = (Node *) lfirst(lc);
    1323      174758 :         Oid         ntype = getBaseType(exprType(nexpr));
    1324             : 
    1325             :         /* move on to next one if no new information... */
    1326      174758 :         if (ntype != UNKNOWNOID && ntype != ptype)
    1327             :         {
    1328             :             TYPCATEGORY ncategory;
    1329             :             bool        nispreferred;
    1330             : 
    1331       35916 :             get_type_category_preferred(ntype, &ncategory, &nispreferred);
    1332       35916 :             if (ptype == UNKNOWNOID)
    1333             :             {
    1334             :                 /* so far, only unknowns so take anything... */
    1335       21466 :                 pexpr = nexpr;
    1336       21466 :                 ptype = ntype;
    1337       21466 :                 pcategory = ncategory;
    1338       21466 :                 pispreferred = nispreferred;
    1339             :             }
    1340       14450 :             else if (ncategory != pcategory)
    1341             :             {
    1342             :                 /*
    1343             :                  * both types in different categories? then not much hope...
    1344             :                  */
    1345           4 :                 if (context == NULL)
    1346           0 :                     return InvalidOid;
    1347           4 :                 ereport(ERROR,
    1348             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    1349             :                 /*------
    1350             :                   translator: first %s is name of a SQL construct, eg CASE */
    1351             :                          errmsg("%s types %s and %s cannot be matched",
    1352             :                                 context,
    1353             :                                 format_type_be(ptype),
    1354             :                                 format_type_be(ntype)),
    1355             :                          parser_errposition(pstate, exprLocation(nexpr))));
    1356             :             }
    1357       21022 :             else if (!pispreferred &&
    1358       12838 :                      can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
    1359        6262 :                      !can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
    1360             :             {
    1361             :                 /*
    1362             :                  * take new type if can coerce to it implicitly but not the
    1363             :                  * other way; but if we have a preferred type, stay on it.
    1364             :                  */
    1365        5928 :                 pexpr = nexpr;
    1366        5928 :                 ptype = ntype;
    1367        5928 :                 pcategory = ncategory;
    1368        5928 :                 pispreferred = nispreferred;
    1369             :             }
    1370             :         }
    1371             :     }
    1372             : 
    1373             :     /*
    1374             :      * If all the inputs were UNKNOWN type --- ie, unknown-type literals ---
    1375             :      * then resolve as type TEXT.  This situation comes up with constructs
    1376             :      * like SELECT (CASE WHEN foo THEN 'bar' ELSE 'baz' END); SELECT 'foo'
    1377             :      * UNION SELECT 'bar'; It might seem desirable to leave the construct's
    1378             :      * output type as UNKNOWN, but that really doesn't work, because we'd
    1379             :      * probably end up needing a runtime coercion from UNKNOWN to something
    1380             :      * else, and we usually won't have it.  We need to coerce the unknown
    1381             :      * literals while they are still literals, so a decision has to be made
    1382             :      * now.
    1383             :      */
    1384       88336 :     if (ptype == UNKNOWNOID)
    1385       20270 :         ptype = TEXTOID;
    1386             : 
    1387       88336 :     if (which_expr)
    1388        4784 :         *which_expr = pexpr;
    1389       88336 :     return ptype;
    1390             : }
    1391             : 
    1392             : /*
    1393             :  * coerce_to_common_type()
    1394             :  *      Coerce an expression to the given type.
    1395             :  *
    1396             :  * This is used following select_common_type() to coerce the individual
    1397             :  * expressions to the desired type.  'context' is a phrase to use in the
    1398             :  * error message if we fail to coerce.
    1399             :  *
    1400             :  * As with coerce_type, pstate may be NULL if no special unknown-Param
    1401             :  * processing is wanted.
    1402             :  */
    1403             : Node *
    1404      442146 : coerce_to_common_type(ParseState *pstate, Node *node,
    1405             :                       Oid targetTypeId, const char *context)
    1406             : {
    1407      442146 :     Oid         inputTypeId = exprType(node);
    1408             : 
    1409      442146 :     if (inputTypeId == targetTypeId)
    1410      262152 :         return node;            /* no work */
    1411      179994 :     if (can_coerce_type(1, &inputTypeId, &targetTypeId, COERCION_IMPLICIT))
    1412      179994 :         node = coerce_type(pstate, node, inputTypeId, targetTypeId, -1,
    1413             :                            COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1);
    1414             :     else
    1415           0 :         ereport(ERROR,
    1416             :                 (errcode(ERRCODE_CANNOT_COERCE),
    1417             :         /* translator: first %s is name of a SQL construct, eg CASE */
    1418             :                  errmsg("%s could not convert type %s to %s",
    1419             :                         context,
    1420             :                         format_type_be(inputTypeId),
    1421             :                         format_type_be(targetTypeId)),
    1422             :                  parser_errposition(pstate, exprLocation(node))));
    1423      179990 :     return node;
    1424             : }
    1425             : 
    1426             : /*
    1427             :  * check_generic_type_consistency()
    1428             :  *      Are the actual arguments potentially compatible with a
    1429             :  *      polymorphic function?
    1430             :  *
    1431             :  * The argument consistency rules are:
    1432             :  *
    1433             :  * 1) All arguments declared ANYELEMENT must have the same datatype.
    1434             :  * 2) All arguments declared ANYARRAY must have the same datatype,
    1435             :  *    which must be a varlena array type.
    1436             :  * 3) All arguments declared ANYRANGE must have the same datatype,
    1437             :  *    which must be a range type.
    1438             :  * 4) If there are arguments of both ANYELEMENT and ANYARRAY, make sure the
    1439             :  *    actual ANYELEMENT datatype is in fact the element type for the actual
    1440             :  *    ANYARRAY datatype.
    1441             :  * 5) Similarly, if there are arguments of both ANYELEMENT and ANYRANGE,
    1442             :  *    make sure the actual ANYELEMENT datatype is in fact the subtype for
    1443             :  *    the actual ANYRANGE type.
    1444             :  * 6) ANYENUM is treated the same as ANYELEMENT except that if it is used
    1445             :  *    (alone or in combination with plain ANYELEMENT), we add the extra
    1446             :  *    condition that the ANYELEMENT type must be an enum.
    1447             :  * 7) ANYNONARRAY is treated the same as ANYELEMENT except that if it is used,
    1448             :  *    we add the extra condition that the ANYELEMENT type must not be an array.
    1449             :  *    (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
    1450             :  *    is an extra restriction if not.)
    1451             :  *
    1452             :  * Domains over arrays match ANYARRAY, and are immediately flattened to their
    1453             :  * base type.  (Thus, for example, we will consider it a match if one ANYARRAY
    1454             :  * argument is a domain over int4[] while another one is just int4[].)  Also
    1455             :  * notice that such a domain does *not* match ANYNONARRAY.
    1456             :  *
    1457             :  * Similarly, domains over ranges match ANYRANGE, and are immediately
    1458             :  * flattened to their base type.
    1459             :  *
    1460             :  * Note that domains aren't currently considered to match ANYENUM,
    1461             :  * even if their base type would match.
    1462             :  *
    1463             :  * If we have UNKNOWN input (ie, an untyped literal) for any polymorphic
    1464             :  * argument, assume it is okay.
    1465             :  *
    1466             :  * If an input is of type ANYARRAY (ie, we know it's an array, but not
    1467             :  * what element type), we will accept it as a match to an argument declared
    1468             :  * ANYARRAY, so long as we don't have to determine an element type ---
    1469             :  * that is, so long as there is no use of ANYELEMENT.  This is mostly for
    1470             :  * backwards compatibility with the pre-7.4 behavior of ANYARRAY.
    1471             :  *
    1472             :  * We do not ereport here, but just return false if a rule is violated.
    1473             :  */
    1474             : bool
    1475      113814 : check_generic_type_consistency(const Oid *actual_arg_types,
    1476             :                                const Oid *declared_arg_types,
    1477             :                                int nargs)
    1478             : {
    1479             :     int         j;
    1480      113814 :     Oid         elem_typeid = InvalidOid;
    1481      113814 :     Oid         array_typeid = InvalidOid;
    1482             :     Oid         array_typelem;
    1483      113814 :     Oid         range_typeid = InvalidOid;
    1484             :     Oid         range_typelem;
    1485      113814 :     bool        have_anyelement = false;
    1486      113814 :     bool        have_anynonarray = false;
    1487      113814 :     bool        have_anyenum = false;
    1488             : 
    1489             :     /*
    1490             :      * Loop through the arguments to see if we have any that are polymorphic.
    1491             :      * If so, require the actual types to be consistent.
    1492             :      */
    1493      267988 :     for (j = 0; j < nargs; j++)
    1494             :     {
    1495      173520 :         Oid         decl_type = declared_arg_types[j];
    1496      173520 :         Oid         actual_type = actual_arg_types[j];
    1497             : 
    1498      173520 :         if (decl_type == ANYELEMENTOID ||
    1499      149210 :             decl_type == ANYNONARRAYOID ||
    1500             :             decl_type == ANYENUMOID)
    1501             :         {
    1502       43536 :             have_anyelement = true;
    1503       43536 :             if (decl_type == ANYNONARRAYOID)
    1504       18036 :                 have_anynonarray = true;
    1505       25500 :             else if (decl_type == ANYENUMOID)
    1506       19226 :                 have_anyenum = true;
    1507       43536 :             if (actual_type == UNKNOWNOID)
    1508        3910 :                 continue;
    1509       39626 :             if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
    1510        6842 :                 return false;
    1511       32784 :             elem_typeid = actual_type;
    1512             :         }
    1513      129984 :         else if (decl_type == ANYARRAYOID)
    1514             :         {
    1515       84332 :             if (actual_type == UNKNOWNOID)
    1516        9100 :                 continue;
    1517       75232 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1518       75232 :             if (OidIsValid(array_typeid) && actual_type != array_typeid)
    1519        6324 :                 return false;
    1520       68908 :             array_typeid = actual_type;
    1521             :         }
    1522       45652 :         else if (decl_type == ANYRANGEOID)
    1523             :         {
    1524       21018 :             if (actual_type == UNKNOWNOID)
    1525        1562 :                 continue;
    1526       19456 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1527       19456 :             if (OidIsValid(range_typeid) && actual_type != range_typeid)
    1528        6180 :                 return false;
    1529       13276 :             range_typeid = actual_type;
    1530             :         }
    1531             :     }
    1532             : 
    1533             :     /* Get the element type based on the array type, if we have one */
    1534       94468 :     if (OidIsValid(array_typeid))
    1535             :     {
    1536       60116 :         if (array_typeid == ANYARRAYOID)
    1537             :         {
    1538             :             /* Special case for ANYARRAY input: okay iff no ANYELEMENT */
    1539           0 :             if (have_anyelement)
    1540           0 :                 return false;
    1541           0 :             return true;
    1542             :         }
    1543             : 
    1544       60116 :         array_typelem = get_element_type(array_typeid);
    1545       60116 :         if (!OidIsValid(array_typelem))
    1546       19704 :             return false;       /* should be an array, but isn't */
    1547             : 
    1548       40412 :         if (!OidIsValid(elem_typeid))
    1549             :         {
    1550             :             /*
    1551             :              * if we don't have an element type yet, use the one we just got
    1552             :              */
    1553       39790 :             elem_typeid = array_typelem;
    1554             :         }
    1555         622 :         else if (array_typelem != elem_typeid)
    1556             :         {
    1557             :             /* otherwise, they better match */
    1558         284 :             return false;
    1559             :         }
    1560             :     }
    1561             : 
    1562             :     /* Get the element type based on the range type, if we have one */
    1563       74480 :     if (OidIsValid(range_typeid))
    1564             :     {
    1565        4654 :         range_typelem = get_range_subtype(range_typeid);
    1566        4654 :         if (!OidIsValid(range_typelem))
    1567        4190 :             return false;       /* should be a range, but isn't */
    1568             : 
    1569         464 :         if (!OidIsValid(elem_typeid))
    1570             :         {
    1571             :             /*
    1572             :              * if we don't have an element type yet, use the one we just got
    1573             :              */
    1574         368 :             elem_typeid = range_typelem;
    1575             :         }
    1576          96 :         else if (range_typelem != elem_typeid)
    1577             :         {
    1578             :             /* otherwise, they better match */
    1579          42 :             return false;
    1580             :         }
    1581             :     }
    1582             : 
    1583       70248 :     if (have_anynonarray)
    1584             :     {
    1585             :         /* require the element type to not be an array or domain over array */
    1586       17684 :         if (type_is_array_domain(elem_typeid))
    1587         692 :             return false;
    1588             :     }
    1589             : 
    1590       69556 :     if (have_anyenum)
    1591             :     {
    1592             :         /* require the element type to be an enum */
    1593        2916 :         if (!type_is_enum(elem_typeid))
    1594        2680 :             return false;
    1595             :     }
    1596             : 
    1597             :     /* Looks valid */
    1598       66876 :     return true;
    1599             : }
    1600             : 
    1601             : /*
    1602             :  * enforce_generic_type_consistency()
    1603             :  *      Make sure a polymorphic function is legally callable, and
    1604             :  *      deduce actual argument and result types.
    1605             :  *
    1606             :  * If any polymorphic pseudotype is used in a function's arguments or
    1607             :  * return type, we make sure the actual data types are consistent with
    1608             :  * each other.  The argument consistency rules are shown above for
    1609             :  * check_generic_type_consistency().
    1610             :  *
    1611             :  * If we have UNKNOWN input (ie, an untyped literal) for any polymorphic
    1612             :  * argument, we attempt to deduce the actual type it should have.  If
    1613             :  * successful, we alter that position of declared_arg_types[] so that
    1614             :  * make_fn_arguments will coerce the literal to the right thing.
    1615             :  *
    1616             :  * Rules are applied to the function's return type (possibly altering it)
    1617             :  * if it is declared as a polymorphic type:
    1618             :  *
    1619             :  * 1) If return type is ANYARRAY, and any argument is ANYARRAY, use the
    1620             :  *    argument's actual type as the function's return type.
    1621             :  * 2) Similarly, if return type is ANYRANGE, and any argument is ANYRANGE,
    1622             :  *    use the argument's actual type as the function's return type.
    1623             :  * 3) If return type is ANYARRAY, no argument is ANYARRAY, but any argument is
    1624             :  *    ANYELEMENT, use the actual type of the argument to determine the
    1625             :  *    function's return type, i.e. the element type's corresponding array
    1626             :  *    type.  (Note: similar behavior does not exist for ANYRANGE, because it's
    1627             :  *    impossible to determine the range type from the subtype alone.)
    1628             :  * 4) If return type is ANYARRAY, but no argument is ANYARRAY or ANYELEMENT,
    1629             :  *    generate an error.  Similarly, if return type is ANYRANGE, but no
    1630             :  *    argument is ANYRANGE, generate an error.  (These conditions are
    1631             :  *    prevented by CREATE FUNCTION and therefore are not expected here.)
    1632             :  * 5) If return type is ANYELEMENT, and any argument is ANYELEMENT, use the
    1633             :  *    argument's actual type as the function's return type.
    1634             :  * 6) If return type is ANYELEMENT, no argument is ANYELEMENT, but any argument
    1635             :  *    is ANYARRAY or ANYRANGE, use the actual type of the argument to determine
    1636             :  *    the function's return type, i.e. the array type's corresponding element
    1637             :  *    type or the range type's corresponding subtype (or both, in which case
    1638             :  *    they must match).
    1639             :  * 7) If return type is ANYELEMENT, no argument is ANYELEMENT, ANYARRAY, or
    1640             :  *    ANYRANGE, generate an error.  (This condition is prevented by CREATE
    1641             :  *    FUNCTION and therefore is not expected here.)
    1642             :  * 8) ANYENUM is treated the same as ANYELEMENT except that if it is used
    1643             :  *    (alone or in combination with plain ANYELEMENT), we add the extra
    1644             :  *    condition that the ANYELEMENT type must be an enum.
    1645             :  * 9) ANYNONARRAY is treated the same as ANYELEMENT except that if it is used,
    1646             :  *    we add the extra condition that the ANYELEMENT type must not be an array.
    1647             :  *    (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
    1648             :  *    is an extra restriction if not.)
    1649             :  *
    1650             :  * Domains over arrays or ranges match ANYARRAY or ANYRANGE arguments,
    1651             :  * respectively, and are immediately flattened to their base type. (In
    1652             :  * particular, if the return type is also ANYARRAY or ANYRANGE, we'll set it
    1653             :  * to the base type not the domain type.)
    1654             :  *
    1655             :  * When allow_poly is false, we are not expecting any of the actual_arg_types
    1656             :  * to be polymorphic, and we should not return a polymorphic result type
    1657             :  * either.  When allow_poly is true, it is okay to have polymorphic "actual"
    1658             :  * arg types, and we can return ANYARRAY, ANYRANGE, or ANYELEMENT as the
    1659             :  * result.  (This case is currently used only to check compatibility of an
    1660             :  * aggregate's declaration with the underlying transfn.)
    1661             :  *
    1662             :  * A special case is that we could see ANYARRAY as an actual_arg_type even
    1663             :  * when allow_poly is false (this is possible only because pg_statistic has
    1664             :  * columns shown as anyarray in the catalogs).  We allow this to match a
    1665             :  * declared ANYARRAY argument, but only if there is no ANYELEMENT argument
    1666             :  * or result (since we can't determine a specific element type to match to
    1667             :  * ANYELEMENT).  Note this means that functions taking ANYARRAY had better
    1668             :  * behave sanely if applied to the pg_statistic columns; they can't just
    1669             :  * assume that successive inputs are of the same actual element type.
    1670             :  */
    1671             : Oid
    1672      937086 : enforce_generic_type_consistency(const Oid *actual_arg_types,
    1673             :                                  Oid *declared_arg_types,
    1674             :                                  int nargs,
    1675             :                                  Oid rettype,
    1676             :                                  bool allow_poly)
    1677             : {
    1678             :     int         j;
    1679      937086 :     bool        have_generics = false;
    1680      937086 :     bool        have_unknowns = false;
    1681      937086 :     Oid         elem_typeid = InvalidOid;
    1682      937086 :     Oid         array_typeid = InvalidOid;
    1683      937086 :     Oid         range_typeid = InvalidOid;
    1684             :     Oid         array_typelem;
    1685             :     Oid         range_typelem;
    1686     1856546 :     bool        have_anyelement = (rettype == ANYELEMENTOID ||
    1687     1856546 :                                    rettype == ANYNONARRAYOID ||
    1688             :                                    rettype == ANYENUMOID);
    1689      937086 :     bool        have_anynonarray = (rettype == ANYNONARRAYOID);
    1690      937086 :     bool        have_anyenum = (rettype == ANYENUMOID);
    1691             : 
    1692             :     /*
    1693             :      * Loop through the arguments to see if we have any that are polymorphic.
    1694             :      * If so, require the actual types to be consistent.
    1695             :      */
    1696     2542978 :     for (j = 0; j < nargs; j++)
    1697             :     {
    1698     1605892 :         Oid         decl_type = declared_arg_types[j];
    1699     1605892 :         Oid         actual_type = actual_arg_types[j];
    1700             : 
    1701     1605892 :         if (decl_type == ANYELEMENTOID ||
    1702     1586334 :             decl_type == ANYNONARRAYOID ||
    1703             :             decl_type == ANYENUMOID)
    1704             :         {
    1705       20138 :             have_generics = have_anyelement = true;
    1706       20138 :             if (decl_type == ANYNONARRAYOID)
    1707       15350 :                 have_anynonarray = true;
    1708        4788 :             else if (decl_type == ANYENUMOID)
    1709         580 :                 have_anyenum = true;
    1710       20138 :             if (actual_type == UNKNOWNOID)
    1711             :             {
    1712         984 :                 have_unknowns = true;
    1713         984 :                 continue;
    1714             :             }
    1715       19154 :             if (allow_poly && decl_type == actual_type)
    1716         132 :                 continue;       /* no new information here */
    1717       19022 :             if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
    1718           0 :                 ereport(ERROR,
    1719             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    1720             :                          errmsg("arguments declared \"anyelement\" are not all alike"),
    1721             :                          errdetail("%s versus %s",
    1722             :                                    format_type_be(elem_typeid),
    1723             :                                    format_type_be(actual_type))));
    1724       19022 :             elem_typeid = actual_type;
    1725             :         }
    1726     1585754 :         else if (decl_type == ANYARRAYOID)
    1727             :         {
    1728       56030 :             have_generics = true;
    1729       56030 :             if (actual_type == UNKNOWNOID)
    1730             :             {
    1731        7128 :                 have_unknowns = true;
    1732        7128 :                 continue;
    1733             :             }
    1734       48902 :             if (allow_poly && decl_type == actual_type)
    1735          60 :                 continue;       /* no new information here */
    1736       48842 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1737       48842 :             if (OidIsValid(array_typeid) && actual_type != array_typeid)
    1738           0 :                 ereport(ERROR,
    1739             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    1740             :                          errmsg("arguments declared \"anyarray\" are not all alike"),
    1741             :                          errdetail("%s versus %s",
    1742             :                                    format_type_be(array_typeid),
    1743             :                                    format_type_be(actual_type))));
    1744       48842 :             array_typeid = actual_type;
    1745             :         }
    1746     1529724 :         else if (decl_type == ANYRANGEOID)
    1747             :         {
    1748        1712 :             have_generics = true;
    1749        1712 :             if (actual_type == UNKNOWNOID)
    1750             :             {
    1751          30 :                 have_unknowns = true;
    1752          30 :                 continue;
    1753             :             }
    1754        1682 :             if (allow_poly && decl_type == actual_type)
    1755           0 :                 continue;       /* no new information here */
    1756        1682 :             actual_type = getBaseType(actual_type); /* flatten domains */
    1757        1682 :             if (OidIsValid(range_typeid) && actual_type != range_typeid)
    1758           0 :                 ereport(ERROR,
    1759             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    1760             :                          errmsg("arguments declared \"anyrange\" are not all alike"),
    1761             :                          errdetail("%s versus %s",
    1762             :                                    format_type_be(range_typeid),
    1763             :                                    format_type_be(actual_type))));
    1764        1682 :             range_typeid = actual_type;
    1765             :         }
    1766             :     }
    1767             : 
    1768             :     /*
    1769             :      * Fast Track: if none of the arguments are polymorphic, return the
    1770             :      * unmodified rettype.  We assume it can't be polymorphic either.
    1771             :      */
    1772      937086 :     if (!have_generics)
    1773      870204 :         return rettype;
    1774             : 
    1775             :     /* Get the element type based on the array type, if we have one */
    1776       66882 :     if (OidIsValid(array_typeid))
    1777             :     {
    1778       47544 :         if (array_typeid == ANYARRAYOID && !have_anyelement)
    1779             :         {
    1780             :             /* Special case for ANYARRAY input: okay iff no ANYELEMENT */
    1781          12 :             array_typelem = ANYELEMENTOID;
    1782             :         }
    1783             :         else
    1784             :         {
    1785       47532 :             array_typelem = get_element_type(array_typeid);
    1786       47532 :             if (!OidIsValid(array_typelem))
    1787           0 :                 ereport(ERROR,
    1788             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    1789             :                          errmsg("argument declared %s is not an array but type %s",
    1790             :                                 "anyarray", format_type_be(array_typeid))));
    1791             :         }
    1792             : 
    1793       47544 :         if (!OidIsValid(elem_typeid))
    1794             :         {
    1795             :             /*
    1796             :              * if we don't have an element type yet, use the one we just got
    1797             :              */
    1798       47154 :             elem_typeid = array_typelem;
    1799             :         }
    1800         390 :         else if (array_typelem != elem_typeid)
    1801             :         {
    1802             :             /* otherwise, they better match */
    1803           0 :             ereport(ERROR,
    1804             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    1805             :                      errmsg("argument declared %s is not consistent with argument declared %s",
    1806             :                             "anyarray", "anyelement"),
    1807             :                      errdetail("%s versus %s",
    1808             :                                format_type_be(array_typeid),
    1809             :                                format_type_be(elem_typeid))));
    1810             :         }
    1811             :     }
    1812             : 
    1813             :     /* Get the element type based on the range type, if we have one */
    1814       66882 :     if (OidIsValid(range_typeid))
    1815             :     {
    1816         956 :         if (range_typeid == ANYRANGEOID && !have_anyelement)
    1817             :         {
    1818             :             /* Special case for ANYRANGE input: okay iff no ANYELEMENT */
    1819           0 :             range_typelem = ANYELEMENTOID;
    1820             :         }
    1821             :         else
    1822             :         {
    1823         956 :             range_typelem = get_range_subtype(range_typeid);
    1824         956 :             if (!OidIsValid(range_typelem))
    1825           0 :                 ereport(ERROR,
    1826             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    1827             :                          errmsg("argument declared %s is not a range type but type %s",
    1828             :                                 "anyrange",
    1829             :                                 format_type_be(range_typeid))));
    1830             :         }
    1831             : 
    1832         956 :         if (!OidIsValid(elem_typeid))
    1833             :         {
    1834             :             /*
    1835             :              * if we don't have an element type yet, use the one we just got
    1836             :              */
    1837         864 :             elem_typeid = range_typelem;
    1838             :         }
    1839          92 :         else if (range_typelem != elem_typeid)
    1840             :         {
    1841             :             /* otherwise, they better match */
    1842           0 :             ereport(ERROR,
    1843             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    1844             :                      errmsg("argument declared %s is not consistent with argument declared %s",
    1845             :                             "anyrange", "anyelement"),
    1846             :                      errdetail("%s versus %s",
    1847             :                                format_type_be(range_typeid),
    1848             :                                format_type_be(elem_typeid))));
    1849             :         }
    1850             :     }
    1851             : 
    1852       66882 :     if (!OidIsValid(elem_typeid))
    1853             :     {
    1854         142 :         if (allow_poly)
    1855             :         {
    1856         138 :             elem_typeid = ANYELEMENTOID;
    1857         138 :             array_typeid = ANYARRAYOID;
    1858         138 :             range_typeid = ANYRANGEOID;
    1859             :         }
    1860             :         else
    1861             :         {
    1862             :             /* Only way to get here is if all the generic args are UNKNOWN */
    1863           4 :             ereport(ERROR,
    1864             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    1865             :                      errmsg("could not determine polymorphic type because input has type %s",
    1866             :                             "unknown")));
    1867             :         }
    1868             :     }
    1869             : 
    1870       66878 :     if (have_anynonarray && elem_typeid != ANYELEMENTOID)
    1871             :     {
    1872             :         /* require the element type to not be an array or domain over array */
    1873       14998 :         if (type_is_array_domain(elem_typeid))
    1874           0 :             ereport(ERROR,
    1875             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    1876             :                      errmsg("type matched to anynonarray is an array type: %s",
    1877             :                             format_type_be(elem_typeid))));
    1878             :     }
    1879             : 
    1880       66878 :     if (have_anyenum && elem_typeid != ANYELEMENTOID)
    1881             :     {
    1882             :         /* require the element type to be an enum */
    1883         392 :         if (!type_is_enum(elem_typeid))
    1884           0 :             ereport(ERROR,
    1885             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    1886             :                      errmsg("type matched to anyenum is not an enum type: %s",
    1887             :                             format_type_be(elem_typeid))));
    1888             :     }
    1889             : 
    1890             :     /*
    1891             :      * If we had any unknown inputs, re-scan to assign correct types
    1892             :      */
    1893       66878 :     if (have_unknowns)
    1894             :     {
    1895       25154 :         for (j = 0; j < nargs; j++)
    1896             :         {
    1897       17032 :             Oid         decl_type = declared_arg_types[j];
    1898       17032 :             Oid         actual_type = actual_arg_types[j];
    1899             : 
    1900       17032 :             if (actual_type != UNKNOWNOID)
    1901        8270 :                 continue;
    1902             : 
    1903        8762 :             if (decl_type == ANYELEMENTOID ||
    1904        7900 :                 decl_type == ANYNONARRAYOID ||
    1905             :                 decl_type == ANYENUMOID)
    1906         980 :                 declared_arg_types[j] = elem_typeid;
    1907        7782 :             else if (decl_type == ANYARRAYOID)
    1908             :             {
    1909        7128 :                 if (!OidIsValid(array_typeid))
    1910             :                 {
    1911          16 :                     array_typeid = get_array_type(elem_typeid);
    1912          16 :                     if (!OidIsValid(array_typeid))
    1913           0 :                         ereport(ERROR,
    1914             :                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
    1915             :                                  errmsg("could not find array type for data type %s",
    1916             :                                         format_type_be(elem_typeid))));
    1917             :                 }
    1918        7128 :                 declared_arg_types[j] = array_typeid;
    1919             :             }
    1920         654 :             else if (decl_type == ANYRANGEOID)
    1921             :             {
    1922          30 :                 if (!OidIsValid(range_typeid))
    1923             :                 {
    1924           0 :                     ereport(ERROR,
    1925             :                             (errcode(ERRCODE_UNDEFINED_OBJECT),
    1926             :                              errmsg("could not find range type for data type %s",
    1927             :                                     format_type_be(elem_typeid))));
    1928             :                 }
    1929          30 :                 declared_arg_types[j] = range_typeid;
    1930             :             }
    1931             :         }
    1932             :     }
    1933             : 
    1934             :     /* if we return ANYARRAY use the appropriate argument type */
    1935       66878 :     if (rettype == ANYARRAYOID)
    1936             :     {
    1937       16874 :         if (!OidIsValid(array_typeid))
    1938             :         {
    1939       14466 :             array_typeid = get_array_type(elem_typeid);
    1940       14466 :             if (!OidIsValid(array_typeid))
    1941           0 :                 ereport(ERROR,
    1942             :                         (errcode(ERRCODE_UNDEFINED_OBJECT),
    1943             :                          errmsg("could not find array type for data type %s",
    1944             :                                 format_type_be(elem_typeid))));
    1945             :         }
    1946       16874 :         return array_typeid;
    1947             :     }
    1948             : 
    1949             :     /* if we return ANYRANGE use the appropriate argument type */
    1950       50004 :     if (rettype == ANYRANGEOID)
    1951             :     {
    1952          56 :         if (!OidIsValid(range_typeid))
    1953             :         {
    1954           0 :             ereport(ERROR,
    1955             :                     (errcode(ERRCODE_UNDEFINED_OBJECT),
    1956             :                      errmsg("could not find range type for data type %s",
    1957             :                             format_type_be(elem_typeid))));
    1958             :         }
    1959          56 :         return range_typeid;
    1960             :     }
    1961             : 
    1962             :     /* if we return ANYELEMENT use the appropriate argument type */
    1963       49948 :     if (rettype == ANYELEMENTOID ||
    1964       32322 :         rettype == ANYNONARRAYOID ||
    1965             :         rettype == ANYENUMOID)
    1966       17778 :         return elem_typeid;
    1967             : 
    1968             :     /* we don't return a generic type; send back the original return type */
    1969       32170 :     return rettype;
    1970             : }
    1971             : 
    1972             : /*
    1973             :  * resolve_generic_type()
    1974             :  *      Deduce an individual actual datatype on the assumption that
    1975             :  *      the rules for polymorphic types are being followed.
    1976             :  *
    1977             :  * declared_type is the declared datatype we want to resolve.
    1978             :  * context_actual_type is the actual input datatype to some argument
    1979             :  * that has declared datatype context_declared_type.
    1980             :  *
    1981             :  * If declared_type isn't polymorphic, we just return it.  Otherwise,
    1982             :  * context_declared_type must be polymorphic, and we deduce the correct
    1983             :  * return type based on the relationship of the two polymorphic types.
    1984             :  */
    1985             : Oid
    1986        6182 : resolve_generic_type(Oid declared_type,
    1987             :                      Oid context_actual_type,
    1988             :                      Oid context_declared_type)
    1989             : {
    1990        6182 :     if (declared_type == ANYARRAYOID)
    1991             :     {
    1992          48 :         if (context_declared_type == ANYARRAYOID)
    1993             :         {
    1994             :             /*
    1995             :              * Use actual type, but it must be an array; or if it's a domain
    1996             :              * over array, use the base array type.
    1997             :              */
    1998           0 :             Oid         context_base_type = getBaseType(context_actual_type);
    1999           0 :             Oid         array_typelem = get_element_type(context_base_type);
    2000             : 
    2001           0 :             if (!OidIsValid(array_typelem))
    2002           0 :                 ereport(ERROR,
    2003             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2004             :                          errmsg("argument declared %s is not an array but type %s",
    2005             :                                 "anyarray", format_type_be(context_base_type))));
    2006           0 :             return context_base_type;
    2007             :         }
    2008          48 :         else if (context_declared_type == ANYELEMENTOID ||
    2009           0 :                  context_declared_type == ANYNONARRAYOID ||
    2010           0 :                  context_declared_type == ANYENUMOID ||
    2011             :                  context_declared_type == ANYRANGEOID)
    2012             :         {
    2013             :             /* Use the array type corresponding to actual type */
    2014          48 :             Oid         array_typeid = get_array_type(context_actual_type);
    2015             : 
    2016          48 :             if (!OidIsValid(array_typeid))
    2017           0 :                 ereport(ERROR,
    2018             :                         (errcode(ERRCODE_UNDEFINED_OBJECT),
    2019             :                          errmsg("could not find array type for data type %s",
    2020             :                                 format_type_be(context_actual_type))));
    2021          48 :             return array_typeid;
    2022             :         }
    2023             :     }
    2024        6134 :     else if (declared_type == ANYELEMENTOID ||
    2025           0 :              declared_type == ANYNONARRAYOID ||
    2026           0 :              declared_type == ANYENUMOID ||
    2027             :              declared_type == ANYRANGEOID)
    2028             :     {
    2029        6134 :         if (context_declared_type == ANYARRAYOID)
    2030             :         {
    2031             :             /* Use the element type corresponding to actual type */
    2032        6122 :             Oid         context_base_type = getBaseType(context_actual_type);
    2033        6122 :             Oid         array_typelem = get_element_type(context_base_type);
    2034             : 
    2035        6122 :             if (!OidIsValid(array_typelem))
    2036           0 :                 ereport(ERROR,
    2037             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2038             :                          errmsg("argument declared %s is not an array but type %s",
    2039             :                                 "anyarray", format_type_be(context_base_type))));
    2040        6122 :             return array_typelem;
    2041             :         }
    2042          12 :         else if (context_declared_type == ANYRANGEOID)
    2043             :         {
    2044             :             /* Use the element type corresponding to actual type */
    2045          12 :             Oid         context_base_type = getBaseType(context_actual_type);
    2046          12 :             Oid         range_typelem = get_range_subtype(context_base_type);
    2047             : 
    2048          12 :             if (!OidIsValid(range_typelem))
    2049           0 :                 ereport(ERROR,
    2050             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    2051             :                          errmsg("argument declared %s is not a range type but type %s",
    2052             :                                 "anyrange", format_type_be(context_base_type))));
    2053          12 :             return range_typelem;
    2054             :         }
    2055           0 :         else if (context_declared_type == ANYELEMENTOID ||
    2056           0 :                  context_declared_type == ANYNONARRAYOID ||
    2057             :                  context_declared_type == ANYENUMOID)
    2058             :         {
    2059             :             /* Use the actual type; it doesn't matter if array or not */
    2060           0 :             return context_actual_type;
    2061             :         }
    2062             :     }
    2063             :     else
    2064             :     {
    2065             :         /* declared_type isn't polymorphic, so return it as-is */
    2066           0 :         return declared_type;
    2067             :     }
    2068             :     /* If we get here, declared_type is polymorphic and context isn't */
    2069             :     /* NB: this is a calling-code logic error, not a user error */
    2070           0 :     elog(ERROR, "could not determine polymorphic type because context isn't polymorphic");
    2071             :     return InvalidOid;          /* keep compiler quiet */
    2072             : }
    2073             : 
    2074             : 
    2075             : /* TypeCategory()
    2076             :  *      Assign a category to the specified type OID.
    2077             :  *
    2078             :  * NB: this must not return TYPCATEGORY_INVALID.
    2079             :  */
    2080             : TYPCATEGORY
    2081       89750 : TypeCategory(Oid type)
    2082             : {
    2083             :     char        typcategory;
    2084             :     bool        typispreferred;
    2085             : 
    2086       89750 :     get_type_category_preferred(type, &typcategory, &typispreferred);
    2087             :     Assert(typcategory != TYPCATEGORY_INVALID);
    2088       89750 :     return (TYPCATEGORY) typcategory;
    2089             : }
    2090             : 
    2091             : 
    2092             : /* IsPreferredType()
    2093             :  *      Check if this type is a preferred type for the given category.
    2094             :  *
    2095             :  * If category is TYPCATEGORY_INVALID, then we'll return true for preferred
    2096             :  * types of any category; otherwise, only for preferred types of that
    2097             :  * category.
    2098             :  */
    2099             : bool
    2100       27446 : IsPreferredType(TYPCATEGORY category, Oid type)
    2101             : {
    2102             :     char        typcategory;
    2103             :     bool        typispreferred;
    2104             : 
    2105       27446 :     get_type_category_preferred(type, &typcategory, &typispreferred);
    2106       27446 :     if (category == typcategory || category == TYPCATEGORY_INVALID)
    2107       20518 :         return typispreferred;
    2108             :     else
    2109        6928 :         return false;
    2110             : }
    2111             : 
    2112             : 
    2113             : /* IsBinaryCoercible()
    2114             :  *      Check if srctype is binary-coercible to targettype.
    2115             :  *
    2116             :  * This notion allows us to cheat and directly exchange values without
    2117             :  * going through the trouble of calling a conversion function.  Note that
    2118             :  * in general, this should only be an implementation shortcut.  Before 7.4,
    2119             :  * this was also used as a heuristic for resolving overloaded functions and
    2120             :  * operators, but that's basically a bad idea.
    2121             :  *
    2122             :  * As of 7.3, binary coercibility isn't hardwired into the code anymore.
    2123             :  * We consider two types binary-coercible if there is an implicitly
    2124             :  * invokable, no-function-needed pg_cast entry.  Also, a domain is always
    2125             :  * binary-coercible to its base type, though *not* vice versa (in the other
    2126             :  * direction, one must apply domain constraint checks before accepting the
    2127             :  * value as legitimate).  We also need to special-case various polymorphic
    2128             :  * types.
    2129             :  *
    2130             :  * This function replaces IsBinaryCompatible(), which was an inherently
    2131             :  * symmetric test.  Since the pg_cast entries aren't necessarily symmetric,
    2132             :  * the order of the operands is now significant.
    2133             :  */
    2134             : bool
    2135     1522788 : IsBinaryCoercible(Oid srctype, Oid targettype)
    2136             : {
    2137             :     HeapTuple   tuple;
    2138             :     Form_pg_cast castForm;
    2139             :     bool        result;
    2140             : 
    2141             :     /* Fast path if same type */
    2142     1522788 :     if (srctype == targettype)
    2143      722428 :         return true;
    2144             : 
    2145             :     /* Anything is coercible to ANY or ANYELEMENT */
    2146      800360 :     if (targettype == ANYOID || targettype == ANYELEMENTOID)
    2147         130 :         return true;
    2148             : 
    2149             :     /* If srctype is a domain, reduce to its base type */
    2150      800230 :     if (OidIsValid(srctype))
    2151      800230 :         srctype = getBaseType(srctype);
    2152             : 
    2153             :     /* Somewhat-fast path for domain -> base type case */
    2154      800230 :     if (srctype == targettype)
    2155          12 :         return true;
    2156             : 
    2157             :     /* Also accept any array type as coercible to ANYARRAY */
    2158      800218 :     if (targettype == ANYARRAYOID)
    2159       42462 :         if (type_is_array(srctype))
    2160        3388 :             return true;
    2161             : 
    2162             :     /* Also accept any non-array type as coercible to ANYNONARRAY */
    2163      796830 :     if (targettype == ANYNONARRAYOID)
    2164           0 :         if (!type_is_array(srctype))
    2165           0 :             return true;
    2166             : 
    2167             :     /* Also accept any enum type as coercible to ANYENUM */
    2168      796830 :     if (targettype == ANYENUMOID)
    2169       38368 :         if (type_is_enum(srctype))
    2170          82 :             return true;
    2171             : 
    2172             :     /* Also accept any range type as coercible to ANYRANGE */
    2173      796748 :     if (targettype == ANYRANGEOID)
    2174       13860 :         if (type_is_range(srctype))
    2175         212 :             return true;
    2176             : 
    2177             :     /* Also accept any composite type as coercible to RECORD */
    2178      796536 :     if (targettype == RECORDOID)
    2179       11220 :         if (ISCOMPLEX(srctype))
    2180         142 :             return true;
    2181             : 
    2182             :     /* Also accept any composite array type as coercible to RECORD[] */
    2183      796394 :     if (targettype == RECORDARRAYOID)
    2184           0 :         if (is_complex_array(srctype))
    2185           0 :             return true;
    2186             : 
    2187             :     /* Else look in pg_cast */
    2188      796394 :     tuple = SearchSysCache2(CASTSOURCETARGET,
    2189             :                             ObjectIdGetDatum(srctype),
    2190             :                             ObjectIdGetDatum(targettype));
    2191      796394 :     if (!HeapTupleIsValid(tuple))
    2192      660788 :         return false;           /* no cast */
    2193      135606 :     castForm = (Form_pg_cast) GETSTRUCT(tuple);
    2194             : 
    2195      147974 :     result = (castForm->castmethod == COERCION_METHOD_BINARY &&
    2196       12368 :               castForm->castcontext == COERCION_CODE_IMPLICIT);
    2197             : 
    2198      135606 :     ReleaseSysCache(tuple);
    2199             : 
    2200      135606 :     return result;
    2201             : }
    2202             : 
    2203             : 
    2204             : /*
    2205             :  * find_coercion_pathway
    2206             :  *      Look for a coercion pathway between two types.
    2207             :  *
    2208             :  * Currently, this deals only with scalar-type cases; it does not consider
    2209             :  * polymorphic types nor casts between composite types.  (Perhaps fold
    2210             :  * those in someday?)
    2211             :  *
    2212             :  * ccontext determines the set of available casts.
    2213             :  *
    2214             :  * The possible result codes are:
    2215             :  *  COERCION_PATH_NONE: failed to find any coercion pathway
    2216             :  *              *funcid is set to InvalidOid
    2217             :  *  COERCION_PATH_FUNC: apply the coercion function returned in *funcid
    2218             :  *  COERCION_PATH_RELABELTYPE: binary-compatible cast, no function needed
    2219             :  *              *funcid is set to InvalidOid
    2220             :  *  COERCION_PATH_ARRAYCOERCE: need an ArrayCoerceExpr node
    2221             :  *              *funcid is set to InvalidOid
    2222             :  *  COERCION_PATH_COERCEVIAIO: need a CoerceViaIO node
    2223             :  *              *funcid is set to InvalidOid
    2224             :  *
    2225             :  * Note: COERCION_PATH_RELABELTYPE does not necessarily mean that no work is
    2226             :  * needed to do the coercion; if the target is a domain then we may need to
    2227             :  * apply domain constraint checking.  If you want to check for a zero-effort
    2228             :  * conversion then use IsBinaryCoercible().
    2229             :  */
    2230             : CoercionPathType
    2231     1268776 : find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
    2232             :                       CoercionContext ccontext,
    2233             :                       Oid *funcid)
    2234             : {
    2235     1268776 :     CoercionPathType result = COERCION_PATH_NONE;
    2236             :     HeapTuple   tuple;
    2237             : 
    2238     1268776 :     *funcid = InvalidOid;
    2239             : 
    2240             :     /* Perhaps the types are domains; if so, look at their base types */
    2241     1268776 :     if (OidIsValid(sourceTypeId))
    2242     1268776 :         sourceTypeId = getBaseType(sourceTypeId);
    2243     1268776 :     if (OidIsValid(targetTypeId))
    2244     1268776 :         targetTypeId = getBaseType(targetTypeId);
    2245             : 
    2246             :     /* Domains are always coercible to and from their base type */
    2247     1268776 :     if (sourceTypeId == targetTypeId)
    2248      249922 :         return COERCION_PATH_RELABELTYPE;
    2249             : 
    2250             :     /* Look in pg_cast */
    2251     1018854 :     tuple = SearchSysCache2(CASTSOURCETARGET,
    2252             :                             ObjectIdGetDatum(sourceTypeId),
    2253             :                             ObjectIdGetDatum(targetTypeId));
    2254             : 
    2255     1018854 :     if (HeapTupleIsValid(tuple))
    2256             :     {
    2257      413266 :         Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
    2258             :         CoercionContext castcontext;
    2259             : 
    2260             :         /* convert char value for castcontext to CoercionContext enum */
    2261      413266 :         switch (castForm->castcontext)
    2262             :         {
    2263             :             case COERCION_CODE_IMPLICIT:
    2264      331002 :                 castcontext = COERCION_IMPLICIT;
    2265      331002 :                 break;
    2266             :             case COERCION_CODE_ASSIGNMENT:
    2267       78162 :                 castcontext = COERCION_ASSIGNMENT;
    2268       78162 :                 break;
    2269             :             case COERCION_CODE_EXPLICIT:
    2270        4102 :                 castcontext = COERCION_EXPLICIT;
    2271        4102 :                 break;
    2272             :             default:
    2273           0 :                 elog(ERROR, "unrecognized castcontext: %d",
    2274             :                      (int) castForm->castcontext);
    2275             :                 castcontext = 0;    /* keep compiler quiet */
    2276             :                 break;
    2277             :         }
    2278             : 
    2279             :         /* Rely on ordering of enum for correct behavior here */
    2280      413266 :         if (ccontext >= castcontext)
    2281             :         {
    2282      357682 :             switch (castForm->castmethod)
    2283             :             {
    2284             :                 case COERCION_METHOD_FUNCTION:
    2285      137988 :                     result = COERCION_PATH_FUNC;
    2286      137988 :                     *funcid = castForm->castfunc;
    2287      137988 :                     break;
    2288             :                 case COERCION_METHOD_INOUT:
    2289           8 :                     result = COERCION_PATH_COERCEVIAIO;
    2290           8 :                     break;
    2291             :                 case COERCION_METHOD_BINARY:
    2292      219686 :                     result = COERCION_PATH_RELABELTYPE;
    2293      219686 :                     break;
    2294             :                 default:
    2295           0 :                     elog(ERROR, "unrecognized castmethod: %d",
    2296             :                          (int) castForm->castmethod);
    2297             :                     break;
    2298             :             }
    2299             :         }
    2300             : 
    2301      413266 :         ReleaseSysCache(tuple);
    2302             :     }
    2303             :     else
    2304             :     {
    2305             :         /*
    2306             :          * If there's no pg_cast entry, perhaps we are dealing with a pair of
    2307             :          * array types.  If so, and if their element types have a conversion
    2308             :          * pathway, report that we can coerce with an ArrayCoerceExpr.
    2309             :          *
    2310             :          * Hack: disallow coercions to oidvector and int2vector, which
    2311             :          * otherwise tend to capture coercions that should go to "real" array
    2312             :          * types.  We want those types to be considered "real" arrays for many
    2313             :          * purposes, but not this one.  (Also, ArrayCoerceExpr isn't
    2314             :          * guaranteed to produce an output that meets the restrictions of
    2315             :          * these datatypes, such as being 1-dimensional.)
    2316             :          */
    2317      605588 :         if (targetTypeId != OIDVECTOROID && targetTypeId != INT2VECTOROID)
    2318             :         {
    2319             :             Oid         targetElem;
    2320             :             Oid         sourceElem;
    2321             : 
    2322      596158 :             if ((targetElem = get_element_type(targetTypeId)) != InvalidOid &&
    2323             :                 (sourceElem = get_element_type(sourceTypeId)) != InvalidOid)
    2324             :             {
    2325             :                 CoercionPathType elempathtype;
    2326             :                 Oid         elemfuncid;
    2327             : 
    2328        3556 :                 elempathtype = find_coercion_pathway(targetElem,
    2329             :                                                      sourceElem,
    2330             :                                                      ccontext,
    2331             :                                                      &elemfuncid);
    2332        3556 :                 if (elempathtype != COERCION_PATH_NONE)
    2333             :                 {
    2334        3462 :                     result = COERCION_PATH_ARRAYCOERCE;
    2335             :                 }
    2336             :             }
    2337             :         }
    2338             : 
    2339             :         /*
    2340             :          * If we still haven't found a possibility, consider automatic casting
    2341             :          * using I/O functions.  We allow assignment casts to string types and
    2342             :          * explicit casts from string types to be handled this way. (The
    2343             :          * CoerceViaIO mechanism is a lot more general than that, but this is
    2344             :          * all we want to allow in the absence of a pg_cast entry.) It would
    2345             :          * probably be better to insist on explicit casts in both directions,
    2346             :          * but this is a compromise to preserve something of the pre-8.3
    2347             :          * behavior that many types had implicit (yipes!) casts to text.
    2348             :          */
    2349      605588 :         if (result == COERCION_PATH_NONE)
    2350             :         {
    2351      631504 :             if (ccontext >= COERCION_ASSIGNMENT &&
    2352       29378 :                 TypeCategory(targetTypeId) == TYPCATEGORY_STRING)
    2353       25768 :                 result = COERCION_PATH_COERCEVIAIO;
    2354      579464 :             else if (ccontext >= COERCION_EXPLICIT &&
    2355        3106 :                      TypeCategory(sourceTypeId) == TYPCATEGORY_STRING)
    2356        1032 :                 result = COERCION_PATH_COERCEVIAIO;
    2357             :         }
    2358             :     }
    2359             : 
    2360     1018854 :     return result;
    2361             : }
    2362             : 
    2363             : 
    2364             : /*
    2365             :  * find_typmod_coercion_function -- does the given type need length coercion?
    2366             :  *
    2367             :  * If the target type possesses a pg_cast function from itself to itself,
    2368             :  * it must need length coercion.
    2369             :  *
    2370             :  * "bpchar" (ie, char(N)) and "numeric" are examples of such types.
    2371             :  *
    2372             :  * If the given type is a varlena array type, we do not look for a coercion
    2373             :  * function associated directly with the array type, but instead look for
    2374             :  * one associated with the element type.  An ArrayCoerceExpr node must be
    2375             :  * used to apply such a function.  (Note: currently, it's pointless to
    2376             :  * return the funcid in this case, because it'll just get looked up again
    2377             :  * in the recursive construction of the ArrayCoerceExpr's elemexpr.)
    2378             :  *
    2379             :  * We use the same result enum as find_coercion_pathway, but the only possible
    2380             :  * result codes are:
    2381             :  *  COERCION_PATH_NONE: no length coercion needed
    2382             :  *  COERCION_PATH_FUNC: apply the function returned in *funcid
    2383             :  *  COERCION_PATH_ARRAYCOERCE: apply the function using ArrayCoerceExpr
    2384             :  */
    2385             : CoercionPathType
    2386       28054 : find_typmod_coercion_function(Oid typeId,
    2387             :                               Oid *funcid)
    2388             : {
    2389             :     CoercionPathType result;
    2390             :     Type        targetType;
    2391             :     Form_pg_type typeForm;
    2392             :     HeapTuple   tuple;
    2393             : 
    2394       28054 :     *funcid = InvalidOid;
    2395       28054 :     result = COERCION_PATH_FUNC;
    2396             : 
    2397       28054 :     targetType = typeidType(typeId);
    2398       28054 :     typeForm = (Form_pg_type) GETSTRUCT(targetType);
    2399             : 
    2400             :     /* Check for a varlena array type */
    2401       28054 :     if (typeForm->typelem != InvalidOid && typeForm->typlen == -1)
    2402             :     {
    2403             :         /* Yes, switch our attention to the element type */
    2404          56 :         typeId = typeForm->typelem;
    2405          56 :         result = COERCION_PATH_ARRAYCOERCE;
    2406             :     }
    2407       28054 :     ReleaseSysCache(targetType);
    2408             : 
    2409             :     /* Look in pg_cast */
    2410       28054 :     tuple = SearchSysCache2(CASTSOURCETARGET,
    2411             :                             ObjectIdGetDatum(typeId),
    2412             :                             ObjectIdGetDatum(typeId));
    2413             : 
    2414       28054 :     if (HeapTupleIsValid(tuple))
    2415             :     {
    2416       28042 :         Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
    2417             : 
    2418       28042 :         *funcid = castForm->castfunc;
    2419       28042 :         ReleaseSysCache(tuple);
    2420             :     }
    2421             : 
    2422       28054 :     if (!OidIsValid(*funcid))
    2423          12 :         result = COERCION_PATH_NONE;
    2424             : 
    2425       28054 :     return result;
    2426             : }
    2427             : 
    2428             : /*
    2429             :  * is_complex_array
    2430             :  *      Is this type an array of composite?
    2431             :  *
    2432             :  * Note: this will not return true for record[]; check for RECORDARRAYOID
    2433             :  * separately if needed.
    2434             :  */
    2435             : static bool
    2436          12 : is_complex_array(Oid typid)
    2437             : {
    2438          12 :     Oid         elemtype = get_element_type(typid);
    2439             : 
    2440          12 :     return (OidIsValid(elemtype) && ISCOMPLEX(elemtype));
    2441             : }
    2442             : 
    2443             : 
    2444             : /*
    2445             :  * Check whether reltypeId is the row type of a typed table of type
    2446             :  * reloftypeId, or is a domain over such a row type.  (This is conceptually
    2447             :  * similar to the subtype relationship checked by typeInheritsFrom().)
    2448             :  */
    2449             : static bool
    2450      626990 : typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId)
    2451             : {
    2452      626990 :     Oid         relid = typeOrDomainTypeRelid(reltypeId);
    2453      626990 :     bool        result = false;
    2454             : 
    2455      626990 :     if (relid)
    2456             :     {
    2457             :         HeapTuple   tp;
    2458             :         Form_pg_class reltup;
    2459             : 
    2460        6838 :         tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
    2461        6838 :         if (!HeapTupleIsValid(tp))
    2462           0 :             elog(ERROR, "cache lookup failed for relation %u", relid);
    2463             : 
    2464        6838 :         reltup = (Form_pg_class) GETSTRUCT(tp);
    2465        6838 :         if (reltup->reloftype == reloftypeId)
    2466           8 :             result = true;
    2467             : 
    2468        6838 :         ReleaseSysCache(tp);
    2469             :     }
    2470             : 
    2471      626990 :     return result;
    2472             : }

Generated by: LCOV version 1.13