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.94 2003/04/08 23:20:02 tgl Exp $
13 *-------------------------------------------------------------------------
17 #include "catalog/pg_cast.h"
18 #include "catalog/pg_proc.h"
19 #include "nodes/makefuncs.h"
20 #include "optimizer/clauses.h"
21 #include "parser/parse_coerce.h"
22 #include "parser/parse_expr.h"
23 #include "parser/parse_func.h"
24 #include "parser/parse_type.h"
25 #include "utils/builtins.h"
26 #include "utils/fmgroids.h"
27 #include "utils/lsyscache.h"
28 #include "utils/syscache.h"
31 static Node *coerce_type_typmod(Node *node,
32 Oid targetTypeId, int32 targetTypMod,
33 CoercionForm cformat, bool isExplicit);
34 static Oid PreferredType(CATEGORY category, Oid type);
35 static Node *build_func_call(Oid funcid, Oid rettype, List *args,
36 CoercionForm fformat);
40 * coerce_to_target_type()
41 * Convert an expression to a target type and typmod.
43 * This is the general-purpose entry point for arbitrary type coercion
44 * operations. Direct use of the component operations can_coerce_type,
45 * coerce_type, and coerce_type_typmod should be restricted to special
46 * cases (eg, when the conversion is expected to succeed).
48 * Returns the possibly-transformed expression tree, or NULL if the type
49 * conversion is not possible. (We do this, rather than elog'ing directly,
50 * so that callers can generate custom error messages indicating context.)
52 * expr - input expression tree (already transformed by transformExpr)
53 * exprtype - result type of expr
54 * targettype - desired result type
55 * targettypmod - desired result typmod
56 * ccontext, cformat - context indicators to control coercions
59 coerce_to_target_type(Node *expr, Oid exprtype,
60 Oid targettype, int32 targettypmod,
61 CoercionContext ccontext,
64 if (can_coerce_type(1, &exprtype, &targettype, ccontext))
65 expr = coerce_type(expr, exprtype, targettype,
68 * String hacks to get transparent conversions for char and varchar:
69 * if a coercion to text is available, use it for forced coercions to
70 * char(n) or varchar(n).
72 * This is pretty grotty, but seems easier to maintain than providing
73 * entries in pg_cast that parallel all the ones for text.
75 else if (ccontext >= COERCION_ASSIGNMENT &&
76 (targettype == BPCHAROID || targettype == VARCHAROID))
78 Oid text_id = TEXTOID;
80 if (can_coerce_type(1, &exprtype, &text_id, ccontext))
82 expr = coerce_type(expr, exprtype, text_id,
84 /* Need a RelabelType if no typmod coercion is performed */
86 expr = (Node *) makeRelabelType((Expr *) expr,
97 * If the target is a fixed-length type, it may need a length coercion
98 * as well as a type coercion.
101 expr = coerce_type_typmod(expr, targettype, targettypmod,
103 (cformat != COERCE_IMPLICIT_CAST));
111 * Convert an expression to a different type.
113 * The caller should already have determined that the coercion is possible;
114 * see can_coerce_type.
116 * No coercion to a typmod (length) is performed here. The caller must
117 * call coerce_type_typmod as well, if a typmod constraint is wanted.
118 * (But if the target type is a domain, it may internally contain a
119 * typmod constraint, which will be applied inside coerce_to_domain.)
122 coerce_type(Node *node, Oid inputTypeId, Oid targetTypeId,
123 CoercionContext ccontext, CoercionForm cformat)
128 if (targetTypeId == inputTypeId ||
131 /* no conversion needed */
134 else if (inputTypeId == UNKNOWNOID && IsA(node, Const))
137 * Input is a string constant with previously undetermined type.
138 * Apply the target type's typinput function to it to produce a
139 * constant of the target type.
141 * NOTE: this case cannot be folded together with the other
142 * constant-input case, since the typinput function does not
143 * necessarily behave the same as a type conversion function. For
144 * example, int4's typinput function will reject "1.2", whereas
145 * float-to-int type conversion will round to integer.
147 * XXX if the typinput function is not immutable, we really ought to
148 * postpone evaluation of the function call until runtime. But
149 * there is no way to represent a typinput function call as an
150 * expression tree, because C-string values are not Datums. (XXX
151 * This *is* possible as of 7.3, do we want to do it?)
153 Const *con = (Const *) node;
154 Const *newcon = makeNode(Const);
155 Type targetType = typeidType(targetTypeId);
156 char targetTyptype = typeTypType(targetType);
158 newcon->consttype = targetTypeId;
159 newcon->constlen = typeLen(targetType);
160 newcon->constbyval = typeByVal(targetType);
161 newcon->constisnull = con->constisnull;
163 if (!con->constisnull)
165 char *val = DatumGetCString(DirectFunctionCall1(unknownout,
169 * We pass typmod -1 to the input routine, primarily because
170 * existing input routines follow implicit-coercion semantics
171 * for length checks, which is not always what we want here.
172 * Any length constraint will be applied later by our caller.
174 * Note that we call stringTypeDatum using the domain's pg_type
175 * row, if it's a domain. This works because the domain row has
176 * the same typinput and typelem as the base type --- ugly...
178 newcon->constvalue = stringTypeDatum(targetType, val, -1);
182 result = (Node *) newcon;
184 /* If target is a domain, apply constraints. */
185 if (targetTyptype == 'd')
186 result = coerce_to_domain(result, InvalidOid, targetTypeId,
189 ReleaseSysCache(targetType);
191 else if (targetTypeId == ANYOID ||
192 targetTypeId == ANYARRAYOID ||
193 targetTypeId == ANYELEMENTOID)
195 /* assume can_coerce_type verified that implicit coercion is okay */
196 /* NB: we do NOT want a RelabelType here */
199 else if (find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
202 if (OidIsValid(funcId))
205 * Generate an expression tree representing run-time
206 * application of the conversion function. If we are dealing
207 * with a domain target type, the conversion function will
208 * yield the base type.
210 Oid baseTypeId = getBaseType(targetTypeId);
212 result = build_func_call(funcId, baseTypeId, makeList1(node),
216 * If domain, coerce to the domain type and relabel with
219 if (targetTypeId != baseTypeId)
220 result = coerce_to_domain(result, baseTypeId, targetTypeId,
224 * If the input is a constant, apply the type conversion
225 * function now instead of delaying to runtime. (We could, of
226 * course, just leave this to be done during
227 * planning/optimization; but it's a very frequent special
228 * case, and we save cycles in the rewriter if we fold the
231 * Note that no folding will occur if the conversion function is
232 * not marked 'immutable'.
234 if (IsA(node, Const))
235 result = eval_const_expressions(result);
240 * We don't need to do a physical conversion, but we do need
241 * to attach a RelabelType node so that the expression will be
242 * seen to have the intended type when inspected by
245 * Also, domains may have value restrictions beyond the base type
246 * that must be accounted for. If the destination is a domain
247 * then we won't need a RelabelType node.
249 result = coerce_to_domain(node, InvalidOid, targetTypeId,
254 * XXX could we label result with exprTypmod(node) instead of
255 * default -1 typmod, to save a possible length-coercion
256 * later? Would work if both types have same interpretation of
257 * typmod, which is likely but not certain.
259 result = (Node *) makeRelabelType((Expr *) result,
265 else if (typeInheritsFrom(inputTypeId, targetTypeId))
268 * Input class type is a subclass of target, so nothing to do ---
269 * except relabel the type. This is binary compatibility for
272 result = (Node *) makeRelabelType((Expr *) node,
278 /* If we get here, caller blew it */
279 elog(ERROR, "coerce_type: no conversion function from %s to %s",
280 format_type_be(inputTypeId), format_type_be(targetTypeId));
281 result = NULL; /* keep compiler quiet */
290 * Can input_typeids be coerced to target_typeids?
292 * We must be told the context (CAST construct, assignment, implicit coercion)
293 * as this determines the set of available casts.
296 can_coerce_type(int nargs, Oid *input_typeids, Oid *target_typeids,
297 CoercionContext ccontext)
299 bool have_generics = false;
302 /* run through argument list... */
303 for (i = 0; i < nargs; i++)
305 Oid inputTypeId = input_typeids[i];
306 Oid targetTypeId = target_typeids[i];
309 /* no problem if same type */
310 if (inputTypeId == targetTypeId)
313 /* don't choke on references to no-longer-existing types */
314 if (!typeidIsValid(inputTypeId))
316 if (!typeidIsValid(targetTypeId))
320 * If input is an untyped string constant, assume we can convert
321 * it to anything except a class type.
323 if (inputTypeId == UNKNOWNOID)
325 if (ISCOMPLEX(targetTypeId))
330 /* accept if target is ANY */
331 if (targetTypeId == ANYOID)
334 /* accept if target is ANYARRAY or ANYELEMENT, for now */
335 if (targetTypeId == ANYARRAYOID ||
336 targetTypeId == ANYELEMENTOID)
338 have_generics = true; /* do more checking later */
343 * If pg_cast shows that we can coerce, accept. This test now
344 * covers both binary-compatible and coercion-function cases.
346 if (find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
351 * If input is a class type that inherits from target, accept
353 if (typeInheritsFrom(inputTypeId, targetTypeId))
357 * Else, cannot coerce at this argument position
362 /* If we found any generic argument types, cross-check them */
365 if (!check_generic_type_consistency(input_typeids, target_typeids,
375 * Create an expression tree to represent coercion to a domain type.
377 * 'arg': input expression
378 * 'baseTypeId': base type of domain, if known (pass InvalidOid if caller
379 * has not bothered to look this up)
380 * 'typeId': target type to coerce to
381 * 'cformat': coercion format
383 * If the target type isn't a domain, the given 'arg' is returned as-is.
386 coerce_to_domain(Node *arg, Oid baseTypeId, Oid typeId, CoercionForm cformat)
388 CoerceToDomain *result;
391 /* Get the base type if it hasn't been supplied */
392 if (baseTypeId == InvalidOid)
393 baseTypeId = getBaseType(typeId);
395 /* If it isn't a domain, return the node as it was passed in */
396 if (baseTypeId == typeId)
400 * If the domain applies a typmod to its base type, build the appropriate
401 * coercion step. Mark it implicit for display purposes, because we don't
402 * want it shown separately by ruleutils.c; but the isExplicit flag passed
403 * to the conversion function depends on the manner in which the domain
404 * coercion is invoked, so that the semantics of implicit and explicit
405 * coercion differ. (Is that really the behavior we want?)
407 * NOTE: because we apply this as part of the fixed expression structure,
408 * ALTER DOMAIN cannot alter the typtypmod. But it's unclear that that
409 * would be safe to do anyway, without lots of knowledge about what the
410 * base type thinks the typmod means.
412 typmod = get_typtypmod(typeId);
414 arg = coerce_type_typmod(arg, baseTypeId, typmod,
415 COERCE_IMPLICIT_CAST,
416 (cformat != COERCE_IMPLICIT_CAST));
419 * Now build the domain coercion node. This represents run-time checking
420 * of any constraints currently attached to the domain. This also
421 * ensures that the expression is properly labeled as to result type.
423 result = makeNode(CoerceToDomain);
424 result->arg = (Expr *) arg;
425 result->resulttype = typeId;
426 result->resulttypmod = -1; /* currently, always -1 for domains */
427 result->coercionformat = cformat;
429 return (Node *) result;
434 * coerce_type_typmod()
435 * Force a value to a particular typmod, if meaningful and possible.
437 * This is applied to values that are going to be stored in a relation
438 * (where we have an atttypmod for the column) as well as values being
439 * explicitly CASTed (where the typmod comes from the target type spec).
441 * The caller must have already ensured that the value is of the correct
442 * type, typically by applying coerce_type.
444 * NOTE: this does not need to work on domain types, because any typmod
445 * coercion for a domain is considered to be part of the type coercion
446 * needed to produce the domain value in the first place. So, no getBaseType.
449 coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod,
450 CoercionForm cformat, bool isExplicit)
456 * A negative typmod is assumed to mean that no coercion is wanted.
458 if (targetTypMod < 0 || targetTypMod == exprTypmod(node))
461 funcId = find_typmod_coercion_function(targetTypeId, &nargs);
463 if (OidIsValid(funcId))
469 /* Pass given value, plus target typmod as an int4 constant */
470 cons = makeConst(INT4OID,
472 Int32GetDatum(targetTypMod),
476 args = makeList2(node, cons);
480 /* Pass it a boolean isExplicit parameter, too */
481 cons = makeConst(BOOLOID,
483 BoolGetDatum(isExplicit),
487 args = lappend(args, cons);
490 fcall = build_func_call(funcId, targetTypeId, args, cformat);
493 * If the input is a constant, apply the length coercion
494 * function now instead of delaying to runtime.
496 * See the comments for the similar case in coerce_type.
498 if (node && IsA(node, Const))
499 node = eval_const_expressions(fcall);
508 /* coerce_to_boolean()
509 * Coerce an argument of a construct that requires boolean input
510 * (AND, OR, NOT, etc). Also check that input is not a set.
512 * Returns the possibly-transformed node tree.
515 coerce_to_boolean(Node *node, const char *constructName)
517 Oid inputTypeId = exprType(node);
519 if (inputTypeId != BOOLOID)
521 node = coerce_to_target_type(node, inputTypeId,
524 COERCE_IMPLICIT_CAST);
527 /* translator: first %s is name of a SQL construct, eg WHERE */
528 elog(ERROR, "Argument of %s must be type boolean, not type %s",
529 constructName, format_type_be(inputTypeId));
533 if (expression_returns_set(node))
535 /* translator: %s is name of a SQL construct, eg WHERE */
536 elog(ERROR, "Argument of %s must not be a set function",
544 /* select_common_type()
545 * Determine the common supertype of a list of input expression types.
546 * This is used for determining the output type of CASE and UNION
549 * typeids is a nonempty list of type OIDs. Note that earlier items
550 * in the list will be preferred if there is doubt.
551 * 'context' is a phrase to use in the error message if we fail to select
555 select_common_type(List *typeids, const char *context)
561 Assert(typeids != NIL);
562 ptype = lfirsto(typeids);
563 pcategory = TypeCategory(ptype);
564 foreach(l, lnext(typeids))
566 Oid ntype = lfirsto(l);
568 /* move on to next one if no new information... */
569 if ((ntype != InvalidOid) && (ntype != UNKNOWNOID) && (ntype != ptype))
571 if ((ptype == InvalidOid) || ptype == UNKNOWNOID)
573 /* so far, only nulls so take anything... */
575 pcategory = TypeCategory(ptype);
577 else if (TypeCategory(ntype) != pcategory)
580 * both types in different categories? then not much
583 elog(ERROR, "%s types '%s' and '%s' not matched",
584 context, format_type_be(ptype), format_type_be(ntype));
586 else if (!IsPreferredType(pcategory, ptype) &&
587 can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
588 !can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
591 * take new type if can coerce to it implicitly but not the
592 * other way; but if we have a preferred type, stay on it.
595 pcategory = TypeCategory(ptype);
601 * If all the inputs were UNKNOWN type --- ie, unknown-type literals
602 * --- then resolve as type TEXT. This situation comes up with
603 * constructs like SELECT (CASE WHEN foo THEN 'bar' ELSE 'baz' END);
604 * SELECT 'foo' UNION SELECT 'bar'; It might seem desirable to leave
605 * the construct's output type as UNKNOWN, but that really doesn't
606 * work, because we'd probably end up needing a runtime coercion from
607 * UNKNOWN to something else, and we usually won't have it. We need
608 * to coerce the unknown literals while they are still literals, so a
609 * decision has to be made now.
611 if (ptype == UNKNOWNOID)
617 /* coerce_to_common_type()
618 * Coerce an expression to the given type.
620 * This is used following select_common_type() to coerce the individual
621 * expressions to the desired type. 'context' is a phrase to use in the
622 * error message if we fail to coerce.
625 coerce_to_common_type(Node *node, Oid targetTypeId, const char *context)
627 Oid inputTypeId = exprType(node);
629 if (inputTypeId == targetTypeId)
630 return node; /* no work */
631 if (can_coerce_type(1, &inputTypeId, &targetTypeId, COERCION_IMPLICIT))
632 node = coerce_type(node, inputTypeId, targetTypeId,
633 COERCION_IMPLICIT, COERCE_IMPLICIT_CAST);
635 elog(ERROR, "%s unable to convert to type %s",
636 context, format_type_be(targetTypeId));
641 * check_generic_type_consistency()
642 * Are the actual arguments potentially compatible with a
643 * polymorphic function?
645 * The argument consistency rules are:
647 * 1) All arguments declared ANYARRAY must have matching datatypes,
648 * and must in fact be varlena arrays.
649 * 2) All arguments declared ANYELEMENT must have matching datatypes.
650 * 3) If there are arguments of both ANYELEMENT and ANYARRAY, make sure
651 * the actual ANYELEMENT datatype is in fact the element type for
652 * the actual ANYARRAY datatype.
654 * If we have UNKNOWN input (ie, an untyped literal) for any ANYELEMENT
655 * or ANYARRAY argument, assume it is okay.
657 * We do not elog here, but just return FALSE if a rule is violated.
660 check_generic_type_consistency(Oid *actual_arg_types,
661 Oid *declared_arg_types,
665 Oid elem_typeid = InvalidOid;
666 Oid array_typeid = InvalidOid;
670 * Loop through the arguments to see if we have any that are
671 * ANYARRAY or ANYELEMENT. If so, require the actual types to be
674 for (j = 0; j < nargs; j++)
676 Oid actual_type = actual_arg_types[j];
678 if (declared_arg_types[j] == ANYELEMENTOID)
680 if (actual_type == UNKNOWNOID)
682 if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
684 elem_typeid = actual_type;
686 else if (declared_arg_types[j] == ANYARRAYOID)
688 if (actual_type == UNKNOWNOID)
690 if (OidIsValid(array_typeid) && actual_type != array_typeid)
692 array_typeid = actual_type;
696 /* Get the element type based on the array type, if we have one */
697 if (OidIsValid(array_typeid))
699 array_typelem = get_element_type(array_typeid);
700 if (!OidIsValid(array_typelem))
701 return false; /* should be an array, but isn't */
703 if (!OidIsValid(elem_typeid))
705 /* if we don't have an element type yet, use the one we just got */
706 elem_typeid = array_typelem;
708 else if (array_typelem != elem_typeid)
710 /* otherwise, they better match */
720 * enforce_generic_type_consistency()
721 * Make sure a polymorphic function is legally callable, and
722 * deduce actual argument and result types.
724 * If ANYARRAY or ANYELEMENT is used for a function's arguments or
725 * return type, we make sure the actual data types are consistent with
726 * each other. The argument consistency rules are shown above for
727 * check_generic_type_consistency().
729 * If we have UNKNOWN input (ie, an untyped literal) for any ANYELEMENT
730 * or ANYARRAY argument, we attempt to deduce the actual type it should
731 * have. If successful, we alter that position of declared_arg_types[]
732 * so that make_fn_arguments will coerce the literal to the right thing.
734 * Rules are applied to the function's return type (possibly altering it)
735 * if it is declared ANYARRAY or ANYELEMENT:
737 * 1) If return type is ANYARRAY, and any argument is ANYARRAY, use the
738 * argument's actual type as the function's return type.
739 * 2) If return type is ANYARRAY, no argument is ANYARRAY, but any argument
740 * is ANYELEMENT, use the actual type of the argument to determine
741 * the function's return type, i.e. the element type's corresponding
743 * 3) If return type is ANYARRAY, no argument is ANYARRAY or ANYELEMENT,
744 * generate an ERROR. This condition is prevented by CREATE FUNCTION
745 * and is therefore not expected here.
746 * 4) If return type is ANYELEMENT, and any argument is ANYELEMENT, use the
747 * argument's actual type as the function's return type.
748 * 5) If return type is ANYELEMENT, no argument is ANYELEMENT, but any
749 * argument is ANYARRAY, use the actual type of the argument to determine
750 * the function's return type, i.e. the array type's corresponding
752 * 6) If return type is ANYELEMENT, no argument is ANYARRAY or ANYELEMENT,
753 * generate an ERROR. This condition is prevented by CREATE FUNCTION
754 * and is therefore not expected here.
757 enforce_generic_type_consistency(Oid *actual_arg_types,
758 Oid *declared_arg_types,
763 bool have_generics = false;
764 bool have_unknowns = false;
765 Oid elem_typeid = InvalidOid;
766 Oid array_typeid = InvalidOid;
767 Oid array_typelem = InvalidOid;
770 * Loop through the arguments to see if we have any that are
771 * ANYARRAY or ANYELEMENT. If so, require the actual types to be
774 for (j = 0; j < nargs; j++)
776 Oid actual_type = actual_arg_types[j];
778 if (declared_arg_types[j] == ANYELEMENTOID)
780 have_generics = true;
781 if (actual_type == UNKNOWNOID)
783 have_unknowns = true;
786 if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
787 elog(ERROR, "Arguments declared ANYELEMENT are not all alike: %s vs %s",
788 format_type_be(elem_typeid),
789 format_type_be(actual_type));
790 elem_typeid = actual_type;
792 else if (declared_arg_types[j] == ANYARRAYOID)
794 have_generics = true;
795 if (actual_type == UNKNOWNOID)
797 have_unknowns = true;
800 if (OidIsValid(array_typeid) && actual_type != array_typeid)
801 elog(ERROR, "Arguments declared ANYARRAY are not all alike: %s vs %s",
802 format_type_be(array_typeid),
803 format_type_be(actual_type));
804 array_typeid = actual_type;
809 * Fast Track: if none of the arguments are ANYARRAY or ANYELEMENT,
810 * return the unmodified rettype.
815 /* Get the element type based on the array type, if we have one */
816 if (OidIsValid(array_typeid))
818 array_typelem = get_element_type(array_typeid);
819 if (!OidIsValid(array_typelem))
820 elog(ERROR, "Argument declared ANYARRAY is not an array: %s",
821 format_type_be(array_typeid));
823 if (!OidIsValid(elem_typeid))
825 /* if we don't have an element type yet, use the one we just got */
826 elem_typeid = array_typelem;
828 else if (array_typelem != elem_typeid)
830 /* otherwise, they better match */
831 elog(ERROR, "Argument declared ANYARRAY is not consistent with "
832 "argument declared ANYELEMENT: %s vs %s",
833 format_type_be(array_typeid),
834 format_type_be(elem_typeid));
837 else if (!OidIsValid(elem_typeid))
839 /* Only way to get here is if all the generic args are UNKNOWN */
840 elog(ERROR, "Cannot determine ANYARRAY/ANYELEMENT type because input is UNKNOWN");
844 * If we had any unknown inputs, re-scan to assign correct types
848 for (j = 0; j < nargs; j++)
850 Oid actual_type = actual_arg_types[j];
852 if (actual_type != UNKNOWNOID)
855 if (declared_arg_types[j] == ANYELEMENTOID)
857 declared_arg_types[j] = elem_typeid;
859 else if (declared_arg_types[j] == ANYARRAYOID)
861 if (!OidIsValid(array_typeid))
863 array_typeid = get_array_type(elem_typeid);
864 if (!OidIsValid(array_typeid))
865 elog(ERROR, "Cannot find array type for datatype %s",
866 format_type_be(elem_typeid));
868 declared_arg_types[j] = array_typeid;
873 /* if we return ANYARRAYOID use the appropriate argument type */
874 if (rettype == ANYARRAYOID)
876 if (!OidIsValid(array_typeid))
878 array_typeid = get_array_type(elem_typeid);
879 if (!OidIsValid(array_typeid))
880 elog(ERROR, "Cannot find array type for datatype %s",
881 format_type_be(elem_typeid));
886 /* if we return ANYELEMENTOID use the appropriate argument type */
887 if (rettype == ANYELEMENTOID)
890 /* we don't return a generic type; send back the original return type */
896 * Assign a category to the specified OID.
897 * XXX This should be moved to system catalog lookups
898 * to allow for better type extensibility.
899 * - thomas 2001-09-30
902 TypeCategory(Oid inType)
909 result = BOOLEAN_TYPE;
917 result = STRING_TYPE;
922 result = BITSTRING_TYPE;
927 case (REGPROCEDUREOID):
929 case (REGOPERATOROID):
939 result = NUMERIC_TYPE;
947 case (TIMESTAMPTZOID):
948 result = DATETIME_TYPE;
954 result = TIMESPAN_TYPE;
964 result = GEOMETRIC_TYPE;
969 result = NETWORK_TYPE;
974 result = UNKNOWN_TYPE;
983 case (LANGUAGE_HANDLEROID):
986 case (ANYELEMENTOID):
987 result = GENERIC_TYPE;
995 } /* TypeCategory() */
999 * Check if this type is a preferred type.
1000 * XXX This should be moved to system catalog lookups
1001 * to allow for better type extensibility.
1002 * - thomas 2001-09-30
1005 IsPreferredType(CATEGORY category, Oid type)
1007 return (type == PreferredType(category, type));
1008 } /* IsPreferredType() */
1012 * Return the preferred type OID for the specified category.
1013 * XXX This should be moved to system catalog lookups
1014 * to allow for better type extensibility.
1015 * - thomas 2001-09-30
1018 PreferredType(CATEGORY category, Oid type)
1024 case (INVALID_TYPE):
1025 case (UNKNOWN_TYPE):
1026 case (GENERIC_TYPE):
1027 result = UNKNOWNOID;
1030 case (BOOLEAN_TYPE):
1038 case (BITSTRING_TYPE):
1042 case (NUMERIC_TYPE):
1043 if (type == OIDOID ||
1044 type == REGPROCOID ||
1045 type == REGPROCEDUREOID ||
1046 type == REGOPEROID ||
1047 type == REGOPERATOROID ||
1048 type == REGCLASSOID ||
1055 case (DATETIME_TYPE):
1056 if (type == DATEOID)
1057 result = TIMESTAMPOID;
1059 result = TIMESTAMPTZOID;
1062 case (TIMESPAN_TYPE):
1063 result = INTERVALOID;
1066 case (GEOMETRIC_TYPE):
1070 case (NETWORK_TYPE):
1079 elog(ERROR, "PreferredType: unknown category");
1080 result = UNKNOWNOID;
1084 } /* PreferredType() */
1087 /* IsBinaryCoercible()
1088 * Check if srctype is binary-coercible to targettype.
1090 * This notion allows us to cheat and directly exchange values without
1091 * going through the trouble of calling a conversion function.
1093 * As of 7.3, binary coercibility isn't hardwired into the code anymore.
1094 * We consider two types binary-coercible if there is an implicitly
1095 * invokable, no-function-needed pg_cast entry.
1097 * This function replaces IsBinaryCompatible(), which was an inherently
1098 * symmetric test. Since the pg_cast entries aren't necessarily symmetric,
1099 * the order of the operands is now significant.
1102 IsBinaryCoercible(Oid srctype, Oid targettype)
1105 Form_pg_cast castForm;
1108 /* Fast path if same type */
1109 if (srctype == targettype)
1112 /* Perhaps the types are domains; if so, look at their base types */
1113 if (OidIsValid(srctype))
1114 srctype = getBaseType(srctype);
1115 if (OidIsValid(targettype))
1116 targettype = getBaseType(targettype);
1118 /* Somewhat-fast path if same base type */
1119 if (srctype == targettype)
1122 /* Else look in pg_cast */
1123 tuple = SearchSysCache(CASTSOURCETARGET,
1124 ObjectIdGetDatum(srctype),
1125 ObjectIdGetDatum(targettype),
1127 if (!HeapTupleIsValid(tuple))
1128 return false; /* no cast */
1129 castForm = (Form_pg_cast) GETSTRUCT(tuple);
1131 result = (castForm->castfunc == InvalidOid &&
1132 castForm->castcontext == COERCION_CODE_IMPLICIT);
1134 ReleaseSysCache(tuple);
1141 * find_coercion_pathway
1142 * Look for a coercion pathway between two types.
1144 * ccontext determines the set of available casts.
1146 * If we find a suitable entry in pg_cast, return TRUE, and set *funcid
1147 * to the castfunc value (which may be InvalidOid for a binary-compatible
1151 find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
1152 CoercionContext ccontext,
1155 bool result = false;
1158 *funcid = InvalidOid;
1160 /* Perhaps the types are domains; if so, look at their base types */
1161 if (OidIsValid(sourceTypeId))
1162 sourceTypeId = getBaseType(sourceTypeId);
1163 if (OidIsValid(targetTypeId))
1164 targetTypeId = getBaseType(targetTypeId);
1166 /* Domains are automatically binary-compatible with their base type */
1167 if (sourceTypeId == targetTypeId)
1170 /* Look in pg_cast */
1171 tuple = SearchSysCache(CASTSOURCETARGET,
1172 ObjectIdGetDatum(sourceTypeId),
1173 ObjectIdGetDatum(targetTypeId),
1176 if (HeapTupleIsValid(tuple))
1178 Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
1179 CoercionContext castcontext;
1181 /* convert char value for castcontext to CoercionContext enum */
1182 switch (castForm->castcontext)
1184 case COERCION_CODE_IMPLICIT:
1185 castcontext = COERCION_IMPLICIT;
1187 case COERCION_CODE_ASSIGNMENT:
1188 castcontext = COERCION_ASSIGNMENT;
1190 case COERCION_CODE_EXPLICIT:
1191 castcontext = COERCION_EXPLICIT;
1194 elog(ERROR, "find_coercion_pathway: bogus castcontext %c",
1195 castForm->castcontext);
1196 castcontext = 0; /* keep compiler quiet */
1200 /* Rely on ordering of enum for correct behavior here */
1201 if (ccontext >= castcontext)
1203 *funcid = castForm->castfunc;
1207 ReleaseSysCache(tuple);
1212 * If there's no pg_cast entry, perhaps we are dealing with a
1213 * pair of array types. If so, and if the element types have
1214 * a suitable cast, use array_type_coerce().
1220 if ((targetElemType = get_element_type(targetTypeId)) != InvalidOid &&
1221 (sourceElemType = get_element_type(sourceTypeId)) != InvalidOid)
1223 if (find_coercion_pathway(targetElemType, sourceElemType,
1224 ccontext, &elemfuncid))
1226 *funcid = F_ARRAY_TYPE_COERCE;
1237 * find_typmod_coercion_function -- does the given type need length coercion?
1239 * If the target type possesses a function named for the type
1240 * and having parameter signature (targettype, int4), we assume that
1241 * the type requires coercion to its own length and that the said
1242 * function should be invoked to do that.
1244 * Alternatively, the length-coercing function may have the signature
1245 * (targettype, int4, bool). On success, *nargs is set to report which
1246 * signature we found.
1248 * "bpchar" (ie, char(N)) and "numeric" are examples of such types.
1250 * If the given type is a varlena array type, we do not look for a coercion
1251 * function associated directly with the array type, but instead look for
1252 * one associated with the element type. If one exists, we report
1253 * array_length_coerce() as the coercion function to use.
1255 * This mechanism may seem pretty grotty and in need of replacement by
1256 * something in pg_cast, but since typmod is only interesting for datatypes
1257 * that have special handling in the grammar, there's not really much
1258 * percentage in making it any easier to apply such coercions ...
1261 find_typmod_coercion_function(Oid typeId, int *nargs)
1263 Oid funcid = InvalidOid;
1264 bool isArray = false;
1266 Form_pg_type typeForm;
1269 Oid oid_array[FUNC_MAX_ARGS];
1272 targetType = typeidType(typeId);
1273 typeForm = (Form_pg_type) GETSTRUCT(targetType);
1275 /* Check for a varlena array type (and not a domain) */
1276 if (typeForm->typelem != InvalidOid &&
1277 typeForm->typlen == -1 &&
1278 typeForm->typtype != 'd')
1280 /* Yes, switch our attention to the element type */
1281 typeId = typeForm->typelem;
1282 ReleaseSysCache(targetType);
1283 targetType = typeidType(typeId);
1284 typeForm = (Form_pg_type) GETSTRUCT(targetType);
1288 /* Function name is same as type internal name, and in same namespace */
1289 typname = NameStr(typeForm->typname);
1290 typnamespace = typeForm->typnamespace;
1292 /* First look for parameters (type, int4) */
1293 MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
1294 oid_array[0] = typeId;
1295 oid_array[1] = INT4OID;
1298 ftup = SearchSysCache(PROCNAMENSP,
1299 CStringGetDatum(typname),
1301 PointerGetDatum(oid_array),
1302 ObjectIdGetDatum(typnamespace));
1303 if (HeapTupleIsValid(ftup))
1305 Form_pg_proc pform = (Form_pg_proc) GETSTRUCT(ftup);
1307 /* Make sure the function's result type is as expected */
1308 if (pform->prorettype == typeId && !pform->proretset &&
1311 /* Okay to use it */
1312 funcid = HeapTupleGetOid(ftup);
1314 ReleaseSysCache(ftup);
1317 if (!OidIsValid(funcid))
1319 /* Didn't find a function, so now try (type, int4, bool) */
1320 oid_array[2] = BOOLOID;
1323 ftup = SearchSysCache(PROCNAMENSP,
1324 CStringGetDatum(typname),
1326 PointerGetDatum(oid_array),
1327 ObjectIdGetDatum(typnamespace));
1328 if (HeapTupleIsValid(ftup))
1330 Form_pg_proc pform = (Form_pg_proc) GETSTRUCT(ftup);
1332 /* Make sure the function's result type is as expected */
1333 if (pform->prorettype == typeId && !pform->proretset &&
1336 /* Okay to use it */
1337 funcid = HeapTupleGetOid(ftup);
1339 ReleaseSysCache(ftup);
1343 ReleaseSysCache(targetType);
1346 * Now, if we did find a coercion function for an array element type,
1347 * report array_length_coerce() as the function to use. We know it
1348 * takes three arguments always.
1350 if (isArray && OidIsValid(funcid))
1352 funcid = F_ARRAY_LENGTH_COERCE;
1360 * Build an expression tree representing a function call.
1362 * The argument expressions must have been transformed already.
1365 build_func_call(Oid funcid, Oid rettype, List *args, CoercionForm fformat)
1369 funcexpr = makeNode(FuncExpr);
1370 funcexpr->funcid = funcid;
1371 funcexpr->funcresulttype = rettype;
1372 funcexpr->funcretset = false; /* only possible case here */
1373 funcexpr->funcformat = fformat;
1374 funcexpr->args = args;
1376 return (Node *) funcexpr;