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