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