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.142 2006/07/26 00:34:48 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
167 * failure when the domain applies a typmod: existing input
168 * routines follow implicit-coercion semantics for length checks,
169 * which is not always what we want here. The needed check will
170 * be applied properly 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
184 * existing input routines follow implicit-coercion semantics for
185 * length checks, which is not always what we want here. Any
186 * length constraint will be applied later by our caller.
188 * We assume here that UNKNOWN's internal representation is the
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;
783 /* coerce_to_boolean()
784 * Coerce an argument of a construct that requires boolean input
785 * (AND, OR, NOT, etc). Also check that input is not a set.
787 * Returns the possibly-transformed node tree.
789 * As with coerce_type, pstate may be NULL if no special unknown-Param
790 * processing is wanted.
793 coerce_to_boolean(ParseState *pstate, Node *node,
794 const char *constructName)
796 Oid inputTypeId = exprType(node);
798 if (inputTypeId != BOOLOID)
800 node = coerce_to_target_type(pstate, node, inputTypeId,
803 COERCE_IMPLICIT_CAST);
806 (errcode(ERRCODE_DATATYPE_MISMATCH),
807 /* translator: first %s is name of a SQL construct, eg WHERE */
808 errmsg("argument of %s must be type boolean, not type %s",
809 constructName, format_type_be(inputTypeId))));
812 if (expression_returns_set(node))
814 (errcode(ERRCODE_DATATYPE_MISMATCH),
815 /* translator: %s is name of a SQL construct, eg WHERE */
816 errmsg("argument of %s must not return a set",
822 /* coerce_to_integer()
823 * Coerce an argument of a construct that requires integer input
824 * Also check that input is not a set.
826 * Returns the possibly-transformed node tree.
828 * As with coerce_type, pstate may be NULL if no special unknown-Param
829 * processing is wanted.
832 coerce_to_integer(ParseState *pstate, Node *node,
833 const char *constructName)
835 Oid inputTypeId = exprType(node);
837 if (inputTypeId != INT4OID)
839 node = coerce_to_target_type(pstate, node, inputTypeId,
842 COERCE_IMPLICIT_CAST);
845 (errcode(ERRCODE_DATATYPE_MISMATCH),
846 /* translator: first %s is name of a SQL construct, eg LIMIT */
847 errmsg("argument of %s must be type integer, not type %s",
848 constructName, format_type_be(inputTypeId))));
851 if (expression_returns_set(node))
853 (errcode(ERRCODE_DATATYPE_MISMATCH),
854 /* translator: %s is name of a SQL construct, eg LIMIT */
855 errmsg("argument of %s must not return a set",
861 /* coerce_to_integer64()
862 * Coerce an argument of a construct that requires integer input
863 * (LIMIT, OFFSET). Also check that input is not a set.
865 * Returns the possibly-transformed node tree.
867 * As with coerce_type, pstate may be NULL if no special unknown-Param
868 * processing is wanted.
871 coerce_to_integer64(ParseState *pstate, Node *node,
872 const char *constructName)
874 Oid inputTypeId = exprType(node);
876 if (inputTypeId != INT8OID)
878 node = coerce_to_target_type(pstate, node, inputTypeId,
879 INT8OID, -1, COERCION_ASSIGNMENT,
880 COERCE_IMPLICIT_CAST);
883 (errcode(ERRCODE_DATATYPE_MISMATCH),
884 /* translator: first %s is name of a SQL construct, eg LIMIT */
885 errmsg("argument of %s must be type integer, not type %s",
886 constructName, format_type_be(inputTypeId))));
889 if (expression_returns_set(node))
891 (errcode(ERRCODE_DATATYPE_MISMATCH),
892 /* translator: %s is name of a SQL construct, eg LIMIT */
893 errmsg("argument of %s must not return a set",
900 /* select_common_type()
901 * Determine the common supertype of a list of input expression types.
902 * This is used for determining the output type of CASE and UNION
905 * typeids is a nonempty list of type OIDs. Note that earlier items
906 * in the list will be preferred if there is doubt.
907 * 'context' is a phrase to use in the error message if we fail to select
911 select_common_type(List *typeids, const char *context)
917 Assert(typeids != NIL);
918 ptype = getBaseType(linitial_oid(typeids));
919 pcategory = TypeCategory(ptype);
921 for_each_cell(type_item, lnext(list_head(typeids)))
923 Oid ntype = getBaseType(lfirst_oid(type_item));
925 /* move on to next one if no new information... */
926 if ((ntype != InvalidOid) && (ntype != UNKNOWNOID) && (ntype != ptype))
928 if ((ptype == InvalidOid) || ptype == UNKNOWNOID)
930 /* so far, only nulls so take anything... */
932 pcategory = TypeCategory(ptype);
934 else if (TypeCategory(ntype) != pcategory)
937 * both types in different categories? then not much hope...
940 (errcode(ERRCODE_DATATYPE_MISMATCH),
943 * translator: first %s is name of a SQL construct, eg CASE
945 errmsg("%s types %s and %s cannot be matched",
947 format_type_be(ptype),
948 format_type_be(ntype))));
950 else if (!IsPreferredType(pcategory, ptype) &&
951 can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
952 !can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
955 * take new type if can coerce to it implicitly but not the
956 * other way; but if we have a preferred type, stay on it.
959 pcategory = TypeCategory(ptype);
965 * If all the inputs were UNKNOWN type --- ie, unknown-type literals ---
966 * then resolve as type TEXT. This situation comes up with constructs
967 * like SELECT (CASE WHEN foo THEN 'bar' ELSE 'baz' END); SELECT 'foo'
968 * UNION SELECT 'bar'; It might seem desirable to leave the construct's
969 * output type as UNKNOWN, but that really doesn't work, because we'd
970 * probably end up needing a runtime coercion from UNKNOWN to something
971 * else, and we usually won't have it. We need to coerce the unknown
972 * literals while they are still literals, so a decision has to be made
975 if (ptype == UNKNOWNOID)
981 /* coerce_to_common_type()
982 * Coerce an expression to the given type.
984 * This is used following select_common_type() to coerce the individual
985 * expressions to the desired type. 'context' is a phrase to use in the
986 * error message if we fail to coerce.
988 * As with coerce_type, pstate may be NULL if no special unknown-Param
989 * processing is wanted.
992 coerce_to_common_type(ParseState *pstate, Node *node,
993 Oid targetTypeId, const char *context)
995 Oid inputTypeId = exprType(node);
997 if (inputTypeId == targetTypeId)
998 return node; /* no work */
999 if (can_coerce_type(1, &inputTypeId, &targetTypeId, COERCION_IMPLICIT))
1000 node = coerce_type(pstate, node, inputTypeId, targetTypeId, -1,
1001 COERCION_IMPLICIT, COERCE_IMPLICIT_CAST);
1004 (errcode(ERRCODE_CANNOT_COERCE),
1005 /* translator: first %s is name of a SQL construct, eg CASE */
1006 errmsg("%s could not convert type %s to %s",
1008 format_type_be(inputTypeId),
1009 format_type_be(targetTypeId))));
1014 * check_generic_type_consistency()
1015 * Are the actual arguments potentially compatible with a
1016 * polymorphic function?
1018 * The argument consistency rules are:
1020 * 1) All arguments declared ANYARRAY must have matching datatypes,
1021 * and must in fact be varlena arrays.
1022 * 2) All arguments declared ANYELEMENT must have matching datatypes.
1023 * 3) If there are arguments of both ANYELEMENT and ANYARRAY, make sure
1024 * the actual ANYELEMENT datatype is in fact the element type for
1025 * the actual ANYARRAY datatype.
1027 * If we have UNKNOWN input (ie, an untyped literal) for any ANYELEMENT
1028 * or ANYARRAY argument, assume it is okay.
1030 * If an input is of type ANYARRAY (ie, we know it's an array, but not
1031 * what element type), we will accept it as a match to an argument declared
1032 * ANYARRAY, so long as we don't have to determine an element type ---
1033 * that is, so long as there is no use of ANYELEMENT. This is mostly for
1034 * backwards compatibility with the pre-7.4 behavior of ANYARRAY.
1036 * We do not ereport here, but just return FALSE if a rule is violated.
1039 check_generic_type_consistency(Oid *actual_arg_types,
1040 Oid *declared_arg_types,
1044 Oid elem_typeid = InvalidOid;
1045 Oid array_typeid = InvalidOid;
1047 bool have_anyelement = false;
1050 * Loop through the arguments to see if we have any that are ANYARRAY or
1051 * ANYELEMENT. If so, require the actual types to be self-consistent
1053 for (j = 0; j < nargs; j++)
1055 Oid actual_type = actual_arg_types[j];
1057 if (declared_arg_types[j] == ANYELEMENTOID)
1059 have_anyelement = true;
1060 if (actual_type == UNKNOWNOID)
1062 if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
1064 elem_typeid = actual_type;
1066 else if (declared_arg_types[j] == ANYARRAYOID)
1068 if (actual_type == UNKNOWNOID)
1070 if (OidIsValid(array_typeid) && actual_type != array_typeid)
1072 array_typeid = actual_type;
1076 /* Get the element type based on the array type, if we have one */
1077 if (OidIsValid(array_typeid))
1079 if (array_typeid == ANYARRAYOID)
1081 /* Special case for ANYARRAY input: okay iff no ANYELEMENT */
1082 if (have_anyelement)
1087 array_typelem = get_element_type(array_typeid);
1088 if (!OidIsValid(array_typelem))
1089 return false; /* should be an array, but isn't */
1091 if (!OidIsValid(elem_typeid))
1094 * if we don't have an element type yet, use the one we just got
1096 elem_typeid = array_typelem;
1098 else if (array_typelem != elem_typeid)
1100 /* otherwise, they better match */
1110 * enforce_generic_type_consistency()
1111 * Make sure a polymorphic function is legally callable, and
1112 * deduce actual argument and result types.
1114 * If ANYARRAY or ANYELEMENT is used for a function's arguments or
1115 * return type, we make sure the actual data types are consistent with
1116 * each other. The argument consistency rules are shown above for
1117 * check_generic_type_consistency().
1119 * If we have UNKNOWN input (ie, an untyped literal) for any ANYELEMENT
1120 * or ANYARRAY argument, we attempt to deduce the actual type it should
1121 * have. If successful, we alter that position of declared_arg_types[]
1122 * so that make_fn_arguments will coerce the literal to the right thing.
1124 * Rules are applied to the function's return type (possibly altering it)
1125 * if it is declared ANYARRAY or ANYELEMENT:
1127 * 1) If return type is ANYARRAY, and any argument is ANYARRAY, use the
1128 * argument's actual type as the function's return type.
1129 * 2) If return type is ANYARRAY, no argument is ANYARRAY, but any argument
1130 * is ANYELEMENT, use the actual type of the argument to determine
1131 * the function's return type, i.e. the element type's corresponding
1133 * 3) If return type is ANYARRAY, no argument is ANYARRAY or ANYELEMENT,
1134 * generate an ERROR. This condition is prevented by CREATE FUNCTION
1135 * and is therefore not expected here.
1136 * 4) If return type is ANYELEMENT, and any argument is ANYELEMENT, use the
1137 * argument's actual type as the function's return type.
1138 * 5) If return type is ANYELEMENT, no argument is ANYELEMENT, but any
1139 * argument is ANYARRAY, use the actual type of the argument to determine
1140 * the function's return type, i.e. the array type's corresponding
1142 * 6) If return type is ANYELEMENT, no argument is ANYARRAY or ANYELEMENT,
1143 * generate an ERROR. This condition is prevented by CREATE FUNCTION
1144 * and is therefore not expected here.
1147 enforce_generic_type_consistency(Oid *actual_arg_types,
1148 Oid *declared_arg_types,
1153 bool have_generics = false;
1154 bool have_unknowns = false;
1155 Oid elem_typeid = InvalidOid;
1156 Oid array_typeid = InvalidOid;
1158 bool have_anyelement = (rettype == ANYELEMENTOID);
1161 * Loop through the arguments to see if we have any that are ANYARRAY or
1162 * ANYELEMENT. If so, require the actual types to be self-consistent
1164 for (j = 0; j < nargs; j++)
1166 Oid actual_type = actual_arg_types[j];
1168 if (declared_arg_types[j] == ANYELEMENTOID)
1170 have_generics = have_anyelement = true;
1171 if (actual_type == UNKNOWNOID)
1173 have_unknowns = true;
1176 if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
1178 (errcode(ERRCODE_DATATYPE_MISMATCH),
1179 errmsg("arguments declared \"anyelement\" are not all alike"),
1180 errdetail("%s versus %s",
1181 format_type_be(elem_typeid),
1182 format_type_be(actual_type))));
1183 elem_typeid = actual_type;
1185 else if (declared_arg_types[j] == ANYARRAYOID)
1187 have_generics = true;
1188 if (actual_type == UNKNOWNOID)
1190 have_unknowns = true;
1193 if (OidIsValid(array_typeid) && actual_type != array_typeid)
1195 (errcode(ERRCODE_DATATYPE_MISMATCH),
1196 errmsg("arguments declared \"anyarray\" are not all alike"),
1197 errdetail("%s versus %s",
1198 format_type_be(array_typeid),
1199 format_type_be(actual_type))));
1200 array_typeid = actual_type;
1205 * Fast Track: if none of the arguments are ANYARRAY or ANYELEMENT, return
1206 * the unmodified rettype.
1211 /* Get the element type based on the array type, if we have one */
1212 if (OidIsValid(array_typeid))
1214 if (array_typeid == ANYARRAYOID && !have_anyelement)
1216 /* Special case for ANYARRAY input: okay iff no ANYELEMENT */
1217 array_typelem = InvalidOid;
1221 array_typelem = get_element_type(array_typeid);
1222 if (!OidIsValid(array_typelem))
1224 (errcode(ERRCODE_DATATYPE_MISMATCH),
1225 errmsg("argument declared \"anyarray\" is not an array but type %s",
1226 format_type_be(array_typeid))));
1229 if (!OidIsValid(elem_typeid))
1232 * if we don't have an element type yet, use the one we just got
1234 elem_typeid = array_typelem;
1236 else if (array_typelem != elem_typeid)
1238 /* otherwise, they better match */
1240 (errcode(ERRCODE_DATATYPE_MISMATCH),
1241 errmsg("argument declared \"anyarray\" is not consistent with argument declared \"anyelement\""),
1242 errdetail("%s versus %s",
1243 format_type_be(array_typeid),
1244 format_type_be(elem_typeid))));
1247 else if (!OidIsValid(elem_typeid))
1249 /* Only way to get here is if all the generic args are UNKNOWN */
1251 (errcode(ERRCODE_DATATYPE_MISMATCH),
1252 errmsg("could not determine anyarray/anyelement type because input has type \"unknown\"")));
1256 * If we had any unknown inputs, re-scan to assign correct types
1260 for (j = 0; j < nargs; j++)
1262 Oid actual_type = actual_arg_types[j];
1264 if (actual_type != UNKNOWNOID)
1267 if (declared_arg_types[j] == ANYELEMENTOID)
1268 declared_arg_types[j] = elem_typeid;
1269 else if (declared_arg_types[j] == ANYARRAYOID)
1271 if (!OidIsValid(array_typeid))
1273 array_typeid = get_array_type(elem_typeid);
1274 if (!OidIsValid(array_typeid))
1276 (errcode(ERRCODE_UNDEFINED_OBJECT),
1277 errmsg("could not find array type for data type %s",
1278 format_type_be(elem_typeid))));
1280 declared_arg_types[j] = array_typeid;
1285 /* if we return ANYARRAYOID use the appropriate argument type */
1286 if (rettype == ANYARRAYOID)
1288 if (!OidIsValid(array_typeid))
1290 array_typeid = get_array_type(elem_typeid);
1291 if (!OidIsValid(array_typeid))
1293 (errcode(ERRCODE_UNDEFINED_OBJECT),
1294 errmsg("could not find array type for data type %s",
1295 format_type_be(elem_typeid))));
1297 return array_typeid;
1300 /* if we return ANYELEMENTOID use the appropriate argument type */
1301 if (rettype == ANYELEMENTOID)
1304 /* we don't return a generic type; send back the original return type */
1309 * resolve_generic_type()
1310 * Deduce an individual actual datatype on the assumption that
1311 * the rules for ANYARRAY/ANYELEMENT are being followed.
1313 * declared_type is the declared datatype we want to resolve.
1314 * context_actual_type is the actual input datatype to some argument
1315 * that has declared datatype context_declared_type.
1317 * If declared_type isn't polymorphic, we just return it. Otherwise,
1318 * context_declared_type must be polymorphic, and we deduce the correct
1319 * return type based on the relationship of the two polymorphic types.
1322 resolve_generic_type(Oid declared_type,
1323 Oid context_actual_type,
1324 Oid context_declared_type)
1326 if (declared_type == ANYARRAYOID)
1328 if (context_declared_type == ANYARRAYOID)
1330 /* Use actual type, but it must be an array */
1331 Oid array_typelem = get_element_type(context_actual_type);
1333 if (!OidIsValid(array_typelem))
1335 (errcode(ERRCODE_DATATYPE_MISMATCH),
1336 errmsg("argument declared \"anyarray\" is not an array but type %s",
1337 format_type_be(context_actual_type))));
1338 return context_actual_type;
1340 else if (context_declared_type == ANYELEMENTOID)
1342 /* Use the array type corresponding to actual type */
1343 Oid array_typeid = get_array_type(context_actual_type);
1345 if (!OidIsValid(array_typeid))
1347 (errcode(ERRCODE_UNDEFINED_OBJECT),
1348 errmsg("could not find array type for data type %s",
1349 format_type_be(context_actual_type))));
1350 return array_typeid;
1353 else if (declared_type == ANYELEMENTOID)
1355 if (context_declared_type == ANYARRAYOID)
1357 /* Use the element type corresponding to actual type */
1358 Oid array_typelem = get_element_type(context_actual_type);
1360 if (!OidIsValid(array_typelem))
1362 (errcode(ERRCODE_DATATYPE_MISMATCH),
1363 errmsg("argument declared \"anyarray\" is not an array but type %s",
1364 format_type_be(context_actual_type))));
1365 return array_typelem;
1367 else if (context_declared_type == ANYELEMENTOID)
1369 /* Use the actual type; it doesn't matter if array or not */
1370 return context_actual_type;
1375 /* declared_type isn't polymorphic, so return it as-is */
1376 return declared_type;
1378 /* If we get here, declared_type is polymorphic and context isn't */
1379 /* NB: this is a calling-code logic error, not a user error */
1380 elog(ERROR, "could not determine ANYARRAY/ANYELEMENT type because context isn't polymorphic");
1381 return InvalidOid; /* keep compiler quiet */
1386 * Assign a category to the specified type OID.
1388 * NB: this must not return INVALID_TYPE.
1390 * XXX This should be moved to system catalog lookups
1391 * to allow for better type extensibility.
1392 * - thomas 2001-09-30
1395 TypeCategory(Oid inType)
1402 result = BOOLEAN_TYPE;
1410 result = STRING_TYPE;
1415 result = BITSTRING_TYPE;
1420 case (REGPROCEDUREOID):
1422 case (REGOPERATOROID):
1432 result = NUMERIC_TYPE;
1439 case (TIMESTAMPOID):
1440 case (TIMESTAMPTZOID):
1441 result = DATETIME_TYPE;
1445 case (TINTERVALOID):
1447 result = TIMESPAN_TYPE;
1457 result = GEOMETRIC_TYPE;
1462 result = NETWORK_TYPE;
1467 result = UNKNOWN_TYPE;
1476 case (LANGUAGE_HANDLEROID):
1479 case (ANYELEMENTOID):
1480 result = GENERIC_TYPE;
1488 } /* TypeCategory() */
1491 /* IsPreferredType()
1492 * Check if this type is a preferred type for the given category.
1494 * If category is INVALID_TYPE, then we'll return TRUE for preferred types
1495 * of any category; otherwise, only for preferred types of that category.
1497 * XXX This should be moved to system catalog lookups
1498 * to allow for better type extensibility.
1499 * - thomas 2001-09-30
1502 IsPreferredType(CATEGORY category, Oid type)
1506 if (category == INVALID_TYPE)
1507 category = TypeCategory(type);
1508 else if (category != TypeCategory(type))
1512 * This switch should agree with TypeCategory(), above. Note that at this
1513 * point, category certainly matches the type.
1517 case (UNKNOWN_TYPE):
1518 case (GENERIC_TYPE):
1519 preftype = UNKNOWNOID;
1522 case (BOOLEAN_TYPE):
1530 case (BITSTRING_TYPE):
1531 preftype = VARBITOID;
1534 case (NUMERIC_TYPE):
1535 if (type == OIDOID ||
1536 type == REGPROCOID ||
1537 type == REGPROCEDUREOID ||
1538 type == REGOPEROID ||
1539 type == REGOPERATOROID ||
1540 type == REGCLASSOID ||
1544 preftype = FLOAT8OID;
1547 case (DATETIME_TYPE):
1548 if (type == DATEOID)
1549 preftype = TIMESTAMPOID;
1551 preftype = TIMESTAMPTZOID;
1554 case (TIMESPAN_TYPE):
1555 preftype = INTERVALOID;
1558 case (GEOMETRIC_TYPE):
1562 case (NETWORK_TYPE):
1571 elog(ERROR, "unrecognized type category: %d", (int) category);
1572 preftype = UNKNOWNOID;
1576 return (type == preftype);
1577 } /* IsPreferredType() */
1580 /* IsBinaryCoercible()
1581 * Check if srctype is binary-coercible to targettype.
1583 * This notion allows us to cheat and directly exchange values without
1584 * going through the trouble of calling a conversion function. Note that
1585 * in general, this should only be an implementation shortcut. Before 7.4,
1586 * this was also used as a heuristic for resolving overloaded functions and
1587 * operators, but that's basically a bad idea.
1589 * As of 7.3, binary coercibility isn't hardwired into the code anymore.
1590 * We consider two types binary-coercible if there is an implicitly
1591 * invokable, no-function-needed pg_cast entry. Also, a domain is always
1592 * binary-coercible to its base type, though *not* vice versa (in the other
1593 * direction, one must apply domain constraint checks before accepting the
1594 * value as legitimate). We also need to special-case the polymorphic
1597 * This function replaces IsBinaryCompatible(), which was an inherently
1598 * symmetric test. Since the pg_cast entries aren't necessarily symmetric,
1599 * the order of the operands is now significant.
1602 IsBinaryCoercible(Oid srctype, Oid targettype)
1605 Form_pg_cast castForm;
1608 /* Fast path if same type */
1609 if (srctype == targettype)
1612 /* If srctype is a domain, reduce to its base type */
1613 if (OidIsValid(srctype))
1614 srctype = getBaseType(srctype);
1616 /* Somewhat-fast path for domain -> base type case */
1617 if (srctype == targettype)
1620 /* Also accept any array type as coercible to ANYARRAY */
1621 if (targettype == ANYARRAYOID)
1622 if (get_element_type(srctype) != InvalidOid)
1625 /* Else look in pg_cast */
1626 tuple = SearchSysCache(CASTSOURCETARGET,
1627 ObjectIdGetDatum(srctype),
1628 ObjectIdGetDatum(targettype),
1630 if (!HeapTupleIsValid(tuple))
1631 return false; /* no cast */
1632 castForm = (Form_pg_cast) GETSTRUCT(tuple);
1634 result = (castForm->castfunc == InvalidOid &&
1635 castForm->castcontext == COERCION_CODE_IMPLICIT);
1637 ReleaseSysCache(tuple);
1644 * find_coercion_pathway
1645 * Look for a coercion pathway between two types.
1647 * ccontext determines the set of available casts.
1649 * If we find a suitable entry in pg_cast, return TRUE, and set *funcid
1650 * to the castfunc value, which may be InvalidOid for a binary-compatible
1653 * NOTE: *funcid == InvalidOid does not necessarily mean that no work is
1654 * needed to do the coercion; if the target is a domain then we may need to
1655 * apply domain constraint checking. If you want to check for a zero-effort
1656 * conversion then use IsBinaryCoercible().
1659 find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
1660 CoercionContext ccontext,
1663 bool result = false;
1666 *funcid = InvalidOid;
1668 /* Perhaps the types are domains; if so, look at their base types */
1669 if (OidIsValid(sourceTypeId))
1670 sourceTypeId = getBaseType(sourceTypeId);
1671 if (OidIsValid(targetTypeId))
1672 targetTypeId = getBaseType(targetTypeId);
1674 /* Domains are always coercible to and from their base type */
1675 if (sourceTypeId == targetTypeId)
1678 /* Look in pg_cast */
1679 tuple = SearchSysCache(CASTSOURCETARGET,
1680 ObjectIdGetDatum(sourceTypeId),
1681 ObjectIdGetDatum(targetTypeId),
1684 if (HeapTupleIsValid(tuple))
1686 Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
1687 CoercionContext castcontext;
1689 /* convert char value for castcontext to CoercionContext enum */
1690 switch (castForm->castcontext)
1692 case COERCION_CODE_IMPLICIT:
1693 castcontext = COERCION_IMPLICIT;
1695 case COERCION_CODE_ASSIGNMENT:
1696 castcontext = COERCION_ASSIGNMENT;
1698 case COERCION_CODE_EXPLICIT:
1699 castcontext = COERCION_EXPLICIT;
1702 elog(ERROR, "unrecognized castcontext: %d",
1703 (int) castForm->castcontext);
1704 castcontext = 0; /* keep compiler quiet */
1708 /* Rely on ordering of enum for correct behavior here */
1709 if (ccontext >= castcontext)
1711 *funcid = castForm->castfunc;
1715 ReleaseSysCache(tuple);
1720 * If there's no pg_cast entry, perhaps we are dealing with a pair of
1721 * array types. If so, and if the element types have a suitable cast,
1722 * use array_type_coerce() or array_type_length_coerce().
1724 * Hack: disallow coercions to oidvector and int2vector, which
1725 * otherwise tend to capture coercions that should go to "real" array
1726 * types. We want those types to be considered "real" arrays for many
1727 * purposes, but not this one. (Also, array_type_coerce isn't
1728 * guaranteed to produce an output that meets the restrictions of
1729 * these datatypes, such as being 1-dimensional.)
1735 if (targetTypeId == OIDVECTOROID || targetTypeId == INT2VECTOROID)
1738 if ((targetElemType = get_element_type(targetTypeId)) != InvalidOid &&
1739 (sourceElemType = get_element_type(sourceTypeId)) != InvalidOid)
1741 if (find_coercion_pathway(targetElemType, sourceElemType,
1742 ccontext, &elemfuncid))
1744 if (!OidIsValid(elemfuncid))
1746 /* binary-compatible element type conversion */
1747 *funcid = F_ARRAY_TYPE_COERCE;
1751 /* does the function take a typmod arg? */
1752 if (get_func_nargs(elemfuncid) > 1)
1753 *funcid = F_ARRAY_TYPE_LENGTH_COERCE;
1755 *funcid = F_ARRAY_TYPE_COERCE;
1767 * find_typmod_coercion_function -- does the given type need length coercion?
1769 * If the target type possesses a pg_cast function from itself to itself,
1770 * it must need length coercion.
1772 * "bpchar" (ie, char(N)) and "numeric" are examples of such types.
1774 * If the given type is a varlena array type, we do not look for a coercion
1775 * function associated directly with the array type, but instead look for
1776 * one associated with the element type. If one exists, we report
1777 * array_length_coerce() as the coercion function to use.
1780 find_typmod_coercion_function(Oid typeId)
1782 Oid funcid = InvalidOid;
1783 bool isArray = false;
1785 Form_pg_type typeForm;
1788 targetType = typeidType(typeId);
1789 typeForm = (Form_pg_type) GETSTRUCT(targetType);
1791 /* Check for a varlena array type (and not a domain) */
1792 if (typeForm->typelem != InvalidOid &&
1793 typeForm->typlen == -1 &&
1794 typeForm->typtype != 'd')
1796 /* Yes, switch our attention to the element type */
1797 typeId = typeForm->typelem;
1800 ReleaseSysCache(targetType);
1802 /* Look in pg_cast */
1803 tuple = SearchSysCache(CASTSOURCETARGET,
1804 ObjectIdGetDatum(typeId),
1805 ObjectIdGetDatum(typeId),
1808 if (HeapTupleIsValid(tuple))
1810 Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
1812 funcid = castForm->castfunc;
1813 ReleaseSysCache(tuple);
1817 * Now, if we did find a coercion function for an array element type,
1818 * report array_length_coerce() as the function to use.
1820 if (isArray && OidIsValid(funcid))
1821 funcid = F_ARRAY_LENGTH_COERCE;