Header And Logo

PostgreSQL
| The world's most advanced open source database.

parse_coerce.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * parse_coerce.c
00004  *      handle type coercions/conversions for parser
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/parser/parse_coerce.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 #include "postgres.h"
00016 
00017 #include "access/htup_details.h"
00018 #include "catalog/pg_cast.h"
00019 #include "catalog/pg_class.h"
00020 #include "catalog/pg_inherits_fn.h"
00021 #include "catalog/pg_proc.h"
00022 #include "catalog/pg_type.h"
00023 #include "nodes/makefuncs.h"
00024 #include "nodes/nodeFuncs.h"
00025 #include "parser/parse_coerce.h"
00026 #include "parser/parse_relation.h"
00027 #include "parser/parse_type.h"
00028 #include "utils/builtins.h"
00029 #include "utils/lsyscache.h"
00030 #include "utils/syscache.h"
00031 #include "utils/typcache.h"
00032 
00033 
00034 static Node *coerce_type_typmod(Node *node,
00035                    Oid targetTypeId, int32 targetTypMod,
00036                    CoercionForm cformat, int location,
00037                    bool isExplicit, bool hideInputCoercion);
00038 static void hide_coercion_node(Node *node);
00039 static Node *build_coercion_expression(Node *node,
00040                           CoercionPathType pathtype,
00041                           Oid funcId,
00042                           Oid targetTypeId, int32 targetTypMod,
00043                           CoercionForm cformat, int location,
00044                           bool isExplicit);
00045 static Node *coerce_record_to_complex(ParseState *pstate, Node *node,
00046                          Oid targetTypeId,
00047                          CoercionContext ccontext,
00048                          CoercionForm cformat,
00049                          int location);
00050 static bool is_complex_array(Oid typid);
00051 static bool typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId);
00052 
00053 
00054 /*
00055  * coerce_to_target_type()
00056  *      Convert an expression to a target type and typmod.
00057  *
00058  * This is the general-purpose entry point for arbitrary type coercion
00059  * operations.  Direct use of the component operations can_coerce_type,
00060  * coerce_type, and coerce_type_typmod should be restricted to special
00061  * cases (eg, when the conversion is expected to succeed).
00062  *
00063  * Returns the possibly-transformed expression tree, or NULL if the type
00064  * conversion is not possible.  (We do this, rather than ereport'ing directly,
00065  * so that callers can generate custom error messages indicating context.)
00066  *
00067  * pstate - parse state (can be NULL, see coerce_type)
00068  * expr - input expression tree (already transformed by transformExpr)
00069  * exprtype - result type of expr
00070  * targettype - desired result type
00071  * targettypmod - desired result typmod
00072  * ccontext, cformat - context indicators to control coercions
00073  * location - parse location of the coercion request, or -1 if unknown/implicit
00074  */
00075 Node *
00076 coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype,
00077                       Oid targettype, int32 targettypmod,
00078                       CoercionContext ccontext,
00079                       CoercionForm cformat,
00080                       int location)
00081 {
00082     Node       *result;
00083     Node       *origexpr;
00084 
00085     if (!can_coerce_type(1, &exprtype, &targettype, ccontext))
00086         return NULL;
00087 
00088     /*
00089      * If the input has a CollateExpr at the top, strip it off, perform the
00090      * coercion, and put a new one back on.  This is annoying since it
00091      * duplicates logic in coerce_type, but if we don't do this then it's too
00092      * hard to tell whether coerce_type actually changed anything, and we
00093      * *must* know that to avoid possibly calling hide_coercion_node on
00094      * something that wasn't generated by coerce_type.  Note that if there are
00095      * multiple stacked CollateExprs, we just discard all but the topmost.
00096      */
00097     origexpr = expr;
00098     while (expr && IsA(expr, CollateExpr))
00099         expr = (Node *) ((CollateExpr *) expr)->arg;
00100 
00101     result = coerce_type(pstate, expr, exprtype,
00102                          targettype, targettypmod,
00103                          ccontext, cformat, location);
00104 
00105     /*
00106      * If the target is a fixed-length type, it may need a length coercion as
00107      * well as a type coercion.  If we find ourselves adding both, force the
00108      * inner coercion node to implicit display form.
00109      */
00110     result = coerce_type_typmod(result,
00111                                 targettype, targettypmod,
00112                                 cformat, location,
00113                                 (cformat != COERCE_IMPLICIT_CAST),
00114                                 (result != expr && !IsA(result, Const)));
00115 
00116     if (expr != origexpr)
00117     {
00118         /* Reinstall top CollateExpr */
00119         CollateExpr *coll = (CollateExpr *) origexpr;
00120         CollateExpr *newcoll = makeNode(CollateExpr);
00121 
00122         newcoll->arg = (Expr *) result;
00123         newcoll->collOid = coll->collOid;
00124         newcoll->location = coll->location;
00125         result = (Node *) newcoll;
00126     }
00127 
00128     return result;
00129 }
00130 
00131 
00132 /*
00133  * coerce_type()
00134  *      Convert an expression to a different type.
00135  *
00136  * The caller should already have determined that the coercion is possible;
00137  * see can_coerce_type.
00138  *
00139  * Normally, no coercion to a typmod (length) is performed here.  The caller
00140  * must call coerce_type_typmod as well, if a typmod constraint is wanted.
00141  * (But if the target type is a domain, it may internally contain a
00142  * typmod constraint, which will be applied inside coerce_to_domain.)
00143  * In some cases pg_cast specifies a type coercion function that also
00144  * applies length conversion, and in those cases only, the result will
00145  * already be properly coerced to the specified typmod.
00146  *
00147  * pstate is only used in the case that we are able to resolve the type of
00148  * a previously UNKNOWN Param.  It is okay to pass pstate = NULL if the
00149  * caller does not want type information updated for Params.
00150  *
00151  * Note: this function must not modify the given expression tree, only add
00152  * decoration on top of it.  See transformSetOperationTree, for example.
00153  */
00154 Node *
00155 coerce_type(ParseState *pstate, Node *node,
00156             Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod,
00157             CoercionContext ccontext, CoercionForm cformat, int location)
00158 {
00159     Node       *result;
00160     CoercionPathType pathtype;
00161     Oid         funcId;
00162 
00163     if (targetTypeId == inputTypeId ||
00164         node == NULL)
00165     {
00166         /* no conversion needed */
00167         return node;
00168     }
00169     if (targetTypeId == ANYOID ||
00170         targetTypeId == ANYELEMENTOID ||
00171         targetTypeId == ANYNONARRAYOID)
00172     {
00173         /*
00174          * Assume can_coerce_type verified that implicit coercion is okay.
00175          *
00176          * Note: by returning the unmodified node here, we are saying that
00177          * it's OK to treat an UNKNOWN constant as a valid input for a
00178          * function accepting ANY, ANYELEMENT, or ANYNONARRAY.  This should be
00179          * all right, since an UNKNOWN value is still a perfectly valid Datum.
00180          *
00181          * NB: we do NOT want a RelabelType here: the exposed type of the
00182          * function argument must be its actual type, not the polymorphic
00183          * pseudotype.
00184          */
00185         return node;
00186     }
00187     if (targetTypeId == ANYARRAYOID ||
00188         targetTypeId == ANYENUMOID ||
00189         targetTypeId == ANYRANGEOID)
00190     {
00191         /*
00192          * Assume can_coerce_type verified that implicit coercion is okay.
00193          *
00194          * These cases are unlike the ones above because the exposed type of
00195          * the argument must be an actual array, enum, or range type.  In
00196          * particular the argument must *not* be an UNKNOWN constant.  If it
00197          * is, we just fall through; below, we'll call anyarray_in,
00198          * anyenum_in, or anyrange_in, which will produce an error.  Also, if
00199          * what we have is a domain over array, enum, or range, we have to
00200          * relabel it to its base type.
00201          *
00202          * Note: currently, we can't actually see a domain-over-enum here,
00203          * since the other functions in this file will not match such a
00204          * parameter to ANYENUM.  But that should get changed eventually.
00205          */
00206         if (inputTypeId != UNKNOWNOID)
00207         {
00208             Oid         baseTypeId = getBaseType(inputTypeId);
00209 
00210             if (baseTypeId != inputTypeId)
00211             {
00212                 RelabelType *r = makeRelabelType((Expr *) node,
00213                                                  baseTypeId, -1,
00214                                                  InvalidOid,
00215                                                  cformat);
00216 
00217                 r->location = location;
00218                 return (Node *) r;
00219             }
00220             /* Not a domain type, so return it as-is */
00221             return node;
00222         }
00223     }
00224     if (inputTypeId == UNKNOWNOID && IsA(node, Const))
00225     {
00226         /*
00227          * Input is a string constant with previously undetermined type. Apply
00228          * the target type's typinput function to it to produce a constant of
00229          * the target type.
00230          *
00231          * NOTE: this case cannot be folded together with the other
00232          * constant-input case, since the typinput function does not
00233          * necessarily behave the same as a type conversion function. For
00234          * example, int4's typinput function will reject "1.2", whereas
00235          * float-to-int type conversion will round to integer.
00236          *
00237          * XXX if the typinput function is not immutable, we really ought to
00238          * postpone evaluation of the function call until runtime. But there
00239          * is no way to represent a typinput function call as an expression
00240          * tree, because C-string values are not Datums. (XXX This *is*
00241          * possible as of 7.3, do we want to do it?)
00242          */
00243         Const      *con = (Const *) node;
00244         Const      *newcon = makeNode(Const);
00245         Oid         baseTypeId;
00246         int32       baseTypeMod;
00247         int32       inputTypeMod;
00248         Type        targetType;
00249         ParseCallbackState pcbstate;
00250 
00251         /*
00252          * If the target type is a domain, we want to call its base type's
00253          * input routine, not domain_in().  This is to avoid premature failure
00254          * when the domain applies a typmod: existing input routines follow
00255          * implicit-coercion semantics for length checks, which is not always
00256          * what we want here.  The needed check will be applied properly
00257          * inside coerce_to_domain().
00258          */
00259         baseTypeMod = targetTypeMod;
00260         baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
00261 
00262         /*
00263          * For most types we pass typmod -1 to the input routine, because
00264          * existing input routines follow implicit-coercion semantics for
00265          * length checks, which is not always what we want here.  Any length
00266          * constraint will be applied later by our caller.  An exception
00267          * however is the INTERVAL type, for which we *must* pass the typmod
00268          * or it won't be able to obey the bizarre SQL-spec input rules. (Ugly
00269          * as sin, but so is this part of the spec...)
00270          */
00271         if (baseTypeId == INTERVALOID)
00272             inputTypeMod = baseTypeMod;
00273         else
00274             inputTypeMod = -1;
00275 
00276         targetType = typeidType(baseTypeId);
00277 
00278         newcon->consttype = baseTypeId;
00279         newcon->consttypmod = inputTypeMod;
00280         newcon->constcollid = typeTypeCollation(targetType);
00281         newcon->constlen = typeLen(targetType);
00282         newcon->constbyval = typeByVal(targetType);
00283         newcon->constisnull = con->constisnull;
00284 
00285         /*
00286          * We use the original literal's location regardless of the position
00287          * of the coercion.  This is a change from pre-9.2 behavior, meant to
00288          * simplify life for pg_stat_statements.
00289          */
00290         newcon->location = con->location;
00291 
00292         /*
00293          * Set up to point at the constant's text if the input routine throws
00294          * an error.
00295          */
00296         setup_parser_errposition_callback(&pcbstate, pstate, con->location);
00297 
00298         /*
00299          * We assume here that UNKNOWN's internal representation is the same
00300          * as CSTRING.
00301          */
00302         if (!con->constisnull)
00303             newcon->constvalue = stringTypeDatum(targetType,
00304                                             DatumGetCString(con->constvalue),
00305                                                  inputTypeMod);
00306         else
00307             newcon->constvalue = stringTypeDatum(targetType,
00308                                                  NULL,
00309                                                  inputTypeMod);
00310 
00311         cancel_parser_errposition_callback(&pcbstate);
00312 
00313         result = (Node *) newcon;
00314 
00315         /* If target is a domain, apply constraints. */
00316         if (baseTypeId != targetTypeId)
00317             result = coerce_to_domain(result,
00318                                       baseTypeId, baseTypeMod,
00319                                       targetTypeId,
00320                                       cformat, location, false, false);
00321 
00322         ReleaseSysCache(targetType);
00323 
00324         return result;
00325     }
00326     if (IsA(node, Param) &&
00327         pstate != NULL && pstate->p_coerce_param_hook != NULL)
00328     {
00329         /*
00330          * Allow the CoerceParamHook to decide what happens.  It can return a
00331          * transformed node (very possibly the same Param node), or return
00332          * NULL to indicate we should proceed with normal coercion.
00333          */
00334         result = (*pstate->p_coerce_param_hook) (pstate,
00335                                                  (Param *) node,
00336                                                  targetTypeId,
00337                                                  targetTypeMod,
00338                                                  location);
00339         if (result)
00340             return result;
00341     }
00342     if (IsA(node, CollateExpr))
00343     {
00344         /*
00345          * If we have a COLLATE clause, we have to push the coercion
00346          * underneath the COLLATE.  This is really ugly, but there is little
00347          * choice because the above hacks on Consts and Params wouldn't happen
00348          * otherwise.  This kluge has consequences in coerce_to_target_type.
00349          */
00350         CollateExpr *coll = (CollateExpr *) node;
00351         CollateExpr *newcoll = makeNode(CollateExpr);
00352 
00353         newcoll->arg = (Expr *)
00354             coerce_type(pstate, (Node *) coll->arg,
00355                         inputTypeId, targetTypeId, targetTypeMod,
00356                         ccontext, cformat, location);
00357         newcoll->collOid = coll->collOid;
00358         newcoll->location = coll->location;
00359         return (Node *) newcoll;
00360     }
00361     pathtype = find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
00362                                      &funcId);
00363     if (pathtype != COERCION_PATH_NONE)
00364     {
00365         if (pathtype != COERCION_PATH_RELABELTYPE)
00366         {
00367             /*
00368              * Generate an expression tree representing run-time application
00369              * of the conversion function.  If we are dealing with a domain
00370              * target type, the conversion function will yield the base type,
00371              * and we need to extract the correct typmod to use from the
00372              * domain's typtypmod.
00373              */
00374             Oid         baseTypeId;
00375             int32       baseTypeMod;
00376 
00377             baseTypeMod = targetTypeMod;
00378             baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
00379 
00380             result = build_coercion_expression(node, pathtype, funcId,
00381                                                baseTypeId, baseTypeMod,
00382                                                cformat, location,
00383                                           (cformat != COERCE_IMPLICIT_CAST));
00384 
00385             /*
00386              * If domain, coerce to the domain type and relabel with domain
00387              * type ID.  We can skip the internal length-coercion step if the
00388              * selected coercion function was a type-and-length coercion.
00389              */
00390             if (targetTypeId != baseTypeId)
00391                 result = coerce_to_domain(result, baseTypeId, baseTypeMod,
00392                                           targetTypeId,
00393                                           cformat, location, true,
00394                                           exprIsLengthCoercion(result,
00395                                                                NULL));
00396         }
00397         else
00398         {
00399             /*
00400              * We don't need to do a physical conversion, but we do need to
00401              * attach a RelabelType node so that the expression will be seen
00402              * to have the intended type when inspected by higher-level code.
00403              *
00404              * Also, domains may have value restrictions beyond the base type
00405              * that must be accounted for.  If the destination is a domain
00406              * then we won't need a RelabelType node.
00407              */
00408             result = coerce_to_domain(node, InvalidOid, -1, targetTypeId,
00409                                       cformat, location, false, false);
00410             if (result == node)
00411             {
00412                 /*
00413                  * XXX could we label result with exprTypmod(node) instead of
00414                  * default -1 typmod, to save a possible length-coercion
00415                  * later? Would work if both types have same interpretation of
00416                  * typmod, which is likely but not certain.
00417                  */
00418                 RelabelType *r = makeRelabelType((Expr *) result,
00419                                                  targetTypeId, -1,
00420                                                  InvalidOid,
00421                                                  cformat);
00422 
00423                 r->location = location;
00424                 result = (Node *) r;
00425             }
00426         }
00427         return result;
00428     }
00429     if (inputTypeId == RECORDOID &&
00430         ISCOMPLEX(targetTypeId))
00431     {
00432         /* Coerce a RECORD to a specific complex type */
00433         return coerce_record_to_complex(pstate, node, targetTypeId,
00434                                         ccontext, cformat, location);
00435     }
00436     if (targetTypeId == RECORDOID &&
00437         ISCOMPLEX(inputTypeId))
00438     {
00439         /* Coerce a specific complex type to RECORD */
00440         /* NB: we do NOT want a RelabelType here */
00441         return node;
00442     }
00443 #ifdef NOT_USED
00444     if (inputTypeId == RECORDARRAYOID &&
00445         is_complex_array(targetTypeId))
00446     {
00447         /* Coerce record[] to a specific complex array type */
00448         /* not implemented yet ... */
00449     }
00450 #endif
00451     if (targetTypeId == RECORDARRAYOID &&
00452         is_complex_array(inputTypeId))
00453     {
00454         /* Coerce a specific complex array type to record[] */
00455         /* NB: we do NOT want a RelabelType here */
00456         return node;
00457     }
00458     if (typeInheritsFrom(inputTypeId, targetTypeId)
00459         || typeIsOfTypedTable(inputTypeId, targetTypeId))
00460     {
00461         /*
00462          * Input class type is a subclass of target, so generate an
00463          * appropriate runtime conversion (removing unneeded columns and
00464          * possibly rearranging the ones that are wanted).
00465          */
00466         ConvertRowtypeExpr *r = makeNode(ConvertRowtypeExpr);
00467 
00468         r->arg = (Expr *) node;
00469         r->resulttype = targetTypeId;
00470         r->convertformat = cformat;
00471         r->location = location;
00472         return (Node *) r;
00473     }
00474     /* If we get here, caller blew it */
00475     elog(ERROR, "failed to find conversion function from %s to %s",
00476          format_type_be(inputTypeId), format_type_be(targetTypeId));
00477     return NULL;                /* keep compiler quiet */
00478 }
00479 
00480 
00481 /*
00482  * can_coerce_type()
00483  *      Can input_typeids be coerced to target_typeids?
00484  *
00485  * We must be told the context (CAST construct, assignment, implicit coercion)
00486  * as this determines the set of available casts.
00487  */
00488 bool
00489 can_coerce_type(int nargs, Oid *input_typeids, Oid *target_typeids,
00490                 CoercionContext ccontext)
00491 {
00492     bool        have_generics = false;
00493     int         i;
00494 
00495     /* run through argument list... */
00496     for (i = 0; i < nargs; i++)
00497     {
00498         Oid         inputTypeId = input_typeids[i];
00499         Oid         targetTypeId = target_typeids[i];
00500         CoercionPathType pathtype;
00501         Oid         funcId;
00502 
00503         /* no problem if same type */
00504         if (inputTypeId == targetTypeId)
00505             continue;
00506 
00507         /* accept if target is ANY */
00508         if (targetTypeId == ANYOID)
00509             continue;
00510 
00511         /* accept if target is polymorphic, for now */
00512         if (IsPolymorphicType(targetTypeId))
00513         {
00514             have_generics = true;       /* do more checking later */
00515             continue;
00516         }
00517 
00518         /*
00519          * If input is an untyped string constant, assume we can convert it to
00520          * anything.
00521          */
00522         if (inputTypeId == UNKNOWNOID)
00523             continue;
00524 
00525         /*
00526          * If pg_cast shows that we can coerce, accept.  This test now covers
00527          * both binary-compatible and coercion-function cases.
00528          */
00529         pathtype = find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
00530                                          &funcId);
00531         if (pathtype != COERCION_PATH_NONE)
00532             continue;
00533 
00534         /*
00535          * If input is RECORD and target is a composite type, assume we can
00536          * coerce (may need tighter checking here)
00537          */
00538         if (inputTypeId == RECORDOID &&
00539             ISCOMPLEX(targetTypeId))
00540             continue;
00541 
00542         /*
00543          * If input is a composite type and target is RECORD, accept
00544          */
00545         if (targetTypeId == RECORDOID &&
00546             ISCOMPLEX(inputTypeId))
00547             continue;
00548 
00549 #ifdef NOT_USED                 /* not implemented yet */
00550 
00551         /*
00552          * If input is record[] and target is a composite array type, assume
00553          * we can coerce (may need tighter checking here)
00554          */
00555         if (inputTypeId == RECORDARRAYOID &&
00556             is_complex_array(targetTypeId))
00557             continue;
00558 #endif
00559 
00560         /*
00561          * If input is a composite array type and target is record[], accept
00562          */
00563         if (targetTypeId == RECORDARRAYOID &&
00564             is_complex_array(inputTypeId))
00565             continue;
00566 
00567         /*
00568          * If input is a class type that inherits from target, accept
00569          */
00570         if (typeInheritsFrom(inputTypeId, targetTypeId)
00571             || typeIsOfTypedTable(inputTypeId, targetTypeId))
00572             continue;
00573 
00574         /*
00575          * Else, cannot coerce at this argument position
00576          */
00577         return false;
00578     }
00579 
00580     /* If we found any generic argument types, cross-check them */
00581     if (have_generics)
00582     {
00583         if (!check_generic_type_consistency(input_typeids, target_typeids,
00584                                             nargs))
00585             return false;
00586     }
00587 
00588     return true;
00589 }
00590 
00591 
00592 /*
00593  * Create an expression tree to represent coercion to a domain type.
00594  *
00595  * 'arg': input expression
00596  * 'baseTypeId': base type of domain, if known (pass InvalidOid if caller
00597  *      has not bothered to look this up)
00598  * 'baseTypeMod': base type typmod of domain, if known (pass -1 if caller
00599  *      has not bothered to look this up)
00600  * 'typeId': target type to coerce to
00601  * 'cformat': coercion format
00602  * 'location': coercion request location
00603  * 'hideInputCoercion': if true, hide the input coercion under this one.
00604  * 'lengthCoercionDone': if true, caller already accounted for length,
00605  *      ie the input is already of baseTypMod as well as baseTypeId.
00606  *
00607  * If the target type isn't a domain, the given 'arg' is returned as-is.
00608  */
00609 Node *
00610 coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId,
00611                  CoercionForm cformat, int location,
00612                  bool hideInputCoercion,
00613                  bool lengthCoercionDone)
00614 {
00615     CoerceToDomain *result;
00616 
00617     /* Get the base type if it hasn't been supplied */
00618     if (baseTypeId == InvalidOid)
00619         baseTypeId = getBaseTypeAndTypmod(typeId, &baseTypeMod);
00620 
00621     /* If it isn't a domain, return the node as it was passed in */
00622     if (baseTypeId == typeId)
00623         return arg;
00624 
00625     /* Suppress display of nested coercion steps */
00626     if (hideInputCoercion)
00627         hide_coercion_node(arg);
00628 
00629     /*
00630      * If the domain applies a typmod to its base type, build the appropriate
00631      * coercion step.  Mark it implicit for display purposes, because we don't
00632      * want it shown separately by ruleutils.c; but the isExplicit flag passed
00633      * to the conversion function depends on the manner in which the domain
00634      * coercion is invoked, so that the semantics of implicit and explicit
00635      * coercion differ.  (Is that really the behavior we want?)
00636      *
00637      * NOTE: because we apply this as part of the fixed expression structure,
00638      * ALTER DOMAIN cannot alter the typtypmod.  But it's unclear that that
00639      * would be safe to do anyway, without lots of knowledge about what the
00640      * base type thinks the typmod means.
00641      */
00642     if (!lengthCoercionDone)
00643     {
00644         if (baseTypeMod >= 0)
00645             arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod,
00646                                      COERCE_IMPLICIT_CAST, location,
00647                                      (cformat != COERCE_IMPLICIT_CAST),
00648                                      false);
00649     }
00650 
00651     /*
00652      * Now build the domain coercion node.  This represents run-time checking
00653      * of any constraints currently attached to the domain.  This also ensures
00654      * that the expression is properly labeled as to result type.
00655      */
00656     result = makeNode(CoerceToDomain);
00657     result->arg = (Expr *) arg;
00658     result->resulttype = typeId;
00659     result->resulttypmod = -1;  /* currently, always -1 for domains */
00660     /* resultcollid will be set by parse_collate.c */
00661     result->coercionformat = cformat;
00662     result->location = location;
00663 
00664     return (Node *) result;
00665 }
00666 
00667 
00668 /*
00669  * coerce_type_typmod()
00670  *      Force a value to a particular typmod, if meaningful and possible.
00671  *
00672  * This is applied to values that are going to be stored in a relation
00673  * (where we have an atttypmod for the column) as well as values being
00674  * explicitly CASTed (where the typmod comes from the target type spec).
00675  *
00676  * The caller must have already ensured that the value is of the correct
00677  * type, typically by applying coerce_type.
00678  *
00679  * cformat determines the display properties of the generated node (if any),
00680  * while isExplicit may affect semantics.  If hideInputCoercion is true
00681  * *and* we generate a node, the input node is forced to IMPLICIT display
00682  * form, so that only the typmod coercion node will be visible when
00683  * displaying the expression.
00684  *
00685  * NOTE: this does not need to work on domain types, because any typmod
00686  * coercion for a domain is considered to be part of the type coercion
00687  * needed to produce the domain value in the first place.  So, no getBaseType.
00688  */
00689 static Node *
00690 coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod,
00691                    CoercionForm cformat, int location,
00692                    bool isExplicit, bool hideInputCoercion)
00693 {
00694     CoercionPathType pathtype;
00695     Oid         funcId;
00696 
00697     /*
00698      * A negative typmod is assumed to mean that no coercion is wanted. Also,
00699      * skip coercion if already done.
00700      */
00701     if (targetTypMod < 0 || targetTypMod == exprTypmod(node))
00702         return node;
00703 
00704     pathtype = find_typmod_coercion_function(targetTypeId, &funcId);
00705 
00706     if (pathtype != COERCION_PATH_NONE)
00707     {
00708         /* Suppress display of nested coercion steps */
00709         if (hideInputCoercion)
00710             hide_coercion_node(node);
00711 
00712         node = build_coercion_expression(node, pathtype, funcId,
00713                                          targetTypeId, targetTypMod,
00714                                          cformat, location,
00715                                          isExplicit);
00716     }
00717 
00718     return node;
00719 }
00720 
00721 /*
00722  * Mark a coercion node as IMPLICIT so it will never be displayed by
00723  * ruleutils.c.  We use this when we generate a nest of coercion nodes
00724  * to implement what is logically one conversion; the inner nodes are
00725  * forced to IMPLICIT_CAST format.  This does not change their semantics,
00726  * only display behavior.
00727  *
00728  * It is caller error to call this on something that doesn't have a
00729  * CoercionForm field.
00730  */
00731 static void
00732 hide_coercion_node(Node *node)
00733 {
00734     if (IsA(node, FuncExpr))
00735         ((FuncExpr *) node)->funcformat = COERCE_IMPLICIT_CAST;
00736     else if (IsA(node, RelabelType))
00737         ((RelabelType *) node)->relabelformat = COERCE_IMPLICIT_CAST;
00738     else if (IsA(node, CoerceViaIO))
00739         ((CoerceViaIO *) node)->coerceformat = COERCE_IMPLICIT_CAST;
00740     else if (IsA(node, ArrayCoerceExpr))
00741         ((ArrayCoerceExpr *) node)->coerceformat = COERCE_IMPLICIT_CAST;
00742     else if (IsA(node, ConvertRowtypeExpr))
00743         ((ConvertRowtypeExpr *) node)->convertformat = COERCE_IMPLICIT_CAST;
00744     else if (IsA(node, RowExpr))
00745         ((RowExpr *) node)->row_format = COERCE_IMPLICIT_CAST;
00746     else if (IsA(node, CoerceToDomain))
00747         ((CoerceToDomain *) node)->coercionformat = COERCE_IMPLICIT_CAST;
00748     else
00749         elog(ERROR, "unsupported node type: %d", (int) nodeTag(node));
00750 }
00751 
00752 /*
00753  * build_coercion_expression()
00754  *      Construct an expression tree for applying a pg_cast entry.
00755  *
00756  * This is used for both type-coercion and length-coercion operations,
00757  * since there is no difference in terms of the calling convention.
00758  */
00759 static Node *
00760 build_coercion_expression(Node *node,
00761                           CoercionPathType pathtype,
00762                           Oid funcId,
00763                           Oid targetTypeId, int32 targetTypMod,
00764                           CoercionForm cformat, int location,
00765                           bool isExplicit)
00766 {
00767     int         nargs = 0;
00768 
00769     if (OidIsValid(funcId))
00770     {
00771         HeapTuple   tp;
00772         Form_pg_proc procstruct;
00773 
00774         tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcId));
00775         if (!HeapTupleIsValid(tp))
00776             elog(ERROR, "cache lookup failed for function %u", funcId);
00777         procstruct = (Form_pg_proc) GETSTRUCT(tp);
00778 
00779         /*
00780          * These Asserts essentially check that function is a legal coercion
00781          * function.  We can't make the seemingly obvious tests on prorettype
00782          * and proargtypes[0], even in the COERCION_PATH_FUNC case, because of
00783          * various binary-compatibility cases.
00784          */
00785         /* Assert(targetTypeId == procstruct->prorettype); */
00786         Assert(!procstruct->proretset);
00787         Assert(!procstruct->proisagg);
00788         Assert(!procstruct->proiswindow);
00789         nargs = procstruct->pronargs;
00790         Assert(nargs >= 1 && nargs <= 3);
00791         /* Assert(procstruct->proargtypes.values[0] == exprType(node)); */
00792         Assert(nargs < 2 || procstruct->proargtypes.values[1] == INT4OID);
00793         Assert(nargs < 3 || procstruct->proargtypes.values[2] == BOOLOID);
00794 
00795         ReleaseSysCache(tp);
00796     }
00797 
00798     if (pathtype == COERCION_PATH_FUNC)
00799     {
00800         /* We build an ordinary FuncExpr with special arguments */
00801         FuncExpr   *fexpr;
00802         List       *args;
00803         Const      *cons;
00804 
00805         Assert(OidIsValid(funcId));
00806 
00807         args = list_make1(node);
00808 
00809         if (nargs >= 2)
00810         {
00811             /* Pass target typmod as an int4 constant */
00812             cons = makeConst(INT4OID,
00813                              -1,
00814                              InvalidOid,
00815                              sizeof(int32),
00816                              Int32GetDatum(targetTypMod),
00817                              false,
00818                              true);
00819 
00820             args = lappend(args, cons);
00821         }
00822 
00823         if (nargs == 3)
00824         {
00825             /* Pass it a boolean isExplicit parameter, too */
00826             cons = makeConst(BOOLOID,
00827                              -1,
00828                              InvalidOid,
00829                              sizeof(bool),
00830                              BoolGetDatum(isExplicit),
00831                              false,
00832                              true);
00833 
00834             args = lappend(args, cons);
00835         }
00836 
00837         fexpr = makeFuncExpr(funcId, targetTypeId, args,
00838                              InvalidOid, InvalidOid, cformat);
00839         fexpr->location = location;
00840         return (Node *) fexpr;
00841     }
00842     else if (pathtype == COERCION_PATH_ARRAYCOERCE)
00843     {
00844         /* We need to build an ArrayCoerceExpr */
00845         ArrayCoerceExpr *acoerce = makeNode(ArrayCoerceExpr);
00846 
00847         acoerce->arg = (Expr *) node;
00848         acoerce->elemfuncid = funcId;
00849         acoerce->resulttype = targetTypeId;
00850 
00851         /*
00852          * Label the output as having a particular typmod only if we are
00853          * really invoking a length-coercion function, ie one with more than
00854          * one argument.
00855          */
00856         acoerce->resulttypmod = (nargs >= 2) ? targetTypMod : -1;
00857         /* resultcollid will be set by parse_collate.c */
00858         acoerce->isExplicit = isExplicit;
00859         acoerce->coerceformat = cformat;
00860         acoerce->location = location;
00861 
00862         return (Node *) acoerce;
00863     }
00864     else if (pathtype == COERCION_PATH_COERCEVIAIO)
00865     {
00866         /* We need to build a CoerceViaIO node */
00867         CoerceViaIO *iocoerce = makeNode(CoerceViaIO);
00868 
00869         Assert(!OidIsValid(funcId));
00870 
00871         iocoerce->arg = (Expr *) node;
00872         iocoerce->resulttype = targetTypeId;
00873         /* resultcollid will be set by parse_collate.c */
00874         iocoerce->coerceformat = cformat;
00875         iocoerce->location = location;
00876 
00877         return (Node *) iocoerce;
00878     }
00879     else
00880     {
00881         elog(ERROR, "unsupported pathtype %d in build_coercion_expression",
00882              (int) pathtype);
00883         return NULL;            /* keep compiler quiet */
00884     }
00885 }
00886 
00887 
00888 /*
00889  * coerce_record_to_complex
00890  *      Coerce a RECORD to a specific composite type.
00891  *
00892  * Currently we only support this for inputs that are RowExprs or whole-row
00893  * Vars.
00894  */
00895 static Node *
00896 coerce_record_to_complex(ParseState *pstate, Node *node,
00897                          Oid targetTypeId,
00898                          CoercionContext ccontext,
00899                          CoercionForm cformat,
00900                          int location)
00901 {
00902     RowExpr    *rowexpr;
00903     TupleDesc   tupdesc;
00904     List       *args = NIL;
00905     List       *newargs;
00906     int         i;
00907     int         ucolno;
00908     ListCell   *arg;
00909 
00910     if (node && IsA(node, RowExpr))
00911     {
00912         /*
00913          * Since the RowExpr must be of type RECORD, we needn't worry about it
00914          * containing any dropped columns.
00915          */
00916         args = ((RowExpr *) node)->args;
00917     }
00918     else if (node && IsA(node, Var) &&
00919              ((Var *) node)->varattno == InvalidAttrNumber)
00920     {
00921         int         rtindex = ((Var *) node)->varno;
00922         int         sublevels_up = ((Var *) node)->varlevelsup;
00923         int         vlocation = ((Var *) node)->location;
00924         RangeTblEntry *rte;
00925 
00926         rte = GetRTEByRangeTablePosn(pstate, rtindex, sublevels_up);
00927         expandRTE(rte, rtindex, sublevels_up, vlocation, false,
00928                   NULL, &args);
00929     }
00930     else
00931         ereport(ERROR,
00932                 (errcode(ERRCODE_CANNOT_COERCE),
00933                  errmsg("cannot cast type %s to %s",
00934                         format_type_be(RECORDOID),
00935                         format_type_be(targetTypeId)),
00936                  parser_coercion_errposition(pstate, location, node)));
00937 
00938     tupdesc = lookup_rowtype_tupdesc(targetTypeId, -1);
00939     newargs = NIL;
00940     ucolno = 1;
00941     arg = list_head(args);
00942     for (i = 0; i < tupdesc->natts; i++)
00943     {
00944         Node       *expr;
00945         Node       *cexpr;
00946         Oid         exprtype;
00947 
00948         /* Fill in NULLs for dropped columns in rowtype */
00949         if (tupdesc->attrs[i]->attisdropped)
00950         {
00951             /*
00952              * can't use atttypid here, but it doesn't really matter what type
00953              * the Const claims to be.
00954              */
00955             newargs = lappend(newargs,
00956                               makeNullConst(INT4OID, -1, InvalidOid));
00957             continue;
00958         }
00959 
00960         if (arg == NULL)
00961             ereport(ERROR,
00962                     (errcode(ERRCODE_CANNOT_COERCE),
00963                      errmsg("cannot cast type %s to %s",
00964                             format_type_be(RECORDOID),
00965                             format_type_be(targetTypeId)),
00966                      errdetail("Input has too few columns."),
00967                      parser_coercion_errposition(pstate, location, node)));
00968         expr = (Node *) lfirst(arg);
00969         exprtype = exprType(expr);
00970 
00971         cexpr = coerce_to_target_type(pstate,
00972                                       expr, exprtype,
00973                                       tupdesc->attrs[i]->atttypid,
00974                                       tupdesc->attrs[i]->atttypmod,
00975                                       ccontext,
00976                                       COERCE_IMPLICIT_CAST,
00977                                       -1);
00978         if (cexpr == NULL)
00979             ereport(ERROR,
00980                     (errcode(ERRCODE_CANNOT_COERCE),
00981                      errmsg("cannot cast type %s to %s",
00982                             format_type_be(RECORDOID),
00983                             format_type_be(targetTypeId)),
00984                      errdetail("Cannot cast type %s to %s in column %d.",
00985                                format_type_be(exprtype),
00986                                format_type_be(tupdesc->attrs[i]->atttypid),
00987                                ucolno),
00988                      parser_coercion_errposition(pstate, location, expr)));
00989         newargs = lappend(newargs, cexpr);
00990         ucolno++;
00991         arg = lnext(arg);
00992     }
00993     if (arg != NULL)
00994         ereport(ERROR,
00995                 (errcode(ERRCODE_CANNOT_COERCE),
00996                  errmsg("cannot cast type %s to %s",
00997                         format_type_be(RECORDOID),
00998                         format_type_be(targetTypeId)),
00999                  errdetail("Input has too many columns."),
01000                  parser_coercion_errposition(pstate, location, node)));
01001 
01002     ReleaseTupleDesc(tupdesc);
01003 
01004     rowexpr = makeNode(RowExpr);
01005     rowexpr->args = newargs;
01006     rowexpr->row_typeid = targetTypeId;
01007     rowexpr->row_format = cformat;
01008     rowexpr->colnames = NIL;    /* not needed for named target type */
01009     rowexpr->location = location;
01010     return (Node *) rowexpr;
01011 }
01012 
01013 /*
01014  * coerce_to_boolean()
01015  *      Coerce an argument of a construct that requires boolean input
01016  *      (AND, OR, NOT, etc).  Also check that input is not a set.
01017  *
01018  * Returns the possibly-transformed node tree.
01019  *
01020  * As with coerce_type, pstate may be NULL if no special unknown-Param
01021  * processing is wanted.
01022  */
01023 Node *
01024 coerce_to_boolean(ParseState *pstate, Node *node,
01025                   const char *constructName)
01026 {
01027     Oid         inputTypeId = exprType(node);
01028 
01029     if (inputTypeId != BOOLOID)
01030     {
01031         Node       *newnode;
01032 
01033         newnode = coerce_to_target_type(pstate, node, inputTypeId,
01034                                         BOOLOID, -1,
01035                                         COERCION_ASSIGNMENT,
01036                                         COERCE_IMPLICIT_CAST,
01037                                         -1);
01038         if (newnode == NULL)
01039             ereport(ERROR,
01040                     (errcode(ERRCODE_DATATYPE_MISMATCH),
01041             /* translator: first %s is name of a SQL construct, eg WHERE */
01042                    errmsg("argument of %s must be type boolean, not type %s",
01043                           constructName, format_type_be(inputTypeId)),
01044                      parser_errposition(pstate, exprLocation(node))));
01045         node = newnode;
01046     }
01047 
01048     if (expression_returns_set(node))
01049         ereport(ERROR,
01050                 (errcode(ERRCODE_DATATYPE_MISMATCH),
01051         /* translator: %s is name of a SQL construct, eg WHERE */
01052                  errmsg("argument of %s must not return a set",
01053                         constructName),
01054                  parser_errposition(pstate, exprLocation(node))));
01055 
01056     return node;
01057 }
01058 
01059 /*
01060  * coerce_to_specific_type()
01061  *      Coerce an argument of a construct that requires a specific data type.
01062  *      Also check that input is not a set.
01063  *
01064  * Returns the possibly-transformed node tree.
01065  *
01066  * As with coerce_type, pstate may be NULL if no special unknown-Param
01067  * processing is wanted.
01068  */
01069 Node *
01070 coerce_to_specific_type(ParseState *pstate, Node *node,
01071                         Oid targetTypeId,
01072                         const char *constructName)
01073 {
01074     Oid         inputTypeId = exprType(node);
01075 
01076     if (inputTypeId != targetTypeId)
01077     {
01078         Node       *newnode;
01079 
01080         newnode = coerce_to_target_type(pstate, node, inputTypeId,
01081                                         targetTypeId, -1,
01082                                         COERCION_ASSIGNMENT,
01083                                         COERCE_IMPLICIT_CAST,
01084                                         -1);
01085         if (newnode == NULL)
01086             ereport(ERROR,
01087                     (errcode(ERRCODE_DATATYPE_MISMATCH),
01088             /* translator: first %s is name of a SQL construct, eg LIMIT */
01089                      errmsg("argument of %s must be type %s, not type %s",
01090                             constructName,
01091                             format_type_be(targetTypeId),
01092                             format_type_be(inputTypeId)),
01093                      parser_errposition(pstate, exprLocation(node))));
01094         node = newnode;
01095     }
01096 
01097     if (expression_returns_set(node))
01098         ereport(ERROR,
01099                 (errcode(ERRCODE_DATATYPE_MISMATCH),
01100         /* translator: %s is name of a SQL construct, eg LIMIT */
01101                  errmsg("argument of %s must not return a set",
01102                         constructName),
01103                  parser_errposition(pstate, exprLocation(node))));
01104 
01105     return node;
01106 }
01107 
01108 
01109 /*
01110  * parser_coercion_errposition - report coercion error location, if possible
01111  *
01112  * We prefer to point at the coercion request (CAST, ::, etc) if possible;
01113  * but there may be no such location in the case of an implicit coercion.
01114  * In that case point at the input expression.
01115  *
01116  * XXX possibly this is more generally useful than coercion errors;
01117  * if so, should rename and place with parser_errposition.
01118  */
01119 int
01120 parser_coercion_errposition(ParseState *pstate,
01121                             int coerce_location,
01122                             Node *input_expr)
01123 {
01124     if (coerce_location >= 0)
01125         return parser_errposition(pstate, coerce_location);
01126     else
01127         return parser_errposition(pstate, exprLocation(input_expr));
01128 }
01129 
01130 
01131 /*
01132  * select_common_type()
01133  *      Determine the common supertype of a list of input expressions.
01134  *      This is used for determining the output type of CASE, UNION,
01135  *      and similar constructs.
01136  *
01137  * 'exprs' is a *nonempty* list of expressions.  Note that earlier items
01138  * in the list will be preferred if there is doubt.
01139  * 'context' is a phrase to use in the error message if we fail to select
01140  * a usable type.  Pass NULL to have the routine return InvalidOid
01141  * rather than throwing an error on failure.
01142  * 'which_expr': if not NULL, receives a pointer to the particular input
01143  * expression from which the result type was taken.
01144  */
01145 Oid
01146 select_common_type(ParseState *pstate, List *exprs, const char *context,
01147                    Node **which_expr)
01148 {
01149     Node       *pexpr;
01150     Oid         ptype;
01151     TYPCATEGORY pcategory;
01152     bool        pispreferred;
01153     ListCell   *lc;
01154 
01155     Assert(exprs != NIL);
01156     pexpr = (Node *) linitial(exprs);
01157     lc = lnext(list_head(exprs));
01158     ptype = exprType(pexpr);
01159 
01160     /*
01161      * If all input types are valid and exactly the same, just pick that type.
01162      * This is the only way that we will resolve the result as being a domain
01163      * type; otherwise domains are smashed to their base types for comparison.
01164      */
01165     if (ptype != UNKNOWNOID)
01166     {
01167         for_each_cell(lc, lc)
01168         {
01169             Node       *nexpr = (Node *) lfirst(lc);
01170             Oid         ntype = exprType(nexpr);
01171 
01172             if (ntype != ptype)
01173                 break;
01174         }
01175         if (lc == NULL)         /* got to the end of the list? */
01176         {
01177             if (which_expr)
01178                 *which_expr = pexpr;
01179             return ptype;
01180         }
01181     }
01182 
01183     /*
01184      * Nope, so set up for the full algorithm.  Note that at this point, lc
01185      * points to the first list item with type different from pexpr's; we need
01186      * not re-examine any items the previous loop advanced over.
01187      */
01188     ptype = getBaseType(ptype);
01189     get_type_category_preferred(ptype, &pcategory, &pispreferred);
01190 
01191     for_each_cell(lc, lc)
01192     {
01193         Node       *nexpr = (Node *) lfirst(lc);
01194         Oid         ntype = getBaseType(exprType(nexpr));
01195 
01196         /* move on to next one if no new information... */
01197         if (ntype != UNKNOWNOID && ntype != ptype)
01198         {
01199             TYPCATEGORY ncategory;
01200             bool        nispreferred;
01201 
01202             get_type_category_preferred(ntype, &ncategory, &nispreferred);
01203             if (ptype == UNKNOWNOID)
01204             {
01205                 /* so far, only unknowns so take anything... */
01206                 pexpr = nexpr;
01207                 ptype = ntype;
01208                 pcategory = ncategory;
01209                 pispreferred = nispreferred;
01210             }
01211             else if (ncategory != pcategory)
01212             {
01213                 /*
01214                  * both types in different categories? then not much hope...
01215                  */
01216                 if (context == NULL)
01217                     return InvalidOid;
01218                 ereport(ERROR,
01219                         (errcode(ERRCODE_DATATYPE_MISMATCH),
01220                 /*------
01221                   translator: first %s is name of a SQL construct, eg CASE */
01222                          errmsg("%s types %s and %s cannot be matched",
01223                                 context,
01224                                 format_type_be(ptype),
01225                                 format_type_be(ntype)),
01226                          parser_errposition(pstate, exprLocation(nexpr))));
01227             }
01228             else if (!pispreferred &&
01229                      can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
01230                      !can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
01231             {
01232                 /*
01233                  * take new type if can coerce to it implicitly but not the
01234                  * other way; but if we have a preferred type, stay on it.
01235                  */
01236                 pexpr = nexpr;
01237                 ptype = ntype;
01238                 pcategory = ncategory;
01239                 pispreferred = nispreferred;
01240             }
01241         }
01242     }
01243 
01244     /*
01245      * If all the inputs were UNKNOWN type --- ie, unknown-type literals ---
01246      * then resolve as type TEXT.  This situation comes up with constructs
01247      * like SELECT (CASE WHEN foo THEN 'bar' ELSE 'baz' END); SELECT 'foo'
01248      * UNION SELECT 'bar'; It might seem desirable to leave the construct's
01249      * output type as UNKNOWN, but that really doesn't work, because we'd
01250      * probably end up needing a runtime coercion from UNKNOWN to something
01251      * else, and we usually won't have it.  We need to coerce the unknown
01252      * literals while they are still literals, so a decision has to be made
01253      * now.
01254      */
01255     if (ptype == UNKNOWNOID)
01256         ptype = TEXTOID;
01257 
01258     if (which_expr)
01259         *which_expr = pexpr;
01260     return ptype;
01261 }
01262 
01263 /*
01264  * coerce_to_common_type()
01265  *      Coerce an expression to the given type.
01266  *
01267  * This is used following select_common_type() to coerce the individual
01268  * expressions to the desired type.  'context' is a phrase to use in the
01269  * error message if we fail to coerce.
01270  *
01271  * As with coerce_type, pstate may be NULL if no special unknown-Param
01272  * processing is wanted.
01273  */
01274 Node *
01275 coerce_to_common_type(ParseState *pstate, Node *node,
01276                       Oid targetTypeId, const char *context)
01277 {
01278     Oid         inputTypeId = exprType(node);
01279 
01280     if (inputTypeId == targetTypeId)
01281         return node;            /* no work */
01282     if (can_coerce_type(1, &inputTypeId, &targetTypeId, COERCION_IMPLICIT))
01283         node = coerce_type(pstate, node, inputTypeId, targetTypeId, -1,
01284                            COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1);
01285     else
01286         ereport(ERROR,
01287                 (errcode(ERRCODE_CANNOT_COERCE),
01288         /* translator: first %s is name of a SQL construct, eg CASE */
01289                  errmsg("%s could not convert type %s to %s",
01290                         context,
01291                         format_type_be(inputTypeId),
01292                         format_type_be(targetTypeId)),
01293                  parser_errposition(pstate, exprLocation(node))));
01294     return node;
01295 }
01296 
01297 /*
01298  * check_generic_type_consistency()
01299  *      Are the actual arguments potentially compatible with a
01300  *      polymorphic function?
01301  *
01302  * The argument consistency rules are:
01303  *
01304  * 1) All arguments declared ANYELEMENT must have the same datatype.
01305  * 2) All arguments declared ANYARRAY must have the same datatype,
01306  *    which must be a varlena array type.
01307  * 3) All arguments declared ANYRANGE must have the same datatype,
01308  *    which must be a range type.
01309  * 4) If there are arguments of both ANYELEMENT and ANYARRAY, make sure the
01310  *    actual ANYELEMENT datatype is in fact the element type for the actual
01311  *    ANYARRAY datatype.
01312  * 5) Similarly, if there are arguments of both ANYELEMENT and ANYRANGE,
01313  *    make sure the actual ANYELEMENT datatype is in fact the subtype for
01314  *    the actual ANYRANGE type.
01315  * 6) ANYENUM is treated the same as ANYELEMENT except that if it is used
01316  *    (alone or in combination with plain ANYELEMENT), we add the extra
01317  *    condition that the ANYELEMENT type must be an enum.
01318  * 7) ANYNONARRAY is treated the same as ANYELEMENT except that if it is used,
01319  *    we add the extra condition that the ANYELEMENT type must not be an array.
01320  *    (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
01321  *    is an extra restriction if not.)
01322  *
01323  * Domains over arrays match ANYARRAY, and are immediately flattened to their
01324  * base type.  (Thus, for example, we will consider it a match if one ANYARRAY
01325  * argument is a domain over int4[] while another one is just int4[].)  Also
01326  * notice that such a domain does *not* match ANYNONARRAY.
01327  *
01328  * Similarly, domains over ranges match ANYRANGE, and are immediately
01329  * flattened to their base type.
01330  *
01331  * Note that domains aren't currently considered to match ANYENUM,
01332  * even if their base type would match.
01333  *
01334  * If we have UNKNOWN input (ie, an untyped literal) for any polymorphic
01335  * argument, assume it is okay.
01336  *
01337  * If an input is of type ANYARRAY (ie, we know it's an array, but not
01338  * what element type), we will accept it as a match to an argument declared
01339  * ANYARRAY, so long as we don't have to determine an element type ---
01340  * that is, so long as there is no use of ANYELEMENT.  This is mostly for
01341  * backwards compatibility with the pre-7.4 behavior of ANYARRAY.
01342  *
01343  * We do not ereport here, but just return FALSE if a rule is violated.
01344  */
01345 bool
01346 check_generic_type_consistency(Oid *actual_arg_types,
01347                                Oid *declared_arg_types,
01348                                int nargs)
01349 {
01350     int         j;
01351     Oid         elem_typeid = InvalidOid;
01352     Oid         array_typeid = InvalidOid;
01353     Oid         array_typelem;
01354     Oid         range_typeid = InvalidOid;
01355     Oid         range_typelem;
01356     bool        have_anyelement = false;
01357     bool        have_anynonarray = false;
01358     bool        have_anyenum = false;
01359 
01360     /*
01361      * Loop through the arguments to see if we have any that are polymorphic.
01362      * If so, require the actual types to be consistent.
01363      */
01364     for (j = 0; j < nargs; j++)
01365     {
01366         Oid         decl_type = declared_arg_types[j];
01367         Oid         actual_type = actual_arg_types[j];
01368 
01369         if (decl_type == ANYELEMENTOID ||
01370             decl_type == ANYNONARRAYOID ||
01371             decl_type == ANYENUMOID)
01372         {
01373             have_anyelement = true;
01374             if (decl_type == ANYNONARRAYOID)
01375                 have_anynonarray = true;
01376             else if (decl_type == ANYENUMOID)
01377                 have_anyenum = true;
01378             if (actual_type == UNKNOWNOID)
01379                 continue;
01380             if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
01381                 return false;
01382             elem_typeid = actual_type;
01383         }
01384         else if (decl_type == ANYARRAYOID)
01385         {
01386             if (actual_type == UNKNOWNOID)
01387                 continue;
01388             actual_type = getBaseType(actual_type);     /* flatten domains */
01389             if (OidIsValid(array_typeid) && actual_type != array_typeid)
01390                 return false;
01391             array_typeid = actual_type;
01392         }
01393         else if (decl_type == ANYRANGEOID)
01394         {
01395             if (actual_type == UNKNOWNOID)
01396                 continue;
01397             actual_type = getBaseType(actual_type);     /* flatten domains */
01398             if (OidIsValid(range_typeid) && actual_type != range_typeid)
01399                 return false;
01400             range_typeid = actual_type;
01401         }
01402     }
01403 
01404     /* Get the element type based on the array type, if we have one */
01405     if (OidIsValid(array_typeid))
01406     {
01407         if (array_typeid == ANYARRAYOID)
01408         {
01409             /* Special case for ANYARRAY input: okay iff no ANYELEMENT */
01410             if (have_anyelement)
01411                 return false;
01412             return true;
01413         }
01414 
01415         array_typelem = get_element_type(array_typeid);
01416         if (!OidIsValid(array_typelem))
01417             return false;       /* should be an array, but isn't */
01418 
01419         if (!OidIsValid(elem_typeid))
01420         {
01421             /*
01422              * if we don't have an element type yet, use the one we just got
01423              */
01424             elem_typeid = array_typelem;
01425         }
01426         else if (array_typelem != elem_typeid)
01427         {
01428             /* otherwise, they better match */
01429             return false;
01430         }
01431     }
01432 
01433     /* Get the element type based on the range type, if we have one */
01434     if (OidIsValid(range_typeid))
01435     {
01436         range_typelem = get_range_subtype(range_typeid);
01437         if (!OidIsValid(range_typelem))
01438             return false;       /* should be a range, but isn't */
01439 
01440         if (!OidIsValid(elem_typeid))
01441         {
01442             /*
01443              * if we don't have an element type yet, use the one we just got
01444              */
01445             elem_typeid = range_typelem;
01446         }
01447         else if (range_typelem != elem_typeid)
01448         {
01449             /* otherwise, they better match */
01450             return false;
01451         }
01452     }
01453 
01454     if (have_anynonarray)
01455     {
01456         /* require the element type to not be an array or domain over array */
01457         if (type_is_array_domain(elem_typeid))
01458             return false;
01459     }
01460 
01461     if (have_anyenum)
01462     {
01463         /* require the element type to be an enum */
01464         if (!type_is_enum(elem_typeid))
01465             return false;
01466     }
01467 
01468     /* Looks valid */
01469     return true;
01470 }
01471 
01472 /*
01473  * enforce_generic_type_consistency()
01474  *      Make sure a polymorphic function is legally callable, and
01475  *      deduce actual argument and result types.
01476  *
01477  * If any polymorphic pseudotype is used in a function's arguments or
01478  * return type, we make sure the actual data types are consistent with
01479  * each other.  The argument consistency rules are shown above for
01480  * check_generic_type_consistency().
01481  *
01482  * If we have UNKNOWN input (ie, an untyped literal) for any polymorphic
01483  * argument, we attempt to deduce the actual type it should have.  If
01484  * successful, we alter that position of declared_arg_types[] so that
01485  * make_fn_arguments will coerce the literal to the right thing.
01486  *
01487  * Rules are applied to the function's return type (possibly altering it)
01488  * if it is declared as a polymorphic type:
01489  *
01490  * 1) If return type is ANYARRAY, and any argument is ANYARRAY, use the
01491  *    argument's actual type as the function's return type.
01492  * 2) Similarly, if return type is ANYRANGE, and any argument is ANYRANGE,
01493  *    use the argument's actual type as the function's return type.
01494  * 3) If return type is ANYARRAY, no argument is ANYARRAY, but any argument is
01495  *    ANYELEMENT, use the actual type of the argument to determine the
01496  *    function's return type, i.e. the element type's corresponding array
01497  *    type.  (Note: similar behavior does not exist for ANYRANGE, because it's
01498  *    impossible to determine the range type from the subtype alone.)
01499  * 4) If return type is ANYARRAY, but no argument is ANYARRAY or ANYELEMENT,
01500  *    generate an error.  Similarly, if return type is ANYRANGE, but no
01501  *    argument is ANYRANGE, generate an error.  (These conditions are
01502  *    prevented by CREATE FUNCTION and therefore are not expected here.)
01503  * 5) If return type is ANYELEMENT, and any argument is ANYELEMENT, use the
01504  *    argument's actual type as the function's return type.
01505  * 6) If return type is ANYELEMENT, no argument is ANYELEMENT, but any argument
01506  *    is ANYARRAY or ANYRANGE, use the actual type of the argument to determine
01507  *    the function's return type, i.e. the array type's corresponding element
01508  *    type or the range type's corresponding subtype (or both, in which case
01509  *    they must match).
01510  * 7) If return type is ANYELEMENT, no argument is ANYELEMENT, ANYARRAY, or
01511  *    ANYRANGE, generate an error.  (This condition is prevented by CREATE
01512  *    FUNCTION and therefore is not expected here.)
01513  * 8) ANYENUM is treated the same as ANYELEMENT except that if it is used
01514  *    (alone or in combination with plain ANYELEMENT), we add the extra
01515  *    condition that the ANYELEMENT type must be an enum.
01516  * 9) ANYNONARRAY is treated the same as ANYELEMENT except that if it is used,
01517  *    we add the extra condition that the ANYELEMENT type must not be an array.
01518  *    (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
01519  *    is an extra restriction if not.)
01520  *
01521  * Domains over arrays or ranges match ANYARRAY or ANYRANGE arguments,
01522  * respectively, and are immediately flattened to their base type. (In
01523  * particular, if the return type is also ANYARRAY or ANYRANGE, we'll set it
01524  * to the base type not the domain type.)
01525  *
01526  * When allow_poly is false, we are not expecting any of the actual_arg_types
01527  * to be polymorphic, and we should not return a polymorphic result type
01528  * either.  When allow_poly is true, it is okay to have polymorphic "actual"
01529  * arg types, and we can return ANYARRAY, ANYRANGE, or ANYELEMENT as the
01530  * result.  (This case is currently used only to check compatibility of an
01531  * aggregate's declaration with the underlying transfn.)
01532  *
01533  * A special case is that we could see ANYARRAY as an actual_arg_type even
01534  * when allow_poly is false (this is possible only because pg_statistic has
01535  * columns shown as anyarray in the catalogs).  We allow this to match a
01536  * declared ANYARRAY argument, but only if there is no ANYELEMENT argument
01537  * or result (since we can't determine a specific element type to match to
01538  * ANYELEMENT).  Note this means that functions taking ANYARRAY had better
01539  * behave sanely if applied to the pg_statistic columns; they can't just
01540  * assume that successive inputs are of the same actual element type.
01541  */
01542 Oid
01543 enforce_generic_type_consistency(Oid *actual_arg_types,
01544                                  Oid *declared_arg_types,
01545                                  int nargs,
01546                                  Oid rettype,
01547                                  bool allow_poly)
01548 {
01549     int         j;
01550     bool        have_generics = false;
01551     bool        have_unknowns = false;
01552     Oid         elem_typeid = InvalidOid;
01553     Oid         array_typeid = InvalidOid;
01554     Oid         range_typeid = InvalidOid;
01555     Oid         array_typelem;
01556     Oid         range_typelem;
01557     bool        have_anyelement = (rettype == ANYELEMENTOID ||
01558                                    rettype == ANYNONARRAYOID ||
01559                                    rettype == ANYENUMOID);
01560     bool        have_anynonarray = (rettype == ANYNONARRAYOID);
01561     bool        have_anyenum = (rettype == ANYENUMOID);
01562 
01563     /*
01564      * Loop through the arguments to see if we have any that are polymorphic.
01565      * If so, require the actual types to be consistent.
01566      */
01567     for (j = 0; j < nargs; j++)
01568     {
01569         Oid         decl_type = declared_arg_types[j];
01570         Oid         actual_type = actual_arg_types[j];
01571 
01572         if (decl_type == ANYELEMENTOID ||
01573             decl_type == ANYNONARRAYOID ||
01574             decl_type == ANYENUMOID)
01575         {
01576             have_generics = have_anyelement = true;
01577             if (decl_type == ANYNONARRAYOID)
01578                 have_anynonarray = true;
01579             else if (decl_type == ANYENUMOID)
01580                 have_anyenum = true;
01581             if (actual_type == UNKNOWNOID)
01582             {
01583                 have_unknowns = true;
01584                 continue;
01585             }
01586             if (allow_poly && decl_type == actual_type)
01587                 continue;       /* no new information here */
01588             if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
01589                 ereport(ERROR,
01590                         (errcode(ERRCODE_DATATYPE_MISMATCH),
01591                 errmsg("arguments declared \"anyelement\" are not all alike"),
01592                          errdetail("%s versus %s",
01593                                    format_type_be(elem_typeid),
01594                                    format_type_be(actual_type))));
01595             elem_typeid = actual_type;
01596         }
01597         else if (decl_type == ANYARRAYOID)
01598         {
01599             have_generics = true;
01600             if (actual_type == UNKNOWNOID)
01601             {
01602                 have_unknowns = true;
01603                 continue;
01604             }
01605             if (allow_poly && decl_type == actual_type)
01606                 continue;       /* no new information here */
01607             actual_type = getBaseType(actual_type);     /* flatten domains */
01608             if (OidIsValid(array_typeid) && actual_type != array_typeid)
01609                 ereport(ERROR,
01610                         (errcode(ERRCODE_DATATYPE_MISMATCH),
01611                  errmsg("arguments declared \"anyarray\" are not all alike"),
01612                          errdetail("%s versus %s",
01613                                    format_type_be(array_typeid),
01614                                    format_type_be(actual_type))));
01615             array_typeid = actual_type;
01616         }
01617         else if (decl_type == ANYRANGEOID)
01618         {
01619             have_generics = true;
01620             if (actual_type == UNKNOWNOID)
01621             {
01622                 have_unknowns = true;
01623                 continue;
01624             }
01625             if (allow_poly && decl_type == actual_type)
01626                 continue;       /* no new information here */
01627             actual_type = getBaseType(actual_type);     /* flatten domains */
01628             if (OidIsValid(range_typeid) && actual_type != range_typeid)
01629                 ereport(ERROR,
01630                         (errcode(ERRCODE_DATATYPE_MISMATCH),
01631                  errmsg("arguments declared \"anyrange\" are not all alike"),
01632                          errdetail("%s versus %s",
01633                                    format_type_be(range_typeid),
01634                                    format_type_be(actual_type))));
01635             range_typeid = actual_type;
01636         }
01637     }
01638 
01639     /*
01640      * Fast Track: if none of the arguments are polymorphic, return the
01641      * unmodified rettype.  We assume it can't be polymorphic either.
01642      */
01643     if (!have_generics)
01644         return rettype;
01645 
01646     /* Get the element type based on the array type, if we have one */
01647     if (OidIsValid(array_typeid))
01648     {
01649         if (array_typeid == ANYARRAYOID && !have_anyelement)
01650         {
01651             /* Special case for ANYARRAY input: okay iff no ANYELEMENT */
01652             array_typelem = ANYELEMENTOID;
01653         }
01654         else
01655         {
01656             array_typelem = get_element_type(array_typeid);
01657             if (!OidIsValid(array_typelem))
01658                 ereport(ERROR,
01659                         (errcode(ERRCODE_DATATYPE_MISMATCH),
01660                          errmsg("argument declared \"anyarray\" is not an array but type %s",
01661                                 format_type_be(array_typeid))));
01662         }
01663 
01664         if (!OidIsValid(elem_typeid))
01665         {
01666             /*
01667              * if we don't have an element type yet, use the one we just got
01668              */
01669             elem_typeid = array_typelem;
01670         }
01671         else if (array_typelem != elem_typeid)
01672         {
01673             /* otherwise, they better match */
01674             ereport(ERROR,
01675                     (errcode(ERRCODE_DATATYPE_MISMATCH),
01676                      errmsg("argument declared \"anyarray\" is not consistent with argument declared \"anyelement\""),
01677                      errdetail("%s versus %s",
01678                                format_type_be(array_typeid),
01679                                format_type_be(elem_typeid))));
01680         }
01681     }
01682 
01683     /* Get the element type based on the range type, if we have one */
01684     if (OidIsValid(range_typeid))
01685     {
01686         if (range_typeid == ANYRANGEOID && !have_anyelement)
01687         {
01688             /* Special case for ANYRANGE input: okay iff no ANYELEMENT */
01689             range_typelem = ANYELEMENTOID;
01690         }
01691         else
01692         {
01693             range_typelem = get_range_subtype(range_typeid);
01694             if (!OidIsValid(range_typelem))
01695                 ereport(ERROR,
01696                         (errcode(ERRCODE_DATATYPE_MISMATCH),
01697                          errmsg("argument declared \"anyrange\" is not a range type but type %s",
01698                                 format_type_be(range_typeid))));
01699         }
01700 
01701         if (!OidIsValid(elem_typeid))
01702         {
01703             /*
01704              * if we don't have an element type yet, use the one we just got
01705              */
01706             elem_typeid = range_typelem;
01707         }
01708         else if (range_typelem != elem_typeid)
01709         {
01710             /* otherwise, they better match */
01711             ereport(ERROR,
01712                     (errcode(ERRCODE_DATATYPE_MISMATCH),
01713                      errmsg("argument declared \"anyrange\" is not consistent with argument declared \"anyelement\""),
01714                      errdetail("%s versus %s",
01715                                format_type_be(range_typeid),
01716                                format_type_be(elem_typeid))));
01717         }
01718     }
01719 
01720     if (!OidIsValid(elem_typeid))
01721     {
01722         if (allow_poly)
01723         {
01724             elem_typeid = ANYELEMENTOID;
01725             array_typeid = ANYARRAYOID;
01726             range_typeid = ANYRANGEOID;
01727         }
01728         else
01729         {
01730             /* Only way to get here is if all the generic args are UNKNOWN */
01731             ereport(ERROR,
01732                     (errcode(ERRCODE_DATATYPE_MISMATCH),
01733                      errmsg("could not determine polymorphic type because input has type \"unknown\"")));
01734         }
01735     }
01736 
01737     if (have_anynonarray && elem_typeid != ANYELEMENTOID)
01738     {
01739         /* require the element type to not be an array or domain over array */
01740         if (type_is_array_domain(elem_typeid))
01741             ereport(ERROR,
01742                     (errcode(ERRCODE_DATATYPE_MISMATCH),
01743                    errmsg("type matched to anynonarray is an array type: %s",
01744                           format_type_be(elem_typeid))));
01745     }
01746 
01747     if (have_anyenum && elem_typeid != ANYELEMENTOID)
01748     {
01749         /* require the element type to be an enum */
01750         if (!type_is_enum(elem_typeid))
01751             ereport(ERROR,
01752                     (errcode(ERRCODE_DATATYPE_MISMATCH),
01753                      errmsg("type matched to anyenum is not an enum type: %s",
01754                             format_type_be(elem_typeid))));
01755     }
01756 
01757     /*
01758      * If we had any unknown inputs, re-scan to assign correct types
01759      */
01760     if (have_unknowns)
01761     {
01762         for (j = 0; j < nargs; j++)
01763         {
01764             Oid         decl_type = declared_arg_types[j];
01765             Oid         actual_type = actual_arg_types[j];
01766 
01767             if (actual_type != UNKNOWNOID)
01768                 continue;
01769 
01770             if (decl_type == ANYELEMENTOID ||
01771                 decl_type == ANYNONARRAYOID ||
01772                 decl_type == ANYENUMOID)
01773                 declared_arg_types[j] = elem_typeid;
01774             else if (decl_type == ANYARRAYOID)
01775             {
01776                 if (!OidIsValid(array_typeid))
01777                 {
01778                     array_typeid = get_array_type(elem_typeid);
01779                     if (!OidIsValid(array_typeid))
01780                         ereport(ERROR,
01781                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
01782                          errmsg("could not find array type for data type %s",
01783                                 format_type_be(elem_typeid))));
01784                 }
01785                 declared_arg_types[j] = array_typeid;
01786             }
01787             else if (decl_type == ANYRANGEOID)
01788             {
01789                 if (!OidIsValid(range_typeid))
01790                 {
01791                     ereport(ERROR,
01792                             (errcode(ERRCODE_UNDEFINED_OBJECT),
01793                          errmsg("could not find range type for data type %s",
01794                                 format_type_be(elem_typeid))));
01795                 }
01796                 declared_arg_types[j] = range_typeid;
01797             }
01798         }
01799     }
01800 
01801     /* if we return ANYARRAY use the appropriate argument type */
01802     if (rettype == ANYARRAYOID)
01803     {
01804         if (!OidIsValid(array_typeid))
01805         {
01806             array_typeid = get_array_type(elem_typeid);
01807             if (!OidIsValid(array_typeid))
01808                 ereport(ERROR,
01809                         (errcode(ERRCODE_UNDEFINED_OBJECT),
01810                          errmsg("could not find array type for data type %s",
01811                                 format_type_be(elem_typeid))));
01812         }
01813         return array_typeid;
01814     }
01815 
01816     /* if we return ANYRANGE use the appropriate argument type */
01817     if (rettype == ANYRANGEOID)
01818     {
01819         if (!OidIsValid(range_typeid))
01820         {
01821             ereport(ERROR,
01822                     (errcode(ERRCODE_UNDEFINED_OBJECT),
01823                      errmsg("could not find range type for data type %s",
01824                             format_type_be(elem_typeid))));
01825         }
01826         return range_typeid;
01827     }
01828 
01829     /* if we return ANYELEMENT use the appropriate argument type */
01830     if (rettype == ANYELEMENTOID ||
01831         rettype == ANYNONARRAYOID ||
01832         rettype == ANYENUMOID)
01833         return elem_typeid;
01834 
01835     /* we don't return a generic type; send back the original return type */
01836     return rettype;
01837 }
01838 
01839 /*
01840  * resolve_generic_type()
01841  *      Deduce an individual actual datatype on the assumption that
01842  *      the rules for polymorphic types are being followed.
01843  *
01844  * declared_type is the declared datatype we want to resolve.
01845  * context_actual_type is the actual input datatype to some argument
01846  * that has declared datatype context_declared_type.
01847  *
01848  * If declared_type isn't polymorphic, we just return it.  Otherwise,
01849  * context_declared_type must be polymorphic, and we deduce the correct
01850  * return type based on the relationship of the two polymorphic types.
01851  */
01852 Oid
01853 resolve_generic_type(Oid declared_type,
01854                      Oid context_actual_type,
01855                      Oid context_declared_type)
01856 {
01857     if (declared_type == ANYARRAYOID)
01858     {
01859         if (context_declared_type == ANYARRAYOID)
01860         {
01861             /*
01862              * Use actual type, but it must be an array; or if it's a domain
01863              * over array, use the base array type.
01864              */
01865             Oid         context_base_type = getBaseType(context_actual_type);
01866             Oid         array_typelem = get_element_type(context_base_type);
01867 
01868             if (!OidIsValid(array_typelem))
01869                 ereport(ERROR,
01870                         (errcode(ERRCODE_DATATYPE_MISMATCH),
01871                          errmsg("argument declared \"anyarray\" is not an array but type %s",
01872                                 format_type_be(context_base_type))));
01873             return context_base_type;
01874         }
01875         else if (context_declared_type == ANYELEMENTOID ||
01876                  context_declared_type == ANYNONARRAYOID ||
01877                  context_declared_type == ANYENUMOID ||
01878                  context_declared_type == ANYRANGEOID)
01879         {
01880             /* Use the array type corresponding to actual type */
01881             Oid         array_typeid = get_array_type(context_actual_type);
01882 
01883             if (!OidIsValid(array_typeid))
01884                 ereport(ERROR,
01885                         (errcode(ERRCODE_UNDEFINED_OBJECT),
01886                          errmsg("could not find array type for data type %s",
01887                                 format_type_be(context_actual_type))));
01888             return array_typeid;
01889         }
01890     }
01891     else if (declared_type == ANYELEMENTOID ||
01892              declared_type == ANYNONARRAYOID ||
01893              declared_type == ANYENUMOID ||
01894              declared_type == ANYRANGEOID)
01895     {
01896         if (context_declared_type == ANYARRAYOID)
01897         {
01898             /* Use the element type corresponding to actual type */
01899             Oid         context_base_type = getBaseType(context_actual_type);
01900             Oid         array_typelem = get_element_type(context_base_type);
01901 
01902             if (!OidIsValid(array_typelem))
01903                 ereport(ERROR,
01904                         (errcode(ERRCODE_DATATYPE_MISMATCH),
01905                          errmsg("argument declared \"anyarray\" is not an array but type %s",
01906                                 format_type_be(context_base_type))));
01907             return array_typelem;
01908         }
01909         else if (context_declared_type == ANYRANGEOID)
01910         {
01911             /* Use the element type corresponding to actual type */
01912             Oid         context_base_type = getBaseType(context_actual_type);
01913             Oid         range_typelem = get_range_subtype(context_base_type);
01914 
01915             if (!OidIsValid(range_typelem))
01916                 ereport(ERROR,
01917                         (errcode(ERRCODE_DATATYPE_MISMATCH),
01918                          errmsg("argument declared \"anyrange\" is not a range type but type %s",
01919                                 format_type_be(context_base_type))));
01920             return range_typelem;
01921         }
01922         else if (context_declared_type == ANYELEMENTOID ||
01923                  context_declared_type == ANYNONARRAYOID ||
01924                  context_declared_type == ANYENUMOID)
01925         {
01926             /* Use the actual type; it doesn't matter if array or not */
01927             return context_actual_type;
01928         }
01929     }
01930     else
01931     {
01932         /* declared_type isn't polymorphic, so return it as-is */
01933         return declared_type;
01934     }
01935     /* If we get here, declared_type is polymorphic and context isn't */
01936     /* NB: this is a calling-code logic error, not a user error */
01937     elog(ERROR, "could not determine polymorphic type because context isn't polymorphic");
01938     return InvalidOid;          /* keep compiler quiet */
01939 }
01940 
01941 
01942 /* TypeCategory()
01943  *      Assign a category to the specified type OID.
01944  *
01945  * NB: this must not return TYPCATEGORY_INVALID.
01946  */
01947 TYPCATEGORY
01948 TypeCategory(Oid type)
01949 {
01950     char        typcategory;
01951     bool        typispreferred;
01952 
01953     get_type_category_preferred(type, &typcategory, &typispreferred);
01954     Assert(typcategory != TYPCATEGORY_INVALID);
01955     return (TYPCATEGORY) typcategory;
01956 }
01957 
01958 
01959 /* IsPreferredType()
01960  *      Check if this type is a preferred type for the given category.
01961  *
01962  * If category is TYPCATEGORY_INVALID, then we'll return TRUE for preferred
01963  * types of any category; otherwise, only for preferred types of that
01964  * category.
01965  */
01966 bool
01967 IsPreferredType(TYPCATEGORY category, Oid type)
01968 {
01969     char        typcategory;
01970     bool        typispreferred;
01971 
01972     get_type_category_preferred(type, &typcategory, &typispreferred);
01973     if (category == typcategory || category == TYPCATEGORY_INVALID)
01974         return typispreferred;
01975     else
01976         return false;
01977 }
01978 
01979 
01980 /* IsBinaryCoercible()
01981  *      Check if srctype is binary-coercible to targettype.
01982  *
01983  * This notion allows us to cheat and directly exchange values without
01984  * going through the trouble of calling a conversion function.  Note that
01985  * in general, this should only be an implementation shortcut.  Before 7.4,
01986  * this was also used as a heuristic for resolving overloaded functions and
01987  * operators, but that's basically a bad idea.
01988  *
01989  * As of 7.3, binary coercibility isn't hardwired into the code anymore.
01990  * We consider two types binary-coercible if there is an implicitly
01991  * invokable, no-function-needed pg_cast entry.  Also, a domain is always
01992  * binary-coercible to its base type, though *not* vice versa (in the other
01993  * direction, one must apply domain constraint checks before accepting the
01994  * value as legitimate).  We also need to special-case various polymorphic
01995  * types.
01996  *
01997  * This function replaces IsBinaryCompatible(), which was an inherently
01998  * symmetric test.  Since the pg_cast entries aren't necessarily symmetric,
01999  * the order of the operands is now significant.
02000  */
02001 bool
02002 IsBinaryCoercible(Oid srctype, Oid targettype)
02003 {
02004     HeapTuple   tuple;
02005     Form_pg_cast castForm;
02006     bool        result;
02007 
02008     /* Fast path if same type */
02009     if (srctype == targettype)
02010         return true;
02011 
02012     /* If srctype is a domain, reduce to its base type */
02013     if (OidIsValid(srctype))
02014         srctype = getBaseType(srctype);
02015 
02016     /* Somewhat-fast path for domain -> base type case */
02017     if (srctype == targettype)
02018         return true;
02019 
02020     /* Also accept any array type as coercible to ANYARRAY */
02021     if (targettype == ANYARRAYOID)
02022         if (type_is_array(srctype))
02023             return true;
02024 
02025     /* Also accept any non-array type as coercible to ANYNONARRAY */
02026     if (targettype == ANYNONARRAYOID)
02027         if (!type_is_array(srctype))
02028             return true;
02029 
02030     /* Also accept any enum type as coercible to ANYENUM */
02031     if (targettype == ANYENUMOID)
02032         if (type_is_enum(srctype))
02033             return true;
02034 
02035     /* Also accept any range type as coercible to ANYRANGE */
02036     if (targettype == ANYRANGEOID)
02037         if (type_is_range(srctype))
02038             return true;
02039 
02040     /* Also accept any composite type as coercible to RECORD */
02041     if (targettype == RECORDOID)
02042         if (ISCOMPLEX(srctype))
02043             return true;
02044 
02045     /* Also accept any composite array type as coercible to RECORD[] */
02046     if (targettype == RECORDARRAYOID)
02047         if (is_complex_array(srctype))
02048             return true;
02049 
02050     /* Else look in pg_cast */
02051     tuple = SearchSysCache2(CASTSOURCETARGET,
02052                             ObjectIdGetDatum(srctype),
02053                             ObjectIdGetDatum(targettype));
02054     if (!HeapTupleIsValid(tuple))
02055         return false;           /* no cast */
02056     castForm = (Form_pg_cast) GETSTRUCT(tuple);
02057 
02058     result = (castForm->castmethod == COERCION_METHOD_BINARY &&
02059               castForm->castcontext == COERCION_CODE_IMPLICIT);
02060 
02061     ReleaseSysCache(tuple);
02062 
02063     return result;
02064 }
02065 
02066 
02067 /*
02068  * find_coercion_pathway
02069  *      Look for a coercion pathway between two types.
02070  *
02071  * Currently, this deals only with scalar-type cases; it does not consider
02072  * polymorphic types nor casts between composite types.  (Perhaps fold
02073  * those in someday?)
02074  *
02075  * ccontext determines the set of available casts.
02076  *
02077  * The possible result codes are:
02078  *  COERCION_PATH_NONE: failed to find any coercion pathway
02079  *              *funcid is set to InvalidOid
02080  *  COERCION_PATH_FUNC: apply the coercion function returned in *funcid
02081  *  COERCION_PATH_RELABELTYPE: binary-compatible cast, no function needed
02082  *              *funcid is set to InvalidOid
02083  *  COERCION_PATH_ARRAYCOERCE: need an ArrayCoerceExpr node
02084  *              *funcid is set to the element cast function, or InvalidOid
02085  *              if the array elements are binary-compatible
02086  *  COERCION_PATH_COERCEVIAIO: need a CoerceViaIO node
02087  *              *funcid is set to InvalidOid
02088  *
02089  * Note: COERCION_PATH_RELABELTYPE does not necessarily mean that no work is
02090  * needed to do the coercion; if the target is a domain then we may need to
02091  * apply domain constraint checking.  If you want to check for a zero-effort
02092  * conversion then use IsBinaryCoercible().
02093  */
02094 CoercionPathType
02095 find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
02096                       CoercionContext ccontext,
02097                       Oid *funcid)
02098 {
02099     CoercionPathType result = COERCION_PATH_NONE;
02100     HeapTuple   tuple;
02101 
02102     *funcid = InvalidOid;
02103 
02104     /* Perhaps the types are domains; if so, look at their base types */
02105     if (OidIsValid(sourceTypeId))
02106         sourceTypeId = getBaseType(sourceTypeId);
02107     if (OidIsValid(targetTypeId))
02108         targetTypeId = getBaseType(targetTypeId);
02109 
02110     /* Domains are always coercible to and from their base type */
02111     if (sourceTypeId == targetTypeId)
02112         return COERCION_PATH_RELABELTYPE;
02113 
02114     /* Look in pg_cast */
02115     tuple = SearchSysCache2(CASTSOURCETARGET,
02116                             ObjectIdGetDatum(sourceTypeId),
02117                             ObjectIdGetDatum(targetTypeId));
02118 
02119     if (HeapTupleIsValid(tuple))
02120     {
02121         Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
02122         CoercionContext castcontext;
02123 
02124         /* convert char value for castcontext to CoercionContext enum */
02125         switch (castForm->castcontext)
02126         {
02127             case COERCION_CODE_IMPLICIT:
02128                 castcontext = COERCION_IMPLICIT;
02129                 break;
02130             case COERCION_CODE_ASSIGNMENT:
02131                 castcontext = COERCION_ASSIGNMENT;
02132                 break;
02133             case COERCION_CODE_EXPLICIT:
02134                 castcontext = COERCION_EXPLICIT;
02135                 break;
02136             default:
02137                 elog(ERROR, "unrecognized castcontext: %d",
02138                      (int) castForm->castcontext);
02139                 castcontext = 0;    /* keep compiler quiet */
02140                 break;
02141         }
02142 
02143         /* Rely on ordering of enum for correct behavior here */
02144         if (ccontext >= castcontext)
02145         {
02146             switch (castForm->castmethod)
02147             {
02148                 case COERCION_METHOD_FUNCTION:
02149                     result = COERCION_PATH_FUNC;
02150                     *funcid = castForm->castfunc;
02151                     break;
02152                 case COERCION_METHOD_INOUT:
02153                     result = COERCION_PATH_COERCEVIAIO;
02154                     break;
02155                 case COERCION_METHOD_BINARY:
02156                     result = COERCION_PATH_RELABELTYPE;
02157                     break;
02158                 default:
02159                     elog(ERROR, "unrecognized castmethod: %d",
02160                          (int) castForm->castmethod);
02161                     break;
02162             }
02163         }
02164 
02165         ReleaseSysCache(tuple);
02166     }
02167     else
02168     {
02169         /*
02170          * If there's no pg_cast entry, perhaps we are dealing with a pair of
02171          * array types.  If so, and if the element types have a suitable cast,
02172          * report that we can coerce with an ArrayCoerceExpr.
02173          *
02174          * Note that the source type can be a domain over array, but not the
02175          * target, because ArrayCoerceExpr won't check domain constraints.
02176          *
02177          * Hack: disallow coercions to oidvector and int2vector, which
02178          * otherwise tend to capture coercions that should go to "real" array
02179          * types.  We want those types to be considered "real" arrays for many
02180          * purposes, but not this one.  (Also, ArrayCoerceExpr isn't
02181          * guaranteed to produce an output that meets the restrictions of
02182          * these datatypes, such as being 1-dimensional.)
02183          */
02184         if (targetTypeId != OIDVECTOROID && targetTypeId != INT2VECTOROID)
02185         {
02186             Oid         targetElem;
02187             Oid         sourceElem;
02188 
02189             if ((targetElem = get_element_type(targetTypeId)) != InvalidOid &&
02190             (sourceElem = get_base_element_type(sourceTypeId)) != InvalidOid)
02191             {
02192                 CoercionPathType elempathtype;
02193                 Oid         elemfuncid;
02194 
02195                 elempathtype = find_coercion_pathway(targetElem,
02196                                                      sourceElem,
02197                                                      ccontext,
02198                                                      &elemfuncid);
02199                 if (elempathtype != COERCION_PATH_NONE &&
02200                     elempathtype != COERCION_PATH_ARRAYCOERCE)
02201                 {
02202                     *funcid = elemfuncid;
02203                     if (elempathtype == COERCION_PATH_COERCEVIAIO)
02204                         result = COERCION_PATH_COERCEVIAIO;
02205                     else
02206                         result = COERCION_PATH_ARRAYCOERCE;
02207                 }
02208             }
02209         }
02210 
02211         /*
02212          * If we still haven't found a possibility, consider automatic casting
02213          * using I/O functions.  We allow assignment casts to string types and
02214          * explicit casts from string types to be handled this way. (The
02215          * CoerceViaIO mechanism is a lot more general than that, but this is
02216          * all we want to allow in the absence of a pg_cast entry.) It would
02217          * probably be better to insist on explicit casts in both directions,
02218          * but this is a compromise to preserve something of the pre-8.3
02219          * behavior that many types had implicit (yipes!) casts to text.
02220          */
02221         if (result == COERCION_PATH_NONE)
02222         {
02223             if (ccontext >= COERCION_ASSIGNMENT &&
02224                 TypeCategory(targetTypeId) == TYPCATEGORY_STRING)
02225                 result = COERCION_PATH_COERCEVIAIO;
02226             else if (ccontext >= COERCION_EXPLICIT &&
02227                      TypeCategory(sourceTypeId) == TYPCATEGORY_STRING)
02228                 result = COERCION_PATH_COERCEVIAIO;
02229         }
02230     }
02231 
02232     return result;
02233 }
02234 
02235 
02236 /*
02237  * find_typmod_coercion_function -- does the given type need length coercion?
02238  *
02239  * If the target type possesses a pg_cast function from itself to itself,
02240  * it must need length coercion.
02241  *
02242  * "bpchar" (ie, char(N)) and "numeric" are examples of such types.
02243  *
02244  * If the given type is a varlena array type, we do not look for a coercion
02245  * function associated directly with the array type, but instead look for
02246  * one associated with the element type.  An ArrayCoerceExpr node must be
02247  * used to apply such a function.
02248  *
02249  * We use the same result enum as find_coercion_pathway, but the only possible
02250  * result codes are:
02251  *  COERCION_PATH_NONE: no length coercion needed
02252  *  COERCION_PATH_FUNC: apply the function returned in *funcid
02253  *  COERCION_PATH_ARRAYCOERCE: apply the function using ArrayCoerceExpr
02254  */
02255 CoercionPathType
02256 find_typmod_coercion_function(Oid typeId,
02257                               Oid *funcid)
02258 {
02259     CoercionPathType result;
02260     Type        targetType;
02261     Form_pg_type typeForm;
02262     HeapTuple   tuple;
02263 
02264     *funcid = InvalidOid;
02265     result = COERCION_PATH_FUNC;
02266 
02267     targetType = typeidType(typeId);
02268     typeForm = (Form_pg_type) GETSTRUCT(targetType);
02269 
02270     /* Check for a varlena array type */
02271     if (typeForm->typelem != InvalidOid && typeForm->typlen == -1)
02272     {
02273         /* Yes, switch our attention to the element type */
02274         typeId = typeForm->typelem;
02275         result = COERCION_PATH_ARRAYCOERCE;
02276     }
02277     ReleaseSysCache(targetType);
02278 
02279     /* Look in pg_cast */
02280     tuple = SearchSysCache2(CASTSOURCETARGET,
02281                             ObjectIdGetDatum(typeId),
02282                             ObjectIdGetDatum(typeId));
02283 
02284     if (HeapTupleIsValid(tuple))
02285     {
02286         Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
02287 
02288         *funcid = castForm->castfunc;
02289         ReleaseSysCache(tuple);
02290     }
02291 
02292     if (!OidIsValid(*funcid))
02293         result = COERCION_PATH_NONE;
02294 
02295     return result;
02296 }
02297 
02298 /*
02299  * is_complex_array
02300  *      Is this type an array of composite?
02301  *
02302  * Note: this will not return true for record[]; check for RECORDARRAYOID
02303  * separately if needed.
02304  */
02305 static bool
02306 is_complex_array(Oid typid)
02307 {
02308     Oid         elemtype = get_element_type(typid);
02309 
02310     return (OidIsValid(elemtype) && ISCOMPLEX(elemtype));
02311 }
02312 
02313 
02314 /*
02315  * Check whether reltypeId is the row type of a typed table of type
02316  * reloftypeId.  (This is conceptually similar to the subtype
02317  * relationship checked by typeInheritsFrom().)
02318  */
02319 static bool
02320 typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId)
02321 {
02322     Oid         relid = typeidTypeRelid(reltypeId);
02323     bool        result = false;
02324 
02325     if (relid)
02326     {
02327         HeapTuple   tp;
02328         Form_pg_class reltup;
02329 
02330         tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
02331         if (!HeapTupleIsValid(tp))
02332             elog(ERROR, "cache lookup failed for relation %u", relid);
02333 
02334         reltup = (Form_pg_class) GETSTRUCT(tp);
02335         if (reltup->reloftype == reloftypeId)
02336             result = true;
02337 
02338         ReleaseSysCache(tp);
02339     }
02340 
02341     return result;
02342 }