Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * parse_coerce.c
4 : * handle type coercions/conversions for parser
5 : *
6 : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : *
10 : * IDENTIFICATION
11 : * src/backend/parser/parse_coerce.c
12 : *
13 : *-------------------------------------------------------------------------
14 : */
15 : #include "postgres.h"
16 :
17 : #include "access/htup_details.h"
18 : #include "catalog/pg_cast.h"
19 : #include "catalog/pg_class.h"
20 : #include "catalog/pg_inherits.h"
21 : #include "catalog/pg_proc.h"
22 : #include "catalog/pg_type.h"
23 : #include "nodes/makefuncs.h"
24 : #include "nodes/nodeFuncs.h"
25 : #include "parser/parse_coerce.h"
26 : #include "parser/parse_relation.h"
27 : #include "parser/parse_type.h"
28 : #include "utils/builtins.h"
29 : #include "utils/datum.h" /* needed for datumIsEqual() */
30 : #include "utils/fmgroids.h"
31 : #include "utils/lsyscache.h"
32 : #include "utils/syscache.h"
33 : #include "utils/typcache.h"
34 :
35 :
36 : static Node *coerce_type_typmod(Node *node,
37 : Oid targetTypeId, int32 targetTypMod,
38 : CoercionContext ccontext, CoercionForm cformat,
39 : int location,
40 : bool hideInputCoercion);
41 : static void hide_coercion_node(Node *node);
42 : static Node *build_coercion_expression(Node *node,
43 : CoercionPathType pathtype,
44 : Oid funcId,
45 : Oid targetTypeId, int32 targetTypMod,
46 : CoercionContext ccontext, CoercionForm cformat,
47 : int location);
48 : static Node *coerce_record_to_complex(ParseState *pstate, Node *node,
49 : Oid targetTypeId,
50 : CoercionContext ccontext,
51 : CoercionForm cformat,
52 : int location);
53 : static bool is_complex_array(Oid typid);
54 : static bool typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId);
55 :
56 :
57 : /*
58 : * coerce_to_target_type()
59 : * Convert an expression to a target type and typmod.
60 : *
61 : * This is the general-purpose entry point for arbitrary type coercion
62 : * operations. Direct use of the component operations can_coerce_type,
63 : * coerce_type, and coerce_type_typmod should be restricted to special
64 : * cases (eg, when the conversion is expected to succeed).
65 : *
66 : * Returns the possibly-transformed expression tree, or NULL if the type
67 : * conversion is not possible. (We do this, rather than ereport'ing directly,
68 : * so that callers can generate custom error messages indicating context.)
69 : *
70 : * pstate - parse state (can be NULL, see coerce_type)
71 : * expr - input expression tree (already transformed by transformExpr)
72 : * exprtype - result type of expr
73 : * targettype - desired result type
74 : * targettypmod - desired result typmod
75 : * ccontext, cformat - context indicators to control coercions
76 : * location - parse location of the coercion request, or -1 if unknown/implicit
77 : */
78 : Node *
79 468255 : coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype,
80 : Oid targettype, int32 targettypmod,
81 : CoercionContext ccontext,
82 : CoercionForm cformat,
83 : int location)
84 : {
85 : Node *result;
86 : Node *origexpr;
87 :
88 468255 : if (!can_coerce_type(1, &exprtype, &targettype, ccontext))
89 302 : return NULL;
90 :
91 : /*
92 : * If the input has a CollateExpr at the top, strip it off, perform the
93 : * coercion, and put a new one back on. This is annoying since it
94 : * duplicates logic in coerce_type, but if we don't do this then it's too
95 : * hard to tell whether coerce_type actually changed anything, and we
96 : * *must* know that to avoid possibly calling hide_coercion_node on
97 : * something that wasn't generated by coerce_type. Note that if there are
98 : * multiple stacked CollateExprs, we just discard all but the topmost.
99 : * Also, if the target type isn't collatable, we discard the CollateExpr.
100 : */
101 467953 : origexpr = expr;
102 467999 : while (expr && IsA(expr, CollateExpr))
103 46 : expr = (Node *) ((CollateExpr *) expr)->arg;
104 :
105 467953 : result = coerce_type(pstate, expr, exprtype,
106 : targettype, targettypmod,
107 : ccontext, cformat, location);
108 :
109 : /*
110 : * If the target is a fixed-length type, it may need a length coercion as
111 : * well as a type coercion. If we find ourselves adding both, force the
112 : * inner coercion node to implicit display form.
113 : */
114 464630 : result = coerce_type_typmod(result,
115 : targettype, targettypmod,
116 : ccontext, cformat, location,
117 464630 : (result != expr && !IsA(result, Const)));
118 :
119 464630 : if (expr != origexpr && type_is_collatable(targettype))
120 : {
121 : /* Reinstall top CollateExpr */
122 38 : CollateExpr *coll = (CollateExpr *) origexpr;
123 38 : CollateExpr *newcoll = makeNode(CollateExpr);
124 :
125 38 : newcoll->arg = (Expr *) result;
126 38 : newcoll->collOid = coll->collOid;
127 38 : newcoll->location = coll->location;
128 38 : result = (Node *) newcoll;
129 : }
130 :
131 464630 : return result;
132 : }
133 :
134 :
135 : /*
136 : * coerce_type()
137 : * Convert an expression to a different type.
138 : *
139 : * The caller should already have determined that the coercion is possible;
140 : * see can_coerce_type.
141 : *
142 : * Normally, no coercion to a typmod (length) is performed here. The caller
143 : * must call coerce_type_typmod as well, if a typmod constraint is wanted.
144 : * (But if the target type is a domain, it may internally contain a
145 : * typmod constraint, which will be applied inside coerce_to_domain.)
146 : * In some cases pg_cast specifies a type coercion function that also
147 : * applies length conversion, and in those cases only, the result will
148 : * already be properly coerced to the specified typmod.
149 : *
150 : * pstate is only used in the case that we are able to resolve the type of
151 : * a previously UNKNOWN Param. It is okay to pass pstate = NULL if the
152 : * caller does not want type information updated for Params.
153 : *
154 : * Note: this function must not modify the given expression tree, only add
155 : * decoration on top of it. See transformSetOperationTree, for example.
156 : */
157 : Node *
158 985619 : coerce_type(ParseState *pstate, Node *node,
159 : Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod,
160 : CoercionContext ccontext, CoercionForm cformat, int location)
161 : {
162 : Node *result;
163 : CoercionPathType pathtype;
164 : Oid funcId;
165 :
166 985619 : if (targetTypeId == inputTypeId ||
167 : node == NULL)
168 : {
169 : /* no conversion needed */
170 187825 : return node;
171 : }
172 797794 : if (targetTypeId == ANYOID ||
173 751169 : targetTypeId == ANYELEMENTOID ||
174 741617 : targetTypeId == ANYNONARRAYOID ||
175 741617 : targetTypeId == ANYCOMPATIBLEOID ||
176 : targetTypeId == ANYCOMPATIBLENONARRAYOID)
177 : {
178 : /*
179 : * Assume can_coerce_type verified that implicit coercion is okay.
180 : *
181 : * Note: by returning the unmodified node here, we are saying that
182 : * it's OK to treat an UNKNOWN constant as a valid input for a
183 : * function accepting one of these pseudotypes. This should be all
184 : * right, since an UNKNOWN value is still a perfectly valid Datum.
185 : *
186 : * NB: we do NOT want a RelabelType here: the exposed type of the
187 : * function argument must be its actual type, not the polymorphic
188 : * pseudotype.
189 : */
190 56177 : return node;
191 : }
192 741617 : if (targetTypeId == ANYARRAYOID ||
193 719883 : targetTypeId == ANYENUMOID ||
194 712750 : targetTypeId == ANYRANGEOID ||
195 708986 : targetTypeId == ANYMULTIRANGEOID ||
196 708986 : targetTypeId == ANYCOMPATIBLEARRAYOID ||
197 708986 : targetTypeId == ANYCOMPATIBLERANGEOID ||
198 : targetTypeId == ANYCOMPATIBLEMULTIRANGEOID)
199 : {
200 : /*
201 : * Assume can_coerce_type verified that implicit coercion is okay.
202 : *
203 : * These cases are unlike the ones above because the exposed type of
204 : * the argument must be an actual array, enum, range, or multirange
205 : * type. In particular the argument must *not* be an UNKNOWN
206 : * constant. If it is, we just fall through; below, we'll call the
207 : * pseudotype's input function, which will produce an error. Also, if
208 : * what we have is a domain over array, enum, range, or multirange, we
209 : * have to relabel it to its base type.
210 : *
211 : * Note: currently, we can't actually see a domain-over-enum here,
212 : * since the other functions in this file will not match such a
213 : * parameter to ANYENUM. But that should get changed eventually.
214 : */
215 32631 : if (inputTypeId != UNKNOWNOID)
216 : {
217 31824 : Oid baseTypeId = getBaseType(inputTypeId);
218 :
219 31824 : if (baseTypeId != inputTypeId)
220 : {
221 60 : RelabelType *r = makeRelabelType((Expr *) node,
222 : baseTypeId, -1,
223 : InvalidOid,
224 : cformat);
225 :
226 60 : r->location = location;
227 60 : return (Node *) r;
228 : }
229 : /* Not a domain type, so return it as-is */
230 31764 : return node;
231 : }
232 : }
233 709793 : if (inputTypeId == UNKNOWNOID && IsA(node, Const))
234 : {
235 : /*
236 : * Input is a string constant with previously undetermined type. Apply
237 : * the target type's typinput function to it to produce a constant of
238 : * the target type.
239 : *
240 : * NOTE: this case cannot be folded together with the other
241 : * constant-input case, since the typinput function does not
242 : * necessarily behave the same as a type conversion function. For
243 : * example, int4's typinput function will reject "1.2", whereas
244 : * float-to-int type conversion will round to integer.
245 : *
246 : * XXX if the typinput function is not immutable, we really ought to
247 : * postpone evaluation of the function call until runtime. But there
248 : * is no way to represent a typinput function call as an expression
249 : * tree, because C-string values are not Datums. (XXX This *is*
250 : * possible as of 7.3, do we want to do it?)
251 : */
252 497981 : Const *con = (Const *) node;
253 497981 : Const *newcon = makeNode(Const);
254 : Oid baseTypeId;
255 : int32 baseTypeMod;
256 : int32 inputTypeMod;
257 : Type baseType;
258 : ParseCallbackState pcbstate;
259 :
260 : /*
261 : * If the target type is a domain, we want to call its base type's
262 : * input routine, not domain_in(). This is to avoid premature failure
263 : * when the domain applies a typmod: existing input routines follow
264 : * implicit-coercion semantics for length checks, which is not always
265 : * what we want here. The needed check will be applied properly
266 : * inside coerce_to_domain().
267 : */
268 497981 : baseTypeMod = targetTypeMod;
269 497981 : baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
270 :
271 : /*
272 : * For most types we pass typmod -1 to the input routine, because
273 : * existing input routines follow implicit-coercion semantics for
274 : * length checks, which is not always what we want here. Any length
275 : * constraint will be applied later by our caller. An exception
276 : * however is the INTERVAL type, for which we *must* pass the typmod
277 : * or it won't be able to obey the bizarre SQL-spec input rules. (Ugly
278 : * as sin, but so is this part of the spec...)
279 : */
280 497981 : if (baseTypeId == INTERVALOID)
281 3418 : inputTypeMod = baseTypeMod;
282 : else
283 494563 : inputTypeMod = -1;
284 :
285 497981 : baseType = typeidType(baseTypeId);
286 :
287 497981 : newcon->consttype = baseTypeId;
288 497981 : newcon->consttypmod = inputTypeMod;
289 497981 : newcon->constcollid = typeTypeCollation(baseType);
290 497981 : newcon->constlen = typeLen(baseType);
291 497981 : newcon->constbyval = typeByVal(baseType);
292 497981 : newcon->constisnull = con->constisnull;
293 :
294 : /*
295 : * We use the original literal's location regardless of the position
296 : * of the coercion. This is a change from pre-9.2 behavior, meant to
297 : * simplify life for pg_stat_statements.
298 : */
299 497981 : newcon->location = con->location;
300 :
301 : /*
302 : * Set up to point at the constant's text if the input routine throws
303 : * an error.
304 : */
305 497981 : setup_parser_errposition_callback(&pcbstate, pstate, con->location);
306 :
307 : /*
308 : * We assume here that UNKNOWN's internal representation is the same
309 : * as CSTRING.
310 : */
311 497981 : if (!con->constisnull)
312 447973 : newcon->constvalue = stringTypeDatum(baseType,
313 : DatumGetCString(con->constvalue),
314 : inputTypeMod);
315 : else
316 50008 : newcon->constvalue = stringTypeDatum(baseType,
317 : NULL,
318 : inputTypeMod);
319 :
320 : /*
321 : * If it's a varlena value, force it to be in non-expanded
322 : * (non-toasted) format; this avoids any possible dependency on
323 : * external values and improves consistency of representation.
324 : */
325 494495 : if (!con->constisnull && newcon->constlen == -1)
326 216258 : newcon->constvalue =
327 216258 : PointerGetDatum(PG_DETOAST_DATUM(newcon->constvalue));
328 :
329 : #ifdef RANDOMIZE_ALLOCATED_MEMORY
330 :
331 : /*
332 : * For pass-by-reference data types, repeat the conversion to see if
333 : * the input function leaves any uninitialized bytes in the result. We
334 : * can only detect that reliably if RANDOMIZE_ALLOCATED_MEMORY is
335 : * enabled, so we don't bother testing otherwise. The reason we don't
336 : * want any instability in the input function is that comparison of
337 : * Const nodes relies on bytewise comparison of the datums, so if the
338 : * input function leaves garbage then subexpressions that should be
339 : * identical may not get recognized as such. See pgsql-hackers
340 : * discussion of 2008-04-04.
341 : */
342 : if (!con->constisnull && !newcon->constbyval)
343 : {
344 : Datum val2;
345 :
346 : val2 = stringTypeDatum(baseType,
347 : DatumGetCString(con->constvalue),
348 : inputTypeMod);
349 : if (newcon->constlen == -1)
350 : val2 = PointerGetDatum(PG_DETOAST_DATUM(val2));
351 : if (!datumIsEqual(newcon->constvalue, val2, false, newcon->constlen))
352 : elog(WARNING, "type %s has unstable input conversion for \"%s\"",
353 : typeTypeName(baseType), DatumGetCString(con->constvalue));
354 : }
355 : #endif
356 :
357 494495 : cancel_parser_errposition_callback(&pcbstate);
358 :
359 494495 : result = (Node *) newcon;
360 :
361 : /* If target is a domain, apply constraints. */
362 494495 : if (baseTypeId != targetTypeId)
363 20464 : result = coerce_to_domain(result,
364 : baseTypeId, baseTypeMod,
365 : targetTypeId,
366 : ccontext, cformat, location,
367 : false);
368 :
369 494495 : ReleaseSysCache(baseType);
370 :
371 494495 : return result;
372 : }
373 211812 : if (IsA(node, Param) &&
374 11949 : pstate != NULL && pstate->p_coerce_param_hook != NULL)
375 : {
376 : /*
377 : * Allow the CoerceParamHook to decide what happens. It can return a
378 : * transformed node (very possibly the same Param node), or return
379 : * NULL to indicate we should proceed with normal coercion.
380 : */
381 6717 : result = pstate->p_coerce_param_hook(pstate,
382 : (Param *) node,
383 : targetTypeId,
384 : targetTypeMod,
385 : location);
386 6717 : if (result)
387 6664 : return result;
388 : }
389 205148 : if (IsA(node, CollateExpr))
390 : {
391 : /*
392 : * If we have a COLLATE clause, we have to push the coercion
393 : * underneath the COLLATE; or discard the COLLATE if the target type
394 : * isn't collatable. This is really ugly, but there is little choice
395 : * because the above hacks on Consts and Params wouldn't happen
396 : * otherwise. This kluge has consequences in coerce_to_target_type.
397 : */
398 5527 : CollateExpr *coll = (CollateExpr *) node;
399 :
400 5527 : result = coerce_type(pstate, (Node *) coll->arg,
401 : inputTypeId, targetTypeId, targetTypeMod,
402 : ccontext, cformat, location);
403 5527 : if (type_is_collatable(targetTypeId))
404 : {
405 5527 : CollateExpr *newcoll = makeNode(CollateExpr);
406 :
407 5527 : newcoll->arg = (Expr *) result;
408 5527 : newcoll->collOid = coll->collOid;
409 5527 : newcoll->location = coll->location;
410 5527 : result = (Node *) newcoll;
411 : }
412 5527 : return result;
413 : }
414 199621 : pathtype = find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
415 : &funcId);
416 199621 : if (pathtype != COERCION_PATH_NONE)
417 : {
418 : Oid baseTypeId;
419 : int32 baseTypeMod;
420 :
421 197344 : baseTypeMod = targetTypeMod;
422 197344 : baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
423 :
424 197344 : if (pathtype != COERCION_PATH_RELABELTYPE)
425 : {
426 : /*
427 : * Generate an expression tree representing run-time application
428 : * of the conversion function. If we are dealing with a domain
429 : * target type, the conversion function will yield the base type,
430 : * and we need to extract the correct typmod to use from the
431 : * domain's typtypmod.
432 : */
433 61810 : result = build_coercion_expression(node, pathtype, funcId,
434 : baseTypeId, baseTypeMod,
435 : ccontext, cformat, location);
436 :
437 : /*
438 : * If domain, coerce to the domain type and relabel with domain
439 : * type ID, hiding the previous coercion node.
440 : */
441 61810 : if (targetTypeId != baseTypeId)
442 1497 : result = coerce_to_domain(result, baseTypeId, baseTypeMod,
443 : targetTypeId,
444 : ccontext, cformat, location,
445 : true);
446 : }
447 : else
448 : {
449 : /*
450 : * We don't need to do a physical conversion, but we do need to
451 : * attach a RelabelType node so that the expression will be seen
452 : * to have the intended type when inspected by higher-level code.
453 : *
454 : * Also, domains may have value restrictions beyond the base type
455 : * that must be accounted for. If the destination is a domain
456 : * then we won't need a RelabelType node.
457 : */
458 135534 : result = coerce_to_domain(node, baseTypeId, baseTypeMod,
459 : targetTypeId,
460 : ccontext, cformat, location,
461 : false);
462 135534 : if (result == node)
463 : {
464 : /*
465 : * XXX could we label result with exprTypmod(node) instead of
466 : * default -1 typmod, to save a possible length-coercion
467 : * later? Would work if both types have same interpretation of
468 : * typmod, which is likely but not certain.
469 : */
470 104982 : RelabelType *r = makeRelabelType((Expr *) result,
471 : targetTypeId, -1,
472 : InvalidOid,
473 : cformat);
474 :
475 104982 : r->location = location;
476 104982 : result = (Node *) r;
477 : }
478 : }
479 197344 : return result;
480 : }
481 3504 : if (inputTypeId == RECORDOID &&
482 1227 : ISCOMPLEX(targetTypeId))
483 : {
484 : /* Coerce a RECORD to a specific complex type */
485 1227 : return coerce_record_to_complex(pstate, node, targetTypeId,
486 : ccontext, cformat, location);
487 : }
488 2046 : if (targetTypeId == RECORDOID &&
489 996 : ISCOMPLEX(inputTypeId))
490 : {
491 : /* Coerce a specific complex type to RECORD */
492 : /* NB: we do NOT want a RelabelType here */
493 996 : return node;
494 : }
495 : #ifdef NOT_USED
496 : if (inputTypeId == RECORDARRAYOID &&
497 : is_complex_array(targetTypeId))
498 : {
499 : /* Coerce record[] to a specific complex array type */
500 : /* not implemented yet ... */
501 : }
502 : #endif
503 64 : if (targetTypeId == RECORDARRAYOID &&
504 10 : is_complex_array(inputTypeId))
505 : {
506 : /* Coerce a specific complex array type to record[] */
507 : /* NB: we do NOT want a RelabelType here */
508 10 : return node;
509 : }
510 44 : if (typeInheritsFrom(inputTypeId, targetTypeId)
511 4 : || typeIsOfTypedTable(inputTypeId, targetTypeId))
512 : {
513 : /*
514 : * Input class type is a subclass of target, so generate an
515 : * appropriate runtime conversion (removing unneeded columns and
516 : * possibly rearranging the ones that are wanted).
517 : *
518 : * We will also get here when the input is a domain over a subclass of
519 : * the target type. To keep life simple for the executor, we define
520 : * ConvertRowtypeExpr as only working between regular composite types;
521 : * therefore, in such cases insert a RelabelType to smash the input
522 : * expression down to its base type.
523 : */
524 44 : Oid baseTypeId = getBaseType(inputTypeId);
525 44 : ConvertRowtypeExpr *r = makeNode(ConvertRowtypeExpr);
526 :
527 44 : if (baseTypeId != inputTypeId)
528 : {
529 0 : RelabelType *rt = makeRelabelType((Expr *) node,
530 : baseTypeId, -1,
531 : InvalidOid,
532 : COERCE_IMPLICIT_CAST);
533 :
534 0 : rt->location = location;
535 0 : node = (Node *) rt;
536 : }
537 44 : r->arg = (Expr *) node;
538 44 : r->resulttype = targetTypeId;
539 44 : r->convertformat = cformat;
540 44 : r->location = location;
541 44 : return (Node *) r;
542 : }
543 : /* If we get here, caller blew it */
544 0 : elog(ERROR, "failed to find conversion function from %s to %s",
545 : format_type_be(inputTypeId), format_type_be(targetTypeId));
546 : return NULL; /* keep compiler quiet */
547 : }
548 :
549 :
550 : /*
551 : * can_coerce_type()
552 : * Can input_typeids be coerced to target_typeids?
553 : *
554 : * We must be told the context (CAST construct, assignment, implicit coercion)
555 : * as this determines the set of available casts.
556 : */
557 : bool
558 1365192 : can_coerce_type(int nargs, const Oid *input_typeids, const Oid *target_typeids,
559 : CoercionContext ccontext)
560 : {
561 1365192 : bool have_generics = false;
562 : int i;
563 :
564 : /* run through argument list... */
565 2415121 : for (i = 0; i < nargs; i++)
566 : {
567 1584855 : Oid inputTypeId = input_typeids[i];
568 1584855 : Oid targetTypeId = target_typeids[i];
569 : CoercionPathType pathtype;
570 : Oid funcId;
571 :
572 : /* no problem if same type */
573 1584855 : if (inputTypeId == targetTypeId)
574 1049929 : continue;
575 :
576 : /* accept if target is ANY */
577 1308569 : if (targetTypeId == ANYOID)
578 42617 : continue;
579 :
580 : /* accept if target is polymorphic, for now */
581 1265952 : if (IsPolymorphicType(targetTypeId))
582 : {
583 131938 : have_generics = true; /* do more checking later */
584 131938 : continue;
585 : }
586 :
587 : /*
588 : * If input is an untyped string constant, assume we can convert it to
589 : * anything.
590 : */
591 1134014 : if (inputTypeId == UNKNOWNOID)
592 428980 : continue;
593 :
594 : /*
595 : * If pg_cast shows that we can coerce, accept. This test now covers
596 : * both binary-compatible and coercion-function cases.
597 : */
598 705034 : pathtype = find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
599 : &funcId);
600 705034 : if (pathtype != COERCION_PATH_NONE)
601 168067 : continue;
602 :
603 : /*
604 : * If input is RECORD and target is a composite type, assume we can
605 : * coerce (may need tighter checking here)
606 : */
607 538286 : if (inputTypeId == RECORDOID &&
608 1319 : ISCOMPLEX(targetTypeId))
609 1227 : continue;
610 :
611 : /*
612 : * If input is a composite type and target is RECORD, accept
613 : */
614 544492 : if (targetTypeId == RECORDOID &&
615 8752 : ISCOMPLEX(inputTypeId))
616 770 : continue;
617 :
618 : #ifdef NOT_USED /* not implemented yet */
619 :
620 : /*
621 : * If input is record[] and target is a composite array type, assume
622 : * we can coerce (may need tighter checking here)
623 : */
624 : if (inputTypeId == RECORDARRAYOID &&
625 : is_complex_array(targetTypeId))
626 : continue;
627 : #endif
628 :
629 : /*
630 : * If input is a composite array type and target is record[], accept
631 : */
632 534978 : if (targetTypeId == RECORDARRAYOID &&
633 8 : is_complex_array(inputTypeId))
634 0 : continue;
635 :
636 : /*
637 : * If input is a class type that inherits from target, accept
638 : */
639 534970 : if (typeInheritsFrom(inputTypeId, targetTypeId)
640 534930 : || typeIsOfTypedTable(inputTypeId, targetTypeId))
641 44 : continue;
642 :
643 : /*
644 : * Else, cannot coerce at this argument position
645 : */
646 534926 : return false;
647 : }
648 :
649 : /* If we found any generic argument types, cross-check them */
650 830266 : if (have_generics)
651 : {
652 89043 : if (!check_generic_type_consistency(input_typeids, target_typeids,
653 : nargs))
654 51577 : return false;
655 : }
656 :
657 778689 : return true;
658 : }
659 :
660 :
661 : /*
662 : * Create an expression tree to represent coercion to a domain type.
663 : *
664 : * 'arg': input expression
665 : * 'baseTypeId': base type of domain
666 : * 'baseTypeMod': base type typmod of domain
667 : * 'typeId': target type to coerce to
668 : * 'ccontext': context indicator to control coercions
669 : * 'cformat': coercion display format
670 : * 'location': coercion request location
671 : * 'hideInputCoercion': if true, hide the input coercion under this one.
672 : *
673 : * If the target type isn't a domain, the given 'arg' is returned as-is.
674 : */
675 : Node *
676 157940 : coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId,
677 : CoercionContext ccontext, CoercionForm cformat, int location,
678 : bool hideInputCoercion)
679 : {
680 : CoerceToDomain *result;
681 :
682 : /* We now require the caller to supply correct baseTypeId/baseTypeMod */
683 : Assert(OidIsValid(baseTypeId));
684 :
685 : /* If it isn't a domain, return the node as it was passed in */
686 157940 : if (baseTypeId == typeId)
687 104982 : return arg;
688 :
689 : /* Suppress display of nested coercion steps */
690 52958 : if (hideInputCoercion)
691 1497 : hide_coercion_node(arg);
692 :
693 : /*
694 : * If the domain applies a typmod to its base type, build the appropriate
695 : * coercion step. Mark it implicit for display purposes, because we don't
696 : * want it shown separately by ruleutils.c; but the isExplicit flag passed
697 : * to the conversion function depends on the manner in which the domain
698 : * coercion is invoked, so that the semantics of implicit and explicit
699 : * coercion differ. (Is that really the behavior we want?)
700 : *
701 : * NOTE: because we apply this as part of the fixed expression structure,
702 : * ALTER DOMAIN cannot alter the typtypmod. But it's unclear that that
703 : * would be safe to do anyway, without lots of knowledge about what the
704 : * base type thinks the typmod means.
705 : */
706 52958 : arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod,
707 : ccontext, COERCE_IMPLICIT_CAST, location,
708 : false);
709 :
710 : /*
711 : * Now build the domain coercion node. This represents run-time checking
712 : * of any constraints currently attached to the domain. This also ensures
713 : * that the expression is properly labeled as to result type.
714 : */
715 52958 : result = makeNode(CoerceToDomain);
716 52958 : result->arg = (Expr *) arg;
717 52958 : result->resulttype = typeId;
718 52958 : result->resulttypmod = -1; /* currently, always -1 for domains */
719 : /* resultcollid will be set by parse_collate.c */
720 52958 : result->coercionformat = cformat;
721 52958 : result->location = location;
722 :
723 52958 : return (Node *) result;
724 : }
725 :
726 :
727 : /*
728 : * coerce_type_typmod()
729 : * Force a value to a particular typmod, if meaningful and possible.
730 : *
731 : * This is applied to values that are going to be stored in a relation
732 : * (where we have an atttypmod for the column) as well as values being
733 : * explicitly CASTed (where the typmod comes from the target type spec).
734 : *
735 : * The caller must have already ensured that the value is of the correct
736 : * type, typically by applying coerce_type.
737 : *
738 : * ccontext may affect semantics, depending on whether the length coercion
739 : * function pays attention to the isExplicit flag it's passed.
740 : *
741 : * cformat determines the display properties of the generated node (if any).
742 : *
743 : * If hideInputCoercion is true *and* we generate a node, the input node is
744 : * forced to IMPLICIT display form, so that only the typmod coercion node will
745 : * be visible when displaying the expression.
746 : *
747 : * NOTE: this does not need to work on domain types, because any typmod
748 : * coercion for a domain is considered to be part of the type coercion
749 : * needed to produce the domain value in the first place. So, no getBaseType.
750 : */
751 : static Node *
752 517588 : coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod,
753 : CoercionContext ccontext, CoercionForm cformat,
754 : int location,
755 : bool hideInputCoercion)
756 : {
757 : CoercionPathType pathtype;
758 : Oid funcId;
759 :
760 : /* Skip coercion if already done */
761 517588 : if (targetTypMod == exprTypmod(node))
762 503767 : return node;
763 :
764 : /* Suppress display of nested coercion steps */
765 13821 : if (hideInputCoercion)
766 628 : hide_coercion_node(node);
767 :
768 : /*
769 : * A negative typmod means that no actual coercion is needed, but we still
770 : * want a RelabelType to ensure that the expression exposes the intended
771 : * typmod.
772 : */
773 13821 : if (targetTypMod < 0)
774 37 : pathtype = COERCION_PATH_NONE;
775 : else
776 13784 : pathtype = find_typmod_coercion_function(targetTypeId, &funcId);
777 :
778 13821 : if (pathtype != COERCION_PATH_NONE)
779 : {
780 13776 : node = build_coercion_expression(node, pathtype, funcId,
781 : targetTypeId, targetTypMod,
782 : ccontext, cformat, location);
783 : }
784 : else
785 : {
786 : /*
787 : * We don't need to perform any actual coercion step, but we should
788 : * apply a RelabelType to ensure that the expression exposes the
789 : * intended typmod.
790 : */
791 45 : node = applyRelabelType(node, targetTypeId, targetTypMod,
792 : exprCollation(node),
793 : cformat, location, false);
794 : }
795 :
796 13821 : return node;
797 : }
798 :
799 : /*
800 : * Mark a coercion node as IMPLICIT so it will never be displayed by
801 : * ruleutils.c. We use this when we generate a nest of coercion nodes
802 : * to implement what is logically one conversion; the inner nodes are
803 : * forced to IMPLICIT_CAST format. This does not change their semantics,
804 : * only display behavior.
805 : *
806 : * It is caller error to call this on something that doesn't have a
807 : * CoercionForm field.
808 : */
809 : static void
810 2125 : hide_coercion_node(Node *node)
811 : {
812 2125 : if (IsA(node, FuncExpr))
813 958 : ((FuncExpr *) node)->funcformat = COERCE_IMPLICIT_CAST;
814 1167 : else if (IsA(node, RelabelType))
815 195 : ((RelabelType *) node)->relabelformat = COERCE_IMPLICIT_CAST;
816 972 : else if (IsA(node, CoerceViaIO))
817 964 : ((CoerceViaIO *) node)->coerceformat = COERCE_IMPLICIT_CAST;
818 8 : else if (IsA(node, ArrayCoerceExpr))
819 8 : ((ArrayCoerceExpr *) node)->coerceformat = COERCE_IMPLICIT_CAST;
820 0 : else if (IsA(node, ConvertRowtypeExpr))
821 0 : ((ConvertRowtypeExpr *) node)->convertformat = COERCE_IMPLICIT_CAST;
822 0 : else if (IsA(node, RowExpr))
823 0 : ((RowExpr *) node)->row_format = COERCE_IMPLICIT_CAST;
824 0 : else if (IsA(node, CoerceToDomain))
825 0 : ((CoerceToDomain *) node)->coercionformat = COERCE_IMPLICIT_CAST;
826 : else
827 0 : elog(ERROR, "unsupported node type: %d", (int) nodeTag(node));
828 2125 : }
829 :
830 : /*
831 : * build_coercion_expression()
832 : * Construct an expression tree for applying a pg_cast entry.
833 : *
834 : * This is used for both type-coercion and length-coercion operations,
835 : * since there is no difference in terms of the calling convention.
836 : */
837 : static Node *
838 75586 : build_coercion_expression(Node *node,
839 : CoercionPathType pathtype,
840 : Oid funcId,
841 : Oid targetTypeId, int32 targetTypMod,
842 : CoercionContext ccontext, CoercionForm cformat,
843 : int location)
844 : {
845 75586 : int nargs = 0;
846 :
847 75586 : if (OidIsValid(funcId))
848 : {
849 : HeapTuple tp;
850 : Form_pg_proc procstruct;
851 :
852 55593 : tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcId));
853 55593 : if (!HeapTupleIsValid(tp))
854 0 : elog(ERROR, "cache lookup failed for function %u", funcId);
855 55593 : procstruct = (Form_pg_proc) GETSTRUCT(tp);
856 :
857 : /*
858 : * These Asserts essentially check that function is a legal coercion
859 : * function. We can't make the seemingly obvious tests on prorettype
860 : * and proargtypes[0], even in the COERCION_PATH_FUNC case, because of
861 : * various binary-compatibility cases.
862 : */
863 : /* Assert(targetTypeId == procstruct->prorettype); */
864 : Assert(!procstruct->proretset);
865 : Assert(procstruct->prokind == PROKIND_FUNCTION);
866 55593 : nargs = procstruct->pronargs;
867 : Assert(nargs >= 1 && nargs <= 3);
868 : /* Assert(procstruct->proargtypes.values[0] == exprType(node)); */
869 : Assert(nargs < 2 || procstruct->proargtypes.values[1] == INT4OID);
870 : Assert(nargs < 3 || procstruct->proargtypes.values[2] == BOOLOID);
871 :
872 55593 : ReleaseSysCache(tp);
873 : }
874 :
875 75586 : if (pathtype == COERCION_PATH_FUNC)
876 : {
877 : /* We build an ordinary FuncExpr with special arguments */
878 : FuncExpr *fexpr;
879 : List *args;
880 : Const *cons;
881 :
882 : Assert(OidIsValid(funcId));
883 :
884 55541 : args = list_make1(node);
885 :
886 55541 : if (nargs >= 2)
887 : {
888 : /* Pass target typmod as an int4 constant */
889 14593 : cons = makeConst(INT4OID,
890 : -1,
891 : InvalidOid,
892 : sizeof(int32),
893 : Int32GetDatum(targetTypMod),
894 : false,
895 : true);
896 :
897 14593 : args = lappend(args, cons);
898 : }
899 :
900 55541 : if (nargs == 3)
901 : {
902 : /* Pass it a boolean isExplicit parameter, too */
903 9689 : cons = makeConst(BOOLOID,
904 : -1,
905 : InvalidOid,
906 : sizeof(bool),
907 : BoolGetDatum(ccontext == COERCION_EXPLICIT),
908 : false,
909 : true);
910 :
911 9689 : args = lappend(args, cons);
912 : }
913 :
914 55541 : fexpr = makeFuncExpr(funcId, targetTypeId, args,
915 : InvalidOid, InvalidOid, cformat);
916 55541 : fexpr->location = location;
917 55541 : return (Node *) fexpr;
918 : }
919 20045 : else if (pathtype == COERCION_PATH_ARRAYCOERCE)
920 : {
921 : /* We need to build an ArrayCoerceExpr */
922 3777 : ArrayCoerceExpr *acoerce = makeNode(ArrayCoerceExpr);
923 3777 : CaseTestExpr *ctest = makeNode(CaseTestExpr);
924 : Oid sourceBaseTypeId;
925 : int32 sourceBaseTypeMod;
926 : Oid targetElementType;
927 : Node *elemexpr;
928 :
929 : /*
930 : * Look through any domain over the source array type. Note we don't
931 : * expect that the target type is a domain; it must be a plain array.
932 : * (To get to a domain target type, we'll do coerce_to_domain later.)
933 : */
934 3777 : sourceBaseTypeMod = exprTypmod(node);
935 3777 : sourceBaseTypeId = getBaseTypeAndTypmod(exprType(node),
936 : &sourceBaseTypeMod);
937 :
938 : /*
939 : * Set up a CaseTestExpr representing one element of the source array.
940 : * This is an abuse of CaseTestExpr, but it's OK as long as there
941 : * can't be any CaseExpr or ArrayCoerceExpr within the completed
942 : * elemexpr.
943 : */
944 3777 : ctest->typeId = get_element_type(sourceBaseTypeId);
945 : Assert(OidIsValid(ctest->typeId));
946 3777 : ctest->typeMod = sourceBaseTypeMod;
947 3777 : ctest->collation = InvalidOid; /* Assume coercions don't care */
948 :
949 : /* And coerce it to the target element type */
950 3777 : targetElementType = get_element_type(targetTypeId);
951 : Assert(OidIsValid(targetElementType));
952 :
953 3777 : elemexpr = coerce_to_target_type(NULL,
954 : (Node *) ctest,
955 : ctest->typeId,
956 : targetElementType,
957 : targetTypMod,
958 : ccontext,
959 : cformat,
960 : location);
961 3777 : if (elemexpr == NULL) /* shouldn't happen */
962 0 : elog(ERROR, "failed to coerce array element type as expected");
963 :
964 3777 : acoerce->arg = (Expr *) node;
965 3777 : acoerce->elemexpr = (Expr *) elemexpr;
966 3777 : acoerce->resulttype = targetTypeId;
967 :
968 : /*
969 : * Label the output as having a particular element typmod only if we
970 : * ended up with a per-element expression that is labeled that way.
971 : */
972 3777 : acoerce->resulttypmod = exprTypmod(elemexpr);
973 : /* resultcollid will be set by parse_collate.c */
974 3777 : acoerce->coerceformat = cformat;
975 3777 : acoerce->location = location;
976 :
977 3777 : return (Node *) acoerce;
978 : }
979 16268 : else if (pathtype == COERCION_PATH_COERCEVIAIO)
980 : {
981 : /* We need to build a CoerceViaIO node */
982 16268 : CoerceViaIO *iocoerce = makeNode(CoerceViaIO);
983 :
984 : Assert(!OidIsValid(funcId));
985 :
986 16268 : iocoerce->arg = (Expr *) node;
987 16268 : iocoerce->resulttype = targetTypeId;
988 : /* resultcollid will be set by parse_collate.c */
989 16268 : iocoerce->coerceformat = cformat;
990 16268 : iocoerce->location = location;
991 :
992 16268 : return (Node *) iocoerce;
993 : }
994 : else
995 : {
996 0 : elog(ERROR, "unsupported pathtype %d in build_coercion_expression",
997 : (int) pathtype);
998 : return NULL; /* keep compiler quiet */
999 : }
1000 : }
1001 :
1002 :
1003 : /*
1004 : * coerce_record_to_complex
1005 : * Coerce a RECORD to a specific composite type.
1006 : *
1007 : * Currently we only support this for inputs that are RowExprs or whole-row
1008 : * Vars.
1009 : */
1010 : static Node *
1011 1227 : coerce_record_to_complex(ParseState *pstate, Node *node,
1012 : Oid targetTypeId,
1013 : CoercionContext ccontext,
1014 : CoercionForm cformat,
1015 : int location)
1016 : {
1017 : RowExpr *rowexpr;
1018 : Oid baseTypeId;
1019 1227 : int32 baseTypeMod = -1;
1020 : TupleDesc tupdesc;
1021 1227 : List *args = NIL;
1022 : List *newargs;
1023 : int i;
1024 : int ucolno;
1025 : ListCell *arg;
1026 :
1027 1227 : if (node && IsA(node, RowExpr))
1028 : {
1029 : /*
1030 : * Since the RowExpr must be of type RECORD, we needn't worry about it
1031 : * containing any dropped columns.
1032 : */
1033 1203 : args = ((RowExpr *) node)->args;
1034 : }
1035 24 : else if (node && IsA(node, Var) &&
1036 24 : ((Var *) node)->varattno == InvalidAttrNumber)
1037 24 : {
1038 24 : Var *var = (Var *) node;
1039 : ParseNamespaceItem *nsitem;
1040 :
1041 24 : nsitem = GetNSItemByVar(pstate, var);
1042 24 : args = expandNSItemVars(pstate, nsitem, var->varlevelsup,
1043 : var->location, NULL);
1044 : }
1045 : else
1046 0 : ereport(ERROR,
1047 : (errcode(ERRCODE_CANNOT_COERCE),
1048 : errmsg("cannot cast type %s to %s",
1049 : format_type_be(RECORDOID),
1050 : format_type_be(targetTypeId)),
1051 : parser_coercion_errposition(pstate, location, node)));
1052 :
1053 : /*
1054 : * Look up the composite type, accounting for possibility that what we are
1055 : * given is a domain over composite.
1056 : */
1057 1227 : baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
1058 1227 : tupdesc = lookup_rowtype_tupdesc(baseTypeId, baseTypeMod);
1059 :
1060 : /* Process the fields */
1061 1227 : newargs = NIL;
1062 1227 : ucolno = 1;
1063 1227 : arg = list_head(args);
1064 4331 : for (i = 0; i < tupdesc->natts; i++)
1065 : {
1066 : Node *expr;
1067 : Node *cexpr;
1068 : Oid exprtype;
1069 3104 : Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
1070 :
1071 : /* Fill in NULLs for dropped columns in rowtype */
1072 3104 : if (attr->attisdropped)
1073 : {
1074 : /*
1075 : * can't use atttypid here, but it doesn't really matter what type
1076 : * the Const claims to be.
1077 : */
1078 3 : newargs = lappend(newargs,
1079 3 : makeNullConst(INT4OID, -1, InvalidOid));
1080 3 : continue;
1081 : }
1082 :
1083 3101 : if (arg == NULL)
1084 0 : ereport(ERROR,
1085 : (errcode(ERRCODE_CANNOT_COERCE),
1086 : errmsg("cannot cast type %s to %s",
1087 : format_type_be(RECORDOID),
1088 : format_type_be(targetTypeId)),
1089 : errdetail("Input has too few columns."),
1090 : parser_coercion_errposition(pstate, location, node)));
1091 3101 : expr = (Node *) lfirst(arg);
1092 3101 : exprtype = exprType(expr);
1093 :
1094 3101 : cexpr = coerce_to_target_type(pstate,
1095 : expr, exprtype,
1096 : attr->atttypid,
1097 : attr->atttypmod,
1098 : ccontext,
1099 : COERCE_IMPLICIT_CAST,
1100 : -1);
1101 3101 : if (cexpr == NULL)
1102 0 : ereport(ERROR,
1103 : (errcode(ERRCODE_CANNOT_COERCE),
1104 : errmsg("cannot cast type %s to %s",
1105 : format_type_be(RECORDOID),
1106 : format_type_be(targetTypeId)),
1107 : errdetail("Cannot cast type %s to %s in column %d.",
1108 : format_type_be(exprtype),
1109 : format_type_be(attr->atttypid),
1110 : ucolno),
1111 : parser_coercion_errposition(pstate, location, expr)));
1112 3101 : newargs = lappend(newargs, cexpr);
1113 3101 : ucolno++;
1114 3101 : arg = lnext(args, arg);
1115 : }
1116 1227 : if (arg != NULL)
1117 0 : ereport(ERROR,
1118 : (errcode(ERRCODE_CANNOT_COERCE),
1119 : errmsg("cannot cast type %s to %s",
1120 : format_type_be(RECORDOID),
1121 : format_type_be(targetTypeId)),
1122 : errdetail("Input has too many columns."),
1123 : parser_coercion_errposition(pstate, location, node)));
1124 :
1125 1227 : ReleaseTupleDesc(tupdesc);
1126 :
1127 1227 : rowexpr = makeNode(RowExpr);
1128 1227 : rowexpr->args = newargs;
1129 1227 : rowexpr->row_typeid = baseTypeId;
1130 1227 : rowexpr->row_format = cformat;
1131 1227 : rowexpr->colnames = NIL; /* not needed for named target type */
1132 1227 : rowexpr->location = location;
1133 :
1134 : /* If target is a domain, apply constraints */
1135 1227 : if (baseTypeId != targetTypeId)
1136 : {
1137 102 : rowexpr->row_format = COERCE_IMPLICIT_CAST;
1138 102 : return coerce_to_domain((Node *) rowexpr,
1139 : baseTypeId, baseTypeMod,
1140 : targetTypeId,
1141 : ccontext, cformat, location,
1142 : false);
1143 : }
1144 :
1145 1125 : return (Node *) rowexpr;
1146 : }
1147 :
1148 : /*
1149 : * coerce_to_boolean()
1150 : * Coerce an argument of a construct that requires boolean input
1151 : * (AND, OR, NOT, etc). Also check that input is not a set.
1152 : *
1153 : * Returns the possibly-transformed node tree.
1154 : *
1155 : * As with coerce_type, pstate may be NULL if no special unknown-Param
1156 : * processing is wanted.
1157 : */
1158 : Node *
1159 550060 : coerce_to_boolean(ParseState *pstate, Node *node,
1160 : const char *constructName)
1161 : {
1162 550060 : Oid inputTypeId = exprType(node);
1163 :
1164 550060 : if (inputTypeId != BOOLOID)
1165 : {
1166 : Node *newnode;
1167 :
1168 48 : newnode = coerce_to_target_type(pstate, node, inputTypeId,
1169 : BOOLOID, -1,
1170 : COERCION_ASSIGNMENT,
1171 : COERCE_IMPLICIT_CAST,
1172 : -1);
1173 48 : if (newnode == NULL)
1174 4 : ereport(ERROR,
1175 : (errcode(ERRCODE_DATATYPE_MISMATCH),
1176 : /* translator: first %s is name of a SQL construct, eg WHERE */
1177 : errmsg("argument of %s must be type %s, not type %s",
1178 : constructName, "boolean",
1179 : format_type_be(inputTypeId)),
1180 : parser_errposition(pstate, exprLocation(node))));
1181 44 : node = newnode;
1182 : }
1183 :
1184 550056 : if (expression_returns_set(node))
1185 0 : ereport(ERROR,
1186 : (errcode(ERRCODE_DATATYPE_MISMATCH),
1187 : /* translator: %s is name of a SQL construct, eg WHERE */
1188 : errmsg("argument of %s must not return a set",
1189 : constructName),
1190 : parser_errposition(pstate, exprLocation(node))));
1191 :
1192 550056 : return node;
1193 : }
1194 :
1195 : /*
1196 : * coerce_to_specific_type_typmod()
1197 : * Coerce an argument of a construct that requires a specific data type,
1198 : * with a specific typmod. Also check that input is not a set.
1199 : *
1200 : * Returns the possibly-transformed node tree.
1201 : *
1202 : * As with coerce_type, pstate may be NULL if no special unknown-Param
1203 : * processing is wanted.
1204 : */
1205 : Node *
1206 7258 : coerce_to_specific_type_typmod(ParseState *pstate, Node *node,
1207 : Oid targetTypeId, int32 targetTypmod,
1208 : const char *constructName)
1209 : {
1210 7258 : Oid inputTypeId = exprType(node);
1211 :
1212 7258 : if (inputTypeId != targetTypeId)
1213 : {
1214 : Node *newnode;
1215 :
1216 6080 : newnode = coerce_to_target_type(pstate, node, inputTypeId,
1217 : targetTypeId, targetTypmod,
1218 : COERCION_ASSIGNMENT,
1219 : COERCE_IMPLICIT_CAST,
1220 : -1);
1221 6072 : if (newnode == NULL)
1222 4 : ereport(ERROR,
1223 : (errcode(ERRCODE_DATATYPE_MISMATCH),
1224 : /* translator: first %s is name of a SQL construct, eg LIMIT */
1225 : errmsg("argument of %s must be type %s, not type %s",
1226 : constructName,
1227 : format_type_be(targetTypeId),
1228 : format_type_be(inputTypeId)),
1229 : parser_errposition(pstate, exprLocation(node))));
1230 6068 : node = newnode;
1231 : }
1232 :
1233 7246 : if (expression_returns_set(node))
1234 0 : ereport(ERROR,
1235 : (errcode(ERRCODE_DATATYPE_MISMATCH),
1236 : /* translator: %s is name of a SQL construct, eg LIMIT */
1237 : errmsg("argument of %s must not return a set",
1238 : constructName),
1239 : parser_errposition(pstate, exprLocation(node))));
1240 :
1241 7246 : return node;
1242 : }
1243 :
1244 : /*
1245 : * coerce_to_specific_type()
1246 : * Coerce an argument of a construct that requires a specific data type.
1247 : * Also check that input is not a set.
1248 : *
1249 : * Returns the possibly-transformed node tree.
1250 : *
1251 : * As with coerce_type, pstate may be NULL if no special unknown-Param
1252 : * processing is wanted.
1253 : */
1254 : Node *
1255 7221 : coerce_to_specific_type(ParseState *pstate, Node *node,
1256 : Oid targetTypeId,
1257 : const char *constructName)
1258 : {
1259 7221 : return coerce_to_specific_type_typmod(pstate, node,
1260 : targetTypeId, -1,
1261 : constructName);
1262 : }
1263 :
1264 : /*
1265 : * coerce_null_to_domain()
1266 : * Build a NULL constant, then wrap it in CoerceToDomain
1267 : * if the desired type is a domain type. This allows any
1268 : * NOT NULL domain constraint to be enforced at runtime.
1269 : */
1270 : Node *
1271 12850 : coerce_null_to_domain(Oid typid, int32 typmod, Oid collation,
1272 : int typlen, bool typbyval)
1273 : {
1274 : Node *result;
1275 : Oid baseTypeId;
1276 12850 : int32 baseTypeMod = typmod;
1277 :
1278 : /*
1279 : * The constant must appear to have the domain's base type/typmod, else
1280 : * coerce_to_domain() will apply a length coercion which is useless.
1281 : */
1282 12850 : baseTypeId = getBaseTypeAndTypmod(typid, &baseTypeMod);
1283 12850 : result = (Node *) makeConst(baseTypeId,
1284 : baseTypeMod,
1285 : collation,
1286 : typlen,
1287 : (Datum) 0,
1288 : true, /* isnull */
1289 : typbyval);
1290 12850 : if (typid != baseTypeId)
1291 55 : result = coerce_to_domain(result,
1292 : baseTypeId, baseTypeMod,
1293 : typid,
1294 : COERCION_IMPLICIT,
1295 : COERCE_IMPLICIT_CAST,
1296 : -1,
1297 : false);
1298 12850 : return result;
1299 : }
1300 :
1301 : /*
1302 : * parser_coercion_errposition - report coercion error location, if possible
1303 : *
1304 : * We prefer to point at the coercion request (CAST, ::, etc) if possible;
1305 : * but there may be no such location in the case of an implicit coercion.
1306 : * In that case point at the input expression.
1307 : *
1308 : * XXX possibly this is more generally useful than coercion errors;
1309 : * if so, should rename and place with parser_errposition.
1310 : */
1311 : int
1312 18 : parser_coercion_errposition(ParseState *pstate,
1313 : int coerce_location,
1314 : Node *input_expr)
1315 : {
1316 18 : if (coerce_location >= 0)
1317 18 : return parser_errposition(pstate, coerce_location);
1318 : else
1319 0 : return parser_errposition(pstate, exprLocation(input_expr));
1320 : }
1321 :
1322 :
1323 : /*
1324 : * select_common_type()
1325 : * Determine the common supertype of a list of input expressions.
1326 : * This is used for determining the output type of CASE, UNION,
1327 : * and similar constructs.
1328 : *
1329 : * 'exprs' is a *nonempty* list of expressions. Note that earlier items
1330 : * in the list will be preferred if there is doubt.
1331 : * 'context' is a phrase to use in the error message if we fail to select
1332 : * a usable type. Pass NULL to have the routine return InvalidOid
1333 : * rather than throwing an error on failure.
1334 : * 'which_expr': if not NULL, receives a pointer to the particular input
1335 : * expression from which the result type was taken.
1336 : *
1337 : * Caution: "failure" just means that there were inputs of different type
1338 : * categories. It is not guaranteed that all the inputs are coercible to the
1339 : * selected type; caller must check that (see verify_common_type).
1340 : */
1341 : Oid
1342 95607 : select_common_type(ParseState *pstate, List *exprs, const char *context,
1343 : Node **which_expr)
1344 : {
1345 : Node *pexpr;
1346 : Oid ptype;
1347 : TYPCATEGORY pcategory;
1348 : bool pispreferred;
1349 : ListCell *lc;
1350 :
1351 : Assert(exprs != NIL);
1352 95607 : pexpr = (Node *) linitial(exprs);
1353 95607 : lc = list_second_cell(exprs);
1354 95607 : ptype = exprType(pexpr);
1355 :
1356 : /*
1357 : * If all input types are valid and exactly the same, just pick that type.
1358 : * This is the only way that we will resolve the result as being a domain
1359 : * type; otherwise domains are smashed to their base types for comparison.
1360 : */
1361 95607 : if (ptype != UNKNOWNOID)
1362 : {
1363 126193 : for_each_cell(lc, exprs, lc)
1364 : {
1365 79870 : Node *nexpr = (Node *) lfirst(lc);
1366 79870 : Oid ntype = exprType(nexpr);
1367 :
1368 79870 : if (ntype != ptype)
1369 26395 : break;
1370 : }
1371 72718 : if (lc == NULL) /* got to the end of the list? */
1372 : {
1373 46323 : if (which_expr)
1374 30719 : *which_expr = pexpr;
1375 46323 : return ptype;
1376 : }
1377 : }
1378 :
1379 : /*
1380 : * Nope, so set up for the full algorithm. Note that at this point, lc
1381 : * points to the first list item with type different from pexpr's; we need
1382 : * not re-examine any items the previous loop advanced over.
1383 : */
1384 49284 : ptype = getBaseType(ptype);
1385 49284 : get_type_category_preferred(ptype, &pcategory, &pispreferred);
1386 :
1387 143823 : for_each_cell(lc, exprs, lc)
1388 : {
1389 94549 : Node *nexpr = (Node *) lfirst(lc);
1390 94549 : Oid ntype = getBaseType(exprType(nexpr));
1391 :
1392 : /* move on to next one if no new information... */
1393 94549 : if (ntype != UNKNOWNOID && ntype != ptype)
1394 : {
1395 : TYPCATEGORY ncategory;
1396 : bool nispreferred;
1397 :
1398 18132 : get_type_category_preferred(ntype, &ncategory, &nispreferred);
1399 18132 : if (ptype == UNKNOWNOID)
1400 : {
1401 : /* so far, only unknowns so take anything... */
1402 12853 : pexpr = nexpr;
1403 12853 : ptype = ntype;
1404 12853 : pcategory = ncategory;
1405 12853 : pispreferred = nispreferred;
1406 : }
1407 5279 : else if (ncategory != pcategory)
1408 : {
1409 : /*
1410 : * both types in different categories? then not much hope...
1411 : */
1412 10 : if (context == NULL)
1413 2 : return InvalidOid;
1414 8 : ereport(ERROR,
1415 : (errcode(ERRCODE_DATATYPE_MISMATCH),
1416 : /*------
1417 : translator: first %s is name of a SQL construct, eg CASE */
1418 : errmsg("%s types %s and %s cannot be matched",
1419 : context,
1420 : format_type_be(ptype),
1421 : format_type_be(ntype)),
1422 : parser_errposition(pstate, exprLocation(nexpr))));
1423 : }
1424 6877 : else if (!pispreferred &&
1425 1608 : can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
1426 1008 : !can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
1427 : {
1428 : /*
1429 : * take new type if can coerce to it implicitly but not the
1430 : * other way; but if we have a preferred type, stay on it.
1431 : */
1432 894 : pexpr = nexpr;
1433 894 : ptype = ntype;
1434 894 : pcategory = ncategory;
1435 894 : pispreferred = nispreferred;
1436 : }
1437 : }
1438 : }
1439 :
1440 : /*
1441 : * If all the inputs were UNKNOWN type --- ie, unknown-type literals ---
1442 : * then resolve as type TEXT. This situation comes up with constructs
1443 : * like SELECT (CASE WHEN foo THEN 'bar' ELSE 'baz' END); SELECT 'foo'
1444 : * UNION SELECT 'bar'; It might seem desirable to leave the construct's
1445 : * output type as UNKNOWN, but that really doesn't work, because we'd
1446 : * probably end up needing a runtime coercion from UNKNOWN to something
1447 : * else, and we usually won't have it. We need to coerce the unknown
1448 : * literals while they are still literals, so a decision has to be made
1449 : * now.
1450 : */
1451 49274 : if (ptype == UNKNOWNOID)
1452 10036 : ptype = TEXTOID;
1453 :
1454 49274 : if (which_expr)
1455 10534 : *which_expr = pexpr;
1456 49274 : return ptype;
1457 : }
1458 :
1459 : /*
1460 : * select_common_type_from_oids()
1461 : * Determine the common supertype of an array of type OIDs.
1462 : *
1463 : * This is the same logic as select_common_type(), but working from
1464 : * an array of type OIDs not a list of expressions. As in that function,
1465 : * earlier entries in the array have some preference over later ones.
1466 : * On failure, return InvalidOid if noerror is true, else throw an error.
1467 : *
1468 : * Caution: "failure" just means that there were inputs of different type
1469 : * categories. It is not guaranteed that all the inputs are coercible to the
1470 : * selected type; caller must check that (see verify_common_type_from_oids).
1471 : *
1472 : * Note: neither caller will pass any UNKNOWNOID entries, so the tests
1473 : * for that in this function are dead code. However, they don't cost much,
1474 : * and it seems better to keep this logic as close to select_common_type()
1475 : * as possible.
1476 : */
1477 : static Oid
1478 5172 : select_common_type_from_oids(int nargs, const Oid *typeids, bool noerror)
1479 : {
1480 : Oid ptype;
1481 : TYPCATEGORY pcategory;
1482 : bool pispreferred;
1483 5172 : int i = 1;
1484 :
1485 : Assert(nargs > 0);
1486 5172 : ptype = typeids[0];
1487 :
1488 : /* If all input types are valid and exactly the same, pick that type. */
1489 5172 : if (ptype != UNKNOWNOID)
1490 : {
1491 7479 : for (; i < nargs; i++)
1492 : {
1493 3081 : if (typeids[i] != ptype)
1494 774 : break;
1495 : }
1496 5172 : if (i == nargs)
1497 4398 : return ptype;
1498 : }
1499 :
1500 : /*
1501 : * Nope, so set up for the full algorithm. Note that at this point, we
1502 : * can skip array entries before "i"; they are all equal to ptype.
1503 : */
1504 774 : ptype = getBaseType(ptype);
1505 774 : get_type_category_preferred(ptype, &pcategory, &pispreferred);
1506 :
1507 1110 : for (; i < nargs; i++)
1508 : {
1509 810 : Oid ntype = getBaseType(typeids[i]);
1510 :
1511 : /* move on to next one if no new information... */
1512 810 : if (ntype != UNKNOWNOID && ntype != ptype)
1513 : {
1514 : TYPCATEGORY ncategory;
1515 : bool nispreferred;
1516 :
1517 802 : get_type_category_preferred(ntype, &ncategory, &nispreferred);
1518 802 : if (ptype == UNKNOWNOID)
1519 : {
1520 : /* so far, only unknowns so take anything... */
1521 0 : ptype = ntype;
1522 0 : pcategory = ncategory;
1523 0 : pispreferred = nispreferred;
1524 : }
1525 802 : else if (ncategory != pcategory)
1526 : {
1527 : /*
1528 : * both types in different categories? then not much hope...
1529 : */
1530 474 : if (noerror)
1531 474 : return InvalidOid;
1532 0 : ereport(ERROR,
1533 : (errcode(ERRCODE_DATATYPE_MISMATCH),
1534 : errmsg("argument types %s and %s cannot be matched",
1535 : format_type_be(ptype),
1536 : format_type_be(ntype))));
1537 : }
1538 608 : else if (!pispreferred &&
1539 280 : can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
1540 180 : !can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
1541 : {
1542 : /*
1543 : * take new type if can coerce to it implicitly but not the
1544 : * other way; but if we have a preferred type, stay on it.
1545 : */
1546 180 : ptype = ntype;
1547 180 : pcategory = ncategory;
1548 180 : pispreferred = nispreferred;
1549 : }
1550 : }
1551 : }
1552 :
1553 : /* Like select_common_type(), choose TEXT if all inputs were UNKNOWN */
1554 300 : if (ptype == UNKNOWNOID)
1555 0 : ptype = TEXTOID;
1556 :
1557 300 : return ptype;
1558 : }
1559 :
1560 : /*
1561 : * coerce_to_common_type()
1562 : * Coerce an expression to the given type.
1563 : *
1564 : * This is used following select_common_type() to coerce the individual
1565 : * expressions to the desired type. 'context' is a phrase to use in the
1566 : * error message if we fail to coerce.
1567 : *
1568 : * As with coerce_type, pstate may be NULL if no special unknown-Param
1569 : * processing is wanted.
1570 : */
1571 : Node *
1572 230892 : coerce_to_common_type(ParseState *pstate, Node *node,
1573 : Oid targetTypeId, const char *context)
1574 : {
1575 230892 : Oid inputTypeId = exprType(node);
1576 :
1577 230892 : if (inputTypeId == targetTypeId)
1578 132000 : return node; /* no work */
1579 98892 : if (can_coerce_type(1, &inputTypeId, &targetTypeId, COERCION_IMPLICIT))
1580 98892 : node = coerce_type(pstate, node, inputTypeId, targetTypeId, -1,
1581 : COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1);
1582 : else
1583 0 : ereport(ERROR,
1584 : (errcode(ERRCODE_CANNOT_COERCE),
1585 : /* translator: first %s is name of a SQL construct, eg CASE */
1586 : errmsg("%s could not convert type %s to %s",
1587 : context,
1588 : format_type_be(inputTypeId),
1589 : format_type_be(targetTypeId)),
1590 : parser_errposition(pstate, exprLocation(node))));
1591 98888 : return node;
1592 : }
1593 :
1594 : /*
1595 : * verify_common_type()
1596 : * Verify that all input types can be coerced to a proposed common type.
1597 : * Return true if so, false if not all coercions are possible.
1598 : *
1599 : * Most callers of select_common_type() don't need to do this explicitly
1600 : * because the checks will happen while trying to convert input expressions
1601 : * to the right type, e.g. in coerce_to_common_type(). However, if a separate
1602 : * check step is needed to validate the applicability of the common type, call
1603 : * this.
1604 : */
1605 : bool
1606 11380 : verify_common_type(Oid common_type, List *exprs)
1607 : {
1608 : ListCell *lc;
1609 :
1610 57919 : foreach(lc, exprs)
1611 : {
1612 46543 : Node *nexpr = (Node *) lfirst(lc);
1613 46543 : Oid ntype = exprType(nexpr);
1614 :
1615 46543 : if (!can_coerce_type(1, &ntype, &common_type, COERCION_IMPLICIT))
1616 4 : return false;
1617 : }
1618 11376 : return true;
1619 : }
1620 :
1621 : /*
1622 : * verify_common_type_from_oids()
1623 : * As above, but work from an array of type OIDs.
1624 : */
1625 : static bool
1626 4698 : verify_common_type_from_oids(Oid common_type, int nargs, const Oid *typeids)
1627 : {
1628 12031 : for (int i = 0; i < nargs; i++)
1629 : {
1630 7341 : if (!can_coerce_type(1, &typeids[i], &common_type, COERCION_IMPLICIT))
1631 8 : return false;
1632 : }
1633 4690 : return true;
1634 : }
1635 :
1636 : /*
1637 : * select_common_typmod()
1638 : * Determine the common typmod of a list of input expressions.
1639 : *
1640 : * common_type is the selected common type of the expressions, typically
1641 : * computed using select_common_type().
1642 : */
1643 : int32
1644 50186 : select_common_typmod(ParseState *pstate, List *exprs, Oid common_type)
1645 : {
1646 : ListCell *lc;
1647 50186 : bool first = true;
1648 50186 : int32 result = -1;
1649 :
1650 157067 : foreach(lc, exprs)
1651 : {
1652 107032 : Node *expr = (Node *) lfirst(lc);
1653 :
1654 : /* Types must match */
1655 107032 : if (exprType(expr) != common_type)
1656 151 : return -1;
1657 106908 : else if (first)
1658 : {
1659 50122 : result = exprTypmod(expr);
1660 50122 : first = false;
1661 : }
1662 : else
1663 : {
1664 : /* As soon as we see a non-matching typmod, fall back to -1 */
1665 56786 : if (result != exprTypmod(expr))
1666 27 : return -1;
1667 : }
1668 : }
1669 :
1670 50035 : return result;
1671 : }
1672 :
1673 : /*
1674 : * check_generic_type_consistency()
1675 : * Are the actual arguments potentially compatible with a
1676 : * polymorphic function?
1677 : *
1678 : * The argument consistency rules are:
1679 : *
1680 : * 1) All arguments declared ANYELEMENT must have the same datatype.
1681 : * 2) All arguments declared ANYARRAY must have the same datatype,
1682 : * which must be a varlena array type.
1683 : * 3) All arguments declared ANYRANGE must be the same range type.
1684 : * Similarly, all arguments declared ANYMULTIRANGE must be the same
1685 : * multirange type; and if both of these appear, the ANYRANGE type
1686 : * must be the element type of the ANYMULTIRANGE type.
1687 : * 4) If there are arguments of more than one of these polymorphic types,
1688 : * the array element type and/or range subtype must be the same as each
1689 : * other and the same as the ANYELEMENT type.
1690 : * 5) ANYENUM is treated the same as ANYELEMENT except that if it is used
1691 : * (alone or in combination with plain ANYELEMENT), we add the extra
1692 : * condition that the ANYELEMENT type must be an enum.
1693 : * 6) ANYNONARRAY is treated the same as ANYELEMENT except that if it is used,
1694 : * we add the extra condition that the ANYELEMENT type must not be an array.
1695 : * (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
1696 : * is an extra restriction if not.)
1697 : * 7) All arguments declared ANYCOMPATIBLE must be implicitly castable
1698 : * to a common supertype (chosen as per select_common_type's rules).
1699 : * ANYCOMPATIBLENONARRAY works like ANYCOMPATIBLE but also requires the
1700 : * common supertype to not be an array. If there are ANYCOMPATIBLEARRAY
1701 : * or ANYCOMPATIBLERANGE or ANYCOMPATIBLEMULTIRANGE arguments, their element
1702 : * types or subtypes are included while making the choice of common supertype.
1703 : * 8) The resolved type of ANYCOMPATIBLEARRAY arguments will be the array
1704 : * type over the common supertype (which might not be the same array type
1705 : * as any of the original arrays).
1706 : * 9) All ANYCOMPATIBLERANGE arguments must be the exact same range type
1707 : * (after domain flattening), since we have no preference rule that would
1708 : * let us choose one over another. Furthermore, that range's subtype
1709 : * must exactly match the common supertype chosen by rule 7.
1710 : * 10) All ANYCOMPATIBLEMULTIRANGE arguments must be the exact same multirange
1711 : * type (after domain flattening), since we have no preference rule that
1712 : * would let us choose one over another. Furthermore, if ANYCOMPATIBLERANGE
1713 : * also appears, that range type must be the multirange's element type;
1714 : * otherwise, the multirange's range's subtype must exactly match the
1715 : * common supertype chosen by rule 7.
1716 : *
1717 : * Domains over arrays match ANYARRAY, and are immediately flattened to their
1718 : * base type. (Thus, for example, we will consider it a match if one ANYARRAY
1719 : * argument is a domain over int4[] while another one is just int4[].) Also
1720 : * notice that such a domain does *not* match ANYNONARRAY. The same goes
1721 : * for ANYCOMPATIBLEARRAY and ANYCOMPATIBLENONARRAY.
1722 : *
1723 : * Similarly, domains over ranges match ANYRANGE or ANYCOMPATIBLERANGE,
1724 : * and are immediately flattened to their base type. Likewise, domains
1725 : * over multiranges match ANYMULTIRANGE or ANYCOMPATIBLEMULTIRANGE and are
1726 : * immediately flattened to their base type.
1727 : *
1728 : * Note that domains aren't currently considered to match ANYENUM,
1729 : * even if their base type would match.
1730 : *
1731 : * If we have UNKNOWN input (ie, an untyped literal) for any polymorphic
1732 : * argument, assume it is okay.
1733 : *
1734 : * We do not ereport here, but just return false if a rule is violated.
1735 : */
1736 : bool
1737 89043 : check_generic_type_consistency(const Oid *actual_arg_types,
1738 : const Oid *declared_arg_types,
1739 : int nargs)
1740 : {
1741 89043 : Oid elem_typeid = InvalidOid;
1742 89043 : Oid array_typeid = InvalidOid;
1743 89043 : Oid range_typeid = InvalidOid;
1744 89043 : Oid multirange_typeid = InvalidOid;
1745 89043 : Oid anycompatible_range_typeid = InvalidOid;
1746 89043 : Oid anycompatible_range_typelem = InvalidOid;
1747 89043 : Oid anycompatible_multirange_typeid = InvalidOid;
1748 89043 : Oid anycompatible_multirange_typelem = InvalidOid;
1749 89043 : Oid range_typelem = InvalidOid;
1750 89043 : bool have_anynonarray = false;
1751 89043 : bool have_anyenum = false;
1752 89043 : bool have_anycompatible_nonarray = false;
1753 89043 : int n_anycompatible_args = 0;
1754 : Oid anycompatible_actual_types[FUNC_MAX_ARGS];
1755 :
1756 : /*
1757 : * Loop through the arguments to see if we have any that are polymorphic.
1758 : * If so, require the actual types to be consistent.
1759 : */
1760 : Assert(nargs <= FUNC_MAX_ARGS);
1761 206780 : for (int j = 0; j < nargs; j++)
1762 : {
1763 143168 : Oid decl_type = declared_arg_types[j];
1764 143168 : Oid actual_type = actual_arg_types[j];
1765 :
1766 143168 : if (decl_type == ANYELEMENTOID ||
1767 128814 : decl_type == ANYNONARRAYOID ||
1768 : decl_type == ANYENUMOID)
1769 : {
1770 30718 : if (decl_type == ANYNONARRAYOID)
1771 10196 : have_anynonarray = true;
1772 20522 : else if (decl_type == ANYENUMOID)
1773 16364 : have_anyenum = true;
1774 30718 : if (actual_type == UNKNOWNOID)
1775 1815 : continue;
1776 28903 : if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
1777 5720 : return false;
1778 23183 : elem_typeid = actual_type;
1779 : }
1780 112450 : else if (decl_type == ANYARRAYOID)
1781 : {
1782 42566 : if (actual_type == UNKNOWNOID)
1783 2182 : continue;
1784 40384 : actual_type = getBaseType(actual_type); /* flatten domains */
1785 40384 : if (OidIsValid(array_typeid) && actual_type != array_typeid)
1786 5700 : return false;
1787 34684 : array_typeid = actual_type;
1788 : }
1789 69884 : else if (decl_type == ANYRANGEOID)
1790 : {
1791 23318 : if (actual_type == UNKNOWNOID)
1792 1554 : continue;
1793 21764 : actual_type = getBaseType(actual_type); /* flatten domains */
1794 21764 : if (OidIsValid(range_typeid) && actual_type != range_typeid)
1795 6281 : return false;
1796 15483 : range_typeid = actual_type;
1797 : }
1798 46566 : else if (decl_type == ANYMULTIRANGEOID)
1799 : {
1800 26749 : if (actual_type == UNKNOWNOID)
1801 1566 : continue;
1802 25183 : actual_type = getBaseType(actual_type); /* flatten domains */
1803 25183 : if (OidIsValid(multirange_typeid) && actual_type != multirange_typeid)
1804 6277 : return false;
1805 18906 : multirange_typeid = actual_type;
1806 : }
1807 19817 : else if (decl_type == ANYCOMPATIBLEOID ||
1808 : decl_type == ANYCOMPATIBLENONARRAYOID)
1809 : {
1810 2882 : if (decl_type == ANYCOMPATIBLENONARRAYOID)
1811 24 : have_anycompatible_nonarray = true;
1812 2882 : if (actual_type == UNKNOWNOID)
1813 1118 : continue;
1814 : /* collect the actual types of non-unknown COMPATIBLE args */
1815 1764 : anycompatible_actual_types[n_anycompatible_args++] = actual_type;
1816 : }
1817 16935 : else if (decl_type == ANYCOMPATIBLEARRAYOID)
1818 : {
1819 : Oid elem_type;
1820 :
1821 4296 : if (actual_type == UNKNOWNOID)
1822 709 : continue;
1823 3587 : actual_type = getBaseType(actual_type); /* flatten domains */
1824 3587 : elem_type = get_element_type(actual_type);
1825 3587 : if (!OidIsValid(elem_type))
1826 1437 : return false; /* not an array */
1827 : /* collect the element type for common-supertype choice */
1828 2150 : anycompatible_actual_types[n_anycompatible_args++] = elem_type;
1829 : }
1830 12639 : else if (decl_type == ANYCOMPATIBLERANGEOID)
1831 : {
1832 124 : if (actual_type == UNKNOWNOID)
1833 8 : continue;
1834 116 : actual_type = getBaseType(actual_type); /* flatten domains */
1835 116 : if (OidIsValid(anycompatible_range_typeid))
1836 : {
1837 : /* All ANYCOMPATIBLERANGE arguments must be the same type */
1838 8 : if (anycompatible_range_typeid != actual_type)
1839 4 : return false;
1840 : }
1841 : else
1842 : {
1843 108 : anycompatible_range_typeid = actual_type;
1844 108 : anycompatible_range_typelem = get_range_subtype(actual_type);
1845 108 : if (!OidIsValid(anycompatible_range_typelem))
1846 4 : return false; /* not a range type */
1847 : /* collect the subtype for common-supertype choice */
1848 104 : anycompatible_actual_types[n_anycompatible_args++] = anycompatible_range_typelem;
1849 : }
1850 : }
1851 12515 : else if (decl_type == ANYCOMPATIBLEMULTIRANGEOID)
1852 : {
1853 92 : if (actual_type == UNKNOWNOID)
1854 12 : continue;
1855 80 : actual_type = getBaseType(actual_type); /* flatten domains */
1856 80 : if (OidIsValid(anycompatible_multirange_typeid))
1857 : {
1858 : /* All ANYCOMPATIBLEMULTIRANGE arguments must be the same type */
1859 8 : if (anycompatible_multirange_typeid != actual_type)
1860 4 : return false;
1861 : }
1862 : else
1863 : {
1864 72 : anycompatible_multirange_typeid = actual_type;
1865 72 : anycompatible_multirange_typelem = get_multirange_range(actual_type);
1866 72 : if (!OidIsValid(anycompatible_multirange_typelem))
1867 4 : return false; /* not a multirange type */
1868 : /* we'll consider the subtype below */
1869 : }
1870 : }
1871 : }
1872 :
1873 : /* Get the element type based on the array type, if we have one */
1874 63612 : if (OidIsValid(array_typeid))
1875 : {
1876 27454 : if (array_typeid == ANYARRAYOID)
1877 : {
1878 : /*
1879 : * Special case for matching ANYARRAY input to an ANYARRAY
1880 : * argument: allow it for now. enforce_generic_type_consistency()
1881 : * might complain later, depending on the presence of other
1882 : * polymorphic arguments or results, but it will deliver a less
1883 : * surprising error message than "function does not exist".
1884 : *
1885 : * (If you think to change this, note that can_coerce_type will
1886 : * consider such a situation as a match, so that we might not even
1887 : * get here.)
1888 : */
1889 : }
1890 : else
1891 : {
1892 : Oid array_typelem;
1893 :
1894 27454 : array_typelem = get_element_type(array_typeid);
1895 27454 : if (!OidIsValid(array_typelem))
1896 10247 : return false; /* should be an array, but isn't */
1897 :
1898 17207 : if (!OidIsValid(elem_typeid))
1899 : {
1900 : /*
1901 : * if we don't have an element type yet, use the one we just
1902 : * got
1903 : */
1904 17121 : elem_typeid = array_typelem;
1905 : }
1906 86 : else if (array_typelem != elem_typeid)
1907 : {
1908 : /* otherwise, they better match */
1909 33 : return false;
1910 : }
1911 : }
1912 : }
1913 :
1914 : /* Deduce range type from multirange type, or check that they agree */
1915 53332 : if (OidIsValid(multirange_typeid))
1916 : {
1917 : Oid multirange_typelem;
1918 :
1919 10800 : multirange_typelem = get_multirange_range(multirange_typeid);
1920 10800 : if (!OidIsValid(multirange_typelem))
1921 9208 : return false; /* should be a multirange, but isn't */
1922 :
1923 1592 : if (!OidIsValid(range_typeid))
1924 : {
1925 : /* If we don't have a range type yet, use the one we just got */
1926 1240 : range_typeid = multirange_typelem;
1927 1240 : range_typelem = get_range_subtype(multirange_typelem);
1928 1240 : if (!OidIsValid(range_typelem))
1929 0 : return false; /* should be a range, but isn't */
1930 : }
1931 352 : else if (multirange_typelem != range_typeid)
1932 : {
1933 : /* otherwise, they better match */
1934 201 : return false;
1935 : }
1936 : }
1937 :
1938 : /* Get the element type based on the range type, if we have one */
1939 43923 : if (OidIsValid(range_typeid))
1940 : {
1941 7335 : range_typelem = get_range_subtype(range_typeid);
1942 7335 : if (!OidIsValid(range_typelem))
1943 3277 : return false; /* should be a range, but isn't */
1944 :
1945 4058 : if (!OidIsValid(elem_typeid))
1946 : {
1947 : /*
1948 : * If we don't have an element type yet, use the one we just got
1949 : */
1950 3786 : elem_typeid = range_typelem;
1951 : }
1952 272 : else if (range_typelem != elem_typeid)
1953 : {
1954 : /* otherwise, they better match */
1955 121 : return false;
1956 : }
1957 : }
1958 :
1959 40525 : if (have_anynonarray)
1960 : {
1961 : /* require the element type to not be an array or domain over array */
1962 10020 : if (type_is_array_domain(elem_typeid))
1963 168 : return false;
1964 : }
1965 :
1966 40357 : if (have_anyenum)
1967 : {
1968 : /* require the element type to be an enum */
1969 2605 : if (!type_is_enum(elem_typeid))
1970 2373 : return false;
1971 : }
1972 :
1973 : /* Deduce range type from multirange type, or check that they agree */
1974 37984 : if (OidIsValid(anycompatible_multirange_typeid))
1975 : {
1976 64 : if (OidIsValid(anycompatible_range_typeid))
1977 : {
1978 8 : if (anycompatible_multirange_typelem !=
1979 : anycompatible_range_typeid)
1980 4 : return false;
1981 : }
1982 : else
1983 : {
1984 56 : anycompatible_range_typeid = anycompatible_multirange_typelem;
1985 56 : anycompatible_range_typelem = get_range_subtype(anycompatible_range_typeid);
1986 56 : if (!OidIsValid(anycompatible_range_typelem))
1987 0 : return false; /* not a range type */
1988 : /* collect the subtype for common-supertype choice */
1989 56 : anycompatible_actual_types[n_anycompatible_args++] =
1990 : anycompatible_range_typelem;
1991 : }
1992 : }
1993 :
1994 : /* Check matching of ANYCOMPATIBLE-family arguments, if any */
1995 37980 : if (n_anycompatible_args > 0)
1996 : {
1997 : Oid anycompatible_typeid;
1998 :
1999 : anycompatible_typeid =
2000 2467 : select_common_type_from_oids(n_anycompatible_args,
2001 : anycompatible_actual_types,
2002 : true);
2003 :
2004 2467 : if (!OidIsValid(anycompatible_typeid))
2005 474 : return false; /* there's definitely no common supertype */
2006 :
2007 : /* We have to verify that the selected type actually works */
2008 1993 : if (!verify_common_type_from_oids(anycompatible_typeid,
2009 : n_anycompatible_args,
2010 : anycompatible_actual_types))
2011 8 : return false;
2012 :
2013 1985 : if (have_anycompatible_nonarray)
2014 : {
2015 : /*
2016 : * require the anycompatible type to not be an array or domain
2017 : * over array
2018 : */
2019 12 : if (type_is_array_domain(anycompatible_typeid))
2020 4 : return false;
2021 : }
2022 :
2023 : /*
2024 : * The anycompatible type must exactly match the range element type,
2025 : * if we were able to identify one. This checks compatibility for
2026 : * anycompatiblemultirange too since that also sets
2027 : * anycompatible_range_typelem above.
2028 : */
2029 1981 : if (OidIsValid(anycompatible_range_typelem) &&
2030 : anycompatible_range_typelem != anycompatible_typeid)
2031 28 : return false;
2032 : }
2033 :
2034 : /* Looks valid */
2035 37466 : return true;
2036 : }
2037 :
2038 : /*
2039 : * enforce_generic_type_consistency()
2040 : * Make sure a polymorphic function is legally callable, and
2041 : * deduce actual argument and result types.
2042 : *
2043 : * If any polymorphic pseudotype is used in a function's arguments or
2044 : * return type, we make sure the actual data types are consistent with
2045 : * each other. The argument consistency rules are shown above for
2046 : * check_generic_type_consistency().
2047 : *
2048 : * If we have UNKNOWN input (ie, an untyped literal) for any polymorphic
2049 : * argument, we attempt to deduce the actual type it should have. If
2050 : * successful, we alter that position of declared_arg_types[] so that
2051 : * make_fn_arguments will coerce the literal to the right thing.
2052 : *
2053 : * If we have polymorphic arguments of the ANYCOMPATIBLE family,
2054 : * we similarly alter declared_arg_types[] entries to show the resolved
2055 : * common supertype, so that make_fn_arguments will coerce the actual
2056 : * arguments to the proper type.
2057 : *
2058 : * Rules are applied to the function's return type (possibly altering it)
2059 : * if it is declared as a polymorphic type and there is at least one
2060 : * polymorphic argument type:
2061 : *
2062 : * 1) If return type is ANYELEMENT, and any argument is ANYELEMENT, use the
2063 : * argument's actual type as the function's return type.
2064 : * 2) If return type is ANYARRAY, and any argument is ANYARRAY, use the
2065 : * argument's actual type as the function's return type.
2066 : * 3) Similarly, if return type is ANYRANGE or ANYMULTIRANGE, and any
2067 : * argument is ANYRANGE or ANYMULTIRANGE, use that argument's actual type
2068 : * (or the corresponding range or multirange type) as the function's return
2069 : * type.
2070 : * 4) Otherwise, if return type is ANYELEMENT or ANYARRAY, and there is
2071 : * at least one ANYELEMENT, ANYARRAY, ANYRANGE, or ANYMULTIRANGE input,
2072 : * deduce the return type from those inputs, or throw error if we can't.
2073 : * 5) Otherwise, if return type is ANYRANGE or ANYMULTIRANGE, throw error.
2074 : * (We have no way to select a specific range type if the arguments don't
2075 : * include ANYRANGE or ANYMULTIRANGE.)
2076 : * 6) ANYENUM is treated the same as ANYELEMENT except that if it is used
2077 : * (alone or in combination with plain ANYELEMENT), we add the extra
2078 : * condition that the ANYELEMENT type must be an enum.
2079 : * 7) ANYNONARRAY is treated the same as ANYELEMENT except that if it is used,
2080 : * we add the extra condition that the ANYELEMENT type must not be an array.
2081 : * (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
2082 : * is an extra restriction if not.)
2083 : * 8) ANYCOMPATIBLE, ANYCOMPATIBLEARRAY, and ANYCOMPATIBLENONARRAY are handled
2084 : * by resolving the common supertype of those arguments (or their element
2085 : * types, for array inputs), and then coercing all those arguments to the
2086 : * common supertype, or the array type over the common supertype for
2087 : * ANYCOMPATIBLEARRAY.
2088 : * 9) For ANYCOMPATIBLERANGE and ANYCOMPATIBLEMULTIRANGE, there must be at
2089 : * least one non-UNKNOWN input matching those arguments, and all such
2090 : * inputs must be the same range type (or its multirange type, as
2091 : * appropriate), since we cannot deduce a range type from non-range types.
2092 : * Furthermore, the range type's subtype is included while choosing the
2093 : * common supertype for ANYCOMPATIBLE et al, and it must exactly match
2094 : * that common supertype.
2095 : *
2096 : * Domains over arrays or ranges match ANYARRAY or ANYRANGE arguments,
2097 : * respectively, and are immediately flattened to their base type. (In
2098 : * particular, if the return type is also ANYARRAY or ANYRANGE, we'll set
2099 : * it to the base type not the domain type.) The same is true for
2100 : * ANYMULTIRANGE, ANYCOMPATIBLEARRAY, ANYCOMPATIBLERANGE, and
2101 : * ANYCOMPATIBLEMULTIRANGE.
2102 : *
2103 : * When allow_poly is false, we are not expecting any of the actual_arg_types
2104 : * to be polymorphic, and we should not return a polymorphic result type
2105 : * either. When allow_poly is true, it is okay to have polymorphic "actual"
2106 : * arg types, and we can return a matching polymorphic type as the result.
2107 : * (This case is currently used only to check compatibility of an aggregate's
2108 : * declaration with the underlying transfn.)
2109 : *
2110 : * A special case is that we could see ANYARRAY as an actual_arg_type even
2111 : * when allow_poly is false (this is possible only because pg_statistic has
2112 : * columns shown as anyarray in the catalogs). We allow this to match a
2113 : * declared ANYARRAY argument, but only if there is no other polymorphic
2114 : * argument that we would need to match it with, and no need to determine
2115 : * the element type to infer the result type. Note this means that functions
2116 : * taking ANYARRAY had better behave sanely if applied to the pg_statistic
2117 : * columns; they can't just assume that successive inputs are of the same
2118 : * actual element type. There is no similar logic for ANYCOMPATIBLEARRAY;
2119 : * there isn't a need for it since there are no catalog columns of that type,
2120 : * so we won't see it as input. We could consider matching an actual ANYARRAY
2121 : * input to an ANYCOMPATIBLEARRAY argument, but at present that seems useless
2122 : * as well, since there's no value in using ANYCOMPATIBLEARRAY unless there's
2123 : * at least one other ANYCOMPATIBLE-family argument or result.
2124 : *
2125 : * Also, if there are no arguments declared to be of polymorphic types,
2126 : * we'll return the rettype unmodified even if it's polymorphic. This should
2127 : * never occur for user-declared functions, because CREATE FUNCTION prevents
2128 : * it. But it does happen for some built-in functions, such as array_in().
2129 : */
2130 : Oid
2131 690681 : enforce_generic_type_consistency(const Oid *actual_arg_types,
2132 : Oid *declared_arg_types,
2133 : int nargs,
2134 : Oid rettype,
2135 : bool allow_poly)
2136 : {
2137 690681 : bool have_poly_anycompatible = false;
2138 690681 : bool have_poly_unknowns = false;
2139 690681 : Oid elem_typeid = InvalidOid;
2140 690681 : Oid array_typeid = InvalidOid;
2141 690681 : Oid range_typeid = InvalidOid;
2142 690681 : Oid multirange_typeid = InvalidOid;
2143 690681 : Oid anycompatible_typeid = InvalidOid;
2144 690681 : Oid anycompatible_array_typeid = InvalidOid;
2145 690681 : Oid anycompatible_range_typeid = InvalidOid;
2146 690681 : Oid anycompatible_range_typelem = InvalidOid;
2147 690681 : Oid anycompatible_multirange_typeid = InvalidOid;
2148 690681 : Oid anycompatible_multirange_typelem = InvalidOid;
2149 690681 : bool have_anynonarray = (rettype == ANYNONARRAYOID);
2150 690681 : bool have_anyenum = (rettype == ANYENUMOID);
2151 690681 : bool have_anymultirange = (rettype == ANYMULTIRANGEOID);
2152 690681 : bool have_anycompatible_nonarray = (rettype == ANYCOMPATIBLENONARRAYOID);
2153 690681 : bool have_anycompatible_array = (rettype == ANYCOMPATIBLEARRAYOID);
2154 690681 : bool have_anycompatible_range = (rettype == ANYCOMPATIBLERANGEOID);
2155 690681 : bool have_anycompatible_multirange = (rettype == ANYCOMPATIBLEMULTIRANGEOID);
2156 690681 : int n_poly_args = 0; /* this counts all family-1 arguments */
2157 690681 : int n_anycompatible_args = 0; /* this counts only non-unknowns */
2158 : Oid anycompatible_actual_types[FUNC_MAX_ARGS];
2159 :
2160 : /*
2161 : * Loop through the arguments to see if we have any that are polymorphic.
2162 : * If so, require the actual types to be consistent.
2163 : */
2164 : Assert(nargs <= FUNC_MAX_ARGS);
2165 2022863 : for (int j = 0; j < nargs; j++)
2166 : {
2167 1332182 : Oid decl_type = declared_arg_types[j];
2168 1332182 : Oid actual_type = actual_arg_types[j];
2169 :
2170 1332182 : if (decl_type == ANYELEMENTOID ||
2171 1317863 : decl_type == ANYNONARRAYOID ||
2172 : decl_type == ANYENUMOID)
2173 : {
2174 14869 : n_poly_args++;
2175 14869 : if (decl_type == ANYNONARRAYOID)
2176 9707 : have_anynonarray = true;
2177 5162 : else if (decl_type == ANYENUMOID)
2178 550 : have_anyenum = true;
2179 14869 : if (actual_type == UNKNOWNOID)
2180 : {
2181 457 : have_poly_unknowns = true;
2182 457 : continue;
2183 : }
2184 14412 : if (allow_poly && decl_type == actual_type)
2185 110 : continue; /* no new information here */
2186 14302 : if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
2187 0 : ereport(ERROR,
2188 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2189 : errmsg("arguments declared \"%s\" are not all alike", "anyelement"),
2190 : errdetail("%s versus %s",
2191 : format_type_be(elem_typeid),
2192 : format_type_be(actual_type))));
2193 14302 : elem_typeid = actual_type;
2194 : }
2195 1317313 : else if (decl_type == ANYARRAYOID)
2196 : {
2197 24043 : n_poly_args++;
2198 24043 : if (actual_type == UNKNOWNOID)
2199 : {
2200 3057 : have_poly_unknowns = true;
2201 3057 : continue;
2202 : }
2203 20986 : if (allow_poly && decl_type == actual_type)
2204 62 : continue; /* no new information here */
2205 20924 : actual_type = getBaseType(actual_type); /* flatten domains */
2206 20924 : if (OidIsValid(array_typeid) && actual_type != array_typeid)
2207 0 : ereport(ERROR,
2208 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2209 : errmsg("arguments declared \"%s\" are not all alike", "anyarray"),
2210 : errdetail("%s versus %s",
2211 : format_type_be(array_typeid),
2212 : format_type_be(actual_type))));
2213 20924 : array_typeid = actual_type;
2214 : }
2215 1293270 : else if (decl_type == ANYRANGEOID)
2216 : {
2217 7607 : n_poly_args++;
2218 7607 : if (actual_type == UNKNOWNOID)
2219 : {
2220 1471 : have_poly_unknowns = true;
2221 1471 : continue;
2222 : }
2223 6136 : if (allow_poly && decl_type == actual_type)
2224 0 : continue; /* no new information here */
2225 6136 : actual_type = getBaseType(actual_type); /* flatten domains */
2226 6136 : if (OidIsValid(range_typeid) && actual_type != range_typeid)
2227 0 : ereport(ERROR,
2228 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2229 : errmsg("arguments declared \"%s\" are not all alike", "anyrange"),
2230 : errdetail("%s versus %s",
2231 : format_type_be(range_typeid),
2232 : format_type_be(actual_type))));
2233 6136 : range_typeid = actual_type;
2234 : }
2235 1285663 : else if (decl_type == ANYMULTIRANGEOID)
2236 : {
2237 3656 : n_poly_args++;
2238 3656 : have_anymultirange = true;
2239 3656 : if (actual_type == UNKNOWNOID)
2240 : {
2241 176 : have_poly_unknowns = true;
2242 176 : continue;
2243 : }
2244 3480 : if (allow_poly && decl_type == actual_type)
2245 0 : continue; /* no new information here */
2246 3480 : actual_type = getBaseType(actual_type); /* flatten domains */
2247 3480 : if (OidIsValid(multirange_typeid) && actual_type != multirange_typeid)
2248 0 : ereport(ERROR,
2249 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2250 : errmsg("arguments declared \"%s\" are not all alike", "anymultirange"),
2251 : errdetail("%s versus %s",
2252 : format_type_be(multirange_typeid),
2253 : format_type_be(actual_type))));
2254 3480 : multirange_typeid = actual_type;
2255 : }
2256 1282007 : else if (decl_type == ANYCOMPATIBLEOID ||
2257 : decl_type == ANYCOMPATIBLENONARRAYOID)
2258 : {
2259 1479 : have_poly_anycompatible = true;
2260 1479 : if (decl_type == ANYCOMPATIBLENONARRAYOID)
2261 16 : have_anycompatible_nonarray = true;
2262 1479 : if (actual_type == UNKNOWNOID)
2263 820 : continue;
2264 659 : if (allow_poly && decl_type == actual_type)
2265 5 : continue; /* no new information here */
2266 : /* collect the actual types of non-unknown COMPATIBLE args */
2267 654 : anycompatible_actual_types[n_anycompatible_args++] = actual_type;
2268 : }
2269 1280528 : else if (decl_type == ANYCOMPATIBLEARRAYOID)
2270 : {
2271 : Oid anycompatible_elem_type;
2272 :
2273 3785 : have_poly_anycompatible = true;
2274 3785 : have_anycompatible_array = true;
2275 3785 : if (actual_type == UNKNOWNOID)
2276 20 : continue;
2277 3765 : if (allow_poly && decl_type == actual_type)
2278 5 : continue; /* no new information here */
2279 3760 : actual_type = getBaseType(actual_type); /* flatten domains */
2280 3760 : anycompatible_elem_type = get_element_type(actual_type);
2281 3760 : if (!OidIsValid(anycompatible_elem_type))
2282 0 : ereport(ERROR,
2283 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2284 : errmsg("argument declared %s is not an array but type %s",
2285 : "anycompatiblearray",
2286 : format_type_be(actual_type))));
2287 : /* collect the element type for common-supertype choice */
2288 3760 : anycompatible_actual_types[n_anycompatible_args++] = anycompatible_elem_type;
2289 : }
2290 1276743 : else if (decl_type == ANYCOMPATIBLERANGEOID)
2291 : {
2292 92 : have_poly_anycompatible = true;
2293 92 : have_anycompatible_range = true;
2294 92 : if (actual_type == UNKNOWNOID)
2295 8 : continue;
2296 84 : if (allow_poly && decl_type == actual_type)
2297 0 : continue; /* no new information here */
2298 84 : actual_type = getBaseType(actual_type); /* flatten domains */
2299 84 : if (OidIsValid(anycompatible_range_typeid))
2300 : {
2301 : /* All ANYCOMPATIBLERANGE arguments must be the same type */
2302 4 : if (anycompatible_range_typeid != actual_type)
2303 0 : ereport(ERROR,
2304 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2305 : errmsg("arguments declared \"%s\" are not all alike", "anycompatiblerange"),
2306 : errdetail("%s versus %s",
2307 : format_type_be(anycompatible_range_typeid),
2308 : format_type_be(actual_type))));
2309 : }
2310 : else
2311 : {
2312 80 : anycompatible_range_typeid = actual_type;
2313 80 : anycompatible_range_typelem = get_range_subtype(actual_type);
2314 80 : if (!OidIsValid(anycompatible_range_typelem))
2315 0 : ereport(ERROR,
2316 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2317 : errmsg("argument declared %s is not a range type but type %s",
2318 : "anycompatiblerange",
2319 : format_type_be(actual_type))));
2320 : /* collect the subtype for common-supertype choice */
2321 80 : anycompatible_actual_types[n_anycompatible_args++] = anycompatible_range_typelem;
2322 : }
2323 : }
2324 1276651 : else if (decl_type == ANYCOMPATIBLEMULTIRANGEOID)
2325 : {
2326 64 : have_poly_anycompatible = true;
2327 64 : have_anycompatible_multirange = true;
2328 64 : if (actual_type == UNKNOWNOID)
2329 12 : continue;
2330 52 : if (allow_poly && decl_type == actual_type)
2331 0 : continue; /* no new information here */
2332 52 : actual_type = getBaseType(actual_type); /* flatten domains */
2333 52 : if (OidIsValid(anycompatible_multirange_typeid))
2334 : {
2335 : /* All ANYCOMPATIBLEMULTIRANGE arguments must be the same type */
2336 4 : if (anycompatible_multirange_typeid != actual_type)
2337 0 : ereport(ERROR,
2338 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2339 : errmsg("arguments declared \"%s\" are not all alike", "anycompatiblemultirange"),
2340 : errdetail("%s versus %s",
2341 : format_type_be(anycompatible_multirange_typeid),
2342 : format_type_be(actual_type))));
2343 : }
2344 : else
2345 : {
2346 48 : anycompatible_multirange_typeid = actual_type;
2347 48 : anycompatible_multirange_typelem = get_multirange_range(actual_type);
2348 48 : if (!OidIsValid(anycompatible_multirange_typelem))
2349 0 : ereport(ERROR,
2350 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2351 : errmsg("argument declared %s is not a multirange type but type %s",
2352 : "anycompatiblemultirange",
2353 : format_type_be(actual_type))));
2354 : /* we'll consider the subtype below */
2355 : }
2356 : }
2357 : }
2358 :
2359 : /*
2360 : * Fast Track: if none of the arguments are polymorphic, return the
2361 : * unmodified rettype. Not our job to resolve it if it's polymorphic.
2362 : */
2363 690681 : if (n_poly_args == 0 && !have_poly_anycompatible)
2364 647945 : return rettype;
2365 :
2366 : /* Check matching of family-1 polymorphic arguments, if any */
2367 42736 : if (n_poly_args)
2368 : {
2369 : /* Get the element type based on the array type, if we have one */
2370 40046 : if (OidIsValid(array_typeid))
2371 : {
2372 : Oid array_typelem;
2373 :
2374 19827 : if (array_typeid == ANYARRAYOID)
2375 : {
2376 : /*
2377 : * Special case for matching ANYARRAY input to an ANYARRAY
2378 : * argument: allow it iff no other arguments are family-1
2379 : * polymorphics (otherwise we couldn't be sure whether the
2380 : * array element type matches up) and the result type doesn't
2381 : * require us to infer a specific element type.
2382 : */
2383 29 : if (n_poly_args != 1 ||
2384 12 : (rettype != ANYARRAYOID &&
2385 4 : IsPolymorphicTypeFamily1(rettype)))
2386 8 : ereport(ERROR,
2387 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2388 : errmsg("cannot determine element type of \"anyarray\" argument")));
2389 21 : array_typelem = ANYELEMENTOID;
2390 : }
2391 : else
2392 : {
2393 19798 : array_typelem = get_element_type(array_typeid);
2394 19798 : if (!OidIsValid(array_typelem))
2395 0 : ereport(ERROR,
2396 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2397 : errmsg("argument declared %s is not an array but type %s",
2398 : "anyarray", format_type_be(array_typeid))));
2399 : }
2400 :
2401 19819 : if (!OidIsValid(elem_typeid))
2402 : {
2403 : /*
2404 : * if we don't have an element type yet, use the one we just
2405 : * got
2406 : */
2407 19766 : elem_typeid = array_typelem;
2408 : }
2409 53 : else if (array_typelem != elem_typeid)
2410 : {
2411 : /* otherwise, they better match */
2412 0 : ereport(ERROR,
2413 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2414 : errmsg("argument declared %s is not consistent with argument declared %s",
2415 : "anyarray", "anyelement"),
2416 : errdetail("%s versus %s",
2417 : format_type_be(array_typeid),
2418 : format_type_be(elem_typeid))));
2419 : }
2420 : }
2421 :
2422 : /* Deduce range type from multirange type, or vice versa */
2423 40038 : if (OidIsValid(multirange_typeid))
2424 : {
2425 : Oid multirange_typelem;
2426 :
2427 2572 : multirange_typelem = get_multirange_range(multirange_typeid);
2428 2572 : if (!OidIsValid(multirange_typelem))
2429 0 : ereport(ERROR,
2430 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2431 : errmsg("argument declared %s is not a multirange type but type %s",
2432 : "anymultirange",
2433 : format_type_be(multirange_typeid))));
2434 :
2435 2572 : if (!OidIsValid(range_typeid))
2436 : {
2437 : /* if we don't have a range type yet, use the one we just got */
2438 1692 : range_typeid = multirange_typelem;
2439 : }
2440 880 : else if (multirange_typelem != range_typeid)
2441 : {
2442 : /* otherwise, they better match */
2443 0 : ereport(ERROR,
2444 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2445 : errmsg("argument declared %s is not consistent with argument declared %s",
2446 : "anymultirange", "anyrange"),
2447 : errdetail("%s versus %s",
2448 : format_type_be(multirange_typeid),
2449 : format_type_be(range_typeid))));
2450 : }
2451 : }
2452 37466 : else if (have_anymultirange && OidIsValid(range_typeid))
2453 : {
2454 202 : multirange_typeid = get_range_multirange(range_typeid);
2455 : /* We'll complain below if that didn't work */
2456 : }
2457 :
2458 : /* Get the element type based on the range type, if we have one */
2459 40038 : if (OidIsValid(range_typeid))
2460 : {
2461 : Oid range_typelem;
2462 :
2463 6436 : range_typelem = get_range_subtype(range_typeid);
2464 6436 : if (!OidIsValid(range_typelem))
2465 0 : ereport(ERROR,
2466 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2467 : errmsg("argument declared %s is not a range type but type %s",
2468 : "anyrange",
2469 : format_type_be(range_typeid))));
2470 :
2471 6436 : if (!OidIsValid(elem_typeid))
2472 : {
2473 : /*
2474 : * if we don't have an element type yet, use the one we just
2475 : * got
2476 : */
2477 6096 : elem_typeid = range_typelem;
2478 : }
2479 340 : else if (range_typelem != elem_typeid)
2480 : {
2481 : /* otherwise, they better match */
2482 0 : ereport(ERROR,
2483 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2484 : errmsg("argument declared %s is not consistent with argument declared %s",
2485 : "anyrange", "anyelement"),
2486 : errdetail("%s versus %s",
2487 : format_type_be(range_typeid),
2488 : format_type_be(elem_typeid))));
2489 : }
2490 : }
2491 :
2492 40038 : if (!OidIsValid(elem_typeid))
2493 : {
2494 139 : if (allow_poly)
2495 : {
2496 123 : elem_typeid = ANYELEMENTOID;
2497 123 : array_typeid = ANYARRAYOID;
2498 123 : range_typeid = ANYRANGEOID;
2499 123 : multirange_typeid = ANYMULTIRANGEOID;
2500 : }
2501 : else
2502 : {
2503 : /*
2504 : * Only way to get here is if all the family-1 polymorphic
2505 : * arguments have UNKNOWN inputs.
2506 : */
2507 16 : ereport(ERROR,
2508 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2509 : errmsg("could not determine polymorphic type because input has type %s",
2510 : "unknown")));
2511 : }
2512 : }
2513 :
2514 40022 : if (have_anynonarray && elem_typeid != ANYELEMENTOID)
2515 : {
2516 : /*
2517 : * require the element type to not be an array or domain over
2518 : * array
2519 : */
2520 9531 : if (type_is_array_domain(elem_typeid))
2521 0 : ereport(ERROR,
2522 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2523 : errmsg("type matched to anynonarray is an array type: %s",
2524 : format_type_be(elem_typeid))));
2525 : }
2526 :
2527 40022 : if (have_anyenum && elem_typeid != ANYELEMENTOID)
2528 : {
2529 : /* require the element type to be an enum */
2530 389 : if (!type_is_enum(elem_typeid))
2531 0 : ereport(ERROR,
2532 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2533 : errmsg("type matched to anyenum is not an enum type: %s",
2534 : format_type_be(elem_typeid))));
2535 : }
2536 : }
2537 :
2538 : /* Check matching of family-2 polymorphic arguments, if any */
2539 42712 : if (have_poly_anycompatible)
2540 : {
2541 : /* Deduce range type from multirange type, or vice versa */
2542 2726 : if (OidIsValid(anycompatible_multirange_typeid))
2543 : {
2544 48 : if (OidIsValid(anycompatible_range_typeid))
2545 : {
2546 4 : if (anycompatible_multirange_typelem !=
2547 : anycompatible_range_typeid)
2548 0 : ereport(ERROR,
2549 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2550 : errmsg("argument declared %s is not consistent with argument declared %s",
2551 : "anycompatiblemultirange",
2552 : "anycompatiblerange"),
2553 : errdetail("%s versus %s",
2554 : format_type_be(anycompatible_multirange_typeid),
2555 : format_type_be(anycompatible_range_typeid))));
2556 : }
2557 : else
2558 : {
2559 44 : anycompatible_range_typeid = anycompatible_multirange_typelem;
2560 44 : anycompatible_range_typelem = get_range_subtype(anycompatible_range_typeid);
2561 44 : if (!OidIsValid(anycompatible_range_typelem))
2562 0 : ereport(ERROR,
2563 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2564 : errmsg("argument declared %s is not a multirange type but type %s",
2565 : "anycompatiblemultirange",
2566 : format_type_be(anycompatible_multirange_typeid))));
2567 : /* this enables element type matching check below */
2568 44 : have_anycompatible_range = true;
2569 : /* collect the subtype for common-supertype choice */
2570 44 : anycompatible_actual_types[n_anycompatible_args++] =
2571 : anycompatible_range_typelem;
2572 : }
2573 : }
2574 2678 : else if (have_anycompatible_multirange &&
2575 : OidIsValid(anycompatible_range_typeid))
2576 : {
2577 4 : anycompatible_multirange_typeid = get_range_multirange(anycompatible_range_typeid);
2578 : /* We'll complain below if that didn't work */
2579 : }
2580 :
2581 2726 : if (n_anycompatible_args > 0)
2582 : {
2583 : anycompatible_typeid =
2584 2705 : select_common_type_from_oids(n_anycompatible_args,
2585 : anycompatible_actual_types,
2586 : false);
2587 :
2588 : /* We have to verify that the selected type actually works */
2589 2705 : if (!verify_common_type_from_oids(anycompatible_typeid,
2590 : n_anycompatible_args,
2591 : anycompatible_actual_types))
2592 0 : ereport(ERROR,
2593 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2594 : errmsg("arguments of anycompatible family cannot be cast to a common type")));
2595 :
2596 2705 : if (have_anycompatible_array)
2597 : {
2598 2573 : anycompatible_array_typeid = get_array_type(anycompatible_typeid);
2599 2573 : if (!OidIsValid(anycompatible_array_typeid))
2600 0 : ereport(ERROR,
2601 : (errcode(ERRCODE_UNDEFINED_OBJECT),
2602 : errmsg("could not find array type for data type %s",
2603 : format_type_be(anycompatible_typeid))));
2604 : }
2605 :
2606 2705 : if (have_anycompatible_range)
2607 : {
2608 : /* we can't infer a range type from the others */
2609 128 : if (!OidIsValid(anycompatible_range_typeid))
2610 4 : ereport(ERROR,
2611 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2612 : errmsg("could not determine polymorphic type %s because input has type %s",
2613 : "anycompatiblerange", "unknown")));
2614 :
2615 : /*
2616 : * the anycompatible type must exactly match the range element
2617 : * type
2618 : */
2619 124 : if (anycompatible_range_typelem != anycompatible_typeid)
2620 0 : ereport(ERROR,
2621 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2622 : errmsg("anycompatiblerange type %s does not match anycompatible type %s",
2623 : format_type_be(anycompatible_range_typeid),
2624 : format_type_be(anycompatible_typeid))));
2625 : }
2626 :
2627 2701 : if (have_anycompatible_multirange)
2628 : {
2629 : /* we can't infer a multirange type from the others */
2630 56 : if (!OidIsValid(anycompatible_multirange_typeid))
2631 4 : ereport(ERROR,
2632 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2633 : errmsg("could not determine polymorphic type %s because input has type %s",
2634 : "anycompatiblemultirange", "unknown")));
2635 :
2636 : /*
2637 : * the anycompatible type must exactly match the multirange
2638 : * element type
2639 : */
2640 52 : if (anycompatible_range_typelem != anycompatible_typeid)
2641 0 : ereport(ERROR,
2642 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2643 : errmsg("anycompatiblemultirange type %s does not match anycompatible type %s",
2644 : format_type_be(anycompatible_multirange_typeid),
2645 : format_type_be(anycompatible_typeid))));
2646 : }
2647 :
2648 2697 : if (have_anycompatible_nonarray)
2649 : {
2650 : /*
2651 : * require the element type to not be an array or domain over
2652 : * array
2653 : */
2654 8 : if (type_is_array_domain(anycompatible_typeid))
2655 0 : ereport(ERROR,
2656 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2657 : errmsg("type matched to anycompatiblenonarray is an array type: %s",
2658 : format_type_be(anycompatible_typeid))));
2659 : }
2660 : }
2661 : else
2662 : {
2663 21 : if (allow_poly)
2664 : {
2665 5 : anycompatible_typeid = ANYCOMPATIBLEOID;
2666 5 : anycompatible_array_typeid = ANYCOMPATIBLEARRAYOID;
2667 5 : anycompatible_range_typeid = ANYCOMPATIBLERANGEOID;
2668 5 : anycompatible_multirange_typeid = ANYCOMPATIBLEMULTIRANGEOID;
2669 : }
2670 : else
2671 : {
2672 : /*
2673 : * Only way to get here is if all the family-2 polymorphic
2674 : * arguments have UNKNOWN inputs. Resolve to TEXT as
2675 : * select_common_type() would do. That doesn't license us to
2676 : * use TEXTRANGE or TEXTMULTIRANGE, though.
2677 : */
2678 16 : anycompatible_typeid = TEXTOID;
2679 16 : anycompatible_array_typeid = TEXTARRAYOID;
2680 16 : if (have_anycompatible_range)
2681 8 : ereport(ERROR,
2682 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2683 : errmsg("could not determine polymorphic type %s because input has type %s",
2684 : "anycompatiblerange", "unknown")));
2685 8 : if (have_anycompatible_multirange)
2686 4 : ereport(ERROR,
2687 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2688 : errmsg("could not determine polymorphic type %s because input has type %s",
2689 : "anycompatiblemultirange", "unknown")));
2690 : }
2691 : }
2692 :
2693 : /* replace family-2 polymorphic types by selected types */
2694 8190 : for (int j = 0; j < nargs; j++)
2695 : {
2696 5484 : Oid decl_type = declared_arg_types[j];
2697 :
2698 5484 : if (decl_type == ANYCOMPATIBLEOID ||
2699 : decl_type == ANYCOMPATIBLENONARRAYOID)
2700 1471 : declared_arg_types[j] = anycompatible_typeid;
2701 4013 : else if (decl_type == ANYCOMPATIBLEARRAYOID)
2702 3785 : declared_arg_types[j] = anycompatible_array_typeid;
2703 228 : else if (decl_type == ANYCOMPATIBLERANGEOID)
2704 84 : declared_arg_types[j] = anycompatible_range_typeid;
2705 144 : else if (decl_type == ANYCOMPATIBLEMULTIRANGEOID)
2706 52 : declared_arg_types[j] = anycompatible_multirange_typeid;
2707 : }
2708 : }
2709 :
2710 : /*
2711 : * If we had any UNKNOWN inputs for family-1 polymorphic arguments,
2712 : * re-scan to assign correct types to them.
2713 : *
2714 : * Note: we don't have to consider unknown inputs that were matched to
2715 : * family-2 polymorphic arguments, because we forcibly updated their
2716 : * declared_arg_types[] positions just above.
2717 : */
2718 42692 : if (have_poly_unknowns)
2719 : {
2720 15898 : for (int j = 0; j < nargs; j++)
2721 : {
2722 10765 : Oid decl_type = declared_arg_types[j];
2723 10765 : Oid actual_type = actual_arg_types[j];
2724 :
2725 10765 : if (actual_type != UNKNOWNOID)
2726 5294 : continue;
2727 :
2728 5471 : if (decl_type == ANYELEMENTOID ||
2729 5131 : decl_type == ANYNONARRAYOID ||
2730 : decl_type == ANYENUMOID)
2731 453 : declared_arg_types[j] = elem_typeid;
2732 5018 : else if (decl_type == ANYARRAYOID)
2733 : {
2734 3057 : if (!OidIsValid(array_typeid))
2735 : {
2736 20 : array_typeid = get_array_type(elem_typeid);
2737 20 : if (!OidIsValid(array_typeid))
2738 0 : ereport(ERROR,
2739 : (errcode(ERRCODE_UNDEFINED_OBJECT),
2740 : errmsg("could not find array type for data type %s",
2741 : format_type_be(elem_typeid))));
2742 : }
2743 3057 : declared_arg_types[j] = array_typeid;
2744 : }
2745 1961 : else if (decl_type == ANYRANGEOID)
2746 : {
2747 1467 : if (!OidIsValid(range_typeid))
2748 : {
2749 : /* we can't infer a range type from the others */
2750 0 : ereport(ERROR,
2751 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2752 : errmsg("could not determine polymorphic type %s because input has type %s",
2753 : "anyrange", "unknown")));
2754 : }
2755 1467 : declared_arg_types[j] = range_typeid;
2756 : }
2757 494 : else if (decl_type == ANYMULTIRANGEOID)
2758 : {
2759 168 : if (!OidIsValid(multirange_typeid))
2760 : {
2761 : /* we can't infer a multirange type from the others */
2762 0 : ereport(ERROR,
2763 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2764 : errmsg("could not determine polymorphic type %s because input has type %s",
2765 : "anymultirange", "unknown")));
2766 : }
2767 168 : declared_arg_types[j] = multirange_typeid;
2768 : }
2769 : }
2770 : }
2771 :
2772 : /* if we return ANYELEMENT use the appropriate argument type */
2773 42692 : if (rettype == ANYELEMENTOID ||
2774 34626 : rettype == ANYNONARRAYOID ||
2775 : rettype == ANYENUMOID)
2776 8242 : return elem_typeid;
2777 :
2778 : /* if we return ANYARRAY use the appropriate argument type */
2779 34450 : if (rettype == ANYARRAYOID)
2780 : {
2781 9807 : if (!OidIsValid(array_typeid))
2782 : {
2783 8999 : array_typeid = get_array_type(elem_typeid);
2784 8999 : if (!OidIsValid(array_typeid))
2785 0 : ereport(ERROR,
2786 : (errcode(ERRCODE_UNDEFINED_OBJECT),
2787 : errmsg("could not find array type for data type %s",
2788 : format_type_be(elem_typeid))));
2789 : }
2790 9807 : return array_typeid;
2791 : }
2792 :
2793 : /* if we return ANYRANGE use the appropriate argument type */
2794 24643 : if (rettype == ANYRANGEOID)
2795 : {
2796 : /* this error is unreachable if the function signature is valid: */
2797 394 : if (!OidIsValid(range_typeid))
2798 0 : ereport(ERROR,
2799 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2800 : errmsg_internal("could not determine polymorphic type %s because input has type %s",
2801 : "anyrange", "unknown")));
2802 394 : return range_typeid;
2803 : }
2804 :
2805 : /* if we return ANYMULTIRANGE use the appropriate argument type */
2806 24249 : if (rettype == ANYMULTIRANGEOID)
2807 : {
2808 : /* this error is unreachable if the function signature is valid: */
2809 691 : if (!OidIsValid(multirange_typeid))
2810 0 : ereport(ERROR,
2811 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2812 : errmsg_internal("could not determine polymorphic type %s because input has type %s",
2813 : "anymultirange", "unknown")));
2814 691 : return multirange_typeid;
2815 : }
2816 :
2817 : /* if we return ANYCOMPATIBLE use the appropriate type */
2818 23558 : if (rettype == ANYCOMPATIBLEOID ||
2819 : rettype == ANYCOMPATIBLENONARRAYOID)
2820 : {
2821 : /* this error is unreachable if the function signature is valid: */
2822 109 : if (!OidIsValid(anycompatible_typeid))
2823 0 : ereport(ERROR,
2824 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2825 : errmsg_internal("could not identify anycompatible type")));
2826 109 : return anycompatible_typeid;
2827 : }
2828 :
2829 : /* if we return ANYCOMPATIBLEARRAY use the appropriate type */
2830 23449 : if (rettype == ANYCOMPATIBLEARRAYOID)
2831 : {
2832 : /* this error is unreachable if the function signature is valid: */
2833 2347 : if (!OidIsValid(anycompatible_array_typeid))
2834 0 : ereport(ERROR,
2835 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2836 : errmsg_internal("could not identify anycompatiblearray type")));
2837 2347 : return anycompatible_array_typeid;
2838 : }
2839 :
2840 : /* if we return ANYCOMPATIBLERANGE use the appropriate argument type */
2841 21102 : if (rettype == ANYCOMPATIBLERANGEOID)
2842 : {
2843 : /* this error is unreachable if the function signature is valid: */
2844 28 : if (!OidIsValid(anycompatible_range_typeid))
2845 0 : ereport(ERROR,
2846 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2847 : errmsg_internal("could not identify anycompatiblerange type")));
2848 28 : return anycompatible_range_typeid;
2849 : }
2850 :
2851 : /* if we return ANYCOMPATIBLEMULTIRANGE use the appropriate argument type */
2852 21074 : if (rettype == ANYCOMPATIBLEMULTIRANGEOID)
2853 : {
2854 : /* this error is unreachable if the function signature is valid: */
2855 20 : if (!OidIsValid(anycompatible_multirange_typeid))
2856 0 : ereport(ERROR,
2857 : (errcode(ERRCODE_DATATYPE_MISMATCH),
2858 : errmsg_internal("could not identify anycompatiblemultirange type")));
2859 20 : return anycompatible_multirange_typeid;
2860 : }
2861 :
2862 : /* we don't return a generic type; send back the original return type */
2863 21054 : return rettype;
2864 : }
2865 :
2866 : /*
2867 : * check_valid_polymorphic_signature()
2868 : * Is a proposed function signature valid per polymorphism rules?
2869 : *
2870 : * Returns NULL if the signature is valid (either ret_type is not polymorphic,
2871 : * or it can be deduced from the given declared argument types). Otherwise,
2872 : * returns a palloc'd, already translated errdetail string saying why not.
2873 : */
2874 : char *
2875 21201 : check_valid_polymorphic_signature(Oid ret_type,
2876 : const Oid *declared_arg_types,
2877 : int nargs)
2878 : {
2879 21201 : if (ret_type == ANYRANGEOID || ret_type == ANYMULTIRANGEOID)
2880 : {
2881 : /*
2882 : * ANYRANGE and ANYMULTIRANGE require an ANYRANGE or ANYMULTIRANGE
2883 : * input, else we can't tell which of several range types with the
2884 : * same element type to use.
2885 : */
2886 149 : for (int i = 0; i < nargs; i++)
2887 : {
2888 101 : if (declared_arg_types[i] == ANYRANGEOID ||
2889 77 : declared_arg_types[i] == ANYMULTIRANGEOID)
2890 48 : return NULL; /* OK */
2891 : }
2892 48 : return psprintf(_("A result of type %s requires at least one input of type anyrange or anymultirange."),
2893 : format_type_be(ret_type));
2894 : }
2895 21105 : else if (ret_type == ANYCOMPATIBLERANGEOID || ret_type == ANYCOMPATIBLEMULTIRANGEOID)
2896 : {
2897 : /*
2898 : * ANYCOMPATIBLERANGE and ANYCOMPATIBLEMULTIRANGE require an
2899 : * ANYCOMPATIBLERANGE or ANYCOMPATIBLEMULTIRANGE input, else we can't
2900 : * tell which of several range types with the same element type to
2901 : * use.
2902 : */
2903 96 : for (int i = 0; i < nargs; i++)
2904 : {
2905 68 : if (declared_arg_types[i] == ANYCOMPATIBLERANGEOID ||
2906 48 : declared_arg_types[i] == ANYCOMPATIBLEMULTIRANGEOID)
2907 32 : return NULL; /* OK */
2908 : }
2909 28 : return psprintf(_("A result of type %s requires at least one input of type anycompatiblerange or anycompatiblemultirange."),
2910 : format_type_be(ret_type));
2911 : }
2912 21045 : else if (IsPolymorphicTypeFamily1(ret_type))
2913 : {
2914 : /* Otherwise, any family-1 type can be deduced from any other */
2915 702 : for (int i = 0; i < nargs; i++)
2916 : {
2917 626 : if (IsPolymorphicTypeFamily1(declared_arg_types[i]))
2918 559 : return NULL; /* OK */
2919 : }
2920 : /* Keep this list in sync with IsPolymorphicTypeFamily1! */
2921 76 : return psprintf(_("A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange."),
2922 : format_type_be(ret_type));
2923 : }
2924 20410 : else if (IsPolymorphicTypeFamily2(ret_type))
2925 : {
2926 : /* Otherwise, any family-2 type can be deduced from any other */
2927 156 : for (int i = 0; i < nargs; i++)
2928 : {
2929 152 : if (IsPolymorphicTypeFamily2(declared_arg_types[i]))
2930 124 : return NULL; /* OK */
2931 : }
2932 : /* Keep this list in sync with IsPolymorphicTypeFamily2! */
2933 4 : return psprintf(_("A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, anycompatiblerange, or anycompatiblemultirange."),
2934 : format_type_be(ret_type));
2935 : }
2936 : else
2937 20282 : return NULL; /* OK, ret_type is not polymorphic */
2938 : }
2939 :
2940 : /*
2941 : * check_valid_internal_signature()
2942 : * Is a proposed function signature valid per INTERNAL safety rules?
2943 : *
2944 : * Returns NULL if OK, or a suitable error message if ret_type is INTERNAL but
2945 : * none of the declared arg types are. (It's unsafe to create such a function
2946 : * since it would allow invocation of INTERNAL-consuming functions directly
2947 : * from SQL.) It's overkill to return the error detail message, since there
2948 : * is only one possibility, but we do it like this to keep the API similar to
2949 : * check_valid_polymorphic_signature().
2950 : */
2951 : char *
2952 20518 : check_valid_internal_signature(Oid ret_type,
2953 : const Oid *declared_arg_types,
2954 : int nargs)
2955 : {
2956 20518 : if (ret_type == INTERNALOID)
2957 : {
2958 983 : for (int i = 0; i < nargs; i++)
2959 : {
2960 983 : if (declared_arg_types[i] == ret_type)
2961 690 : return NULL; /* OK */
2962 : }
2963 0 : return pstrdup(_("A result of type internal requires at least one input of type internal."));
2964 : }
2965 : else
2966 19828 : return NULL; /* OK, ret_type is not INTERNAL */
2967 : }
2968 :
2969 :
2970 : /*
2971 : * TypeCategory()
2972 : * Assign a category to the specified type OID.
2973 : *
2974 : * NB: this must not return TYPCATEGORY_INVALID.
2975 : */
2976 : TYPCATEGORY
2977 122811 : TypeCategory(Oid type)
2978 : {
2979 : char typcategory;
2980 : bool typispreferred;
2981 :
2982 122811 : get_type_category_preferred(type, &typcategory, &typispreferred);
2983 : Assert(typcategory != TYPCATEGORY_INVALID);
2984 122811 : return (TYPCATEGORY) typcategory;
2985 : }
2986 :
2987 :
2988 : /*
2989 : * IsPreferredType()
2990 : * Check if this type is a preferred type for the given category.
2991 : *
2992 : * If category is TYPCATEGORY_INVALID, then we'll return true for preferred
2993 : * types of any category; otherwise, only for preferred types of that
2994 : * category.
2995 : */
2996 : bool
2997 22026 : IsPreferredType(TYPCATEGORY category, Oid type)
2998 : {
2999 : char typcategory;
3000 : bool typispreferred;
3001 :
3002 22026 : get_type_category_preferred(type, &typcategory, &typispreferred);
3003 22026 : if (category == typcategory || category == TYPCATEGORY_INVALID)
3004 13394 : return typispreferred;
3005 : else
3006 8632 : return false;
3007 : }
3008 :
3009 :
3010 : /*
3011 : * IsBinaryCoercible()
3012 : * Check if srctype is binary-coercible to targettype.
3013 : *
3014 : * This notion allows us to cheat and directly exchange values without
3015 : * going through the trouble of calling a conversion function. Note that
3016 : * in general, this should only be an implementation shortcut. Before 7.4,
3017 : * this was also used as a heuristic for resolving overloaded functions and
3018 : * operators, but that's basically a bad idea.
3019 : *
3020 : * As of 7.3, binary coercibility isn't hardwired into the code anymore.
3021 : * We consider two types binary-coercible if there is an implicitly
3022 : * invokable, no-function-needed pg_cast entry. Also, a domain is always
3023 : * binary-coercible to its base type, though *not* vice versa (in the other
3024 : * direction, one must apply domain constraint checks before accepting the
3025 : * value as legitimate). We also need to special-case various polymorphic
3026 : * types.
3027 : *
3028 : * This function replaces IsBinaryCompatible(), which was an inherently
3029 : * symmetric test. Since the pg_cast entries aren't necessarily symmetric,
3030 : * the order of the operands is now significant.
3031 : */
3032 : bool
3033 1592344 : IsBinaryCoercible(Oid srctype, Oid targettype)
3034 : {
3035 : Oid castoid;
3036 :
3037 1592344 : return IsBinaryCoercibleWithCast(srctype, targettype, &castoid);
3038 : }
3039 :
3040 : /*
3041 : * IsBinaryCoercibleWithCast()
3042 : * Check if srctype is binary-coercible to targettype.
3043 : *
3044 : * This variant also returns the OID of the pg_cast entry if one is involved.
3045 : * *castoid is set to InvalidOid if no binary-coercible cast exists, or if
3046 : * there is a hard-wired rule for it rather than a pg_cast entry.
3047 : */
3048 : bool
3049 1592464 : IsBinaryCoercibleWithCast(Oid srctype, Oid targettype,
3050 : Oid *castoid)
3051 : {
3052 : HeapTuple tuple;
3053 : Form_pg_cast castForm;
3054 : bool result;
3055 :
3056 1592464 : *castoid = InvalidOid;
3057 :
3058 : /* Fast path if same type */
3059 1592464 : if (srctype == targettype)
3060 301735 : return true;
3061 :
3062 : /* Anything is coercible to ANY or ANYELEMENT or ANYCOMPATIBLE */
3063 1290729 : if (targettype == ANYOID || targettype == ANYELEMENTOID ||
3064 : targettype == ANYCOMPATIBLEOID)
3065 112 : return true;
3066 :
3067 : /* If srctype is a domain, reduce to its base type */
3068 1290617 : if (OidIsValid(srctype))
3069 1290617 : srctype = getBaseType(srctype);
3070 :
3071 : /* Somewhat-fast path for domain -> base type case */
3072 1290617 : if (srctype == targettype)
3073 8 : return true;
3074 :
3075 : /* Also accept any array type as coercible to ANY[COMPATIBLE]ARRAY */
3076 1290609 : if (targettype == ANYARRAYOID || targettype == ANYCOMPATIBLEARRAYOID)
3077 66522 : if (type_is_array(srctype))
3078 3107 : return true;
3079 :
3080 : /* Also accept any non-array type as coercible to ANY[COMPATIBLE]NONARRAY */
3081 1287502 : if (targettype == ANYNONARRAYOID || targettype == ANYCOMPATIBLENONARRAYOID)
3082 0 : if (!type_is_array(srctype))
3083 0 : return true;
3084 :
3085 : /* Also accept any enum type as coercible to ANYENUM */
3086 1287502 : if (targettype == ANYENUMOID)
3087 61438 : if (type_is_enum(srctype))
3088 120 : return true;
3089 :
3090 : /* Also accept any range type as coercible to ANY[COMPATIBLE]RANGE */
3091 1287382 : if (targettype == ANYRANGEOID || targettype == ANYCOMPATIBLERANGEOID)
3092 17192 : if (type_is_range(srctype))
3093 3439 : return true;
3094 :
3095 : /* Also, any multirange type is coercible to ANY[COMPATIBLE]MULTIRANGE */
3096 1283943 : if (targettype == ANYMULTIRANGEOID || targettype == ANYCOMPATIBLEMULTIRANGEOID)
3097 36349 : if (type_is_multirange(srctype))
3098 368 : return true;
3099 :
3100 : /* Also accept any composite type as coercible to RECORD */
3101 1283575 : if (targettype == RECORDOID)
3102 13578 : if (ISCOMPLEX(srctype))
3103 631 : return true;
3104 :
3105 : /* Also accept any composite array type as coercible to RECORD[] */
3106 1282944 : if (targettype == RECORDARRAYOID)
3107 0 : if (is_complex_array(srctype))
3108 0 : return true;
3109 :
3110 : /* Else look in pg_cast */
3111 1282944 : tuple = SearchSysCache2(CASTSOURCETARGET,
3112 : ObjectIdGetDatum(srctype),
3113 : ObjectIdGetDatum(targettype));
3114 1282944 : if (!HeapTupleIsValid(tuple))
3115 1025768 : return false; /* no cast */
3116 257176 : castForm = (Form_pg_cast) GETSTRUCT(tuple);
3117 :
3118 281124 : result = (castForm->castmethod == COERCION_METHOD_BINARY &&
3119 23948 : castForm->castcontext == COERCION_CODE_IMPLICIT);
3120 :
3121 257176 : if (result)
3122 9575 : *castoid = castForm->oid;
3123 :
3124 257176 : ReleaseSysCache(tuple);
3125 :
3126 257176 : return result;
3127 : }
3128 :
3129 :
3130 : /*
3131 : * find_coercion_pathway
3132 : * Look for a coercion pathway between two types.
3133 : *
3134 : * Currently, this deals only with scalar-type cases; it does not consider
3135 : * polymorphic types nor casts between composite types. (Perhaps fold
3136 : * those in someday?)
3137 : *
3138 : * ccontext determines the set of available casts.
3139 : *
3140 : * The possible result codes are:
3141 : * COERCION_PATH_NONE: failed to find any coercion pathway
3142 : * *funcid is set to InvalidOid
3143 : * COERCION_PATH_FUNC: apply the coercion function returned in *funcid
3144 : * COERCION_PATH_RELABELTYPE: binary-compatible cast, no function needed
3145 : * *funcid is set to InvalidOid
3146 : * COERCION_PATH_ARRAYCOERCE: need an ArrayCoerceExpr node
3147 : * *funcid is set to InvalidOid
3148 : * COERCION_PATH_COERCEVIAIO: need a CoerceViaIO node
3149 : * *funcid is set to InvalidOid
3150 : *
3151 : * Note: COERCION_PATH_RELABELTYPE does not necessarily mean that no work is
3152 : * needed to do the coercion; if the target is a domain then we may need to
3153 : * apply domain constraint checking. If you want to check for a zero-effort
3154 : * conversion then use IsBinaryCoercible().
3155 : */
3156 : CoercionPathType
3157 911741 : find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
3158 : CoercionContext ccontext,
3159 : Oid *funcid)
3160 : {
3161 911741 : CoercionPathType result = COERCION_PATH_NONE;
3162 : HeapTuple tuple;
3163 :
3164 911741 : *funcid = InvalidOid;
3165 :
3166 : /* Perhaps the types are domains; if so, look at their base types */
3167 911741 : if (OidIsValid(sourceTypeId))
3168 911741 : sourceTypeId = getBaseType(sourceTypeId);
3169 911741 : if (OidIsValid(targetTypeId))
3170 911741 : targetTypeId = getBaseType(targetTypeId);
3171 :
3172 : /* Domains are always coercible to and from their base type */
3173 911741 : if (sourceTypeId == targetTypeId)
3174 60597 : return COERCION_PATH_RELABELTYPE;
3175 :
3176 : /* Look in pg_cast */
3177 851144 : tuple = SearchSysCache2(CASTSOURCETARGET,
3178 : ObjectIdGetDatum(sourceTypeId),
3179 : ObjectIdGetDatum(targetTypeId));
3180 :
3181 851144 : if (HeapTupleIsValid(tuple))
3182 : {
3183 329793 : Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
3184 : CoercionContext castcontext;
3185 :
3186 : /* convert char value for castcontext to CoercionContext enum */
3187 329793 : switch (castForm->castcontext)
3188 : {
3189 257526 : case COERCION_CODE_IMPLICIT:
3190 257526 : castcontext = COERCION_IMPLICIT;
3191 257526 : break;
3192 64604 : case COERCION_CODE_ASSIGNMENT:
3193 64604 : castcontext = COERCION_ASSIGNMENT;
3194 64604 : break;
3195 7663 : case COERCION_CODE_EXPLICIT:
3196 7663 : castcontext = COERCION_EXPLICIT;
3197 7663 : break;
3198 0 : default:
3199 0 : elog(ERROR, "unrecognized castcontext: %d",
3200 : (int) castForm->castcontext);
3201 : castcontext = 0; /* keep compiler quiet */
3202 : break;
3203 : }
3204 :
3205 : /* Rely on ordering of enum for correct behavior here */
3206 329793 : if (ccontext >= castcontext)
3207 : {
3208 272878 : switch (castForm->castmethod)
3209 : {
3210 97942 : case COERCION_METHOD_FUNCTION:
3211 97942 : result = COERCION_PATH_FUNC;
3212 97942 : *funcid = castForm->castfunc;
3213 97942 : break;
3214 578 : case COERCION_METHOD_INOUT:
3215 578 : result = COERCION_PATH_COERCEVIAIO;
3216 578 : break;
3217 174358 : case COERCION_METHOD_BINARY:
3218 174358 : result = COERCION_PATH_RELABELTYPE;
3219 174358 : break;
3220 0 : default:
3221 0 : elog(ERROR, "unrecognized castmethod: %d",
3222 : (int) castForm->castmethod);
3223 : break;
3224 : }
3225 : }
3226 :
3227 329793 : ReleaseSysCache(tuple);
3228 : }
3229 : else
3230 : {
3231 : /*
3232 : * If there's no pg_cast entry, perhaps we are dealing with a pair of
3233 : * array types. If so, and if their element types have a conversion
3234 : * pathway, report that we can coerce with an ArrayCoerceExpr.
3235 : *
3236 : * Hack: disallow coercions to oidvector and int2vector, which
3237 : * otherwise tend to capture coercions that should go to "real" array
3238 : * types. We want those types to be considered "real" arrays for many
3239 : * purposes, but not this one. (Also, ArrayCoerceExpr isn't
3240 : * guaranteed to produce an output that meets the restrictions of
3241 : * these datatypes, such as being 1-dimensional.)
3242 : */
3243 521351 : if (targetTypeId != OIDVECTOROID && targetTypeId != INT2VECTOROID)
3244 : {
3245 : Oid targetElem;
3246 : Oid sourceElem;
3247 :
3248 521076 : if ((targetElem = get_element_type(targetTypeId)) != InvalidOid &&
3249 7681 : (sourceElem = get_element_type(sourceTypeId)) != InvalidOid)
3250 : {
3251 : CoercionPathType elempathtype;
3252 : Oid elemfuncid;
3253 :
3254 6867 : elempathtype = find_coercion_pathway(targetElem,
3255 : sourceElem,
3256 : ccontext,
3257 : &elemfuncid);
3258 6867 : if (elempathtype != COERCION_PATH_NONE)
3259 : {
3260 6765 : result = COERCION_PATH_ARRAYCOERCE;
3261 : }
3262 : }
3263 : }
3264 :
3265 : /*
3266 : * If we still haven't found a possibility, consider automatic casting
3267 : * using I/O functions. We allow assignment casts to string types and
3268 : * explicit casts from string types to be handled this way. (The
3269 : * CoerceViaIO mechanism is a lot more general than that, but this is
3270 : * all we want to allow in the absence of a pg_cast entry.) It would
3271 : * probably be better to insist on explicit casts in both directions,
3272 : * but this is a compromise to preserve something of the pre-8.3
3273 : * behavior that many types had implicit (yipes!) casts to text.
3274 : */
3275 521351 : if (result == COERCION_PATH_NONE)
3276 : {
3277 549384 : if (ccontext >= COERCION_ASSIGNMENT &&
3278 34798 : TypeCategory(targetTypeId) == TYPCATEGORY_STRING)
3279 27934 : result = COERCION_PATH_COERCEVIAIO;
3280 492809 : else if (ccontext >= COERCION_EXPLICIT &&
3281 6157 : TypeCategory(sourceTypeId) == TYPCATEGORY_STRING)
3282 4004 : result = COERCION_PATH_COERCEVIAIO;
3283 : }
3284 : }
3285 :
3286 : /*
3287 : * When parsing PL/pgSQL assignments, allow an I/O cast to be used
3288 : * whenever no normal coercion is available.
3289 : */
3290 851144 : if (result == COERCION_PATH_NONE &&
3291 : ccontext == COERCION_PLPGSQL)
3292 182 : result = COERCION_PATH_COERCEVIAIO;
3293 :
3294 851144 : return result;
3295 : }
3296 :
3297 :
3298 : /*
3299 : * find_typmod_coercion_function -- does the given type need length coercion?
3300 : *
3301 : * If the target type possesses a pg_cast function from itself to itself,
3302 : * it must need length coercion.
3303 : *
3304 : * "bpchar" (ie, char(N)) and "numeric" are examples of such types.
3305 : *
3306 : * If the given type is a varlena array type, we do not look for a coercion
3307 : * function associated directly with the array type, but instead look for
3308 : * one associated with the element type. An ArrayCoerceExpr node must be
3309 : * used to apply such a function. (Note: currently, it's pointless to
3310 : * return the funcid in this case, because it'll just get looked up again
3311 : * in the recursive construction of the ArrayCoerceExpr's elemexpr.)
3312 : *
3313 : * We use the same result enum as find_coercion_pathway, but the only possible
3314 : * result codes are:
3315 : * COERCION_PATH_NONE: no length coercion needed
3316 : * COERCION_PATH_FUNC: apply the function returned in *funcid
3317 : * COERCION_PATH_ARRAYCOERCE: apply the function using ArrayCoerceExpr
3318 : */
3319 : CoercionPathType
3320 13784 : find_typmod_coercion_function(Oid typeId,
3321 : Oid *funcid)
3322 : {
3323 : CoercionPathType result;
3324 : Type targetType;
3325 : Form_pg_type typeForm;
3326 : HeapTuple tuple;
3327 :
3328 13784 : *funcid = InvalidOid;
3329 13784 : result = COERCION_PATH_FUNC;
3330 :
3331 13784 : targetType = typeidType(typeId);
3332 13784 : typeForm = (Form_pg_type) GETSTRUCT(targetType);
3333 :
3334 : /* Check for a "true" array type */
3335 13784 : if (IsTrueArrayType(typeForm))
3336 : {
3337 : /* Yes, switch our attention to the element type */
3338 52 : typeId = typeForm->typelem;
3339 52 : result = COERCION_PATH_ARRAYCOERCE;
3340 : }
3341 13784 : ReleaseSysCache(targetType);
3342 :
3343 : /* Look in pg_cast */
3344 13784 : tuple = SearchSysCache2(CASTSOURCETARGET,
3345 : ObjectIdGetDatum(typeId),
3346 : ObjectIdGetDatum(typeId));
3347 :
3348 13784 : if (HeapTupleIsValid(tuple))
3349 : {
3350 13776 : Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
3351 :
3352 13776 : *funcid = castForm->castfunc;
3353 13776 : ReleaseSysCache(tuple);
3354 : }
3355 :
3356 13784 : if (!OidIsValid(*funcid))
3357 8 : result = COERCION_PATH_NONE;
3358 :
3359 13784 : return result;
3360 : }
3361 :
3362 : /*
3363 : * is_complex_array
3364 : * Is this type an array of composite?
3365 : *
3366 : * Note: this will not return true for record[]; check for RECORDARRAYOID
3367 : * separately if needed.
3368 : */
3369 : static bool
3370 18 : is_complex_array(Oid typid)
3371 : {
3372 18 : Oid elemtype = get_element_type(typid);
3373 :
3374 18 : return (OidIsValid(elemtype) && ISCOMPLEX(elemtype));
3375 : }
3376 :
3377 :
3378 : /*
3379 : * Check whether reltypeId is the row type of a typed table of type
3380 : * reloftypeId, or is a domain over such a row type. (This is conceptually
3381 : * similar to the subtype relationship checked by typeInheritsFrom().)
3382 : */
3383 : static bool
3384 534934 : typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId)
3385 : {
3386 534934 : Oid relid = typeOrDomainTypeRelid(reltypeId);
3387 534934 : bool result = false;
3388 :
3389 534934 : if (relid)
3390 : {
3391 : HeapTuple tp;
3392 : Form_pg_class reltup;
3393 :
3394 9278 : tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
3395 9278 : if (!HeapTupleIsValid(tp))
3396 0 : elog(ERROR, "cache lookup failed for relation %u", relid);
3397 :
3398 9278 : reltup = (Form_pg_class) GETSTRUCT(tp);
3399 9278 : if (reltup->reloftype == reloftypeId)
3400 8 : result = true;
3401 :
3402 9278 : ReleaseSysCache(tp);
3403 : }
3404 :
3405 534934 : return result;
3406 : }
|