1 /*-------------------------------------------------------------------------
4 * handle type coercions/conversions for parser
6 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.96 2003/04/29 22:13:10 tgl Exp $
13 *-------------------------------------------------------------------------
17 #include "catalog/pg_cast.h"
18 #include "catalog/pg_proc.h"
19 #include "nodes/makefuncs.h"
20 #include "nodes/params.h"
21 #include "optimizer/clauses.h"
22 #include "parser/parse_coerce.h"
23 #include "parser/parse_expr.h"
24 #include "parser/parse_func.h"
25 #include "parser/parse_type.h"
26 #include "utils/builtins.h"
27 #include "utils/fmgroids.h"
28 #include "utils/lsyscache.h"
29 #include "utils/syscache.h"
32 static Node *coerce_type_typmod(Node *node,
33 Oid targetTypeId, int32 targetTypMod,
34 CoercionForm cformat, bool isExplicit);
35 static Oid PreferredType(CATEGORY category, Oid type);
36 static Node *build_func_call(Oid funcid, Oid rettype, List *args,
37 CoercionForm fformat);
41 * coerce_to_target_type()
42 * Convert an expression to a target type and typmod.
44 * This is the general-purpose entry point for arbitrary type coercion
45 * operations. Direct use of the component operations can_coerce_type,
46 * coerce_type, and coerce_type_typmod should be restricted to special
47 * cases (eg, when the conversion is expected to succeed).
49 * Returns the possibly-transformed expression tree, or NULL if the type
50 * conversion is not possible. (We do this, rather than elog'ing directly,
51 * so that callers can generate custom error messages indicating context.)
53 * pstate - parse state (can be NULL, see coerce_type)
54 * expr - input expression tree (already transformed by transformExpr)
55 * exprtype - result type of expr
56 * targettype - desired result type
57 * targettypmod - desired result typmod
58 * ccontext, cformat - context indicators to control coercions
61 coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype,
62 Oid targettype, int32 targettypmod,
63 CoercionContext ccontext,
66 if (can_coerce_type(1, &exprtype, &targettype, ccontext))
67 expr = coerce_type(pstate, expr, exprtype, targettype,
70 * String hacks to get transparent conversions for char and varchar:
71 * if a coercion to text is available, use it for forced coercions to
72 * char(n) or varchar(n).
74 * This is pretty grotty, but seems easier to maintain than providing
75 * entries in pg_cast that parallel all the ones for text.
77 else if (ccontext >= COERCION_ASSIGNMENT &&
78 (targettype == BPCHAROID || targettype == VARCHAROID))
80 Oid text_id = TEXTOID;
82 if (can_coerce_type(1, &exprtype, &text_id, ccontext))
84 expr = coerce_type(pstate, expr, exprtype, text_id,
86 /* Need a RelabelType if no typmod coercion is performed */
88 expr = (Node *) makeRelabelType((Expr *) expr,
99 * If the target is a fixed-length type, it may need a length coercion
100 * as well as a type coercion.
103 expr = coerce_type_typmod(expr, targettype, targettypmod,
105 (cformat != COERCE_IMPLICIT_CAST));
113 * Convert an expression to a different type.
115 * The caller should already have determined that the coercion is possible;
116 * see can_coerce_type.
118 * No coercion to a typmod (length) is performed here. The caller must
119 * call coerce_type_typmod as well, if a typmod constraint is wanted.
120 * (But if the target type is a domain, it may internally contain a
121 * typmod constraint, which will be applied inside coerce_to_domain.)
123 * pstate is only used in the case that we are able to resolve the type of
124 * a previously UNKNOWN Param. It is okay to pass pstate = NULL if the
125 * caller does not want type information updated for Params.
128 coerce_type(ParseState *pstate, Node *node,
129 Oid inputTypeId, Oid targetTypeId,
130 CoercionContext ccontext, CoercionForm cformat)
135 if (targetTypeId == inputTypeId ||
138 /* no conversion needed */
141 if (inputTypeId == UNKNOWNOID && IsA(node, Const))
144 * Input is a string constant with previously undetermined type.
145 * Apply the target type's typinput function to it to produce a
146 * constant of the target type.
148 * NOTE: this case cannot be folded together with the other
149 * constant-input case, since the typinput function does not
150 * necessarily behave the same as a type conversion function. For
151 * example, int4's typinput function will reject "1.2", whereas
152 * float-to-int type conversion will round to integer.
154 * XXX if the typinput function is not immutable, we really ought to
155 * postpone evaluation of the function call until runtime. But
156 * there is no way to represent a typinput function call as an
157 * expression tree, because C-string values are not Datums. (XXX
158 * This *is* possible as of 7.3, do we want to do it?)
160 Const *con = (Const *) node;
161 Const *newcon = makeNode(Const);
162 Type targetType = typeidType(targetTypeId);
163 char targetTyptype = typeTypType(targetType);
165 newcon->consttype = targetTypeId;
166 newcon->constlen = typeLen(targetType);
167 newcon->constbyval = typeByVal(targetType);
168 newcon->constisnull = con->constisnull;
170 if (!con->constisnull)
172 char *val = DatumGetCString(DirectFunctionCall1(unknownout,
176 * We pass typmod -1 to the input routine, primarily because
177 * existing input routines follow implicit-coercion semantics
178 * for length checks, which is not always what we want here.
179 * Any length constraint will be applied later by our caller.
181 * Note that we call stringTypeDatum using the domain's pg_type
182 * row, if it's a domain. This works because the domain row has
183 * the same typinput and typelem as the base type --- ugly...
185 newcon->constvalue = stringTypeDatum(targetType, val, -1);
189 result = (Node *) newcon;
191 /* If target is a domain, apply constraints. */
192 if (targetTyptype == 'd')
193 result = coerce_to_domain(result, InvalidOid, targetTypeId,
196 ReleaseSysCache(targetType);
200 if (inputTypeId == UNKNOWNOID && IsA(node, Param) &&
201 ((Param *) node)->paramkind == PARAM_NUM &&
202 pstate != NULL && pstate->p_variableparams)
205 * Input is a Param of previously undetermined type, and we want
206 * to update our knowledge of the Param's type. Find the topmost
207 * ParseState and update the state.
209 Param *param = (Param *) node;
210 int paramno = param->paramid;
211 ParseState *toppstate;
214 while (toppstate->parentParseState != NULL)
215 toppstate = toppstate->parentParseState;
217 if (paramno <= 0 || /* shouldn't happen, but... */
218 paramno > toppstate->p_numparams)
219 elog(ERROR, "Parameter '$%d' is out of range", paramno);
221 if (toppstate->p_paramtypes[paramno-1] == UNKNOWNOID)
223 /* We've successfully resolved the type */
224 toppstate->p_paramtypes[paramno-1] = targetTypeId;
226 else if (toppstate->p_paramtypes[paramno-1] == targetTypeId)
228 /* We previously resolved the type, and it matches */
233 elog(ERROR, "Inconsistent types deduced for parameter '$%d'"
234 "\n\tCould be either %s or %s",
236 format_type_be(toppstate->p_paramtypes[paramno-1]),
237 format_type_be(targetTypeId));
240 param->paramtype = targetTypeId;
241 return (Node *) param;
243 if (targetTypeId == ANYOID ||
244 targetTypeId == ANYARRAYOID ||
245 targetTypeId == ANYELEMENTOID)
247 /* assume can_coerce_type verified that implicit coercion is okay */
248 /* NB: we do NOT want a RelabelType here */
251 if (find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
254 if (OidIsValid(funcId))
257 * Generate an expression tree representing run-time
258 * application of the conversion function. If we are dealing
259 * with a domain target type, the conversion function will
260 * yield the base type.
262 Oid baseTypeId = getBaseType(targetTypeId);
264 result = build_func_call(funcId, baseTypeId, makeList1(node),
268 * If domain, coerce to the domain type and relabel with
271 if (targetTypeId != baseTypeId)
272 result = coerce_to_domain(result, baseTypeId, targetTypeId,
278 * We don't need to do a physical conversion, but we do need
279 * to attach a RelabelType node so that the expression will be
280 * seen to have the intended type when inspected by
283 * Also, domains may have value restrictions beyond the base type
284 * that must be accounted for. If the destination is a domain
285 * then we won't need a RelabelType node.
287 result = coerce_to_domain(node, InvalidOid, targetTypeId,
292 * XXX could we label result with exprTypmod(node) instead of
293 * default -1 typmod, to save a possible length-coercion
294 * later? Would work if both types have same interpretation of
295 * typmod, which is likely but not certain.
297 result = (Node *) makeRelabelType((Expr *) result,
304 if (typeInheritsFrom(inputTypeId, targetTypeId))
307 * Input class type is a subclass of target, so nothing to do ---
308 * except relabel the type. This is binary compatibility for
311 return (Node *) makeRelabelType((Expr *) node,
315 /* If we get here, caller blew it */
316 elog(ERROR, "coerce_type: no conversion function from %s to %s",
317 format_type_be(inputTypeId), format_type_be(targetTypeId));
318 return NULL; /* keep compiler quiet */
324 * Can input_typeids be coerced to target_typeids?
326 * We must be told the context (CAST construct, assignment, implicit coercion)
327 * as this determines the set of available casts.
330 can_coerce_type(int nargs, Oid *input_typeids, Oid *target_typeids,
331 CoercionContext ccontext)
333 bool have_generics = false;
336 /* run through argument list... */
337 for (i = 0; i < nargs; i++)
339 Oid inputTypeId = input_typeids[i];
340 Oid targetTypeId = target_typeids[i];
343 /* no problem if same type */
344 if (inputTypeId == targetTypeId)
347 /* don't choke on references to no-longer-existing types */
348 if (!typeidIsValid(inputTypeId))
350 if (!typeidIsValid(targetTypeId))
354 * If input is an untyped string constant, assume we can convert
355 * it to anything except a class type.
357 if (inputTypeId == UNKNOWNOID)
359 if (ISCOMPLEX(targetTypeId))
364 /* accept if target is ANY */
365 if (targetTypeId == ANYOID)
368 /* accept if target is ANYARRAY or ANYELEMENT, for now */
369 if (targetTypeId == ANYARRAYOID ||
370 targetTypeId == ANYELEMENTOID)
372 have_generics = true; /* do more checking later */
377 * If pg_cast shows that we can coerce, accept. This test now
378 * covers both binary-compatible and coercion-function cases.
380 if (find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
385 * If input is a class type that inherits from target, accept
387 if (typeInheritsFrom(inputTypeId, targetTypeId))
391 * Else, cannot coerce at this argument position
396 /* If we found any generic argument types, cross-check them */
399 if (!check_generic_type_consistency(input_typeids, target_typeids,
409 * Create an expression tree to represent coercion to a domain type.
411 * 'arg': input expression
412 * 'baseTypeId': base type of domain, if known (pass InvalidOid if caller
413 * has not bothered to look this up)
414 * 'typeId': target type to coerce to
415 * 'cformat': coercion format
417 * If the target type isn't a domain, the given 'arg' is returned as-is.
420 coerce_to_domain(Node *arg, Oid baseTypeId, Oid typeId, CoercionForm cformat)
422 CoerceToDomain *result;
425 /* Get the base type if it hasn't been supplied */
426 if (baseTypeId == InvalidOid)
427 baseTypeId = getBaseType(typeId);
429 /* If it isn't a domain, return the node as it was passed in */
430 if (baseTypeId == typeId)
434 * If the domain applies a typmod to its base type, build the appropriate
435 * coercion step. Mark it implicit for display purposes, because we don't
436 * want it shown separately by ruleutils.c; but the isExplicit flag passed
437 * to the conversion function depends on the manner in which the domain
438 * coercion is invoked, so that the semantics of implicit and explicit
439 * coercion differ. (Is that really the behavior we want?)
441 * NOTE: because we apply this as part of the fixed expression structure,
442 * ALTER DOMAIN cannot alter the typtypmod. But it's unclear that that
443 * would be safe to do anyway, without lots of knowledge about what the
444 * base type thinks the typmod means.
446 typmod = get_typtypmod(typeId);
448 arg = coerce_type_typmod(arg, baseTypeId, typmod,
449 COERCE_IMPLICIT_CAST,
450 (cformat != COERCE_IMPLICIT_CAST));
453 * Now build the domain coercion node. This represents run-time checking
454 * of any constraints currently attached to the domain. This also
455 * ensures that the expression is properly labeled as to result type.
457 result = makeNode(CoerceToDomain);
458 result->arg = (Expr *) arg;
459 result->resulttype = typeId;
460 result->resulttypmod = -1; /* currently, always -1 for domains */
461 result->coercionformat = cformat;
463 return (Node *) result;
468 * coerce_type_typmod()
469 * Force a value to a particular typmod, if meaningful and possible.
471 * This is applied to values that are going to be stored in a relation
472 * (where we have an atttypmod for the column) as well as values being
473 * explicitly CASTed (where the typmod comes from the target type spec).
475 * The caller must have already ensured that the value is of the correct
476 * type, typically by applying coerce_type.
478 * NOTE: this does not need to work on domain types, because any typmod
479 * coercion for a domain is considered to be part of the type coercion
480 * needed to produce the domain value in the first place. So, no getBaseType.
483 coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod,
484 CoercionForm cformat, bool isExplicit)
490 * A negative typmod is assumed to mean that no coercion is wanted.
492 if (targetTypMod < 0 || targetTypMod == exprTypmod(node))
495 funcId = find_typmod_coercion_function(targetTypeId, &nargs);
497 if (OidIsValid(funcId))
502 /* Pass given value, plus target typmod as an int4 constant */
503 cons = makeConst(INT4OID,
505 Int32GetDatum(targetTypMod),
509 args = makeList2(node, cons);
513 /* Pass it a boolean isExplicit parameter, too */
514 cons = makeConst(BOOLOID,
516 BoolGetDatum(isExplicit),
520 args = lappend(args, cons);
523 node = build_func_call(funcId, targetTypeId, args, cformat);
530 /* coerce_to_boolean()
531 * Coerce an argument of a construct that requires boolean input
532 * (AND, OR, NOT, etc). Also check that input is not a set.
534 * Returns the possibly-transformed node tree.
536 * As with coerce_type, pstate may be NULL if no special unknown-Param
537 * processing is wanted.
540 coerce_to_boolean(ParseState *pstate, Node *node,
541 const char *constructName)
543 Oid inputTypeId = exprType(node);
545 if (inputTypeId != BOOLOID)
547 node = coerce_to_target_type(pstate, node, inputTypeId,
550 COERCE_IMPLICIT_CAST);
553 /* translator: first %s is name of a SQL construct, eg WHERE */
554 elog(ERROR, "Argument of %s must be type boolean, not type %s",
555 constructName, format_type_be(inputTypeId));
559 if (expression_returns_set(node))
561 /* translator: %s is name of a SQL construct, eg WHERE */
562 elog(ERROR, "Argument of %s must not be a set function",
570 /* select_common_type()
571 * Determine the common supertype of a list of input expression types.
572 * This is used for determining the output type of CASE and UNION
575 * typeids is a nonempty list of type OIDs. Note that earlier items
576 * in the list will be preferred if there is doubt.
577 * 'context' is a phrase to use in the error message if we fail to select
581 select_common_type(List *typeids, const char *context)
587 Assert(typeids != NIL);
588 ptype = lfirsto(typeids);
589 pcategory = TypeCategory(ptype);
590 foreach(l, lnext(typeids))
592 Oid ntype = lfirsto(l);
594 /* move on to next one if no new information... */
595 if ((ntype != InvalidOid) && (ntype != UNKNOWNOID) && (ntype != ptype))
597 if ((ptype == InvalidOid) || ptype == UNKNOWNOID)
599 /* so far, only nulls so take anything... */
601 pcategory = TypeCategory(ptype);
603 else if (TypeCategory(ntype) != pcategory)
606 * both types in different categories? then not much
609 elog(ERROR, "%s types '%s' and '%s' not matched",
610 context, format_type_be(ptype), format_type_be(ntype));
612 else if (!IsPreferredType(pcategory, ptype) &&
613 can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
614 !can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
617 * take new type if can coerce to it implicitly but not the
618 * other way; but if we have a preferred type, stay on it.
621 pcategory = TypeCategory(ptype);
627 * If all the inputs were UNKNOWN type --- ie, unknown-type literals
628 * --- then resolve as type TEXT. This situation comes up with
629 * constructs like SELECT (CASE WHEN foo THEN 'bar' ELSE 'baz' END);
630 * SELECT 'foo' UNION SELECT 'bar'; It might seem desirable to leave
631 * the construct's output type as UNKNOWN, but that really doesn't
632 * work, because we'd probably end up needing a runtime coercion from
633 * UNKNOWN to something else, and we usually won't have it. We need
634 * to coerce the unknown literals while they are still literals, so a
635 * decision has to be made now.
637 if (ptype == UNKNOWNOID)
643 /* coerce_to_common_type()
644 * Coerce an expression to the given type.
646 * This is used following select_common_type() to coerce the individual
647 * expressions to the desired type. 'context' is a phrase to use in the
648 * error message if we fail to coerce.
650 * As with coerce_type, pstate may be NULL if no special unknown-Param
651 * processing is wanted.
654 coerce_to_common_type(ParseState *pstate, Node *node,
655 Oid targetTypeId, const char *context)
657 Oid inputTypeId = exprType(node);
659 if (inputTypeId == targetTypeId)
660 return node; /* no work */
661 if (can_coerce_type(1, &inputTypeId, &targetTypeId, COERCION_IMPLICIT))
662 node = coerce_type(pstate, node, inputTypeId, targetTypeId,
663 COERCION_IMPLICIT, COERCE_IMPLICIT_CAST);
665 elog(ERROR, "%s unable to convert to type %s",
666 context, format_type_be(targetTypeId));
671 * check_generic_type_consistency()
672 * Are the actual arguments potentially compatible with a
673 * polymorphic function?
675 * The argument consistency rules are:
677 * 1) All arguments declared ANYARRAY must have matching datatypes,
678 * and must in fact be varlena arrays.
679 * 2) All arguments declared ANYELEMENT must have matching datatypes.
680 * 3) If there are arguments of both ANYELEMENT and ANYARRAY, make sure
681 * the actual ANYELEMENT datatype is in fact the element type for
682 * the actual ANYARRAY datatype.
684 * If we have UNKNOWN input (ie, an untyped literal) for any ANYELEMENT
685 * or ANYARRAY argument, assume it is okay.
687 * We do not elog here, but just return FALSE if a rule is violated.
690 check_generic_type_consistency(Oid *actual_arg_types,
691 Oid *declared_arg_types,
695 Oid elem_typeid = InvalidOid;
696 Oid array_typeid = InvalidOid;
700 * Loop through the arguments to see if we have any that are
701 * ANYARRAY or ANYELEMENT. If so, require the actual types to be
704 for (j = 0; j < nargs; j++)
706 Oid actual_type = actual_arg_types[j];
708 if (declared_arg_types[j] == ANYELEMENTOID)
710 if (actual_type == UNKNOWNOID)
712 if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
714 elem_typeid = actual_type;
716 else if (declared_arg_types[j] == ANYARRAYOID)
718 if (actual_type == UNKNOWNOID)
720 if (OidIsValid(array_typeid) && actual_type != array_typeid)
722 array_typeid = actual_type;
726 /* Get the element type based on the array type, if we have one */
727 if (OidIsValid(array_typeid))
729 array_typelem = get_element_type(array_typeid);
730 if (!OidIsValid(array_typelem))
731 return false; /* should be an array, but isn't */
733 if (!OidIsValid(elem_typeid))
735 /* if we don't have an element type yet, use the one we just got */
736 elem_typeid = array_typelem;
738 else if (array_typelem != elem_typeid)
740 /* otherwise, they better match */
750 * enforce_generic_type_consistency()
751 * Make sure a polymorphic function is legally callable, and
752 * deduce actual argument and result types.
754 * If ANYARRAY or ANYELEMENT is used for a function's arguments or
755 * return type, we make sure the actual data types are consistent with
756 * each other. The argument consistency rules are shown above for
757 * check_generic_type_consistency().
759 * If we have UNKNOWN input (ie, an untyped literal) for any ANYELEMENT
760 * or ANYARRAY argument, we attempt to deduce the actual type it should
761 * have. If successful, we alter that position of declared_arg_types[]
762 * so that make_fn_arguments will coerce the literal to the right thing.
764 * Rules are applied to the function's return type (possibly altering it)
765 * if it is declared ANYARRAY or ANYELEMENT:
767 * 1) If return type is ANYARRAY, and any argument is ANYARRAY, use the
768 * argument's actual type as the function's return type.
769 * 2) If return type is ANYARRAY, no argument is ANYARRAY, but any argument
770 * is ANYELEMENT, use the actual type of the argument to determine
771 * the function's return type, i.e. the element type's corresponding
773 * 3) If return type is ANYARRAY, no argument is ANYARRAY or ANYELEMENT,
774 * generate an ERROR. This condition is prevented by CREATE FUNCTION
775 * and is therefore not expected here.
776 * 4) If return type is ANYELEMENT, and any argument is ANYELEMENT, use the
777 * argument's actual type as the function's return type.
778 * 5) If return type is ANYELEMENT, no argument is ANYELEMENT, but any
779 * argument is ANYARRAY, use the actual type of the argument to determine
780 * the function's return type, i.e. the array type's corresponding
782 * 6) If return type is ANYELEMENT, no argument is ANYARRAY or ANYELEMENT,
783 * generate an ERROR. This condition is prevented by CREATE FUNCTION
784 * and is therefore not expected here.
787 enforce_generic_type_consistency(Oid *actual_arg_types,
788 Oid *declared_arg_types,
793 bool have_generics = false;
794 bool have_unknowns = false;
795 Oid elem_typeid = InvalidOid;
796 Oid array_typeid = InvalidOid;
797 Oid array_typelem = InvalidOid;
800 * Loop through the arguments to see if we have any that are
801 * ANYARRAY or ANYELEMENT. If so, require the actual types to be
804 for (j = 0; j < nargs; j++)
806 Oid actual_type = actual_arg_types[j];
808 if (declared_arg_types[j] == ANYELEMENTOID)
810 have_generics = true;
811 if (actual_type == UNKNOWNOID)
813 have_unknowns = true;
816 if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
817 elog(ERROR, "Arguments declared ANYELEMENT are not all alike: %s vs %s",
818 format_type_be(elem_typeid),
819 format_type_be(actual_type));
820 elem_typeid = actual_type;
822 else if (declared_arg_types[j] == ANYARRAYOID)
824 have_generics = true;
825 if (actual_type == UNKNOWNOID)
827 have_unknowns = true;
830 if (OidIsValid(array_typeid) && actual_type != array_typeid)
831 elog(ERROR, "Arguments declared ANYARRAY are not all alike: %s vs %s",
832 format_type_be(array_typeid),
833 format_type_be(actual_type));
834 array_typeid = actual_type;
839 * Fast Track: if none of the arguments are ANYARRAY or ANYELEMENT,
840 * return the unmodified rettype.
845 /* Get the element type based on the array type, if we have one */
846 if (OidIsValid(array_typeid))
848 array_typelem = get_element_type(array_typeid);
849 if (!OidIsValid(array_typelem))
850 elog(ERROR, "Argument declared ANYARRAY is not an array: %s",
851 format_type_be(array_typeid));
853 if (!OidIsValid(elem_typeid))
855 /* if we don't have an element type yet, use the one we just got */
856 elem_typeid = array_typelem;
858 else if (array_typelem != elem_typeid)
860 /* otherwise, they better match */
861 elog(ERROR, "Argument declared ANYARRAY is not consistent with "
862 "argument declared ANYELEMENT: %s vs %s",
863 format_type_be(array_typeid),
864 format_type_be(elem_typeid));
867 else if (!OidIsValid(elem_typeid))
869 /* Only way to get here is if all the generic args are UNKNOWN */
870 elog(ERROR, "Cannot determine ANYARRAY/ANYELEMENT type because input is UNKNOWN");
874 * If we had any unknown inputs, re-scan to assign correct types
878 for (j = 0; j < nargs; j++)
880 Oid actual_type = actual_arg_types[j];
882 if (actual_type != UNKNOWNOID)
885 if (declared_arg_types[j] == ANYELEMENTOID)
887 declared_arg_types[j] = elem_typeid;
889 else if (declared_arg_types[j] == ANYARRAYOID)
891 if (!OidIsValid(array_typeid))
893 array_typeid = get_array_type(elem_typeid);
894 if (!OidIsValid(array_typeid))
895 elog(ERROR, "Cannot find array type for datatype %s",
896 format_type_be(elem_typeid));
898 declared_arg_types[j] = array_typeid;
903 /* if we return ANYARRAYOID use the appropriate argument type */
904 if (rettype == ANYARRAYOID)
906 if (!OidIsValid(array_typeid))
908 array_typeid = get_array_type(elem_typeid);
909 if (!OidIsValid(array_typeid))
910 elog(ERROR, "Cannot find array type for datatype %s",
911 format_type_be(elem_typeid));
916 /* if we return ANYELEMENTOID use the appropriate argument type */
917 if (rettype == ANYELEMENTOID)
920 /* we don't return a generic type; send back the original return type */
926 * Assign a category to the specified OID.
927 * XXX This should be moved to system catalog lookups
928 * to allow for better type extensibility.
929 * - thomas 2001-09-30
932 TypeCategory(Oid inType)
939 result = BOOLEAN_TYPE;
947 result = STRING_TYPE;
952 result = BITSTRING_TYPE;
957 case (REGPROCEDUREOID):
959 case (REGOPERATOROID):
969 result = NUMERIC_TYPE;
977 case (TIMESTAMPTZOID):
978 result = DATETIME_TYPE;
984 result = TIMESPAN_TYPE;
994 result = GEOMETRIC_TYPE;
999 result = NETWORK_TYPE;
1004 result = UNKNOWN_TYPE;
1013 case (LANGUAGE_HANDLEROID):
1016 case (ANYELEMENTOID):
1017 result = GENERIC_TYPE;
1025 } /* TypeCategory() */
1028 /* IsPreferredType()
1029 * Check if this type is a preferred type.
1030 * XXX This should be moved to system catalog lookups
1031 * to allow for better type extensibility.
1032 * - thomas 2001-09-30
1035 IsPreferredType(CATEGORY category, Oid type)
1037 return (type == PreferredType(category, type));
1038 } /* IsPreferredType() */
1042 * Return the preferred type OID for the specified category.
1043 * XXX This should be moved to system catalog lookups
1044 * to allow for better type extensibility.
1045 * - thomas 2001-09-30
1048 PreferredType(CATEGORY category, Oid type)
1054 case (INVALID_TYPE):
1055 case (UNKNOWN_TYPE):
1056 case (GENERIC_TYPE):
1057 result = UNKNOWNOID;
1060 case (BOOLEAN_TYPE):
1068 case (BITSTRING_TYPE):
1072 case (NUMERIC_TYPE):
1073 if (type == OIDOID ||
1074 type == REGPROCOID ||
1075 type == REGPROCEDUREOID ||
1076 type == REGOPEROID ||
1077 type == REGOPERATOROID ||
1078 type == REGCLASSOID ||
1085 case (DATETIME_TYPE):
1086 if (type == DATEOID)
1087 result = TIMESTAMPOID;
1089 result = TIMESTAMPTZOID;
1092 case (TIMESPAN_TYPE):
1093 result = INTERVALOID;
1096 case (GEOMETRIC_TYPE):
1100 case (NETWORK_TYPE):
1109 elog(ERROR, "PreferredType: unknown category");
1110 result = UNKNOWNOID;
1114 } /* PreferredType() */
1117 /* IsBinaryCoercible()
1118 * Check if srctype is binary-coercible to targettype.
1120 * This notion allows us to cheat and directly exchange values without
1121 * going through the trouble of calling a conversion function.
1123 * As of 7.3, binary coercibility isn't hardwired into the code anymore.
1124 * We consider two types binary-coercible if there is an implicitly
1125 * invokable, no-function-needed pg_cast entry.
1127 * This function replaces IsBinaryCompatible(), which was an inherently
1128 * symmetric test. Since the pg_cast entries aren't necessarily symmetric,
1129 * the order of the operands is now significant.
1132 IsBinaryCoercible(Oid srctype, Oid targettype)
1135 Form_pg_cast castForm;
1138 /* Fast path if same type */
1139 if (srctype == targettype)
1142 /* Perhaps the types are domains; if so, look at their base types */
1143 if (OidIsValid(srctype))
1144 srctype = getBaseType(srctype);
1145 if (OidIsValid(targettype))
1146 targettype = getBaseType(targettype);
1148 /* Somewhat-fast path if same base type */
1149 if (srctype == targettype)
1152 /* Else look in pg_cast */
1153 tuple = SearchSysCache(CASTSOURCETARGET,
1154 ObjectIdGetDatum(srctype),
1155 ObjectIdGetDatum(targettype),
1157 if (!HeapTupleIsValid(tuple))
1158 return false; /* no cast */
1159 castForm = (Form_pg_cast) GETSTRUCT(tuple);
1161 result = (castForm->castfunc == InvalidOid &&
1162 castForm->castcontext == COERCION_CODE_IMPLICIT);
1164 ReleaseSysCache(tuple);
1171 * find_coercion_pathway
1172 * Look for a coercion pathway between two types.
1174 * ccontext determines the set of available casts.
1176 * If we find a suitable entry in pg_cast, return TRUE, and set *funcid
1177 * to the castfunc value (which may be InvalidOid for a binary-compatible
1181 find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
1182 CoercionContext ccontext,
1185 bool result = false;
1188 *funcid = InvalidOid;
1190 /* Perhaps the types are domains; if so, look at their base types */
1191 if (OidIsValid(sourceTypeId))
1192 sourceTypeId = getBaseType(sourceTypeId);
1193 if (OidIsValid(targetTypeId))
1194 targetTypeId = getBaseType(targetTypeId);
1196 /* Domains are automatically binary-compatible with their base type */
1197 if (sourceTypeId == targetTypeId)
1200 /* Look in pg_cast */
1201 tuple = SearchSysCache(CASTSOURCETARGET,
1202 ObjectIdGetDatum(sourceTypeId),
1203 ObjectIdGetDatum(targetTypeId),
1206 if (HeapTupleIsValid(tuple))
1208 Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
1209 CoercionContext castcontext;
1211 /* convert char value for castcontext to CoercionContext enum */
1212 switch (castForm->castcontext)
1214 case COERCION_CODE_IMPLICIT:
1215 castcontext = COERCION_IMPLICIT;
1217 case COERCION_CODE_ASSIGNMENT:
1218 castcontext = COERCION_ASSIGNMENT;
1220 case COERCION_CODE_EXPLICIT:
1221 castcontext = COERCION_EXPLICIT;
1224 elog(ERROR, "find_coercion_pathway: bogus castcontext %c",
1225 castForm->castcontext);
1226 castcontext = 0; /* keep compiler quiet */
1230 /* Rely on ordering of enum for correct behavior here */
1231 if (ccontext >= castcontext)
1233 *funcid = castForm->castfunc;
1237 ReleaseSysCache(tuple);
1242 * If there's no pg_cast entry, perhaps we are dealing with a
1243 * pair of array types. If so, and if the element types have
1244 * a suitable cast, use array_type_coerce().
1250 if ((targetElemType = get_element_type(targetTypeId)) != InvalidOid &&
1251 (sourceElemType = get_element_type(sourceTypeId)) != InvalidOid)
1253 if (find_coercion_pathway(targetElemType, sourceElemType,
1254 ccontext, &elemfuncid))
1256 *funcid = F_ARRAY_TYPE_COERCE;
1267 * find_typmod_coercion_function -- does the given type need length coercion?
1269 * If the target type possesses a function named for the type
1270 * and having parameter signature (targettype, int4), we assume that
1271 * the type requires coercion to its own length and that the said
1272 * function should be invoked to do that.
1274 * Alternatively, the length-coercing function may have the signature
1275 * (targettype, int4, bool). On success, *nargs is set to report which
1276 * signature we found.
1278 * "bpchar" (ie, char(N)) and "numeric" are examples of such types.
1280 * If the given type is a varlena array type, we do not look for a coercion
1281 * function associated directly with the array type, but instead look for
1282 * one associated with the element type. If one exists, we report
1283 * array_length_coerce() as the coercion function to use.
1285 * This mechanism may seem pretty grotty and in need of replacement by
1286 * something in pg_cast, but since typmod is only interesting for datatypes
1287 * that have special handling in the grammar, there's not really much
1288 * percentage in making it any easier to apply such coercions ...
1291 find_typmod_coercion_function(Oid typeId, int *nargs)
1293 Oid funcid = InvalidOid;
1294 bool isArray = false;
1296 Form_pg_type typeForm;
1299 Oid oid_array[FUNC_MAX_ARGS];
1302 targetType = typeidType(typeId);
1303 typeForm = (Form_pg_type) GETSTRUCT(targetType);
1305 /* Check for a varlena array type (and not a domain) */
1306 if (typeForm->typelem != InvalidOid &&
1307 typeForm->typlen == -1 &&
1308 typeForm->typtype != 'd')
1310 /* Yes, switch our attention to the element type */
1311 typeId = typeForm->typelem;
1312 ReleaseSysCache(targetType);
1313 targetType = typeidType(typeId);
1314 typeForm = (Form_pg_type) GETSTRUCT(targetType);
1318 /* Function name is same as type internal name, and in same namespace */
1319 typname = NameStr(typeForm->typname);
1320 typnamespace = typeForm->typnamespace;
1322 /* First look for parameters (type, int4) */
1323 MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
1324 oid_array[0] = typeId;
1325 oid_array[1] = INT4OID;
1328 ftup = SearchSysCache(PROCNAMENSP,
1329 CStringGetDatum(typname),
1331 PointerGetDatum(oid_array),
1332 ObjectIdGetDatum(typnamespace));
1333 if (HeapTupleIsValid(ftup))
1335 Form_pg_proc pform = (Form_pg_proc) GETSTRUCT(ftup);
1337 /* Make sure the function's result type is as expected */
1338 if (pform->prorettype == typeId && !pform->proretset &&
1341 /* Okay to use it */
1342 funcid = HeapTupleGetOid(ftup);
1344 ReleaseSysCache(ftup);
1347 if (!OidIsValid(funcid))
1349 /* Didn't find a function, so now try (type, int4, bool) */
1350 oid_array[2] = BOOLOID;
1353 ftup = SearchSysCache(PROCNAMENSP,
1354 CStringGetDatum(typname),
1356 PointerGetDatum(oid_array),
1357 ObjectIdGetDatum(typnamespace));
1358 if (HeapTupleIsValid(ftup))
1360 Form_pg_proc pform = (Form_pg_proc) GETSTRUCT(ftup);
1362 /* Make sure the function's result type is as expected */
1363 if (pform->prorettype == typeId && !pform->proretset &&
1366 /* Okay to use it */
1367 funcid = HeapTupleGetOid(ftup);
1369 ReleaseSysCache(ftup);
1373 ReleaseSysCache(targetType);
1376 * Now, if we did find a coercion function for an array element type,
1377 * report array_length_coerce() as the function to use. We know it
1378 * takes three arguments always.
1380 if (isArray && OidIsValid(funcid))
1382 funcid = F_ARRAY_LENGTH_COERCE;
1390 * Build an expression tree representing a function call.
1392 * The argument expressions must have been transformed already.
1395 build_func_call(Oid funcid, Oid rettype, List *args, CoercionForm fformat)
1399 funcexpr = makeNode(FuncExpr);
1400 funcexpr->funcid = funcid;
1401 funcexpr->funcresulttype = rettype;
1402 funcexpr->funcretset = false; /* only possible case here */
1403 funcexpr->funcformat = fformat;
1404 funcexpr->args = args;
1406 return (Node *) funcexpr;