1 /*-------------------------------------------------------------------------
4 * handle type coercions/conversions for parser
6 * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.144 2006/10/04 00:29:55 momjian Exp $
13 *-------------------------------------------------------------------------
17 #include "catalog/pg_cast.h"
18 #include "catalog/pg_proc.h"
19 #include "catalog/pg_type.h"
20 #include "nodes/makefuncs.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_relation.h"
26 #include "parser/parse_type.h"
27 #include "utils/builtins.h"
28 #include "utils/fmgroids.h"
29 #include "utils/lsyscache.h"
30 #include "utils/syscache.h"
31 #include "utils/typcache.h"
34 static Node *coerce_type_typmod(Node *node,
35 Oid targetTypeId, int32 targetTypMod,
36 CoercionForm cformat, bool isExplicit,
37 bool hideInputCoercion);
38 static void hide_coercion_node(Node *node);
39 static Node *build_coercion_expression(Node *node, Oid funcId,
40 Oid targetTypeId, int32 targetTypMod,
41 CoercionForm cformat, bool isExplicit);
42 static Node *coerce_record_to_complex(ParseState *pstate, Node *node,
44 CoercionContext ccontext,
45 CoercionForm cformat);
49 * coerce_to_target_type()
50 * Convert an expression to a target type and typmod.
52 * This is the general-purpose entry point for arbitrary type coercion
53 * operations. Direct use of the component operations can_coerce_type,
54 * coerce_type, and coerce_type_typmod should be restricted to special
55 * cases (eg, when the conversion is expected to succeed).
57 * Returns the possibly-transformed expression tree, or NULL if the type
58 * conversion is not possible. (We do this, rather than ereport'ing directly,
59 * so that callers can generate custom error messages indicating context.)
61 * pstate - parse state (can be NULL, see coerce_type)
62 * expr - input expression tree (already transformed by transformExpr)
63 * exprtype - result type of expr
64 * targettype - desired result type
65 * targettypmod - desired result typmod
66 * ccontext, cformat - context indicators to control coercions
69 coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype,
70 Oid targettype, int32 targettypmod,
71 CoercionContext ccontext,
76 if (!can_coerce_type(1, &exprtype, &targettype, ccontext))
79 result = coerce_type(pstate, expr, exprtype,
80 targettype, targettypmod,
84 * If the target is a fixed-length type, it may need a length coercion as
85 * well as a type coercion. If we find ourselves adding both, force the
86 * inner coercion node to implicit display form.
88 result = coerce_type_typmod(result,
89 targettype, targettypmod,
91 (cformat != COERCE_IMPLICIT_CAST),
92 (result != expr && !IsA(result, Const)));
100 * Convert an expression to a different type.
102 * The caller should already have determined that the coercion is possible;
103 * see can_coerce_type.
105 * Normally, no coercion to a typmod (length) is performed here. The caller
106 * must call coerce_type_typmod as well, if a typmod constraint is wanted.
107 * (But if the target type is a domain, it may internally contain a
108 * typmod constraint, which will be applied inside coerce_to_domain.)
109 * In some cases pg_cast specifies a type coercion function that also
110 * applies length conversion, and in those cases only, the result will
111 * already be properly coerced to the specified typmod.
113 * pstate is only used in the case that we are able to resolve the type of
114 * a previously UNKNOWN Param. It is okay to pass pstate = NULL if the
115 * caller does not want type information updated for Params.
118 coerce_type(ParseState *pstate, Node *node,
119 Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod,
120 CoercionContext ccontext, CoercionForm cformat)
125 if (targetTypeId == inputTypeId ||
128 /* no conversion needed */
131 if (targetTypeId == ANYOID ||
132 targetTypeId == ANYARRAYOID ||
133 targetTypeId == ANYELEMENTOID)
135 /* assume can_coerce_type verified that implicit coercion is okay */
136 /* NB: we do NOT want a RelabelType here */
139 if (inputTypeId == UNKNOWNOID && IsA(node, Const))
142 * Input is a string constant with previously undetermined type. Apply
143 * the target type's typinput function to it to produce a constant of
146 * NOTE: this case cannot be folded together with the other
147 * constant-input case, since the typinput function does not
148 * necessarily behave the same as a type conversion function. For
149 * example, int4's typinput function will reject "1.2", whereas
150 * float-to-int type conversion will round to integer.
152 * XXX if the typinput function is not immutable, we really ought to
153 * postpone evaluation of the function call until runtime. But there
154 * is no way to represent a typinput function call as an expression
155 * tree, because C-string values are not Datums. (XXX This *is*
156 * possible as of 7.3, do we want to do it?)
158 Const *con = (Const *) node;
159 Const *newcon = makeNode(Const);
165 * If the target type is a domain, we want to call its base type's
166 * input routine, not domain_in(). This is to avoid premature failure
167 * when the domain applies a typmod: existing input routines follow
168 * implicit-coercion semantics for length checks, which is not always
169 * what we want here. The needed check will be applied properly
170 * inside coerce_to_domain().
173 baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
175 targetType = typeidType(baseTypeId);
177 newcon->consttype = baseTypeId;
178 newcon->constlen = typeLen(targetType);
179 newcon->constbyval = typeByVal(targetType);
180 newcon->constisnull = con->constisnull;
183 * We pass typmod -1 to the input routine, primarily because existing
184 * input routines follow implicit-coercion semantics for length
185 * checks, which is not always what we want here. Any length
186 * constraint will be applied later by our caller.
188 * We assume here that UNKNOWN's internal representation is the same
191 if (!con->constisnull)
192 newcon->constvalue = stringTypeDatum(targetType,
193 DatumGetCString(con->constvalue),
196 newcon->constvalue = stringTypeDatum(targetType, NULL, -1);
198 result = (Node *) newcon;
200 /* If target is a domain, apply constraints. */
201 if (baseTypeId != targetTypeId)
202 result = coerce_to_domain(result,
203 baseTypeId, baseTypeMod,
205 cformat, false, false);
207 ReleaseSysCache(targetType);
211 if (inputTypeId == UNKNOWNOID && IsA(node, Param) &&
212 ((Param *) node)->paramkind == PARAM_EXTERN &&
213 pstate != NULL && pstate->p_variableparams)
216 * Input is a Param of previously undetermined type, and we want to
217 * update our knowledge of the Param's type. Find the topmost
218 * ParseState and update the state.
220 Param *param = (Param *) node;
221 int paramno = param->paramid;
222 ParseState *toppstate;
225 while (toppstate->parentParseState != NULL)
226 toppstate = toppstate->parentParseState;
228 if (paramno <= 0 || /* shouldn't happen, but... */
229 paramno > toppstate->p_numparams)
231 (errcode(ERRCODE_UNDEFINED_PARAMETER),
232 errmsg("there is no parameter $%d", paramno)));
234 if (toppstate->p_paramtypes[paramno - 1] == UNKNOWNOID)
236 /* We've successfully resolved the type */
237 toppstate->p_paramtypes[paramno - 1] = targetTypeId;
239 else if (toppstate->p_paramtypes[paramno - 1] == targetTypeId)
241 /* We previously resolved the type, and it matches */
247 (errcode(ERRCODE_AMBIGUOUS_PARAMETER),
248 errmsg("inconsistent types deduced for parameter $%d",
250 errdetail("%s versus %s",
251 format_type_be(toppstate->p_paramtypes[paramno - 1]),
252 format_type_be(targetTypeId))));
255 param->paramtype = targetTypeId;
257 return (Node *) param;
259 if (find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
262 if (OidIsValid(funcId))
265 * Generate an expression tree representing run-time application
266 * of the conversion function. If we are dealing with a domain
267 * target type, the conversion function will yield the base type,
268 * and we need to extract the correct typmod to use from the
269 * domain's typtypmod.
274 baseTypeMod = targetTypeMod;
275 baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
277 result = build_coercion_expression(node, funcId,
278 baseTypeId, baseTypeMod,
280 (cformat != COERCE_IMPLICIT_CAST));
283 * If domain, coerce to the domain type and relabel with domain
284 * type ID. We can skip the internal length-coercion step if the
285 * selected coercion function was a type-and-length coercion.
287 if (targetTypeId != baseTypeId)
288 result = coerce_to_domain(result, baseTypeId, baseTypeMod,
291 exprIsLengthCoercion(result,
297 * We don't need to do a physical conversion, but we do need to
298 * attach a RelabelType node so that the expression will be seen
299 * to have the intended type when inspected by higher-level code.
301 * Also, domains may have value restrictions beyond the base type
302 * that must be accounted for. If the destination is a domain
303 * then we won't need a RelabelType node.
305 result = coerce_to_domain(node, InvalidOid, -1, targetTypeId,
306 cformat, false, false);
310 * XXX could we label result with exprTypmod(node) instead of
311 * default -1 typmod, to save a possible length-coercion
312 * later? Would work if both types have same interpretation of
313 * typmod, which is likely but not certain.
315 result = (Node *) makeRelabelType((Expr *) result,
322 if (inputTypeId == RECORDOID &&
323 ISCOMPLEX(targetTypeId))
325 /* Coerce a RECORD to a specific complex type */
326 return coerce_record_to_complex(pstate, node, targetTypeId,
329 if (targetTypeId == RECORDOID &&
330 ISCOMPLEX(inputTypeId))
332 /* Coerce a specific complex type to RECORD */
333 /* NB: we do NOT want a RelabelType here */
336 if (typeInheritsFrom(inputTypeId, targetTypeId))
339 * Input class type is a subclass of target, so generate an
340 * appropriate runtime conversion (removing unneeded columns and
341 * possibly rearranging the ones that are wanted).
343 ConvertRowtypeExpr *r = makeNode(ConvertRowtypeExpr);
345 r->arg = (Expr *) node;
346 r->resulttype = targetTypeId;
347 r->convertformat = cformat;
350 /* If we get here, caller blew it */
351 elog(ERROR, "failed to find conversion function from %s to %s",
352 format_type_be(inputTypeId), format_type_be(targetTypeId));
353 return NULL; /* keep compiler quiet */
359 * Can input_typeids be coerced to target_typeids?
361 * We must be told the context (CAST construct, assignment, implicit coercion)
362 * as this determines the set of available casts.
365 can_coerce_type(int nargs, Oid *input_typeids, Oid *target_typeids,
366 CoercionContext ccontext)
368 bool have_generics = false;
371 /* run through argument list... */
372 for (i = 0; i < nargs; i++)
374 Oid inputTypeId = input_typeids[i];
375 Oid targetTypeId = target_typeids[i];
378 /* no problem if same type */
379 if (inputTypeId == targetTypeId)
382 /* accept if target is ANY */
383 if (targetTypeId == ANYOID)
386 /* accept if target is ANYARRAY or ANYELEMENT, for now */
387 if (targetTypeId == ANYARRAYOID ||
388 targetTypeId == ANYELEMENTOID)
390 have_generics = true; /* do more checking later */
395 * If input is an untyped string constant, assume we can convert it to
398 if (inputTypeId == UNKNOWNOID)
402 * If pg_cast shows that we can coerce, accept. This test now covers
403 * both binary-compatible and coercion-function cases.
405 if (find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
410 * If input is RECORD and target is a composite type, assume we can
411 * coerce (may need tighter checking here)
413 if (inputTypeId == RECORDOID &&
414 ISCOMPLEX(targetTypeId))
418 * If input is a composite type and target is RECORD, accept
420 if (targetTypeId == RECORDOID &&
421 ISCOMPLEX(inputTypeId))
425 * If input is a class type that inherits from target, accept
427 if (typeInheritsFrom(inputTypeId, targetTypeId))
431 * Else, cannot coerce at this argument position
436 /* If we found any generic argument types, cross-check them */
439 if (!check_generic_type_consistency(input_typeids, target_typeids,
449 * Create an expression tree to represent coercion to a domain type.
451 * 'arg': input expression
452 * 'baseTypeId': base type of domain, if known (pass InvalidOid if caller
453 * has not bothered to look this up)
454 * 'baseTypeMod': base type typmod of domain, if known (pass -1 if caller
455 * has not bothered to look this up)
456 * 'typeId': target type to coerce to
457 * 'cformat': coercion format
458 * 'hideInputCoercion': if true, hide the input coercion under this one.
459 * 'lengthCoercionDone': if true, caller already accounted for length,
460 * ie the input is already of baseTypMod as well as baseTypeId.
462 * If the target type isn't a domain, the given 'arg' is returned as-is.
465 coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId,
466 CoercionForm cformat, bool hideInputCoercion,
467 bool lengthCoercionDone)
469 CoerceToDomain *result;
471 /* Get the base type if it hasn't been supplied */
472 if (baseTypeId == InvalidOid)
473 baseTypeId = getBaseTypeAndTypmod(typeId, &baseTypeMod);
475 /* If it isn't a domain, return the node as it was passed in */
476 if (baseTypeId == typeId)
479 /* Suppress display of nested coercion steps */
480 if (hideInputCoercion)
481 hide_coercion_node(arg);
484 * If the domain applies a typmod to its base type, build the appropriate
485 * coercion step. Mark it implicit for display purposes, because we don't
486 * want it shown separately by ruleutils.c; but the isExplicit flag passed
487 * to the conversion function depends on the manner in which the domain
488 * coercion is invoked, so that the semantics of implicit and explicit
489 * coercion differ. (Is that really the behavior we want?)
491 * NOTE: because we apply this as part of the fixed expression structure,
492 * ALTER DOMAIN cannot alter the typtypmod. But it's unclear that that
493 * would be safe to do anyway, without lots of knowledge about what the
494 * base type thinks the typmod means.
496 if (!lengthCoercionDone)
498 if (baseTypeMod >= 0)
499 arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod,
500 COERCE_IMPLICIT_CAST,
501 (cformat != COERCE_IMPLICIT_CAST),
506 * Now build the domain coercion node. This represents run-time checking
507 * of any constraints currently attached to the domain. This also ensures
508 * that the expression is properly labeled as to result type.
510 result = makeNode(CoerceToDomain);
511 result->arg = (Expr *) arg;
512 result->resulttype = typeId;
513 result->resulttypmod = -1; /* currently, always -1 for domains */
514 result->coercionformat = cformat;
516 return (Node *) result;
521 * coerce_type_typmod()
522 * Force a value to a particular typmod, if meaningful and possible.
524 * This is applied to values that are going to be stored in a relation
525 * (where we have an atttypmod for the column) as well as values being
526 * explicitly CASTed (where the typmod comes from the target type spec).
528 * The caller must have already ensured that the value is of the correct
529 * type, typically by applying coerce_type.
531 * cformat determines the display properties of the generated node (if any),
532 * while isExplicit may affect semantics. If hideInputCoercion is true
533 * *and* we generate a node, the input node is forced to IMPLICIT display
534 * form, so that only the typmod coercion node will be visible when
535 * displaying the expression.
537 * NOTE: this does not need to work on domain types, because any typmod
538 * coercion for a domain is considered to be part of the type coercion
539 * needed to produce the domain value in the first place. So, no getBaseType.
542 coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod,
543 CoercionForm cformat, bool isExplicit,
544 bool hideInputCoercion)
549 * A negative typmod is assumed to mean that no coercion is wanted. Also,
550 * skip coercion if already done.
552 if (targetTypMod < 0 || targetTypMod == exprTypmod(node))
555 funcId = find_typmod_coercion_function(targetTypeId);
557 if (OidIsValid(funcId))
559 /* Suppress display of nested coercion steps */
560 if (hideInputCoercion)
561 hide_coercion_node(node);
563 node = build_coercion_expression(node, funcId,
564 targetTypeId, targetTypMod,
565 cformat, isExplicit);
572 * Mark a coercion node as IMPLICIT so it will never be displayed by
573 * ruleutils.c. We use this when we generate a nest of coercion nodes
574 * to implement what is logically one conversion; the inner nodes are
575 * forced to IMPLICIT_CAST format. This does not change their semantics,
576 * only display behavior.
578 * It is caller error to call this on something that doesn't have a
579 * CoercionForm field.
582 hide_coercion_node(Node *node)
584 if (IsA(node, FuncExpr))
585 ((FuncExpr *) node)->funcformat = COERCE_IMPLICIT_CAST;
586 else if (IsA(node, RelabelType))
587 ((RelabelType *) node)->relabelformat = COERCE_IMPLICIT_CAST;
588 else if (IsA(node, ConvertRowtypeExpr))
589 ((ConvertRowtypeExpr *) node)->convertformat = COERCE_IMPLICIT_CAST;
590 else if (IsA(node, RowExpr))
591 ((RowExpr *) node)->row_format = COERCE_IMPLICIT_CAST;
592 else if (IsA(node, CoerceToDomain))
593 ((CoerceToDomain *) node)->coercionformat = COERCE_IMPLICIT_CAST;
595 elog(ERROR, "unsupported node type: %d", (int) nodeTag(node));
599 * build_coercion_expression()
600 * Construct a function-call expression for applying a pg_cast entry.
602 * This is used for both type-coercion and length-coercion functions,
603 * since there is no difference in terms of the calling convention.
606 build_coercion_expression(Node *node, Oid funcId,
607 Oid targetTypeId, int32 targetTypMod,
608 CoercionForm cformat, bool isExplicit)
611 Form_pg_proc procstruct;
616 tp = SearchSysCache(PROCOID,
617 ObjectIdGetDatum(funcId),
619 if (!HeapTupleIsValid(tp))
620 elog(ERROR, "cache lookup failed for function %u", funcId);
621 procstruct = (Form_pg_proc) GETSTRUCT(tp);
624 * Asserts essentially check that function is a legal coercion function.
625 * We can't make the seemingly obvious tests on prorettype and
626 * proargtypes[0], because of various binary-compatibility cases.
628 /* Assert(targetTypeId == procstruct->prorettype); */
629 Assert(!procstruct->proretset);
630 Assert(!procstruct->proisagg);
631 nargs = procstruct->pronargs;
632 Assert(nargs >= 1 && nargs <= 3);
633 /* Assert(procstruct->proargtypes.values[0] == exprType(node)); */
634 Assert(nargs < 2 || procstruct->proargtypes.values[1] == INT4OID);
635 Assert(nargs < 3 || procstruct->proargtypes.values[2] == BOOLOID);
639 args = list_make1(node);
643 /* Pass target typmod as an int4 constant */
644 cons = makeConst(INT4OID,
646 Int32GetDatum(targetTypMod),
650 args = lappend(args, cons);
655 /* Pass it a boolean isExplicit parameter, too */
656 cons = makeConst(BOOLOID,
658 BoolGetDatum(isExplicit),
662 args = lappend(args, cons);
665 return (Node *) makeFuncExpr(funcId, targetTypeId, args, cformat);
670 * coerce_record_to_complex
671 * Coerce a RECORD to a specific composite type.
673 * Currently we only support this for inputs that are RowExprs or whole-row
677 coerce_record_to_complex(ParseState *pstate, Node *node,
679 CoercionContext ccontext,
680 CoercionForm cformat)
690 if (node && IsA(node, RowExpr))
693 * Since the RowExpr must be of type RECORD, we needn't worry about it
694 * containing any dropped columns.
696 args = ((RowExpr *) node)->args;
698 else if (node && IsA(node, Var) &&
699 ((Var *) node)->varattno == InvalidAttrNumber)
701 int rtindex = ((Var *) node)->varno;
702 int sublevels_up = ((Var *) node)->varlevelsup;
705 rte = GetRTEByRangeTablePosn(pstate, rtindex, sublevels_up);
706 expandRTE(rte, rtindex, sublevels_up, false,
711 (errcode(ERRCODE_CANNOT_COERCE),
712 errmsg("cannot cast type %s to %s",
713 format_type_be(RECORDOID),
714 format_type_be(targetTypeId))));
716 tupdesc = lookup_rowtype_tupdesc(targetTypeId, -1);
719 arg = list_head(args);
720 for (i = 0; i < tupdesc->natts; i++)
725 /* Fill in NULLs for dropped columns in rowtype */
726 if (tupdesc->attrs[i]->attisdropped)
729 * can't use atttypid here, but it doesn't really matter what type
730 * the Const claims to be.
732 newargs = lappend(newargs, makeNullConst(INT4OID));
738 (errcode(ERRCODE_CANNOT_COERCE),
739 errmsg("cannot cast type %s to %s",
740 format_type_be(RECORDOID),
741 format_type_be(targetTypeId)),
742 errdetail("Input has too few columns.")));
743 expr = (Node *) lfirst(arg);
744 exprtype = exprType(expr);
746 expr = coerce_to_target_type(pstate,
748 tupdesc->attrs[i]->atttypid,
749 tupdesc->attrs[i]->atttypmod,
751 COERCE_IMPLICIT_CAST);
754 (errcode(ERRCODE_CANNOT_COERCE),
755 errmsg("cannot cast type %s to %s",
756 format_type_be(RECORDOID),
757 format_type_be(targetTypeId)),
758 errdetail("Cannot cast type %s to %s in column %d.",
759 format_type_be(exprtype),
760 format_type_be(tupdesc->attrs[i]->atttypid),
762 newargs = lappend(newargs, expr);
768 (errcode(ERRCODE_CANNOT_COERCE),
769 errmsg("cannot cast type %s to %s",
770 format_type_be(RECORDOID),
771 format_type_be(targetTypeId)),
772 errdetail("Input has too many columns.")));
774 ReleaseTupleDesc(tupdesc);
776 rowexpr = makeNode(RowExpr);
777 rowexpr->args = newargs;
778 rowexpr->row_typeid = targetTypeId;
779 rowexpr->row_format = cformat;
780 return (Node *) rowexpr;
784 * coerce_to_boolean()
785 * Coerce an argument of a construct that requires boolean input
786 * (AND, OR, NOT, etc). Also check that input is not a set.
788 * Returns the possibly-transformed node tree.
790 * As with coerce_type, pstate may be NULL if no special unknown-Param
791 * processing is wanted.
794 coerce_to_boolean(ParseState *pstate, Node *node,
795 const char *constructName)
797 Oid inputTypeId = exprType(node);
799 if (inputTypeId != BOOLOID)
801 node = coerce_to_target_type(pstate, node, inputTypeId,
804 COERCE_IMPLICIT_CAST);
807 (errcode(ERRCODE_DATATYPE_MISMATCH),
808 /* translator: first %s is name of a SQL construct, eg WHERE */
809 errmsg("argument of %s must be type boolean, not type %s",
810 constructName, format_type_be(inputTypeId))));
813 if (expression_returns_set(node))
815 (errcode(ERRCODE_DATATYPE_MISMATCH),
816 /* translator: %s is name of a SQL construct, eg WHERE */
817 errmsg("argument of %s must not return a set",
824 * coerce_to_integer()
825 * Coerce an argument of a construct that requires integer input.
826 * Also check that input is not a set.
828 * Returns the possibly-transformed node tree.
830 * As with coerce_type, pstate may be NULL if no special unknown-Param
831 * processing is wanted.
834 coerce_to_integer(ParseState *pstate, Node *node,
835 const char *constructName)
837 Oid inputTypeId = exprType(node);
839 if (inputTypeId != INT4OID)
841 node = coerce_to_target_type(pstate, node, inputTypeId,
844 COERCE_IMPLICIT_CAST);
847 (errcode(ERRCODE_DATATYPE_MISMATCH),
848 /* translator: first %s is name of a SQL construct, eg LIMIT */
849 errmsg("argument of %s must be type integer, not type %s",
850 constructName, format_type_be(inputTypeId))));
853 if (expression_returns_set(node))
855 (errcode(ERRCODE_DATATYPE_MISMATCH),
856 /* translator: %s is name of a SQL construct, eg LIMIT */
857 errmsg("argument of %s must not return a set",
865 * Coerce an argument of a construct that requires int8 input.
866 * Also check that input is not a set.
868 * Returns the possibly-transformed node tree.
870 * As with coerce_type, pstate may be NULL if no special unknown-Param
871 * processing is wanted.
874 coerce_to_bigint(ParseState *pstate, Node *node,
875 const char *constructName)
877 Oid inputTypeId = exprType(node);
879 if (inputTypeId != INT8OID)
881 node = coerce_to_target_type(pstate, node, inputTypeId,
884 COERCE_IMPLICIT_CAST);
887 (errcode(ERRCODE_DATATYPE_MISMATCH),
888 /* translator: first %s is name of a SQL construct, eg LIMIT */
889 errmsg("argument of %s must be type bigint, not type %s",
890 constructName, format_type_be(inputTypeId))));
893 if (expression_returns_set(node))
895 (errcode(ERRCODE_DATATYPE_MISMATCH),
896 /* translator: %s is name of a SQL construct, eg LIMIT */
897 errmsg("argument of %s must not return a set",
904 /* select_common_type()
905 * Determine the common supertype of a list of input expression types.
906 * This is used for determining the output type of CASE and UNION
909 * typeids is a nonempty list of type OIDs. Note that earlier items
910 * in the list will be preferred if there is doubt.
911 * 'context' is a phrase to use in the error message if we fail to select
915 select_common_type(List *typeids, const char *context)
921 Assert(typeids != NIL);
922 ptype = getBaseType(linitial_oid(typeids));
923 pcategory = TypeCategory(ptype);
925 for_each_cell(type_item, lnext(list_head(typeids)))
927 Oid ntype = getBaseType(lfirst_oid(type_item));
929 /* move on to next one if no new information... */
930 if ((ntype != InvalidOid) && (ntype != UNKNOWNOID) && (ntype != ptype))
932 if ((ptype == InvalidOid) || ptype == UNKNOWNOID)
934 /* so far, only nulls so take anything... */
936 pcategory = TypeCategory(ptype);
938 else if (TypeCategory(ntype) != pcategory)
941 * both types in different categories? then not much hope...
944 (errcode(ERRCODE_DATATYPE_MISMATCH),
947 * translator: first %s is name of a SQL construct, eg CASE
949 errmsg("%s types %s and %s cannot be matched",
951 format_type_be(ptype),
952 format_type_be(ntype))));
954 else if (!IsPreferredType(pcategory, ptype) &&
955 can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
956 !can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
959 * take new type if can coerce to it implicitly but not the
960 * other way; but if we have a preferred type, stay on it.
963 pcategory = TypeCategory(ptype);
969 * If all the inputs were UNKNOWN type --- ie, unknown-type literals ---
970 * then resolve as type TEXT. This situation comes up with constructs
971 * like SELECT (CASE WHEN foo THEN 'bar' ELSE 'baz' END); SELECT 'foo'
972 * UNION SELECT 'bar'; It might seem desirable to leave the construct's
973 * output type as UNKNOWN, but that really doesn't work, because we'd
974 * probably end up needing a runtime coercion from UNKNOWN to something
975 * else, and we usually won't have it. We need to coerce the unknown
976 * literals while they are still literals, so a decision has to be made
979 if (ptype == UNKNOWNOID)
985 /* coerce_to_common_type()
986 * Coerce an expression to the given type.
988 * This is used following select_common_type() to coerce the individual
989 * expressions to the desired type. 'context' is a phrase to use in the
990 * error message if we fail to coerce.
992 * As with coerce_type, pstate may be NULL if no special unknown-Param
993 * processing is wanted.
996 coerce_to_common_type(ParseState *pstate, Node *node,
997 Oid targetTypeId, const char *context)
999 Oid inputTypeId = exprType(node);
1001 if (inputTypeId == targetTypeId)
1002 return node; /* no work */
1003 if (can_coerce_type(1, &inputTypeId, &targetTypeId, COERCION_IMPLICIT))
1004 node = coerce_type(pstate, node, inputTypeId, targetTypeId, -1,
1005 COERCION_IMPLICIT, COERCE_IMPLICIT_CAST);
1008 (errcode(ERRCODE_CANNOT_COERCE),
1009 /* translator: first %s is name of a SQL construct, eg CASE */
1010 errmsg("%s could not convert type %s to %s",
1012 format_type_be(inputTypeId),
1013 format_type_be(targetTypeId))));
1018 * check_generic_type_consistency()
1019 * Are the actual arguments potentially compatible with a
1020 * polymorphic function?
1022 * The argument consistency rules are:
1024 * 1) All arguments declared ANYARRAY must have matching datatypes,
1025 * and must in fact be varlena arrays.
1026 * 2) All arguments declared ANYELEMENT must have matching datatypes.
1027 * 3) If there are arguments of both ANYELEMENT and ANYARRAY, make sure
1028 * the actual ANYELEMENT datatype is in fact the element type for
1029 * the actual ANYARRAY datatype.
1031 * If we have UNKNOWN input (ie, an untyped literal) for any ANYELEMENT
1032 * or ANYARRAY argument, assume it is okay.
1034 * If an input is of type ANYARRAY (ie, we know it's an array, but not
1035 * what element type), we will accept it as a match to an argument declared
1036 * ANYARRAY, so long as we don't have to determine an element type ---
1037 * that is, so long as there is no use of ANYELEMENT. This is mostly for
1038 * backwards compatibility with the pre-7.4 behavior of ANYARRAY.
1040 * We do not ereport here, but just return FALSE if a rule is violated.
1043 check_generic_type_consistency(Oid *actual_arg_types,
1044 Oid *declared_arg_types,
1048 Oid elem_typeid = InvalidOid;
1049 Oid array_typeid = InvalidOid;
1051 bool have_anyelement = false;
1054 * Loop through the arguments to see if we have any that are ANYARRAY or
1055 * ANYELEMENT. If so, require the actual types to be self-consistent
1057 for (j = 0; j < nargs; j++)
1059 Oid actual_type = actual_arg_types[j];
1061 if (declared_arg_types[j] == ANYELEMENTOID)
1063 have_anyelement = true;
1064 if (actual_type == UNKNOWNOID)
1066 if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
1068 elem_typeid = actual_type;
1070 else if (declared_arg_types[j] == ANYARRAYOID)
1072 if (actual_type == UNKNOWNOID)
1074 if (OidIsValid(array_typeid) && actual_type != array_typeid)
1076 array_typeid = actual_type;
1080 /* Get the element type based on the array type, if we have one */
1081 if (OidIsValid(array_typeid))
1083 if (array_typeid == ANYARRAYOID)
1085 /* Special case for ANYARRAY input: okay iff no ANYELEMENT */
1086 if (have_anyelement)
1091 array_typelem = get_element_type(array_typeid);
1092 if (!OidIsValid(array_typelem))
1093 return false; /* should be an array, but isn't */
1095 if (!OidIsValid(elem_typeid))
1098 * if we don't have an element type yet, use the one we just got
1100 elem_typeid = array_typelem;
1102 else if (array_typelem != elem_typeid)
1104 /* otherwise, they better match */
1114 * enforce_generic_type_consistency()
1115 * Make sure a polymorphic function is legally callable, and
1116 * deduce actual argument and result types.
1118 * If ANYARRAY or ANYELEMENT is used for a function's arguments or
1119 * return type, we make sure the actual data types are consistent with
1120 * each other. The argument consistency rules are shown above for
1121 * check_generic_type_consistency().
1123 * If we have UNKNOWN input (ie, an untyped literal) for any ANYELEMENT
1124 * or ANYARRAY argument, we attempt to deduce the actual type it should
1125 * have. If successful, we alter that position of declared_arg_types[]
1126 * so that make_fn_arguments will coerce the literal to the right thing.
1128 * Rules are applied to the function's return type (possibly altering it)
1129 * if it is declared ANYARRAY or ANYELEMENT:
1131 * 1) If return type is ANYARRAY, and any argument is ANYARRAY, use the
1132 * argument's actual type as the function's return type.
1133 * 2) If return type is ANYARRAY, no argument is ANYARRAY, but any argument
1134 * is ANYELEMENT, use the actual type of the argument to determine
1135 * the function's return type, i.e. the element type's corresponding
1137 * 3) If return type is ANYARRAY, no argument is ANYARRAY or ANYELEMENT,
1138 * generate an ERROR. This condition is prevented by CREATE FUNCTION
1139 * and is therefore not expected here.
1140 * 4) If return type is ANYELEMENT, and any argument is ANYELEMENT, use the
1141 * argument's actual type as the function's return type.
1142 * 5) If return type is ANYELEMENT, no argument is ANYELEMENT, but any
1143 * argument is ANYARRAY, use the actual type of the argument to determine
1144 * the function's return type, i.e. the array type's corresponding
1146 * 6) If return type is ANYELEMENT, no argument is ANYARRAY or ANYELEMENT,
1147 * generate an ERROR. This condition is prevented by CREATE FUNCTION
1148 * and is therefore not expected here.
1151 enforce_generic_type_consistency(Oid *actual_arg_types,
1152 Oid *declared_arg_types,
1157 bool have_generics = false;
1158 bool have_unknowns = false;
1159 Oid elem_typeid = InvalidOid;
1160 Oid array_typeid = InvalidOid;
1162 bool have_anyelement = (rettype == ANYELEMENTOID);
1165 * Loop through the arguments to see if we have any that are ANYARRAY or
1166 * ANYELEMENT. If so, require the actual types to be self-consistent
1168 for (j = 0; j < nargs; j++)
1170 Oid actual_type = actual_arg_types[j];
1172 if (declared_arg_types[j] == ANYELEMENTOID)
1174 have_generics = have_anyelement = true;
1175 if (actual_type == UNKNOWNOID)
1177 have_unknowns = true;
1180 if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
1182 (errcode(ERRCODE_DATATYPE_MISMATCH),
1183 errmsg("arguments declared \"anyelement\" are not all alike"),
1184 errdetail("%s versus %s",
1185 format_type_be(elem_typeid),
1186 format_type_be(actual_type))));
1187 elem_typeid = actual_type;
1189 else if (declared_arg_types[j] == ANYARRAYOID)
1191 have_generics = true;
1192 if (actual_type == UNKNOWNOID)
1194 have_unknowns = true;
1197 if (OidIsValid(array_typeid) && actual_type != array_typeid)
1199 (errcode(ERRCODE_DATATYPE_MISMATCH),
1200 errmsg("arguments declared \"anyarray\" are not all alike"),
1201 errdetail("%s versus %s",
1202 format_type_be(array_typeid),
1203 format_type_be(actual_type))));
1204 array_typeid = actual_type;
1209 * Fast Track: if none of the arguments are ANYARRAY or ANYELEMENT, return
1210 * the unmodified rettype.
1215 /* Get the element type based on the array type, if we have one */
1216 if (OidIsValid(array_typeid))
1218 if (array_typeid == ANYARRAYOID && !have_anyelement)
1220 /* Special case for ANYARRAY input: okay iff no ANYELEMENT */
1221 array_typelem = InvalidOid;
1225 array_typelem = get_element_type(array_typeid);
1226 if (!OidIsValid(array_typelem))
1228 (errcode(ERRCODE_DATATYPE_MISMATCH),
1229 errmsg("argument declared \"anyarray\" is not an array but type %s",
1230 format_type_be(array_typeid))));
1233 if (!OidIsValid(elem_typeid))
1236 * if we don't have an element type yet, use the one we just got
1238 elem_typeid = array_typelem;
1240 else if (array_typelem != elem_typeid)
1242 /* otherwise, they better match */
1244 (errcode(ERRCODE_DATATYPE_MISMATCH),
1245 errmsg("argument declared \"anyarray\" is not consistent with argument declared \"anyelement\""),
1246 errdetail("%s versus %s",
1247 format_type_be(array_typeid),
1248 format_type_be(elem_typeid))));
1251 else if (!OidIsValid(elem_typeid))
1253 /* Only way to get here is if all the generic args are UNKNOWN */
1255 (errcode(ERRCODE_DATATYPE_MISMATCH),
1256 errmsg("could not determine anyarray/anyelement type because input has type \"unknown\"")));
1260 * If we had any unknown inputs, re-scan to assign correct types
1264 for (j = 0; j < nargs; j++)
1266 Oid actual_type = actual_arg_types[j];
1268 if (actual_type != UNKNOWNOID)
1271 if (declared_arg_types[j] == ANYELEMENTOID)
1272 declared_arg_types[j] = elem_typeid;
1273 else if (declared_arg_types[j] == ANYARRAYOID)
1275 if (!OidIsValid(array_typeid))
1277 array_typeid = get_array_type(elem_typeid);
1278 if (!OidIsValid(array_typeid))
1280 (errcode(ERRCODE_UNDEFINED_OBJECT),
1281 errmsg("could not find array type for data type %s",
1282 format_type_be(elem_typeid))));
1284 declared_arg_types[j] = array_typeid;
1289 /* if we return ANYARRAYOID use the appropriate argument type */
1290 if (rettype == ANYARRAYOID)
1292 if (!OidIsValid(array_typeid))
1294 array_typeid = get_array_type(elem_typeid);
1295 if (!OidIsValid(array_typeid))
1297 (errcode(ERRCODE_UNDEFINED_OBJECT),
1298 errmsg("could not find array type for data type %s",
1299 format_type_be(elem_typeid))));
1301 return array_typeid;
1304 /* if we return ANYELEMENTOID use the appropriate argument type */
1305 if (rettype == ANYELEMENTOID)
1308 /* we don't return a generic type; send back the original return type */
1313 * resolve_generic_type()
1314 * Deduce an individual actual datatype on the assumption that
1315 * the rules for ANYARRAY/ANYELEMENT are being followed.
1317 * declared_type is the declared datatype we want to resolve.
1318 * context_actual_type is the actual input datatype to some argument
1319 * that has declared datatype context_declared_type.
1321 * If declared_type isn't polymorphic, we just return it. Otherwise,
1322 * context_declared_type must be polymorphic, and we deduce the correct
1323 * return type based on the relationship of the two polymorphic types.
1326 resolve_generic_type(Oid declared_type,
1327 Oid context_actual_type,
1328 Oid context_declared_type)
1330 if (declared_type == ANYARRAYOID)
1332 if (context_declared_type == ANYARRAYOID)
1334 /* Use actual type, but it must be an array */
1335 Oid array_typelem = get_element_type(context_actual_type);
1337 if (!OidIsValid(array_typelem))
1339 (errcode(ERRCODE_DATATYPE_MISMATCH),
1340 errmsg("argument declared \"anyarray\" is not an array but type %s",
1341 format_type_be(context_actual_type))));
1342 return context_actual_type;
1344 else if (context_declared_type == ANYELEMENTOID)
1346 /* Use the array type corresponding to actual type */
1347 Oid array_typeid = get_array_type(context_actual_type);
1349 if (!OidIsValid(array_typeid))
1351 (errcode(ERRCODE_UNDEFINED_OBJECT),
1352 errmsg("could not find array type for data type %s",
1353 format_type_be(context_actual_type))));
1354 return array_typeid;
1357 else if (declared_type == ANYELEMENTOID)
1359 if (context_declared_type == ANYARRAYOID)
1361 /* Use the element type corresponding to actual type */
1362 Oid array_typelem = get_element_type(context_actual_type);
1364 if (!OidIsValid(array_typelem))
1366 (errcode(ERRCODE_DATATYPE_MISMATCH),
1367 errmsg("argument declared \"anyarray\" is not an array but type %s",
1368 format_type_be(context_actual_type))));
1369 return array_typelem;
1371 else if (context_declared_type == ANYELEMENTOID)
1373 /* Use the actual type; it doesn't matter if array or not */
1374 return context_actual_type;
1379 /* declared_type isn't polymorphic, so return it as-is */
1380 return declared_type;
1382 /* If we get here, declared_type is polymorphic and context isn't */
1383 /* NB: this is a calling-code logic error, not a user error */
1384 elog(ERROR, "could not determine ANYARRAY/ANYELEMENT type because context isn't polymorphic");
1385 return InvalidOid; /* keep compiler quiet */
1390 * Assign a category to the specified type OID.
1392 * NB: this must not return INVALID_TYPE.
1394 * XXX This should be moved to system catalog lookups
1395 * to allow for better type extensibility.
1396 * - thomas 2001-09-30
1399 TypeCategory(Oid inType)
1406 result = BOOLEAN_TYPE;
1414 result = STRING_TYPE;
1419 result = BITSTRING_TYPE;
1424 case (REGPROCEDUREOID):
1426 case (REGOPERATOROID):
1436 result = NUMERIC_TYPE;
1443 case (TIMESTAMPOID):
1444 case (TIMESTAMPTZOID):
1445 result = DATETIME_TYPE;
1449 case (TINTERVALOID):
1451 result = TIMESPAN_TYPE;
1461 result = GEOMETRIC_TYPE;
1466 result = NETWORK_TYPE;
1471 result = UNKNOWN_TYPE;
1480 case (LANGUAGE_HANDLEROID):
1483 case (ANYELEMENTOID):
1484 result = GENERIC_TYPE;
1492 } /* TypeCategory() */
1495 /* IsPreferredType()
1496 * Check if this type is a preferred type for the given category.
1498 * If category is INVALID_TYPE, then we'll return TRUE for preferred types
1499 * of any category; otherwise, only for preferred types of that category.
1501 * XXX This should be moved to system catalog lookups
1502 * to allow for better type extensibility.
1503 * - thomas 2001-09-30
1506 IsPreferredType(CATEGORY category, Oid type)
1510 if (category == INVALID_TYPE)
1511 category = TypeCategory(type);
1512 else if (category != TypeCategory(type))
1516 * This switch should agree with TypeCategory(), above. Note that at this
1517 * point, category certainly matches the type.
1521 case (UNKNOWN_TYPE):
1522 case (GENERIC_TYPE):
1523 preftype = UNKNOWNOID;
1526 case (BOOLEAN_TYPE):
1534 case (BITSTRING_TYPE):
1535 preftype = VARBITOID;
1538 case (NUMERIC_TYPE):
1539 if (type == OIDOID ||
1540 type == REGPROCOID ||
1541 type == REGPROCEDUREOID ||
1542 type == REGOPEROID ||
1543 type == REGOPERATOROID ||
1544 type == REGCLASSOID ||
1548 preftype = FLOAT8OID;
1551 case (DATETIME_TYPE):
1552 if (type == DATEOID)
1553 preftype = TIMESTAMPOID;
1555 preftype = TIMESTAMPTZOID;
1558 case (TIMESPAN_TYPE):
1559 preftype = INTERVALOID;
1562 case (GEOMETRIC_TYPE):
1566 case (NETWORK_TYPE):
1575 elog(ERROR, "unrecognized type category: %d", (int) category);
1576 preftype = UNKNOWNOID;
1580 return (type == preftype);
1581 } /* IsPreferredType() */
1584 /* IsBinaryCoercible()
1585 * Check if srctype is binary-coercible to targettype.
1587 * This notion allows us to cheat and directly exchange values without
1588 * going through the trouble of calling a conversion function. Note that
1589 * in general, this should only be an implementation shortcut. Before 7.4,
1590 * this was also used as a heuristic for resolving overloaded functions and
1591 * operators, but that's basically a bad idea.
1593 * As of 7.3, binary coercibility isn't hardwired into the code anymore.
1594 * We consider two types binary-coercible if there is an implicitly
1595 * invokable, no-function-needed pg_cast entry. Also, a domain is always
1596 * binary-coercible to its base type, though *not* vice versa (in the other
1597 * direction, one must apply domain constraint checks before accepting the
1598 * value as legitimate). We also need to special-case the polymorphic
1601 * This function replaces IsBinaryCompatible(), which was an inherently
1602 * symmetric test. Since the pg_cast entries aren't necessarily symmetric,
1603 * the order of the operands is now significant.
1606 IsBinaryCoercible(Oid srctype, Oid targettype)
1609 Form_pg_cast castForm;
1612 /* Fast path if same type */
1613 if (srctype == targettype)
1616 /* If srctype is a domain, reduce to its base type */
1617 if (OidIsValid(srctype))
1618 srctype = getBaseType(srctype);
1620 /* Somewhat-fast path for domain -> base type case */
1621 if (srctype == targettype)
1624 /* Also accept any array type as coercible to ANYARRAY */
1625 if (targettype == ANYARRAYOID)
1626 if (get_element_type(srctype) != InvalidOid)
1629 /* Else look in pg_cast */
1630 tuple = SearchSysCache(CASTSOURCETARGET,
1631 ObjectIdGetDatum(srctype),
1632 ObjectIdGetDatum(targettype),
1634 if (!HeapTupleIsValid(tuple))
1635 return false; /* no cast */
1636 castForm = (Form_pg_cast) GETSTRUCT(tuple);
1638 result = (castForm->castfunc == InvalidOid &&
1639 castForm->castcontext == COERCION_CODE_IMPLICIT);
1641 ReleaseSysCache(tuple);
1648 * find_coercion_pathway
1649 * Look for a coercion pathway between two types.
1651 * ccontext determines the set of available casts.
1653 * If we find a suitable entry in pg_cast, return TRUE, and set *funcid
1654 * to the castfunc value, which may be InvalidOid for a binary-compatible
1657 * NOTE: *funcid == InvalidOid does not necessarily mean that no work is
1658 * needed to do the coercion; if the target is a domain then we may need to
1659 * apply domain constraint checking. If you want to check for a zero-effort
1660 * conversion then use IsBinaryCoercible().
1663 find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
1664 CoercionContext ccontext,
1667 bool result = false;
1670 *funcid = InvalidOid;
1672 /* Perhaps the types are domains; if so, look at their base types */
1673 if (OidIsValid(sourceTypeId))
1674 sourceTypeId = getBaseType(sourceTypeId);
1675 if (OidIsValid(targetTypeId))
1676 targetTypeId = getBaseType(targetTypeId);
1678 /* Domains are always coercible to and from their base type */
1679 if (sourceTypeId == targetTypeId)
1682 /* Look in pg_cast */
1683 tuple = SearchSysCache(CASTSOURCETARGET,
1684 ObjectIdGetDatum(sourceTypeId),
1685 ObjectIdGetDatum(targetTypeId),
1688 if (HeapTupleIsValid(tuple))
1690 Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
1691 CoercionContext castcontext;
1693 /* convert char value for castcontext to CoercionContext enum */
1694 switch (castForm->castcontext)
1696 case COERCION_CODE_IMPLICIT:
1697 castcontext = COERCION_IMPLICIT;
1699 case COERCION_CODE_ASSIGNMENT:
1700 castcontext = COERCION_ASSIGNMENT;
1702 case COERCION_CODE_EXPLICIT:
1703 castcontext = COERCION_EXPLICIT;
1706 elog(ERROR, "unrecognized castcontext: %d",
1707 (int) castForm->castcontext);
1708 castcontext = 0; /* keep compiler quiet */
1712 /* Rely on ordering of enum for correct behavior here */
1713 if (ccontext >= castcontext)
1715 *funcid = castForm->castfunc;
1719 ReleaseSysCache(tuple);
1724 * If there's no pg_cast entry, perhaps we are dealing with a pair of
1725 * array types. If so, and if the element types have a suitable cast,
1726 * use array_type_coerce() or array_type_length_coerce().
1728 * Hack: disallow coercions to oidvector and int2vector, which
1729 * otherwise tend to capture coercions that should go to "real" array
1730 * types. We want those types to be considered "real" arrays for many
1731 * purposes, but not this one. (Also, array_type_coerce isn't
1732 * guaranteed to produce an output that meets the restrictions of
1733 * these datatypes, such as being 1-dimensional.)
1739 if (targetTypeId == OIDVECTOROID || targetTypeId == INT2VECTOROID)
1742 if ((targetElemType = get_element_type(targetTypeId)) != InvalidOid &&
1743 (sourceElemType = get_element_type(sourceTypeId)) != InvalidOid)
1745 if (find_coercion_pathway(targetElemType, sourceElemType,
1746 ccontext, &elemfuncid))
1748 if (!OidIsValid(elemfuncid))
1750 /* binary-compatible element type conversion */
1751 *funcid = F_ARRAY_TYPE_COERCE;
1755 /* does the function take a typmod arg? */
1756 if (get_func_nargs(elemfuncid) > 1)
1757 *funcid = F_ARRAY_TYPE_LENGTH_COERCE;
1759 *funcid = F_ARRAY_TYPE_COERCE;
1771 * find_typmod_coercion_function -- does the given type need length coercion?
1773 * If the target type possesses a pg_cast function from itself to itself,
1774 * it must need length coercion.
1776 * "bpchar" (ie, char(N)) and "numeric" are examples of such types.
1778 * If the given type is a varlena array type, we do not look for a coercion
1779 * function associated directly with the array type, but instead look for
1780 * one associated with the element type. If one exists, we report
1781 * array_length_coerce() as the coercion function to use.
1784 find_typmod_coercion_function(Oid typeId)
1786 Oid funcid = InvalidOid;
1787 bool isArray = false;
1789 Form_pg_type typeForm;
1792 targetType = typeidType(typeId);
1793 typeForm = (Form_pg_type) GETSTRUCT(targetType);
1795 /* Check for a varlena array type (and not a domain) */
1796 if (typeForm->typelem != InvalidOid &&
1797 typeForm->typlen == -1 &&
1798 typeForm->typtype != 'd')
1800 /* Yes, switch our attention to the element type */
1801 typeId = typeForm->typelem;
1804 ReleaseSysCache(targetType);
1806 /* Look in pg_cast */
1807 tuple = SearchSysCache(CASTSOURCETARGET,
1808 ObjectIdGetDatum(typeId),
1809 ObjectIdGetDatum(typeId),
1812 if (HeapTupleIsValid(tuple))
1814 Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
1816 funcid = castForm->castfunc;
1817 ReleaseSysCache(tuple);
1821 * Now, if we did find a coercion function for an array element type,
1822 * report array_length_coerce() as the function to use.
1824 if (isArray && OidIsValid(funcid))
1825 funcid = F_ARRAY_LENGTH_COERCE;