]> granicus.if.org Git - postgresql/blob - src/backend/parser/parse_coerce.c
A visit from the message-style police ...
[postgresql] / src / backend / parser / parse_coerce.c
1 /*-------------------------------------------------------------------------
2  *
3  * parse_coerce.c
4  *              handle type coercions/conversions for parser
5  *
6  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.106 2003/07/28 00:09:15 tgl Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16
17 #include "catalog/pg_cast.h"
18 #include "catalog/pg_proc.h"
19 #include "nodes/makefuncs.h"
20 #include "nodes/params.h"
21 #include "optimizer/clauses.h"
22 #include "parser/parse_coerce.h"
23 #include "parser/parse_expr.h"
24 #include "parser/parse_func.h"
25 #include "parser/parse_type.h"
26 #include "utils/builtins.h"
27 #include "utils/fmgroids.h"
28 #include "utils/lsyscache.h"
29 #include "utils/syscache.h"
30
31
32 static Node *coerce_type_typmod(Node *node,
33                                                                 Oid targetTypeId, int32 targetTypMod,
34                                                                 CoercionForm cformat, bool isExplicit);
35
36
37 /*
38  * coerce_to_target_type()
39  *              Convert an expression to a target type and typmod.
40  *
41  * This is the general-purpose entry point for arbitrary type coercion
42  * operations.  Direct use of the component operations can_coerce_type,
43  * coerce_type, and coerce_type_typmod should be restricted to special
44  * cases (eg, when the conversion is expected to succeed).
45  *
46  * Returns the possibly-transformed expression tree, or NULL if the type
47  * conversion is not possible.  (We do this, rather than ereport'ing directly,
48  * so that callers can generate custom error messages indicating context.)
49  *
50  * pstate - parse state (can be NULL, see coerce_type)
51  * expr - input expression tree (already transformed by transformExpr)
52  * exprtype - result type of expr
53  * targettype - desired result type
54  * targettypmod - desired result typmod
55  * ccontext, cformat - context indicators to control coercions
56  */
57 Node *
58 coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype,
59                                           Oid targettype, int32 targettypmod,
60                                           CoercionContext ccontext,
61                                           CoercionForm cformat)
62 {
63         if (can_coerce_type(1, &exprtype, &targettype, ccontext))
64                 expr = coerce_type(pstate, expr, exprtype, targettype,
65                                                    ccontext, cformat);
66         else if (ccontext >= COERCION_ASSIGNMENT)
67         {
68                 /*
69                  * String hacks to get transparent conversions for char and varchar:
70                  * if a coercion to text is available, use it for forced coercions to
71                  * char(n) or varchar(n) or domains thereof.
72                  *
73                  * This is pretty grotty, but seems easier to maintain than providing
74                  * entries in pg_cast that parallel all the ones for text.
75                  */
76                 Oid             targetbasetype = getBaseType(targettype);
77
78                 if (targetbasetype == BPCHAROID || targetbasetype == VARCHAROID)
79                 {
80                         Oid                     text_id = TEXTOID;
81
82                         if (can_coerce_type(1, &exprtype, &text_id, ccontext))
83                         {
84                                 expr = coerce_type(pstate, expr, exprtype, text_id,
85                                                                    ccontext, cformat);
86                                 if (targetbasetype != targettype)
87                                 {
88                                         /* need to coerce to domain over char or varchar */
89                                         expr = coerce_to_domain(expr, targetbasetype, targettype,
90                                                                                         cformat);
91                                 }
92                                 else
93                                 {
94                                         /* need a RelabelType if no typmod coercion will be performed */
95                                         if (targettypmod < 0)
96                                                 expr = (Node *) makeRelabelType((Expr *) expr,
97                                                                                                                 targettype, -1,
98                                                                                                                 cformat);
99                                 }
100                         }
101                         else
102                                 expr = NULL;
103                 }
104                 else
105                         expr = NULL;
106         }
107         else
108                 expr = NULL;
109
110         /*
111          * If the target is a fixed-length type, it may need a length coercion
112          * as well as a type coercion.
113          */
114         if (expr != NULL)
115                 expr = coerce_type_typmod(expr, targettype, targettypmod,
116                                                                   cformat,
117                                                                   (cformat != COERCE_IMPLICIT_CAST));
118
119         return expr;
120 }
121
122
123 /*
124  * coerce_type()
125  *              Convert an expression to a different type.
126  *
127  * The caller should already have determined that the coercion is possible;
128  * see can_coerce_type.
129  *
130  * No coercion to a typmod (length) is performed here.  The caller must
131  * call coerce_type_typmod as well, if a typmod constraint is wanted.
132  * (But if the target type is a domain, it may internally contain a
133  * typmod constraint, which will be applied inside coerce_to_domain.)
134  *
135  * pstate is only used in the case that we are able to resolve the type of
136  * a previously UNKNOWN Param.  It is okay to pass pstate = NULL if the
137  * caller does not want type information updated for Params.
138  */
139 Node *
140 coerce_type(ParseState *pstate, Node *node,
141                         Oid inputTypeId, Oid targetTypeId,
142                         CoercionContext ccontext, CoercionForm cformat)
143 {
144         Node       *result;
145         Oid                     funcId;
146
147         if (targetTypeId == inputTypeId ||
148                 node == NULL)
149         {
150                 /* no conversion needed */
151                 return node;
152         }
153         if (inputTypeId == UNKNOWNOID && IsA(node, Const))
154         {
155                 /*
156                  * Input is a string constant with previously undetermined type.
157                  * Apply the target type's typinput function to it to produce a
158                  * constant of the target type.
159                  *
160                  * NOTE: this case cannot be folded together with the other
161                  * constant-input case, since the typinput function does not
162                  * necessarily behave the same as a type conversion function. For
163                  * example, int4's typinput function will reject "1.2", whereas
164                  * float-to-int type conversion will round to integer.
165                  *
166                  * XXX if the typinput function is not immutable, we really ought to
167                  * postpone evaluation of the function call until runtime. But
168                  * there is no way to represent a typinput function call as an
169                  * expression tree, because C-string values are not Datums. (XXX
170                  * This *is* possible as of 7.3, do we want to do it?)
171                  */
172                 Const      *con = (Const *) node;
173                 Const      *newcon = makeNode(Const);
174                 Type            targetType = typeidType(targetTypeId);
175                 char            targetTyptype = typeTypType(targetType);
176
177                 newcon->consttype = targetTypeId;
178                 newcon->constlen = typeLen(targetType);
179                 newcon->constbyval = typeByVal(targetType);
180                 newcon->constisnull = con->constisnull;
181
182                 if (!con->constisnull)
183                 {
184                         char       *val = DatumGetCString(DirectFunctionCall1(unknownout,
185                                                                                                            con->constvalue));
186
187                         /*
188                          * We pass typmod -1 to the input routine, primarily because
189                          * existing input routines follow implicit-coercion semantics
190                          * for length checks, which is not always what we want here.
191                          * Any length constraint will be applied later by our caller.
192                          *
193                          * Note that we call stringTypeDatum using the domain's pg_type
194                          * row, if it's a domain.  This works because the domain row has
195                          * the same typinput and typelem as the base type --- ugly...
196                          */
197                         newcon->constvalue = stringTypeDatum(targetType, val, -1);
198                         pfree(val);
199                 }
200
201                 result = (Node *) newcon;
202
203                 /* If target is a domain, apply constraints. */
204                 if (targetTyptype == 'd')
205                         result = coerce_to_domain(result, InvalidOid, targetTypeId,
206                                                                           cformat);
207
208                 ReleaseSysCache(targetType);
209
210                 return result;
211         }
212         if (inputTypeId == UNKNOWNOID && IsA(node, Param) &&
213                 ((Param *) node)->paramkind == PARAM_NUM &&
214                 pstate != NULL && pstate->p_variableparams)
215         {
216                 /*
217                  * Input is a Param of previously undetermined type, and we want
218                  * to update our knowledge of the Param's type.  Find the topmost
219                  * ParseState and update the state.
220                  */
221                 Param      *param = (Param *) node;
222                 int                     paramno = param->paramid;
223                 ParseState *toppstate;
224
225                 toppstate = pstate;
226                 while (toppstate->parentParseState != NULL)
227                         toppstate = toppstate->parentParseState;
228
229                 if (paramno <= 0 ||             /* shouldn't happen, but... */
230                         paramno > toppstate->p_numparams)
231                         ereport(ERROR,
232                                         (errcode(ERRCODE_UNDEFINED_PARAMETER),
233                                          errmsg("there is no parameter $%d", paramno)));
234
235                 if (toppstate->p_paramtypes[paramno-1] == UNKNOWNOID)
236                 {
237                         /* We've successfully resolved the type */
238                         toppstate->p_paramtypes[paramno-1] = targetTypeId;
239                 }
240                 else if (toppstate->p_paramtypes[paramno-1] == targetTypeId)
241                 {
242                         /* We previously resolved the type, and it matches */
243                 }
244                 else
245                 {
246                         /* Ooops */
247                         ereport(ERROR,
248                                         (errcode(ERRCODE_AMBIGUOUS_PARAMETER),
249                                          errmsg("inconsistent types deduced for parameter $%d",
250                                                         paramno),
251                                          errdetail("%s versus %s",
252                                                            format_type_be(toppstate->p_paramtypes[paramno-1]),
253                                                            format_type_be(targetTypeId))));
254                 }
255
256                 param->paramtype = targetTypeId;
257                 return (Node *) param;
258         }
259         if (targetTypeId == ANYOID ||
260                 targetTypeId == ANYARRAYOID ||
261                 targetTypeId == ANYELEMENTOID)
262         {
263                 /* assume can_coerce_type verified that implicit coercion is okay */
264                 /* NB: we do NOT want a RelabelType here */
265                 return node;
266         }
267         if (find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
268                                                           &funcId))
269         {
270                 if (OidIsValid(funcId))
271                 {
272                         /*
273                          * Generate an expression tree representing run-time
274                          * application of the conversion function.      If we are dealing
275                          * with a domain target type, the conversion function will
276                          * yield the base type.
277                          */
278                         Oid                     baseTypeId = getBaseType(targetTypeId);
279
280                         result = (Node *) makeFuncExpr(funcId, baseTypeId,
281                                                                                    makeList1(node),
282                                                                                    cformat);
283
284                         /*
285                          * If domain, coerce to the domain type and relabel with
286                          * domain type ID
287                          */
288                         if (targetTypeId != baseTypeId)
289                                 result = coerce_to_domain(result, baseTypeId, targetTypeId,
290                                                                                   cformat);
291                 }
292                 else
293                 {
294                         /*
295                          * We don't need to do a physical conversion, but we do need
296                          * to attach a RelabelType node so that the expression will be
297                          * seen to have the intended type when inspected by
298                          * higher-level code.
299                          *
300                          * Also, domains may have value restrictions beyond the base type
301                          * that must be accounted for.  If the destination is a domain
302                          * then we won't need a RelabelType node.
303                          */
304                         result = coerce_to_domain(node, InvalidOid, targetTypeId,
305                                                                           cformat);
306                         if (result == node)
307                         {
308                                 /*
309                                  * XXX could we label result with exprTypmod(node) instead of
310                                  * default -1 typmod, to save a possible length-coercion
311                                  * later? Would work if both types have same interpretation of
312                                  * typmod, which is likely but not certain.
313                                  */
314                                 result = (Node *) makeRelabelType((Expr *) result,
315                                                                                                   targetTypeId, -1,
316                                                                                                   cformat);
317                         }
318                 }
319                 return result;
320         }
321         if (typeInheritsFrom(inputTypeId, targetTypeId))
322         {
323                 /*
324                  * Input class type is a subclass of target, so nothing to do ---
325                  * except relabel the type.  This is binary compatibility for
326                  * complex types.
327                  */
328                 return (Node *) makeRelabelType((Expr *) node,
329                                                                                 targetTypeId, -1,
330                                                                                 cformat);
331         }
332         /* If we get here, caller blew it */
333         elog(ERROR, "failed to find conversion function from %s to %s",
334                  format_type_be(inputTypeId), format_type_be(targetTypeId));
335         return NULL;                            /* keep compiler quiet */
336 }
337
338
339 /*
340  * can_coerce_type()
341  *              Can input_typeids be coerced to target_typeids?
342  *
343  * We must be told the context (CAST construct, assignment, implicit coercion)
344  * as this determines the set of available casts.
345  */
346 bool
347 can_coerce_type(int nargs, Oid *input_typeids, Oid *target_typeids,
348                                 CoercionContext ccontext)
349 {
350         bool            have_generics = false;
351         int                     i;
352
353         /* run through argument list... */
354         for (i = 0; i < nargs; i++)
355         {
356                 Oid                     inputTypeId = input_typeids[i];
357                 Oid                     targetTypeId = target_typeids[i];
358                 Oid                     funcId;
359
360                 /* no problem if same type */
361                 if (inputTypeId == targetTypeId)
362                         continue;
363
364                 /* don't choke on references to no-longer-existing types */
365                 if (!typeidIsValid(inputTypeId))
366                         return false;
367                 if (!typeidIsValid(targetTypeId))
368                         return false;
369
370                 /*
371                  * If input is an untyped string constant, assume we can convert
372                  * it to anything except a class type.
373                  */
374                 if (inputTypeId == UNKNOWNOID)
375                 {
376                         if (ISCOMPLEX(targetTypeId))
377                                 return false;
378                         continue;
379                 }
380
381                 /* accept if target is ANY */
382                 if (targetTypeId == ANYOID)
383                         continue;
384
385                 /* accept if target is ANYARRAY or ANYELEMENT, for now */
386                 if (targetTypeId == ANYARRAYOID ||
387                         targetTypeId == ANYELEMENTOID)
388                 {
389                         have_generics = true; /* do more checking later */
390                         continue;
391                 }
392
393                 /*
394                  * If pg_cast shows that we can coerce, accept.  This test now
395                  * covers both binary-compatible and coercion-function cases.
396                  */
397                 if (find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
398                                                                   &funcId))
399                         continue;
400
401                 /*
402                  * If input is a class type that inherits from target, accept
403                  */
404                 if (typeInheritsFrom(inputTypeId, targetTypeId))
405                         continue;
406
407                 /*
408                  * Else, cannot coerce at this argument position
409                  */
410                 return false;
411         }
412
413         /* If we found any generic argument types, cross-check them */
414         if (have_generics)
415         {
416                 if (!check_generic_type_consistency(input_typeids, target_typeids,
417                                                                                         nargs))
418                         return false;
419         }
420
421         return true;
422 }
423
424
425 /*
426  * Create an expression tree to represent coercion to a domain type.
427  *
428  * 'arg': input expression
429  * 'baseTypeId': base type of domain, if known (pass InvalidOid if caller
430  *              has not bothered to look this up)
431  * 'typeId': target type to coerce to
432  * 'cformat': coercion format
433  *
434  * If the target type isn't a domain, the given 'arg' is returned as-is.
435  */
436 Node *
437 coerce_to_domain(Node *arg, Oid baseTypeId, Oid typeId, CoercionForm cformat)
438 {
439         CoerceToDomain *result;
440         int32   typmod;
441
442         /* Get the base type if it hasn't been supplied */
443         if (baseTypeId == InvalidOid)
444                 baseTypeId = getBaseType(typeId);
445
446         /* If it isn't a domain, return the node as it was passed in */
447         if (baseTypeId == typeId)
448                 return arg;
449
450         /*
451          * If the domain applies a typmod to its base type, build the appropriate
452          * coercion step.  Mark it implicit for display purposes, because we don't
453          * want it shown separately by ruleutils.c; but the isExplicit flag passed
454          * to the conversion function depends on the manner in which the domain
455          * coercion is invoked, so that the semantics of implicit and explicit
456          * coercion differ.  (Is that really the behavior we want?)
457          *
458          * NOTE: because we apply this as part of the fixed expression structure,
459          * ALTER DOMAIN cannot alter the typtypmod.  But it's unclear that that
460          * would be safe to do anyway, without lots of knowledge about what the
461          * base type thinks the typmod means.
462          */
463         typmod = get_typtypmod(typeId);
464         if (typmod >= 0)
465                 arg = coerce_type_typmod(arg, baseTypeId, typmod,
466                                                                  COERCE_IMPLICIT_CAST,
467                                                                  (cformat != COERCE_IMPLICIT_CAST));
468
469         /*
470          * Now build the domain coercion node.  This represents run-time checking
471          * of any constraints currently attached to the domain.  This also
472          * ensures that the expression is properly labeled as to result type.
473          */
474         result = makeNode(CoerceToDomain);
475         result->arg = (Expr *) arg;
476         result->resulttype = typeId;
477         result->resulttypmod = -1;      /* currently, always -1 for domains */
478         result->coercionformat = cformat;
479
480         return (Node *) result;
481 }
482
483
484 /*
485  * coerce_type_typmod()
486  *              Force a value to a particular typmod, if meaningful and possible.
487  *
488  * This is applied to values that are going to be stored in a relation
489  * (where we have an atttypmod for the column) as well as values being
490  * explicitly CASTed (where the typmod comes from the target type spec).
491  *
492  * The caller must have already ensured that the value is of the correct
493  * type, typically by applying coerce_type.
494  *
495  * NOTE: this does not need to work on domain types, because any typmod
496  * coercion for a domain is considered to be part of the type coercion
497  * needed to produce the domain value in the first place.  So, no getBaseType.
498  */
499 static Node *
500 coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod,
501                                    CoercionForm cformat, bool isExplicit)
502 {
503         Oid                     funcId;
504         int                     nargs;
505
506         /*
507          * A negative typmod is assumed to mean that no coercion is wanted.
508          */
509         if (targetTypMod < 0 || targetTypMod == exprTypmod(node))
510                 return node;
511
512         funcId = find_typmod_coercion_function(targetTypeId, &nargs);
513
514         if (OidIsValid(funcId))
515         {
516                 List       *args;
517                 Const      *cons;
518
519                 /* Pass given value, plus target typmod as an int4 constant */
520                 cons = makeConst(INT4OID,
521                                                  sizeof(int32),
522                                                  Int32GetDatum(targetTypMod),
523                                                  false,
524                                                  true);
525
526                 args = makeList2(node, cons);
527
528                 if (nargs == 3)
529                 {
530                         /* Pass it a boolean isExplicit parameter, too */
531                         cons = makeConst(BOOLOID,
532                                                          sizeof(bool),
533                                                          BoolGetDatum(isExplicit),
534                                                          false,
535                                                          true);
536
537                         args = lappend(args, cons);
538                 }
539
540                 node = (Node *) makeFuncExpr(funcId, targetTypeId, args, cformat);
541         }
542
543         return node;
544 }
545
546
547 /* coerce_to_boolean()
548  *              Coerce an argument of a construct that requires boolean input
549  *              (AND, OR, NOT, etc).  Also check that input is not a set.
550  *
551  * Returns the possibly-transformed node tree.
552  *
553  * As with coerce_type, pstate may be NULL if no special unknown-Param
554  * processing is wanted.
555  */
556 Node *
557 coerce_to_boolean(ParseState *pstate, Node *node,
558                                   const char *constructName)
559 {
560         Oid                     inputTypeId = exprType(node);
561
562         if (inputTypeId != BOOLOID)
563         {
564                 node = coerce_to_target_type(pstate, node, inputTypeId,
565                                                                          BOOLOID, -1,
566                                                                          COERCION_ASSIGNMENT,
567                                                                          COERCE_IMPLICIT_CAST);
568                 if (node == NULL)
569                         ereport(ERROR,
570                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
571                                          /* translator: first %s is name of a SQL construct, eg WHERE */
572                                          errmsg("argument of %s must be type boolean, not type %s",
573                                                         constructName, format_type_be(inputTypeId))));
574         }
575
576         if (expression_returns_set(node))
577                 ereport(ERROR,
578                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
579                                  /* translator: %s is name of a SQL construct, eg WHERE */
580                                  errmsg("argument of %s must not return a set",
581                                                 constructName)));
582
583         return node;
584 }
585
586 /* coerce_to_integer()
587  *              Coerce an argument of a construct that requires integer input
588  *              (LIMIT, OFFSET, etc).  Also check that input is not a set.
589  *
590  * Returns the possibly-transformed node tree.
591  *
592  * As with coerce_type, pstate may be NULL if no special unknown-Param
593  * processing is wanted.
594  */
595 Node *
596 coerce_to_integer(ParseState *pstate, Node *node,
597                                   const char *constructName)
598 {
599         Oid                     inputTypeId = exprType(node);
600
601         if (inputTypeId != INT4OID)
602         {
603                 node = coerce_to_target_type(pstate, node, inputTypeId,
604                                                                          INT4OID, -1,
605                                                                          COERCION_ASSIGNMENT,
606                                                                          COERCE_IMPLICIT_CAST);
607                 if (node == NULL)
608                         ereport(ERROR,
609                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
610                                          /* translator: first %s is name of a SQL construct, eg LIMIT */
611                                          errmsg("argument of %s must be type integer, not type %s",
612                                                         constructName, format_type_be(inputTypeId))));
613         }
614
615         if (expression_returns_set(node))
616                 ereport(ERROR,
617                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
618                                  /* translator: %s is name of a SQL construct, eg LIMIT */
619                                  errmsg("argument of %s must not return a set",
620                                                 constructName)));
621
622         return node;
623 }
624
625
626 /* select_common_type()
627  *              Determine the common supertype of a list of input expression types.
628  *              This is used for determining the output type of CASE and UNION
629  *              constructs.
630  *
631  * typeids is a nonempty list of type OIDs.  Note that earlier items
632  * in the list will be preferred if there is doubt.
633  * 'context' is a phrase to use in the error message if we fail to select
634  * a usable type.
635  */
636 Oid
637 select_common_type(List *typeids, const char *context)
638 {
639         Oid                     ptype;
640         CATEGORY        pcategory;
641         List       *l;
642
643         Assert(typeids != NIL);
644         ptype = getBaseType(lfirsto(typeids));
645         pcategory = TypeCategory(ptype);
646         foreach(l, lnext(typeids))
647         {
648                 Oid                     ntype = getBaseType(lfirsto(l));
649
650                 /* move on to next one if no new information... */
651                 if ((ntype != InvalidOid) && (ntype != UNKNOWNOID) && (ntype != ptype))
652                 {
653                         if ((ptype == InvalidOid) || ptype == UNKNOWNOID)
654                         {
655                                 /* so far, only nulls so take anything... */
656                                 ptype = ntype;
657                                 pcategory = TypeCategory(ptype);
658                         }
659                         else if (TypeCategory(ntype) != pcategory)
660                         {
661                                 /*
662                                  * both types in different categories? then not much
663                                  * hope...
664                                  */
665                                 ereport(ERROR,
666                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
667                                                  /* translator: first %s is name of a SQL construct, eg CASE */
668                                                  errmsg("%s types %s and %s cannot be matched",
669                                                                 context,
670                                                                 format_type_be(ptype),
671                                                                 format_type_be(ntype))));
672                         }
673                         else if (!IsPreferredType(pcategory, ptype) &&
674                                          can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
675                                          !can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
676                         {
677                                 /*
678                                  * take new type if can coerce to it implicitly but not the
679                                  * other way; but if we have a preferred type, stay on it.
680                                  */
681                                 ptype = ntype;
682                                 pcategory = TypeCategory(ptype);
683                         }
684                 }
685         }
686
687         /*
688          * If all the inputs were UNKNOWN type --- ie, unknown-type literals
689          * --- then resolve as type TEXT.  This situation comes up with
690          * constructs like SELECT (CASE WHEN foo THEN 'bar' ELSE 'baz' END);
691          * SELECT 'foo' UNION SELECT 'bar'; It might seem desirable to leave
692          * the construct's output type as UNKNOWN, but that really doesn't
693          * work, because we'd probably end up needing a runtime coercion from
694          * UNKNOWN to something else, and we usually won't have it.  We need
695          * to coerce the unknown literals while they are still literals, so a
696          * decision has to be made now.
697          */
698         if (ptype == UNKNOWNOID)
699                 ptype = TEXTOID;
700
701         return ptype;
702 }
703
704 /* coerce_to_common_type()
705  *              Coerce an expression to the given type.
706  *
707  * This is used following select_common_type() to coerce the individual
708  * expressions to the desired type.  'context' is a phrase to use in the
709  * error message if we fail to coerce.
710  *
711  * As with coerce_type, pstate may be NULL if no special unknown-Param
712  * processing is wanted.
713  */
714 Node *
715 coerce_to_common_type(ParseState *pstate, Node *node,
716                                           Oid targetTypeId, const char *context)
717 {
718         Oid                     inputTypeId = exprType(node);
719
720         if (inputTypeId == targetTypeId)
721                 return node;                    /* no work */
722         if (can_coerce_type(1, &inputTypeId, &targetTypeId, COERCION_IMPLICIT))
723                 node = coerce_type(pstate, node, inputTypeId, targetTypeId,
724                                                    COERCION_IMPLICIT, COERCE_IMPLICIT_CAST);
725         else
726                 ereport(ERROR,
727                                 (errcode(ERRCODE_CANNOT_COERCE),
728                                  /* translator: first %s is name of a SQL construct, eg CASE */
729                                  errmsg("%s could not convert type %s to %s",
730                                                 context,
731                                                 format_type_be(inputTypeId),
732                                                 format_type_be(targetTypeId))));
733         return node;
734 }
735
736 /*
737  * check_generic_type_consistency()
738  *              Are the actual arguments potentially compatible with a
739  *              polymorphic function?
740  *
741  * The argument consistency rules are:
742  *
743  * 1) All arguments declared ANYARRAY must have matching datatypes,
744  *        and must in fact be varlena arrays.
745  * 2) All arguments declared ANYELEMENT must have matching datatypes.
746  * 3) If there are arguments of both ANYELEMENT and ANYARRAY, make sure
747  *    the actual ANYELEMENT datatype is in fact the element type for
748  *    the actual ANYARRAY datatype.
749  *
750  * If we have UNKNOWN input (ie, an untyped literal) for any ANYELEMENT
751  * or ANYARRAY argument, assume it is okay.
752  *
753  * We do not ereport here, but just return FALSE if a rule is violated.
754  */
755 bool
756 check_generic_type_consistency(Oid *actual_arg_types,
757                                                            Oid *declared_arg_types,
758                                                            int nargs)
759 {
760         int                     j;
761         Oid                     elem_typeid = InvalidOid;
762         Oid                     array_typeid = InvalidOid;
763         Oid                     array_typelem;
764
765         /*
766          * Loop through the arguments to see if we have any that are
767          * ANYARRAY or ANYELEMENT. If so, require the actual types to be
768          * self-consistent
769          */
770         for (j = 0; j < nargs; j++)
771         {
772                 Oid             actual_type = actual_arg_types[j];
773
774                 if (declared_arg_types[j] == ANYELEMENTOID)
775                 {
776                         if (actual_type == UNKNOWNOID)
777                                 continue;
778                         if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
779                                 return false;
780                         elem_typeid = actual_type;
781                 }
782                 else if (declared_arg_types[j] == ANYARRAYOID)
783                 {
784                         if (actual_type == UNKNOWNOID)
785                                 continue;
786                         if (OidIsValid(array_typeid) && actual_type != array_typeid)
787                                 return false;
788                         array_typeid = actual_type;
789                 }
790         }
791
792         /* Get the element type based on the array type, if we have one */
793         if (OidIsValid(array_typeid))
794         {
795                 array_typelem = get_element_type(array_typeid);
796                 if (!OidIsValid(array_typelem))
797                         return false;           /* should be an array, but isn't */
798
799                 if (!OidIsValid(elem_typeid))
800                 {
801                         /* if we don't have an element type yet, use the one we just got */
802                         elem_typeid = array_typelem;
803                 }
804                 else if (array_typelem != elem_typeid)
805                 {
806                         /* otherwise, they better match */
807                         return false;
808                 }
809         }
810
811         /* Looks valid */
812         return true;
813 }
814
815 /*
816  * enforce_generic_type_consistency()
817  *              Make sure a polymorphic function is legally callable, and
818  *              deduce actual argument and result types.
819  *
820  * If ANYARRAY or ANYELEMENT is used for a function's arguments or
821  * return type, we make sure the actual data types are consistent with
822  * each other. The argument consistency rules are shown above for
823  * check_generic_type_consistency().
824  *
825  * If we have UNKNOWN input (ie, an untyped literal) for any ANYELEMENT
826  * or ANYARRAY argument, we attempt to deduce the actual type it should
827  * have.  If successful, we alter that position of declared_arg_types[]
828  * so that make_fn_arguments will coerce the literal to the right thing.
829  *
830  * Rules are applied to the function's return type (possibly altering it)
831  * if it is declared ANYARRAY or ANYELEMENT:
832  *
833  * 1) If return type is ANYARRAY, and any argument is ANYARRAY, use the
834  *    argument's actual type as the function's return type.
835  * 2) If return type is ANYARRAY, no argument is ANYARRAY, but any argument
836  *    is ANYELEMENT, use the actual type of the argument to determine
837  *    the function's return type, i.e. the element type's corresponding
838  *    array type.
839  * 3) If return type is ANYARRAY, no argument is ANYARRAY or ANYELEMENT,
840  *    generate an ERROR. This condition is prevented by CREATE FUNCTION
841  *    and is therefore not expected here.
842  * 4) If return type is ANYELEMENT, and any argument is ANYELEMENT, use the
843  *    argument's actual type as the function's return type.
844  * 5) If return type is ANYELEMENT, no argument is ANYELEMENT, but any
845  *    argument is ANYARRAY, use the actual type of the argument to determine
846  *    the function's return type, i.e. the array type's corresponding
847  *    element type.
848  * 6) If return type is ANYELEMENT, no argument is ANYARRAY or ANYELEMENT,
849  *    generate an ERROR. This condition is prevented by CREATE FUNCTION
850  *    and is therefore not expected here.
851  */
852 Oid
853 enforce_generic_type_consistency(Oid *actual_arg_types,
854                                                                  Oid *declared_arg_types,
855                                                                  int nargs,
856                                                                  Oid rettype)
857 {
858         int                     j;
859         bool            have_generics = false;
860         bool            have_unknowns = false;
861         Oid                     elem_typeid = InvalidOid;
862         Oid                     array_typeid = InvalidOid;
863         Oid                     array_typelem = InvalidOid;
864
865         /*
866          * Loop through the arguments to see if we have any that are
867          * ANYARRAY or ANYELEMENT. If so, require the actual types to be
868          * self-consistent
869          */
870         for (j = 0; j < nargs; j++)
871         {
872                 Oid             actual_type = actual_arg_types[j];
873
874                 if (declared_arg_types[j] == ANYELEMENTOID)
875                 {
876                         have_generics = true;
877                         if (actual_type == UNKNOWNOID)
878                         {
879                                 have_unknowns = true;
880                                 continue;
881                         }
882                         if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
883                                 ereport(ERROR,
884                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
885                                                  errmsg("arguments declared ANYELEMENT are not all alike"),
886                                                  errdetail("%s versus %s",
887                                                                    format_type_be(elem_typeid),
888                                                                    format_type_be(actual_type))));
889                         elem_typeid = actual_type;
890                 }
891                 else if (declared_arg_types[j] == ANYARRAYOID)
892                 {
893                         have_generics = true;
894                         if (actual_type == UNKNOWNOID)
895                         {
896                                 have_unknowns = true;
897                                 continue;
898                         }
899                         if (OidIsValid(array_typeid) && actual_type != array_typeid)
900                                 ereport(ERROR,
901                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
902                                                  errmsg("arguments declared ANYARRAY are not all alike"),
903                                                  errdetail("%s versus %s",
904                                                                    format_type_be(array_typeid),
905                                                                    format_type_be(actual_type))));
906                         array_typeid = actual_type;
907                 }
908         }
909
910         /*
911          * Fast Track: if none of the arguments are ANYARRAY or ANYELEMENT,
912          * return the unmodified rettype.
913          */
914         if (!have_generics)
915                 return rettype;
916
917         /* Get the element type based on the array type, if we have one */
918         if (OidIsValid(array_typeid))
919         {
920                 array_typelem = get_element_type(array_typeid);
921                 if (!OidIsValid(array_typelem))
922                         ereport(ERROR,
923                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
924                                          errmsg("argument declared ANYARRAY is not an array but %s",
925                                                         format_type_be(array_typeid))));
926
927                 if (!OidIsValid(elem_typeid))
928                 {
929                         /* if we don't have an element type yet, use the one we just got */
930                         elem_typeid = array_typelem;
931                 }
932                 else if (array_typelem != elem_typeid)
933                 {
934                         /* otherwise, they better match */
935                         ereport(ERROR,
936                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
937                                          errmsg("argument declared ANYARRAY is not consistent with argument declared ANYELEMENT"),
938                                          errdetail("%s versus %s",
939                                                            format_type_be(array_typeid),
940                                                            format_type_be(elem_typeid))));
941                 }
942         }
943         else if (!OidIsValid(elem_typeid))
944         {
945                 /* Only way to get here is if all the generic args are UNKNOWN */
946                 ereport(ERROR,
947                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
948                                  errmsg("could not determine ANYARRAY/ANYELEMENT type because input is UNKNOWN")));
949         }
950
951         /*
952          * If we had any unknown inputs, re-scan to assign correct types
953          */
954         if (have_unknowns)
955         {
956                 for (j = 0; j < nargs; j++)
957                 {
958                         Oid             actual_type = actual_arg_types[j];
959
960                         if (actual_type != UNKNOWNOID)
961                                 continue;
962
963                         if (declared_arg_types[j] == ANYELEMENTOID)
964                         {
965                                 declared_arg_types[j] = elem_typeid;
966                         }
967                         else if (declared_arg_types[j] == ANYARRAYOID)
968                         {
969                                 if (!OidIsValid(array_typeid))
970                                 {
971                                         array_typeid = get_array_type(elem_typeid);
972                                         if (!OidIsValid(array_typeid))
973                                                 ereport(ERROR,
974                                                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
975                                                                  errmsg("could not find array type for datatype %s",
976                                                                                 format_type_be(elem_typeid))));
977                                 }
978                                 declared_arg_types[j] = array_typeid;
979                         }
980                 }
981         }
982
983         /* if we return ANYARRAYOID use the appropriate argument type */
984         if (rettype == ANYARRAYOID)
985         {
986                 if (!OidIsValid(array_typeid))
987                 {
988                         array_typeid = get_array_type(elem_typeid);
989                         if (!OidIsValid(array_typeid))
990                                 ereport(ERROR,
991                                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
992                                                  errmsg("could not find array type for datatype %s",
993                                                                 format_type_be(elem_typeid))));
994                 }
995                 return array_typeid;
996         }
997
998         /* if we return ANYELEMENTOID use the appropriate argument type */
999         if (rettype == ANYELEMENTOID)
1000                 return elem_typeid;
1001
1002         /* we don't return a generic type; send back the original return type */
1003         return rettype;
1004 }
1005
1006 /*
1007  * resolve_generic_type()
1008  *              Deduce an individual actual datatype on the assumption that
1009  *              the rules for ANYARRAY/ANYELEMENT are being followed.
1010  *
1011  * declared_type is the declared datatype we want to resolve.
1012  * context_actual_type is the actual input datatype to some argument
1013  * that has declared datatype context_declared_type.
1014  *
1015  * If declared_type isn't polymorphic, we just return it.  Otherwise,
1016  * context_declared_type must be polymorphic, and we deduce the correct
1017  * return type based on the relationship of the two polymorphic types.
1018  */
1019 Oid
1020 resolve_generic_type(Oid declared_type,
1021                                          Oid context_actual_type,
1022                                          Oid context_declared_type)
1023 {
1024         if (declared_type == ANYARRAYOID)
1025         {
1026                 if (context_declared_type == ANYARRAYOID)
1027                 {
1028                         /* Use actual type, but it must be an array */
1029                         Oid             array_typelem = get_element_type(context_actual_type);
1030
1031                         if (!OidIsValid(array_typelem))
1032                                 ereport(ERROR,
1033                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
1034                                                  errmsg("argument declared ANYARRAY is not an array but %s",
1035                                                                 format_type_be(context_actual_type))));
1036                         return context_actual_type;
1037                 }
1038                 else if (context_declared_type == ANYELEMENTOID)
1039                 {
1040                         /* Use the array type corresponding to actual type */
1041                         Oid             array_typeid = get_array_type(context_actual_type);
1042
1043                         if (!OidIsValid(array_typeid))
1044                                 ereport(ERROR,
1045                                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
1046                                                  errmsg("could not find array type for datatype %s",
1047                                                                 format_type_be(context_actual_type))));
1048                         return array_typeid;
1049                 }
1050         }
1051         else if (declared_type == ANYELEMENTOID)
1052         {
1053                 if (context_declared_type == ANYARRAYOID)
1054                 {
1055                         /* Use the element type corresponding to actual type */
1056                         Oid             array_typelem = get_element_type(context_actual_type);
1057
1058                         if (!OidIsValid(array_typelem))
1059                                 ereport(ERROR,
1060                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
1061                                                  errmsg("argument declared ANYARRAY is not an array but %s",
1062                                                                 format_type_be(context_actual_type))));
1063                         return array_typelem;
1064                 }
1065                 else if (context_declared_type == ANYELEMENTOID)
1066                 {
1067                         /* Use the actual type; it doesn't matter if array or not */
1068                         return context_actual_type;
1069                 }
1070         }
1071         else
1072         {
1073                 /* declared_type isn't polymorphic, so return it as-is */
1074                 return declared_type;
1075         }
1076         /* If we get here, declared_type is polymorphic and context isn't */
1077         /* NB: this is a calling-code logic error, not a user error */
1078         elog(ERROR, "could not determine ANYARRAY/ANYELEMENT type because context isn't polymorphic");
1079         return InvalidOid;                      /* keep compiler quiet */
1080 }
1081
1082
1083 /* TypeCategory()
1084  *              Assign a category to the specified type OID.
1085  *
1086  * NB: this must not return INVALID_TYPE.
1087  *
1088  * XXX This should be moved to system catalog lookups
1089  * to allow for better type extensibility.
1090  * - thomas 2001-09-30
1091  */
1092 CATEGORY
1093 TypeCategory(Oid inType)
1094 {
1095         CATEGORY        result;
1096
1097         switch (inType)
1098         {
1099                 case (BOOLOID):
1100                         result = BOOLEAN_TYPE;
1101                         break;
1102
1103                 case (CHAROID):
1104                 case (NAMEOID):
1105                 case (BPCHAROID):
1106                 case (VARCHAROID):
1107                 case (TEXTOID):
1108                         result = STRING_TYPE;
1109                         break;
1110
1111                 case (BITOID):
1112                 case (VARBITOID):
1113                         result = BITSTRING_TYPE;
1114                         break;
1115
1116                 case (OIDOID):
1117                 case (REGPROCOID):
1118                 case (REGPROCEDUREOID):
1119                 case (REGOPEROID):
1120                 case (REGOPERATOROID):
1121                 case (REGCLASSOID):
1122                 case (REGTYPEOID):
1123                 case (INT2OID):
1124                 case (INT4OID):
1125                 case (INT8OID):
1126                 case (FLOAT4OID):
1127                 case (FLOAT8OID):
1128                 case (NUMERICOID):
1129                 case (CASHOID):
1130                         result = NUMERIC_TYPE;
1131                         break;
1132
1133                 case (DATEOID):
1134                 case (TIMEOID):
1135                 case (TIMETZOID):
1136                 case (ABSTIMEOID):
1137                 case (TIMESTAMPOID):
1138                 case (TIMESTAMPTZOID):
1139                         result = DATETIME_TYPE;
1140                         break;
1141
1142                 case (RELTIMEOID):
1143                 case (TINTERVALOID):
1144                 case (INTERVALOID):
1145                         result = TIMESPAN_TYPE;
1146                         break;
1147
1148                 case (POINTOID):
1149                 case (LSEGOID):
1150                 case (PATHOID):
1151                 case (BOXOID):
1152                 case (POLYGONOID):
1153                 case (LINEOID):
1154                 case (CIRCLEOID):
1155                         result = GEOMETRIC_TYPE;
1156                         break;
1157
1158                 case (INETOID):
1159                 case (CIDROID):
1160                         result = NETWORK_TYPE;
1161                         break;
1162
1163                 case (UNKNOWNOID):
1164                 case (InvalidOid):
1165                         result = UNKNOWN_TYPE;
1166                         break;
1167
1168                 case (RECORDOID):
1169                 case (CSTRINGOID):
1170                 case (ANYOID):
1171                 case (ANYARRAYOID):
1172                 case (VOIDOID):
1173                 case (TRIGGEROID):
1174                 case (LANGUAGE_HANDLEROID):
1175                 case (INTERNALOID):
1176                 case (OPAQUEOID):
1177                 case (ANYELEMENTOID):
1178                         result = GENERIC_TYPE;
1179                         break;
1180
1181                 default:
1182                         result = USER_TYPE;
1183                         break;
1184         }
1185         return result;
1186 }       /* TypeCategory() */
1187
1188
1189 /* IsPreferredType()
1190  *              Check if this type is a preferred type for the given category.
1191  *
1192  * If category is INVALID_TYPE, then we'll return TRUE for preferred types
1193  * of any category; otherwise, only for preferred types of that category.
1194  *
1195  * XXX This should be moved to system catalog lookups
1196  * to allow for better type extensibility.
1197  * - thomas 2001-09-30
1198  */
1199 bool
1200 IsPreferredType(CATEGORY category, Oid type)
1201 {
1202         Oid                     preftype;
1203
1204         if (category == INVALID_TYPE)
1205                 category = TypeCategory(type);
1206         else if (category != TypeCategory(type))
1207                 return false;
1208
1209         /*
1210          * This switch should agree with TypeCategory(), above.  Note that
1211          * at this point, category certainly matches the type.
1212          */
1213         switch (category)
1214         {
1215                 case (UNKNOWN_TYPE):
1216                 case (GENERIC_TYPE):
1217                         preftype = UNKNOWNOID;
1218                         break;
1219
1220                 case (BOOLEAN_TYPE):
1221                         preftype = BOOLOID;
1222                         break;
1223
1224                 case (STRING_TYPE):
1225                         preftype = TEXTOID;
1226                         break;
1227
1228                 case (BITSTRING_TYPE):
1229                         preftype = VARBITOID;
1230                         break;
1231
1232                 case (NUMERIC_TYPE):
1233                         if (type == OIDOID ||
1234                                 type == REGPROCOID ||
1235                                 type == REGPROCEDUREOID ||
1236                                 type == REGOPEROID ||
1237                                 type == REGOPERATOROID ||
1238                                 type == REGCLASSOID ||
1239                                 type == REGTYPEOID)
1240                                 preftype = OIDOID;
1241                         else
1242                                 preftype = FLOAT8OID;
1243                         break;
1244
1245                 case (DATETIME_TYPE):
1246                         if (type == DATEOID)
1247                                 preftype = TIMESTAMPOID;
1248                         else
1249                                 preftype = TIMESTAMPTZOID;
1250                         break;
1251
1252                 case (TIMESPAN_TYPE):
1253                         preftype = INTERVALOID;
1254                         break;
1255
1256                 case (GEOMETRIC_TYPE):
1257                         preftype = type;
1258                         break;
1259
1260                 case (NETWORK_TYPE):
1261                         preftype = INETOID;
1262                         break;
1263
1264                 case (USER_TYPE):
1265                         preftype = type;
1266                         break;
1267
1268                 default:
1269                         elog(ERROR, "unrecognized type category: %d", (int) category);
1270                         preftype = UNKNOWNOID;
1271                         break;
1272         }
1273
1274         return (type == preftype);
1275 }       /* IsPreferredType() */
1276
1277
1278 /* IsBinaryCoercible()
1279  *              Check if srctype is binary-coercible to targettype.
1280  *
1281  * This notion allows us to cheat and directly exchange values without
1282  * going through the trouble of calling a conversion function.  Note that
1283  * in general, this should only be an implementation shortcut.  Before 7.4,
1284  * this was also used as a heuristic for resolving overloaded functions and
1285  * operators, but that's basically a bad idea.
1286  *
1287  * As of 7.3, binary coercibility isn't hardwired into the code anymore.
1288  * We consider two types binary-coercible if there is an implicitly
1289  * invokable, no-function-needed pg_cast entry.  Also, a domain is always
1290  * binary-coercible to its base type, though *not* vice versa (in the other
1291  * direction, one must apply domain constraint checks before accepting the
1292  * value as legitimate).  We also need to special-case the polymorphic
1293  * ANYARRAY type.
1294  *
1295  * This function replaces IsBinaryCompatible(), which was an inherently
1296  * symmetric test.  Since the pg_cast entries aren't necessarily symmetric,
1297  * the order of the operands is now significant.
1298  */
1299 bool
1300 IsBinaryCoercible(Oid srctype, Oid targettype)
1301 {
1302         HeapTuple       tuple;
1303         Form_pg_cast castForm;
1304         bool            result;
1305
1306         /* Fast path if same type */
1307         if (srctype == targettype)
1308                 return true;
1309
1310         /* If srctype is a domain, reduce to its base type */
1311         if (OidIsValid(srctype))
1312                 srctype = getBaseType(srctype);
1313
1314         /* Somewhat-fast path for domain -> base type case */
1315         if (srctype == targettype)
1316                 return true;
1317
1318         /* Also accept any array type as coercible to ANYARRAY */
1319         if (targettype == ANYARRAYOID)
1320                 if (get_element_type(srctype) != InvalidOid)
1321                         return true;
1322
1323         /* Else look in pg_cast */
1324         tuple = SearchSysCache(CASTSOURCETARGET,
1325                                                    ObjectIdGetDatum(srctype),
1326                                                    ObjectIdGetDatum(targettype),
1327                                                    0, 0);
1328         if (!HeapTupleIsValid(tuple))
1329                 return false;                   /* no cast */
1330         castForm = (Form_pg_cast) GETSTRUCT(tuple);
1331
1332         result = (castForm->castfunc == InvalidOid &&
1333                           castForm->castcontext == COERCION_CODE_IMPLICIT);
1334
1335         ReleaseSysCache(tuple);
1336
1337         return result;
1338 }
1339
1340
1341 /*
1342  * find_coercion_pathway
1343  *              Look for a coercion pathway between two types.
1344  *
1345  * ccontext determines the set of available casts.
1346  *
1347  * If we find a suitable entry in pg_cast, return TRUE, and set *funcid
1348  * to the castfunc value, which may be InvalidOid for a binary-compatible
1349  * coercion.
1350  *
1351  * NOTE: *funcid == InvalidOid does not necessarily mean that no work is
1352  * needed to do the coercion; if the target is a domain then we may need to
1353  * apply domain constraint checking.  If you want to check for a zero-effort
1354  * conversion then use IsBinaryCoercible().
1355  */
1356 bool
1357 find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
1358                                           CoercionContext ccontext,
1359                                           Oid *funcid)
1360 {
1361         bool            result = false;
1362         HeapTuple       tuple;
1363
1364         *funcid = InvalidOid;
1365
1366         /* Perhaps the types are domains; if so, look at their base types */
1367         if (OidIsValid(sourceTypeId))
1368                 sourceTypeId = getBaseType(sourceTypeId);
1369         if (OidIsValid(targetTypeId))
1370                 targetTypeId = getBaseType(targetTypeId);
1371
1372         /* Domains are always coercible to and from their base type */
1373         if (sourceTypeId == targetTypeId)
1374                 return true;
1375
1376         /* Look in pg_cast */
1377         tuple = SearchSysCache(CASTSOURCETARGET,
1378                                                    ObjectIdGetDatum(sourceTypeId),
1379                                                    ObjectIdGetDatum(targetTypeId),
1380                                                    0, 0);
1381
1382         if (HeapTupleIsValid(tuple))
1383         {
1384                 Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
1385                 CoercionContext castcontext;
1386
1387                 /* convert char value for castcontext to CoercionContext enum */
1388                 switch (castForm->castcontext)
1389                 {
1390                         case COERCION_CODE_IMPLICIT:
1391                                 castcontext = COERCION_IMPLICIT;
1392                                 break;
1393                         case COERCION_CODE_ASSIGNMENT:
1394                                 castcontext = COERCION_ASSIGNMENT;
1395                                 break;
1396                         case COERCION_CODE_EXPLICIT:
1397                                 castcontext = COERCION_EXPLICIT;
1398                                 break;
1399                         default:
1400                                 elog(ERROR, "unrecognized castcontext: %d",
1401                                          (int) castForm->castcontext);
1402                                 castcontext = 0;        /* keep compiler quiet */
1403                                 break;
1404                 }
1405
1406                 /* Rely on ordering of enum for correct behavior here */
1407                 if (ccontext >= castcontext)
1408                 {
1409                         *funcid = castForm->castfunc;
1410                         result = true;
1411                 }
1412
1413                 ReleaseSysCache(tuple);
1414         }
1415         else
1416         {
1417                 /*
1418                  * If there's no pg_cast entry, perhaps we are dealing with a
1419                  * pair of array types.  If so, and if the element types have
1420                  * a suitable cast, use array_type_coerce().
1421                  */
1422                 Oid                     targetElemType;
1423                 Oid                     sourceElemType;
1424                 Oid                     elemfuncid;
1425
1426                 if ((targetElemType = get_element_type(targetTypeId)) != InvalidOid &&
1427                         (sourceElemType = get_element_type(sourceTypeId)) != InvalidOid)
1428                 {
1429                         if (find_coercion_pathway(targetElemType, sourceElemType,
1430                                                                           ccontext, &elemfuncid))
1431                         {
1432                                 *funcid = F_ARRAY_TYPE_COERCE;
1433                                 result = true;
1434                         }
1435                 }
1436         }
1437
1438         return result;
1439 }
1440
1441
1442 /*
1443  * find_typmod_coercion_function -- does the given type need length coercion?
1444  *
1445  * If the target type possesses a function named for the type
1446  * and having parameter signature (targettype, int4), we assume that
1447  * the type requires coercion to its own length and that the said
1448  * function should be invoked to do that.
1449  *
1450  * Alternatively, the length-coercing function may have the signature
1451  * (targettype, int4, bool).  On success, *nargs is set to report which
1452  * signature we found.
1453  *
1454  * "bpchar" (ie, char(N)) and "numeric" are examples of such types.
1455  *
1456  * If the given type is a varlena array type, we do not look for a coercion
1457  * function associated directly with the array type, but instead look for
1458  * one associated with the element type.  If one exists, we report
1459  * array_length_coerce() as the coercion function to use.
1460  *
1461  * This mechanism may seem pretty grotty and in need of replacement by
1462  * something in pg_cast, but since typmod is only interesting for datatypes
1463  * that have special handling in the grammar, there's not really much
1464  * percentage in making it any easier to apply such coercions ...
1465  */
1466 Oid
1467 find_typmod_coercion_function(Oid typeId, int *nargs)
1468 {
1469         Oid                     funcid = InvalidOid;
1470         bool            isArray = false;
1471         Type            targetType;
1472         Form_pg_type typeForm;
1473         char       *typname;
1474         Oid                     typnamespace;
1475         Oid                     oid_array[FUNC_MAX_ARGS];
1476         HeapTuple       ftup;
1477
1478         targetType = typeidType(typeId);
1479         typeForm = (Form_pg_type) GETSTRUCT(targetType);
1480
1481         /* Check for a varlena array type (and not a domain) */
1482         if (typeForm->typelem != InvalidOid &&
1483                 typeForm->typlen == -1 &&
1484                 typeForm->typtype != 'd')
1485         {
1486                 /* Yes, switch our attention to the element type */
1487                 typeId = typeForm->typelem;
1488                 ReleaseSysCache(targetType);
1489                 targetType = typeidType(typeId);
1490                 typeForm = (Form_pg_type) GETSTRUCT(targetType);
1491                 isArray = true;
1492         }
1493
1494         /* Function name is same as type internal name, and in same namespace */
1495         typname = NameStr(typeForm->typname);
1496         typnamespace = typeForm->typnamespace;
1497
1498         /* First look for parameters (type, int4) */
1499         MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
1500         oid_array[0] = typeId;
1501         oid_array[1] = INT4OID;
1502         *nargs = 2;
1503
1504         ftup = SearchSysCache(PROCNAMENSP,
1505                                                   CStringGetDatum(typname),
1506                                                   Int16GetDatum(2),
1507                                                   PointerGetDatum(oid_array),
1508                                                   ObjectIdGetDatum(typnamespace));
1509         if (HeapTupleIsValid(ftup))
1510         {
1511                 Form_pg_proc pform = (Form_pg_proc) GETSTRUCT(ftup);
1512
1513                 /* Make sure the function's result type is as expected */
1514                 if (pform->prorettype == typeId && !pform->proretset &&
1515                         !pform->proisagg)
1516                 {
1517                         /* Okay to use it */
1518                         funcid = HeapTupleGetOid(ftup);
1519                 }
1520                 ReleaseSysCache(ftup);
1521         }
1522
1523         if (!OidIsValid(funcid))
1524         {
1525                 /* Didn't find a function, so now try (type, int4, bool) */
1526                 oid_array[2] = BOOLOID;
1527                 *nargs = 3;
1528
1529                 ftup = SearchSysCache(PROCNAMENSP,
1530                                                           CStringGetDatum(typname),
1531                                                           Int16GetDatum(3),
1532                                                           PointerGetDatum(oid_array),
1533                                                           ObjectIdGetDatum(typnamespace));
1534                 if (HeapTupleIsValid(ftup))
1535                 {
1536                         Form_pg_proc pform = (Form_pg_proc) GETSTRUCT(ftup);
1537
1538                         /* Make sure the function's result type is as expected */
1539                         if (pform->prorettype == typeId && !pform->proretset &&
1540                                 !pform->proisagg)
1541                         {
1542                                 /* Okay to use it */
1543                                 funcid = HeapTupleGetOid(ftup);
1544                         }
1545                         ReleaseSysCache(ftup);
1546                 }
1547         }
1548
1549         ReleaseSysCache(targetType);
1550
1551         /*
1552          * Now, if we did find a coercion function for an array element type,
1553          * report array_length_coerce() as the function to use.  We know it
1554          * takes three arguments always.
1555          */
1556         if (isArray && OidIsValid(funcid))
1557         {
1558                 funcid = F_ARRAY_LENGTH_COERCE;
1559                 *nargs = 3;
1560         }
1561
1562         return funcid;
1563 }