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