Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * parse_func.c
4 : : * handle function calls in parser
5 : : *
6 : : * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7 : : * Portions Copyright (c) 1994, Regents of the University of California
8 : : *
9 : : *
10 : : * IDENTIFICATION
11 : : * src/backend/parser/parse_func.c
12 : : *
13 : : *-------------------------------------------------------------------------
14 : : */
15 : : #include "postgres.h"
16 : :
17 : : #include "access/htup_details.h"
18 : : #include "catalog/pg_aggregate.h"
19 : : #include "catalog/pg_proc.h"
20 : : #include "catalog/pg_type.h"
21 : : #include "funcapi.h"
22 : : #include "lib/stringinfo.h"
23 : : #include "nodes/makefuncs.h"
24 : : #include "nodes/nodeFuncs.h"
25 : : #include "parser/parse_agg.h"
26 : : #include "parser/parse_clause.h"
27 : : #include "parser/parse_coerce.h"
28 : : #include "parser/parse_expr.h"
29 : : #include "parser/parse_func.h"
30 : : #include "parser/parse_relation.h"
31 : : #include "parser/parse_target.h"
32 : : #include "parser/parse_type.h"
33 : : #include "utils/builtins.h"
34 : : #include "utils/lsyscache.h"
35 : : #include "utils/syscache.h"
36 : :
37 : :
38 : : /* Possible error codes from LookupFuncNameInternal */
39 : : typedef enum
40 : : {
41 : : FUNCLOOKUP_NOSUCHFUNC,
42 : : FUNCLOOKUP_AMBIGUOUS,
43 : : } FuncLookupError;
44 : :
45 : : static void unify_hypothetical_args(ParseState *pstate,
46 : : List *fargs, int numAggregatedArgs,
47 : : Oid *actual_arg_types, Oid *declared_arg_types);
48 : : static Oid FuncNameAsType(List *funcname);
49 : : static Node *ParseComplexProjection(ParseState *pstate, const char *funcname,
50 : : Node *first_arg, int location);
51 : : static Oid LookupFuncNameInternal(ObjectType objtype, List *funcname,
52 : : int nargs, const Oid *argtypes,
53 : : bool include_out_arguments, bool missing_ok,
54 : : FuncLookupError *lookupError);
55 : :
56 : :
57 : : /*
58 : : * Parse a function call
59 : : *
60 : : * For historical reasons, Postgres tries to treat the notations tab.col
61 : : * and col(tab) as equivalent: if a single-argument function call has an
62 : : * argument of complex type and the (unqualified) function name matches
63 : : * any attribute of the type, we can interpret it as a column projection.
64 : : * Conversely a function of a single complex-type argument can be written
65 : : * like a column reference, allowing functions to act like computed columns.
66 : : *
67 : : * If both interpretations are possible, we prefer the one matching the
68 : : * syntactic form, but otherwise the form does not matter.
69 : : *
70 : : * Hence, both cases come through here. If fn is null, we're dealing with
71 : : * column syntax not function syntax. In the function-syntax case,
72 : : * the FuncCall struct is needed to carry various decoration that applies
73 : : * to aggregate and window functions.
74 : : *
75 : : * Also, when fn is null, we return NULL on failure rather than
76 : : * reporting a no-such-function error.
77 : : *
78 : : * The argument expressions (in fargs) must have been transformed
79 : : * already. However, nothing in *fn has been transformed.
80 : : *
81 : : * last_srf should be a copy of pstate->p_last_srf from just before we
82 : : * started transforming fargs. If the caller knows that fargs couldn't
83 : : * contain any SRF calls, last_srf can just be pstate->p_last_srf.
84 : : *
85 : : * proc_call is true if we are considering a CALL statement, so that the
86 : : * name must resolve to a procedure name, not anything else. This flag
87 : : * also specifies that the argument list includes any OUT-mode arguments.
88 : : */
89 : : Node *
8041 tgl@sss.pgh.pa.us 90 :CBC 179228 : ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
91 : : Node *last_srf, FuncCall *fn, bool proc_call, int location)
92 : : {
3765 93 : 179228 : bool is_column = (fn == NULL);
94 [ + + ]: 179228 : List *agg_order = (fn ? fn->agg_order : NIL);
95 : 179228 : Expr *agg_filter = NULL;
1257 96 [ + + ]: 179228 : WindowDef *over = (fn ? fn->over : NULL);
3765 97 [ + + + + ]: 179228 : bool agg_within_group = (fn ? fn->agg_within_group : false);
98 [ + + + + ]: 179228 : bool agg_star = (fn ? fn->agg_star : false);
99 [ + + + + ]: 179228 : bool agg_distinct = (fn ? fn->agg_distinct : false);
100 [ + + + + ]: 179228 : bool func_variadic = (fn ? fn->func_variadic : false);
1257 101 [ + + ]: 179228 : CoercionForm funcformat = (fn ? fn->funcformat : COERCE_EXPLICIT_CALL);
102 : : bool could_be_projection;
103 : : Oid rettype;
104 : : Oid funcid;
105 : : ListCell *l;
9637 bruce@momjian.us 106 : 179228 : Node *first_arg = NULL;
107 : : int nargs;
108 : : int nargsplusdefs;
109 : : Oid actual_arg_types[FUNC_MAX_ARGS];
110 : : Oid *declared_arg_types;
111 : : List *argnames;
112 : : List *argdefaults;
113 : : Node *retval;
114 : : bool retset;
115 : : int nvargs;
116 : : Oid vatype;
117 : : FuncDetailCode fdresult;
3765 tgl@sss.pgh.pa.us 118 : 179228 : char aggkind = 0;
119 : : ParseCallbackState pcbstate;
120 : :
121 : : /*
122 : : * If there's an aggregate filter, transform it using transformWhereClause
123 : : */
124 [ + + + + ]: 179228 : if (fn && fn->agg_filter != NULL)
125 : 397 : agg_filter = (Expr *) transformWhereClause(pstate, fn->agg_filter,
126 : : EXPR_KIND_FILTER,
127 : : "FILTER");
128 : :
129 : : /*
130 : : * Most of the rest of the parser just assumes that functions do not have
131 : : * more than FUNC_MAX_ARGS parameters. We have to test here to protect
132 : : * against array overruns, etc. Of course, this may not be a function,
133 : : * but the test doesn't hurt.
134 : : */
6871 135 [ - + ]: 179222 : if (list_length(fargs) > FUNC_MAX_ARGS)
7576 tgl@sss.pgh.pa.us 136 [ # # ]:UBC 0 : ereport(ERROR,
137 : : (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
138 : : errmsg_plural("cannot pass more than %d argument to a function",
139 : : "cannot pass more than %d arguments to a function",
140 : : FUNC_MAX_ARGS,
141 : : FUNC_MAX_ARGS),
142 : : parser_errposition(pstate, location)));
143 : :
144 : : /*
145 : : * Extract arg type info in preparation for function lookup.
146 : : *
147 : : * If any arguments are Param markers of type VOID, we discard them from
148 : : * the parameter list. This is a hack to allow the JDBC driver to not have
149 : : * to distinguish "input" and "output" parameter symbols while parsing
150 : : * function-call constructs. Don't do this if dealing with column syntax,
151 : : * nor if we had WITHIN GROUP (because in that case it's critical to keep
152 : : * the argument count unchanged).
153 : : */
6871 tgl@sss.pgh.pa.us 154 :CBC 179222 : nargs = 0;
1735 155 [ + + + + : 435828 : foreach(l, fargs)
+ + ]
156 : : {
6871 157 : 256606 : Node *arg = lfirst(l);
158 : 256606 : Oid argtype = exprType(arg);
159 : :
3765 160 [ + + - + ]: 256606 : if (argtype == VOIDOID && IsA(arg, Param) &&
3765 tgl@sss.pgh.pa.us 161 [ # # # # ]:UBC 0 : !is_column && !agg_within_group)
162 : : {
1735 163 : 0 : fargs = foreach_delete_current(fargs, l);
6871 164 : 0 : continue;
165 : : }
166 : :
6871 tgl@sss.pgh.pa.us 167 :CBC 256606 : actual_arg_types[nargs++] = argtype;
168 : : }
169 : :
170 : : /*
171 : : * Check for named arguments; if there are any, build a list of names.
172 : : *
173 : : * We allow mixed notation (some named and some not), but only with all
174 : : * the named parameters after all the unnamed ones. So the name list
175 : : * corresponds to the last N actual parameters and we don't need any extra
176 : : * bookkeeping to match things up.
177 : : */
5302 178 : 179222 : argnames = NIL;
179 [ + + + + : 435822 : foreach(l, fargs)
+ + ]
180 : : {
5161 bruce@momjian.us 181 : 256606 : Node *arg = lfirst(l);
182 : :
5302 tgl@sss.pgh.pa.us 183 [ + + ]: 256606 : if (IsA(arg, NamedArgExpr))
184 : : {
185 : 23356 : NamedArgExpr *na = (NamedArgExpr *) arg;
186 : : ListCell *lc;
187 : :
188 : : /* Reject duplicate arg names */
189 [ + + + + : 50642 : foreach(lc, argnames)
+ + ]
190 : : {
191 [ + + ]: 27289 : if (strcmp(na->name, (char *) lfirst(lc)) == 0)
192 [ + - ]: 3 : ereport(ERROR,
193 : : (errcode(ERRCODE_SYNTAX_ERROR),
194 : : errmsg("argument name \"%s\" used more than once",
195 : : na->name),
196 : : parser_errposition(pstate, na->location)));
197 : : }
198 : 23353 : argnames = lappend(argnames, na->name);
199 : : }
200 : : else
201 : : {
202 [ + + ]: 233250 : if (argnames != NIL)
203 [ + - ]: 3 : ereport(ERROR,
204 : : (errcode(ERRCODE_SYNTAX_ERROR),
205 : : errmsg("positional argument cannot follow named argument"),
206 : : parser_errposition(pstate, exprLocation(arg))));
207 : : }
208 : : }
209 : :
9637 bruce@momjian.us 210 [ + + ]: 179216 : if (fargs)
211 : : {
7263 neilc@samurai.com 212 : 149331 : first_arg = linitial(fargs);
7576 tgl@sss.pgh.pa.us 213 [ - + ]: 149331 : Assert(first_arg != NULL);
214 : : }
215 : :
216 : : /*
217 : : * Decide whether it's legitimate to consider the construct to be a column
218 : : * projection. For that, there has to be a single argument of complex
219 : : * type, the function name must not be qualified, and there cannot be any
220 : : * syntactic decoration that'd require it to be a function (such as
221 : : * aggregate or variadic decoration, or named arguments).
222 : : */
2127 223 [ + + + + ]: 66397 : could_be_projection = (nargs == 1 && !proc_call &&
224 [ + + ]: 65685 : agg_order == NIL && agg_filter == NULL &&
225 [ + - + + : 65402 : !agg_star && !agg_distinct && over == NULL &&
+ + ]
226 [ + + + + : 127759 : !func_variadic && argnames == NIL &&
+ + ]
227 [ + + ]: 309318 : list_length(funcname) == 1 &&
228 [ + + + + ]: 89139 : (actual_arg_types[0] == RECORDOID ||
229 : 43942 : ISCOMPLEX(actual_arg_types[0])));
230 : :
231 : : /*
232 : : * If it's column syntax, check for column projection case first.
233 : : */
234 [ + + + + ]: 179216 : if (could_be_projection && is_column)
235 : : {
236 : 4591 : retval = ParseComplexProjection(pstate,
237 : 4591 : strVal(linitial(funcname)),
238 : : first_arg,
239 : : location);
240 [ + + ]: 4591 : if (retval)
241 : 4485 : return retval;
242 : :
243 : : /*
244 : : * If ParseComplexProjection doesn't recognize it as a projection,
245 : : * just press on.
246 : : */
247 : : }
248 : :
249 : : /*
250 : : * func_get_detail looks up the function in the catalogs, does
251 : : * disambiguation for polymorphic functions, handles inheritance, and
252 : : * returns the funcid and type and set or singleton status of the
253 : : * function's return value. It also returns the true argument types to
254 : : * the function.
255 : : *
256 : : * Note: for a named-notation or variadic function call, the reported
257 : : * "true" types aren't really what is in pg_proc: the types are reordered
258 : : * to match the given argument order of named arguments, and a variadic
259 : : * argument is replaced by a suitable number of copies of its element
260 : : * type. We'll fix up the variadic case below. We may also have to deal
261 : : * with default arguments.
262 : : */
263 : :
3315 alvherre@alvh.no-ip. 264 : 174731 : setup_parser_errposition_callback(&pcbstate, pstate, location);
265 : :
5302 tgl@sss.pgh.pa.us 266 : 174731 : fdresult = func_get_detail(funcname, fargs, argnames, nargs,
267 : : actual_arg_types,
1039 tgl@sss.pgh.pa.us 268 :GIC 174731 : !func_variadic, true, proc_call,
269 : : &funcid, &rettype, &retset,
270 : : &nvargs, &vatype,
5610 peter_e@gmx.net 271 :CBC 174731 : &declared_arg_types, &argdefaults);
272 : :
3315 alvherre@alvh.no-ip. 273 : 174731 : cancel_parser_errposition_callback(&pcbstate);
274 : :
275 : : /*
276 : : * Check for various wrong-kind-of-routine cases.
277 : : */
278 : :
279 : : /* If this is a CALL, reject things that aren't procedures */
2129 tgl@sss.pgh.pa.us 280 [ + + + + ]: 174731 : if (proc_call &&
281 [ + + ]: 217 : (fdresult == FUNCDETAIL_NORMAL ||
282 [ + - ]: 214 : fdresult == FUNCDETAIL_AGGREGATE ||
283 [ - + ]: 214 : fdresult == FUNCDETAIL_WINDOWFUNC ||
284 : : fdresult == FUNCDETAIL_COERCION))
285 [ + - ]: 9 : ereport(ERROR,
286 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
287 : : errmsg("%s is not a procedure",
288 : : func_signature_string(funcname, nargs,
289 : : argnames,
290 : : actual_arg_types)),
291 : : errhint("To call a function, use SELECT."),
292 : : parser_errposition(pstate, location)));
293 : : /* Conversely, if not a CALL, reject procedures */
294 [ + + + + ]: 174722 : if (fdresult == FUNCDETAIL_PROCEDURE && !proc_call)
295 [ + - ]: 3 : ereport(ERROR,
296 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
297 : : errmsg("%s is a procedure",
298 : : func_signature_string(funcname, nargs,
299 : : argnames,
300 : : actual_arg_types)),
301 : : errhint("To call a procedure, use CALL."),
302 : : parser_errposition(pstate, location)));
303 : :
304 [ + + + + ]: 174719 : if (fdresult == FUNCDETAIL_NORMAL ||
305 [ + + ]: 22506 : fdresult == FUNCDETAIL_PROCEDURE ||
306 : : fdresult == FUNCDETAIL_COERCION)
307 : : {
308 : : /*
309 : : * In these cases, complain if there was anything indicating it must
310 : : * be an aggregate or window function.
311 : : */
8039 312 [ - + ]: 152445 : if (agg_star)
7576 tgl@sss.pgh.pa.us 313 [ # # ]:UBC 0 : ereport(ERROR,
314 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
315 : : errmsg("%s(*) specified, but %s is not an aggregate function",
316 : : NameListToString(funcname),
317 : : NameListToString(funcname)),
318 : : parser_errposition(pstate, location)));
8039 tgl@sss.pgh.pa.us 319 [ - + ]:CBC 152445 : if (agg_distinct)
7576 tgl@sss.pgh.pa.us 320 [ # # ]:UBC 0 : ereport(ERROR,
321 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
322 : : errmsg("DISTINCT specified, but %s is not an aggregate function",
323 : : NameListToString(funcname)),
324 : : parser_errposition(pstate, location)));
3765 tgl@sss.pgh.pa.us 325 [ - + ]:CBC 152445 : if (agg_within_group)
3765 tgl@sss.pgh.pa.us 326 [ # # ]:UBC 0 : ereport(ERROR,
327 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
328 : : errmsg("WITHIN GROUP specified, but %s is not an aggregate function",
329 : : NameListToString(funcname)),
330 : : parser_errposition(pstate, location)));
5234 tgl@sss.pgh.pa.us 331 [ - + ]:CBC 152445 : if (agg_order != NIL)
5234 tgl@sss.pgh.pa.us 332 [ # # ]:UBC 0 : ereport(ERROR,
333 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
334 : : errmsg("ORDER BY specified, but %s is not an aggregate function",
335 : : NameListToString(funcname)),
336 : : parser_errposition(pstate, location)));
3925 noah@leadboat.com 337 [ - + ]:CBC 152445 : if (agg_filter)
3925 noah@leadboat.com 338 [ # # ]:UBC 0 : ereport(ERROR,
339 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
340 : : errmsg("FILTER specified, but %s is not an aggregate function",
341 : : NameListToString(funcname)),
342 : : parser_errposition(pstate, location)));
5586 tgl@sss.pgh.pa.us 343 [ + + ]:CBC 152445 : if (over)
344 [ + - ]: 3 : ereport(ERROR,
345 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
346 : : errmsg("OVER specified, but %s is not a window function nor an aggregate function",
347 : : NameListToString(funcname)),
348 : : parser_errposition(pstate, location)));
349 : : }
350 : :
351 : : /*
352 : : * So far so good, so do some fdresult-type-specific processing.
353 : : */
2129 354 [ + + + + ]: 174716 : if (fdresult == FUNCDETAIL_NORMAL || fdresult == FUNCDETAIL_PROCEDURE)
355 : : {
356 : : /* Nothing special to do for these cases. */
357 : : }
3765 358 [ + + ]: 22506 : else if (fdresult == FUNCDETAIL_AGGREGATE)
359 : : {
360 : : /*
361 : : * It's an aggregate; fetch needed info from the pg_aggregate entry.
362 : : */
363 : : HeapTuple tup;
364 : : Form_pg_aggregate classForm;
365 : : int catDirectArgs;
366 : :
367 : 21074 : tup = SearchSysCache1(AGGFNOID, ObjectIdGetDatum(funcid));
2489 368 [ - + ]: 21074 : if (!HeapTupleIsValid(tup)) /* should not happen */
3765 tgl@sss.pgh.pa.us 369 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for aggregate %u", funcid);
3765 tgl@sss.pgh.pa.us 370 :CBC 21074 : classForm = (Form_pg_aggregate) GETSTRUCT(tup);
371 : 21074 : aggkind = classForm->aggkind;
372 : 21074 : catDirectArgs = classForm->aggnumdirectargs;
373 : 21074 : ReleaseSysCache(tup);
374 : :
375 : : /* Now check various disallowed cases. */
376 [ + + ]: 21074 : if (AGGKIND_IS_ORDERED_SET(aggkind))
377 : : {
378 : : int numAggregatedArgs;
379 : : int numDirectArgs;
380 : :
381 [ + + ]: 171 : if (!agg_within_group)
382 [ + - ]: 3 : ereport(ERROR,
383 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
384 : : errmsg("WITHIN GROUP is required for ordered-set aggregate %s",
385 : : NameListToString(funcname)),
386 : : parser_errposition(pstate, location)));
387 [ - + ]: 168 : if (over)
3765 tgl@sss.pgh.pa.us 388 [ # # ]:UBC 0 : ereport(ERROR,
389 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
390 : : errmsg("OVER is not supported for ordered-set aggregate %s",
391 : : NameListToString(funcname)),
392 : : parser_errposition(pstate, location)));
393 : : /* gram.y rejects DISTINCT + WITHIN GROUP */
3765 tgl@sss.pgh.pa.us 394 [ - + ]:CBC 168 : Assert(!agg_distinct);
395 : : /* gram.y rejects VARIADIC + WITHIN GROUP */
396 [ - + ]: 168 : Assert(!func_variadic);
397 : :
398 : : /*
399 : : * Since func_get_detail was working with an undifferentiated list
400 : : * of arguments, it might have selected an aggregate that doesn't
401 : : * really match because it requires a different division of direct
402 : : * and aggregated arguments. Check that the number of direct
403 : : * arguments is actually OK; if not, throw an "undefined function"
404 : : * error, similarly to the case where a misplaced ORDER BY is used
405 : : * in a regular aggregate call.
406 : : */
407 : 168 : numAggregatedArgs = list_length(agg_order);
408 : 168 : numDirectArgs = nargs - numAggregatedArgs;
409 [ - + ]: 168 : Assert(numDirectArgs >= 0);
410 : :
411 [ + + ]: 168 : if (!OidIsValid(vatype))
412 : : {
413 : : /* Test is simple if aggregate isn't variadic */
414 [ - + ]: 93 : if (numDirectArgs != catDirectArgs)
3765 tgl@sss.pgh.pa.us 415 [ # # ]:UBC 0 : ereport(ERROR,
416 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
417 : : errmsg("function %s does not exist",
418 : : func_signature_string(funcname, nargs,
419 : : argnames,
420 : : actual_arg_types)),
421 : : errhint_plural("There is an ordered-set aggregate %s, but it requires %d direct argument, not %d.",
422 : : "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d.",
423 : : catDirectArgs,
424 : : NameListToString(funcname),
425 : : catDirectArgs, numDirectArgs),
426 : : parser_errposition(pstate, location)));
427 : : }
428 : : else
429 : : {
430 : : /*
431 : : * If it's variadic, we have two cases depending on whether
432 : : * the agg was "... ORDER BY VARIADIC" or "..., VARIADIC ORDER
433 : : * BY VARIADIC". It's the latter if catDirectArgs equals
434 : : * pronargs; to save a catalog lookup, we reverse-engineer
435 : : * pronargs from the info we got from func_get_detail.
436 : : */
437 : : int pronargs;
438 : :
3765 tgl@sss.pgh.pa.us 439 :CBC 75 : pronargs = nargs;
440 [ + - ]: 75 : if (nvargs > 1)
441 : 75 : pronargs -= nvargs - 1;
442 [ - + ]: 75 : if (catDirectArgs < pronargs)
443 : : {
444 : : /* VARIADIC isn't part of direct args, so still easy */
3765 tgl@sss.pgh.pa.us 445 [ # # ]:UBC 0 : if (numDirectArgs != catDirectArgs)
446 [ # # ]: 0 : ereport(ERROR,
447 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
448 : : errmsg("function %s does not exist",
449 : : func_signature_string(funcname, nargs,
450 : : argnames,
451 : : actual_arg_types)),
452 : : errhint_plural("There is an ordered-set aggregate %s, but it requires %d direct argument, not %d.",
453 : : "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d.",
454 : : catDirectArgs,
455 : : NameListToString(funcname),
456 : : catDirectArgs, numDirectArgs),
457 : : parser_errposition(pstate, location)));
458 : : }
459 : : else
460 : : {
461 : : /*
462 : : * Both direct and aggregated args were declared variadic.
463 : : * For a standard ordered-set aggregate, it's okay as long
464 : : * as there aren't too few direct args. For a
465 : : * hypothetical-set aggregate, we assume that the
466 : : * hypothetical arguments are those that matched the
467 : : * variadic parameter; there must be just as many of them
468 : : * as there are aggregated arguments.
469 : : */
3765 tgl@sss.pgh.pa.us 470 [ + - ]:CBC 75 : if (aggkind == AGGKIND_HYPOTHETICAL)
471 : : {
472 [ + + ]: 75 : if (nvargs != 2 * numAggregatedArgs)
473 [ + - ]: 3 : ereport(ERROR,
474 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
475 : : errmsg("function %s does not exist",
476 : : func_signature_string(funcname, nargs,
477 : : argnames,
478 : : actual_arg_types)),
479 : : errhint("To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d).",
480 : : NameListToString(funcname),
481 : : nvargs - numAggregatedArgs, numAggregatedArgs),
482 : : parser_errposition(pstate, location)));
483 : : }
484 : : else
485 : : {
3765 tgl@sss.pgh.pa.us 486 [ # # ]:UBC 0 : if (nvargs <= numAggregatedArgs)
487 [ # # ]: 0 : ereport(ERROR,
488 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
489 : : errmsg("function %s does not exist",
490 : : func_signature_string(funcname, nargs,
491 : : argnames,
492 : : actual_arg_types)),
493 : : errhint_plural("There is an ordered-set aggregate %s, but it requires at least %d direct argument.",
494 : : "There is an ordered-set aggregate %s, but it requires at least %d direct arguments.",
495 : : catDirectArgs,
496 : : NameListToString(funcname),
497 : : catDirectArgs),
498 : : parser_errposition(pstate, location)));
499 : : }
500 : : }
501 : : }
502 : :
503 : : /* Check type matching of hypothetical arguments */
3765 tgl@sss.pgh.pa.us 504 [ + + ]:CBC 165 : if (aggkind == AGGKIND_HYPOTHETICAL)
505 : 72 : unify_hypothetical_args(pstate, fargs, numAggregatedArgs,
506 : : actual_arg_types, declared_arg_types);
507 : : }
508 : : else
509 : : {
510 : : /* Normal aggregate, so it can't have WITHIN GROUP */
511 [ + + ]: 20903 : if (agg_within_group)
512 [ + - ]: 3 : ereport(ERROR,
513 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
514 : : errmsg("%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP",
515 : : NameListToString(funcname)),
516 : : parser_errposition(pstate, location)));
517 : : }
518 : : }
519 [ + + ]: 1432 : else if (fdresult == FUNCDETAIL_WINDOWFUNC)
520 : : {
521 : : /*
522 : : * True window functions must be called with a window definition.
523 : : */
524 [ - + ]: 910 : if (!over)
3765 tgl@sss.pgh.pa.us 525 [ # # ]:UBC 0 : ereport(ERROR,
526 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
527 : : errmsg("window function %s requires an OVER clause",
528 : : NameListToString(funcname)),
529 : : parser_errposition(pstate, location)));
530 : : /* And, per spec, WITHIN GROUP isn't allowed */
3765 tgl@sss.pgh.pa.us 531 [ - + ]:CBC 910 : if (agg_within_group)
3765 tgl@sss.pgh.pa.us 532 [ # # ]:UBC 0 : ereport(ERROR,
533 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
534 : : errmsg("window function %s cannot have WITHIN GROUP",
535 : : NameListToString(funcname)),
536 : : parser_errposition(pstate, location)));
537 : : }
2129 tgl@sss.pgh.pa.us 538 [ + + ]:CBC 522 : else if (fdresult == FUNCDETAIL_COERCION)
539 : : {
540 : : /*
541 : : * We interpreted it as a type coercion. coerce_type can handle these
542 : : * cases, so why duplicate code...
543 : : */
544 : 232 : return coerce_type(pstate, linitial(fargs),
545 : : actual_arg_types[0], rettype, -1,
546 : : COERCION_EXPLICIT, COERCE_EXPLICIT_CALL, location);
547 : : }
2127 548 [ + + ]: 290 : else if (fdresult == FUNCDETAIL_MULTIPLE)
549 : : {
550 : : /*
551 : : * We found multiple possible functional matches. If we are dealing
552 : : * with attribute notation, return failure, letting the caller report
553 : : * "no such column" (we already determined there wasn't one). If
554 : : * dealing with function notation, report "ambiguous function",
555 : : * regardless of whether there's also a column by this name.
556 : : */
557 [ - + ]: 15 : if (is_column)
2127 tgl@sss.pgh.pa.us 558 :UBC 0 : return NULL;
559 : :
2108 peter_e@gmx.net 560 [ - + ]:CBC 15 : if (proc_call)
2108 peter_e@gmx.net 561 [ # # ]:UBC 0 : ereport(ERROR,
562 : : (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
563 : : errmsg("procedure %s is not unique",
564 : : func_signature_string(funcname, nargs, argnames,
565 : : actual_arg_types)),
566 : : errhint("Could not choose a best candidate procedure. "
567 : : "You might need to add explicit type casts."),
568 : : parser_errposition(pstate, location)));
569 : : else
2108 peter_e@gmx.net 570 [ + - ]:CBC 15 : ereport(ERROR,
571 : : (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
572 : : errmsg("function %s is not unique",
573 : : func_signature_string(funcname, nargs, argnames,
574 : : actual_arg_types)),
575 : : errhint("Could not choose a best candidate function. "
576 : : "You might need to add explicit type casts."),
577 : : parser_errposition(pstate, location)));
578 : : }
579 : : else
580 : : {
581 : : /*
582 : : * Not found as a function. If we are dealing with attribute
583 : : * notation, return failure, letting the caller report "no such
584 : : * column" (we already determined there wasn't one).
585 : : */
8060 tgl@sss.pgh.pa.us 586 [ + + ]: 275 : if (is_column)
5279 587 : 49 : return NULL;
588 : :
589 : : /*
590 : : * Check for column projection interpretation, since we didn't before.
591 : : */
2127 592 [ + + ]: 226 : if (could_be_projection)
593 : : {
594 : 78 : retval = ParseComplexProjection(pstate,
595 : 78 : strVal(linitial(funcname)),
596 : : first_arg,
597 : : location);
598 [ + + ]: 78 : if (retval)
599 : 72 : return retval;
600 : : }
601 : :
602 : : /*
603 : : * No function, and no column either. Since we're dealing with
604 : : * function notation, report "function does not exist".
605 : : */
606 [ - + - - ]: 154 : if (list_length(agg_order) > 1 && !agg_within_group)
607 : : {
608 : : /* It's agg(x, ORDER BY y,z) ... perhaps misplaced ORDER BY */
5001 tgl@sss.pgh.pa.us 609 [ # # ]:UBC 0 : ereport(ERROR,
610 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
611 : : errmsg("function %s does not exist",
612 : : func_signature_string(funcname, nargs, argnames,
613 : : actual_arg_types)),
614 : : errhint("No aggregate function matches the given name and argument types. "
615 : : "Perhaps you misplaced ORDER BY; ORDER BY must appear "
616 : : "after all regular arguments of the aggregate."),
617 : : parser_errposition(pstate, location)));
618 : : }
2108 peter_e@gmx.net 619 [ + + ]:CBC 154 : else if (proc_call)
620 [ + - ]: 6 : ereport(ERROR,
621 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
622 : : errmsg("procedure %s does not exist",
623 : : func_signature_string(funcname, nargs, argnames,
624 : : actual_arg_types)),
625 : : errhint("No procedure matches the given name and argument types. "
626 : : "You might need to add explicit type casts."),
627 : : parser_errposition(pstate, location)));
628 : : else
7590 tgl@sss.pgh.pa.us 629 [ + - ]: 148 : ereport(ERROR,
630 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
631 : : errmsg("function %s does not exist",
632 : : func_signature_string(funcname, nargs, argnames,
633 : : actual_arg_types)),
634 : : errhint("No function matches the given name and argument types. "
635 : : "You might need to add explicit type casts."),
636 : : parser_errposition(pstate, location)));
637 : : }
638 : :
639 : : /*
640 : : * If there are default arguments, we have to include their types in
641 : : * actual_arg_types for the purpose of checking generic type consistency.
642 : : * However, we do NOT put them into the generated parse node, because
643 : : * their actual values might change before the query gets run. The
644 : : * planner has to insert the up-to-date values at plan time.
645 : : */
5596 646 : 174179 : nargsplusdefs = nargs;
647 [ + + + + : 186495 : foreach(l, argdefaults)
+ + ]
648 : : {
5421 bruce@momjian.us 649 : 12316 : Node *expr = (Node *) lfirst(l);
650 : :
651 : : /* probably shouldn't happen ... */
5596 tgl@sss.pgh.pa.us 652 [ - + ]: 12316 : if (nargsplusdefs >= FUNC_MAX_ARGS)
5596 tgl@sss.pgh.pa.us 653 [ # # ]:UBC 0 : ereport(ERROR,
654 : : (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
655 : : errmsg_plural("cannot pass more than %d argument to a function",
656 : : "cannot pass more than %d arguments to a function",
657 : : FUNC_MAX_ARGS,
658 : : FUNC_MAX_ARGS),
659 : : parser_errposition(pstate, location)));
660 : :
5596 tgl@sss.pgh.pa.us 661 :CBC 12316 : actual_arg_types[nargsplusdefs++] = exprType(expr);
662 : : }
663 : :
664 : : /*
665 : : * enforce consistency with polymorphic argument and return types,
666 : : * possibly adjusting return type or declared_arg_types (which will be
667 : : * used as the cast destination by make_fn_arguments)
668 : : */
7677 669 : 174179 : rettype = enforce_generic_type_consistency(actual_arg_types,
670 : : declared_arg_types,
671 : : nargsplusdefs,
672 : : rettype,
673 : : false);
674 : :
675 : : /* perform the necessary typecasting of arguments */
7656 676 : 174146 : make_fn_arguments(pstate, fargs, actual_arg_types, declared_arg_types);
677 : :
678 : : /*
679 : : * If the function isn't actually variadic, forget any VARIADIC decoration
680 : : * on the call. (Perhaps we should throw an error instead, but
681 : : * historically we've allowed people to write that.)
682 : : */
3664 683 [ + + ]: 174111 : if (!OidIsValid(vatype))
684 : : {
685 [ - + ]: 171256 : Assert(nvargs == 0);
686 : 171256 : func_variadic = false;
687 : : }
688 : :
689 : : /*
690 : : * If it's a variadic function call, transform the last nvargs arguments
691 : : * into an array --- unless it's an "any" variadic.
692 : : */
693 [ + + + + ]: 174111 : if (nvargs > 0 && vatype != ANYOID)
694 : : {
5421 bruce@momjian.us 695 : 1018 : ArrayExpr *newa = makeNode(ArrayExpr);
696 : 1018 : int non_var_args = nargs - nvargs;
697 : : List *vargs;
698 : :
5751 tgl@sss.pgh.pa.us 699 [ - + ]: 1018 : Assert(non_var_args >= 0);
700 : 1018 : vargs = list_copy_tail(fargs, non_var_args);
701 : 1018 : fargs = list_truncate(fargs, non_var_args);
702 : :
703 : 1018 : newa->elements = vargs;
704 : : /* assume all the variadic arguments were coerced to the same type */
705 : 1018 : newa->element_typeid = exprType((Node *) linitial(vargs));
706 : 1018 : newa->array_typeid = get_array_type(newa->element_typeid);
707 [ - + ]: 1018 : if (!OidIsValid(newa->array_typeid))
5751 tgl@sss.pgh.pa.us 708 [ # # ]:UBC 0 : ereport(ERROR,
709 : : (errcode(ERRCODE_UNDEFINED_OBJECT),
710 : : errmsg("could not find array type for data type %s",
711 : : format_type_be(newa->element_typeid)),
712 : : parser_errposition(pstate, exprLocation((Node *) vargs))));
713 : : /* array_collid will be set by parse_collate.c */
5751 tgl@sss.pgh.pa.us 714 :CBC 1018 : newa->multidims = false;
5708 715 : 1018 : newa->location = exprLocation((Node *) vargs);
716 : :
5751 717 : 1018 : fargs = lappend(fargs, newa);
718 : :
719 : : /* We could not have had VARIADIC marking before ... */
3664 720 [ - + ]: 1018 : Assert(!func_variadic);
721 : : /* ... but now, it's a VARIADIC call */
722 : 1018 : func_variadic = true;
723 : : }
724 : :
725 : : /*
726 : : * If an "any" variadic is called with explicit VARIADIC marking, insist
727 : : * that the variadic parameter be of some array type.
728 : : */
3923 andrew@dunslane.net 729 [ + + + + : 174111 : if (nargs > 0 && vatype == ANYOID && func_variadic)
+ + ]
730 : : {
3664 tgl@sss.pgh.pa.us 731 : 177 : Oid va_arr_typid = actual_arg_types[nargs - 1];
732 : :
733 [ + + ]: 177 : if (!OidIsValid(get_base_element_type(va_arr_typid)))
3923 andrew@dunslane.net 734 [ + - ]: 3 : ereport(ERROR,
735 : : (errcode(ERRCODE_DATATYPE_MISMATCH),
736 : : errmsg("VARIADIC argument must be an array"),
737 : : parser_errposition(pstate,
738 : : exprLocation((Node *) llast(fargs)))));
739 : : }
740 : :
741 : : /* if it returns a set, check that's OK */
2770 tgl@sss.pgh.pa.us 742 [ + + ]: 174108 : if (retset)
2497 743 : 23248 : check_srf_call_placement(pstate, last_srf, location);
744 : :
745 : : /* build the appropriate output structure */
2327 peter_e@gmx.net 746 [ + + + + ]: 174075 : if (fdresult == FUNCDETAIL_NORMAL || fdresult == FUNCDETAIL_PROCEDURE)
9637 bruce@momjian.us 747 : 152106 : {
7794 tgl@sss.pgh.pa.us 748 : 152106 : FuncExpr *funcexpr = makeNode(FuncExpr);
749 : :
750 : 152106 : funcexpr->funcid = funcid;
751 : 152106 : funcexpr->funcresulttype = rettype;
752 : 152106 : funcexpr->funcretset = retset;
4101 753 : 152106 : funcexpr->funcvariadic = func_variadic;
1257 754 : 152106 : funcexpr->funcformat = funcformat;
755 : : /* funccollid and inputcollid will be set by parse_collate.c */
7794 756 : 152106 : funcexpr->args = fargs;
5708 757 : 152106 : funcexpr->location = location;
758 : :
7794 759 : 152106 : retval = (Node *) funcexpr;
760 : : }
5586 761 [ + + + + ]: 21969 : else if (fdresult == FUNCDETAIL_AGGREGATE && !over)
8366 bruce@momjian.us 762 : 20224 : {
763 : : /* aggregate function */
8039 tgl@sss.pgh.pa.us 764 : 20311 : Aggref *aggref = makeNode(Aggref);
765 : :
766 : 20311 : aggref->aggfnoid = funcid;
2849 767 : 20311 : aggref->aggtype = rettype;
768 : : /* aggcollid and inputcollid will be set by parse_collate.c */
2489 769 : 20311 : aggref->aggtranstype = InvalidOid; /* will be set by planner */
770 : : /* aggargtypes will be set by transformAggregateCall */
771 : : /* aggdirectargs and args will be set by transformAggregateCall */
772 : : /* aggorder and aggdistinct will be set by transformAggregateCall */
3925 noah@leadboat.com 773 : 20311 : aggref->aggfilter = agg_filter;
3876 tgl@sss.pgh.pa.us 774 : 20311 : aggref->aggstar = agg_star;
775 : 20311 : aggref->aggvariadic = func_variadic;
3765 776 : 20311 : aggref->aggkind = aggkind;
621 drowley@postgresql.o 777 : 20311 : aggref->aggpresorted = false;
778 : : /* agglevelsup will be set by transformAggregateCall */
2489 tgl@sss.pgh.pa.us 779 : 20311 : aggref->aggsplit = AGGSPLIT_SIMPLE; /* planner might change this */
1237 heikki.linnakangas@i 780 : 20311 : aggref->aggno = -1; /* planner will set aggno and aggtransno */
781 : 20311 : aggref->aggtransno = -1;
5708 tgl@sss.pgh.pa.us 782 : 20311 : aggref->location = location;
783 : :
784 : : /*
785 : : * Reject attempt to call a parameterless aggregate without (*)
786 : : * syntax. This is mere pedantry but some folks insisted ...
787 : : */
3765 788 [ + + - + : 20311 : if (fargs == NIL && !agg_star && !agg_within_group)
- - ]
6471 tgl@sss.pgh.pa.us 789 [ # # ]:UBC 0 : ereport(ERROR,
790 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
791 : : errmsg("%s(*) must be used to call a parameterless aggregate function",
792 : : NameListToString(funcname)),
793 : : parser_errposition(pstate, location)));
794 : :
5586 tgl@sss.pgh.pa.us 795 [ - + ]:CBC 20311 : if (retset)
5586 tgl@sss.pgh.pa.us 796 [ # # ]:UBC 0 : ereport(ERROR,
797 : : (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
798 : : errmsg("aggregates cannot return sets"),
799 : : parser_errposition(pstate, location)));
800 : :
801 : : /*
802 : : * We might want to support named arguments later, but disallow it for
803 : : * now. We'd need to figure out the parsed representation (should the
804 : : * NamedArgExprs go above or below the TargetEntry nodes?) and then
805 : : * teach the planner to reorder the list properly. Or maybe we could
806 : : * make transformAggregateCall do that? However, if you'd also like
807 : : * to allow default arguments for aggregates, we'd need to do it in
808 : : * planning to avoid semantic problems.
809 : : */
5302 tgl@sss.pgh.pa.us 810 [ - + ]:CBC 20311 : if (argnames != NIL)
5302 tgl@sss.pgh.pa.us 811 [ # # ]:UBC 0 : ereport(ERROR,
812 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
813 : : errmsg("aggregates cannot use named arguments"),
814 : : parser_errposition(pstate, location)));
815 : :
816 : : /* parse_agg.c does additional aggregate-specific processing */
5142 tgl@sss.pgh.pa.us 817 :CBC 20311 : transformAggregateCall(pstate, aggref, fargs, agg_order, agg_distinct);
818 : :
8039 819 : 20224 : retval = (Node *) aggref;
820 : : }
821 : : else
822 : : {
823 : : /* window function */
5586 824 : 1658 : WindowFunc *wfunc = makeNode(WindowFunc);
825 : :
3765 826 [ - + ]: 1658 : Assert(over); /* lack of this was checked above */
2489 827 [ - + ]: 1658 : Assert(!agg_within_group); /* also checked above */
828 : :
5586 829 : 1658 : wfunc->winfnoid = funcid;
830 : 1658 : wfunc->wintype = rettype;
831 : : /* wincollid and inputcollid will be set by parse_collate.c */
832 : 1658 : wfunc->args = fargs;
833 : : /* winref will be set by transformWindowFuncCall */
834 : 1658 : wfunc->winstar = agg_star;
835 : 1658 : wfunc->winagg = (fdresult == FUNCDETAIL_AGGREGATE);
3925 noah@leadboat.com 836 : 1658 : wfunc->aggfilter = agg_filter;
5586 tgl@sss.pgh.pa.us 837 : 1658 : wfunc->location = location;
838 : :
839 : : /*
840 : : * agg_star is allowed for aggregate functions but distinct isn't
841 : : */
842 [ - + ]: 1658 : if (agg_distinct)
5586 tgl@sss.pgh.pa.us 843 [ # # ]:UBC 0 : ereport(ERROR,
844 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
845 : : errmsg("DISTINCT is not implemented for window functions"),
846 : : parser_errposition(pstate, location)));
847 : :
848 : : /*
849 : : * Reject attempt to call a parameterless aggregate without (*)
850 : : * syntax. This is mere pedantry but some folks insisted ...
851 : : */
5586 tgl@sss.pgh.pa.us 852 [ + + + + :CBC 1658 : if (wfunc->winagg && fargs == NIL && !agg_star)
+ + ]
853 [ + - ]: 3 : ereport(ERROR,
854 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
855 : : errmsg("%s(*) must be used to call a parameterless aggregate function",
856 : : NameListToString(funcname)),
857 : : parser_errposition(pstate, location)));
858 : :
859 : : /*
860 : : * ordered aggs not allowed in windows yet
861 : : */
3765 862 [ - + ]: 1655 : if (agg_order != NIL)
3925 noah@leadboat.com 863 [ # # ]:UBC 0 : ereport(ERROR,
864 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
865 : : errmsg("aggregate ORDER BY is not implemented for window functions"),
866 : : parser_errposition(pstate, location)));
867 : :
868 : : /*
869 : : * FILTER is not yet supported with true window functions
870 : : */
3765 tgl@sss.pgh.pa.us 871 [ + + - + ]:CBC 1655 : if (!wfunc->winagg && agg_filter)
5234 tgl@sss.pgh.pa.us 872 [ # # ]:UBC 0 : ereport(ERROR,
873 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
874 : : errmsg("FILTER is not implemented for non-aggregate window functions"),
875 : : parser_errposition(pstate, location)));
876 : :
877 : : /*
878 : : * Window functions can't either take or return sets
879 : : */
2497 tgl@sss.pgh.pa.us 880 [ + + ]:CBC 1655 : if (pstate->p_last_srf != last_srf)
881 [ + - ]: 3 : ereport(ERROR,
882 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
883 : : errmsg("window function calls cannot contain set-returning function calls"),
884 : : errhint("You might be able to move the set-returning function into a LATERAL FROM item."),
885 : : parser_errposition(pstate,
886 : : exprLocation(pstate->p_last_srf))));
887 : :
8039 888 [ - + ]: 1652 : if (retset)
7576 tgl@sss.pgh.pa.us 889 [ # # ]:UBC 0 : ereport(ERROR,
890 : : (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
891 : : errmsg("window functions cannot return sets"),
892 : : parser_errposition(pstate, location)));
893 : :
894 : : /* parse_agg.c does additional window-func-specific processing */
5586 tgl@sss.pgh.pa.us 895 :CBC 1652 : transformWindowFuncCall(pstate, wfunc, over);
896 : :
897 : 1628 : retval = (Node *) wfunc;
898 : : }
899 : :
900 : : /* if it returns a set, remember it for error checks at higher levels */
2497 901 [ + + ]: 173958 : if (retset)
902 : 23215 : pstate->p_last_srf = retval;
903 : :
8039 904 : 173958 : return retval;
905 : : }
906 : :
907 : :
908 : : /* func_match_argtypes()
909 : : *
910 : : * Given a list of candidate functions (having the right name and number
911 : : * of arguments) and an array of input datatype OIDs, produce a shortlist of
912 : : * those candidates that actually accept the input datatypes (either exactly
913 : : * or by coercion), and return the number of such candidates.
914 : : *
915 : : * Note that can_coerce_type will assume that UNKNOWN inputs are coercible to
916 : : * anything, so candidates will not be eliminated on that basis.
917 : : *
918 : : * NB: okay to modify input list structure, as long as we find at least
919 : : * one match. If no match at all, the list must remain unmodified.
920 : : */
921 : : int
7629 922 : 84091 : func_match_argtypes(int nargs,
923 : : Oid *input_typeids,
924 : : FuncCandidateList raw_candidates,
925 : : FuncCandidateList *candidates) /* return value */
926 : : {
927 : : FuncCandidateList current_candidate;
928 : : FuncCandidateList next_candidate;
9637 bruce@momjian.us 929 : 84091 : int ncandidates = 0;
930 : :
931 : 84091 : *candidates = NULL;
932 : :
7629 tgl@sss.pgh.pa.us 933 : 84091 : for (current_candidate = raw_candidates;
9637 bruce@momjian.us 934 [ + + ]: 551175 : current_candidate != NULL;
8044 tgl@sss.pgh.pa.us 935 : 467084 : current_candidate = next_candidate)
936 : : {
937 : 467084 : next_candidate = current_candidate->next;
8039 938 [ + + ]: 467084 : if (can_coerce_type(nargs, input_typeids, current_candidate->args,
939 : : COERCION_IMPLICIT))
940 : : {
8044 941 : 97720 : current_candidate->next = *candidates;
942 : 97720 : *candidates = current_candidate;
9637 bruce@momjian.us 943 : 97720 : ncandidates++;
944 : : }
945 : : }
946 : :
947 : 84091 : return ncandidates;
948 : : } /* func_match_argtypes() */
949 : :
950 : :
951 : : /* func_select_candidate()
952 : : * Given the input argtype array and more than one candidate
953 : : * for the function, attempt to resolve the conflict.
954 : : *
955 : : * Returns the selected candidate if the conflict can be resolved,
956 : : * otherwise returns NULL.
957 : : *
958 : : * Note that the caller has already determined that there is no candidate
959 : : * exactly matching the input argtypes, and has pruned away any "candidates"
960 : : * that aren't actually coercion-compatible with the input types.
961 : : *
962 : : * This is also used for resolving ambiguous operator references. Formerly
963 : : * parse_oper.c had its own, essentially duplicate code for the purpose.
964 : : * The following comments (formerly in parse_oper.c) are kept to record some
965 : : * of the history of these heuristics.
966 : : *
967 : : * OLD COMMENTS:
968 : : *
969 : : * This routine is new code, replacing binary_oper_select_candidate()
970 : : * which dates from v4.2/v1.0.x days. It tries very hard to match up
971 : : * operators with types, including allowing type coercions if necessary.
972 : : * The important thing is that the code do as much as possible,
973 : : * while _never_ doing the wrong thing, where "the wrong thing" would
974 : : * be returning an operator when other better choices are available,
975 : : * or returning an operator which is a non-intuitive possibility.
976 : : * - thomas 1998-05-21
977 : : *
978 : : * The comments below came from binary_oper_select_candidate(), and
979 : : * illustrate the issues and choices which are possible:
980 : : * - thomas 1998-05-20
981 : : *
982 : : * current wisdom holds that the default operator should be one in which
983 : : * both operands have the same type (there will only be one such
984 : : * operator)
985 : : *
986 : : * 7.27.93 - I have decided not to do this; it's too hard to justify, and
987 : : * it's easy enough to typecast explicitly - avi
988 : : * [the rest of this routine was commented out since then - ay]
989 : : *
990 : : * 6/23/95 - I don't complete agree with avi. In particular, casting
991 : : * floats is a pain for users. Whatever the rationale behind not doing
992 : : * this is, I need the following special case to work.
993 : : *
994 : : * In the WHERE clause of a query, if a float is specified without
995 : : * quotes, we treat it as float8. I added the float48* operators so
996 : : * that we can operate on float4 and float8. But now we have more than
997 : : * one matching operator if the right arg is unknown (eg. float
998 : : * specified with quotes). This break some stuff in the regression
999 : : * test where there are floats in quotes not properly casted. Below is
1000 : : * the solution. In addition to requiring the operator operates on the
1001 : : * same type for both operands [as in the code Avi originally
1002 : : * commented out], we also require that the operators be equivalent in
1003 : : * some sense. (see equivalentOpersAfterPromotion for details.)
1004 : : * - ay 6/95
1005 : : */
1006 : : FuncCandidateList
1007 : 5635 : func_select_candidate(int nargs,
1008 : : Oid *input_typeids,
1009 : : FuncCandidateList candidates)
1010 : : {
1011 : : FuncCandidateList current_candidate,
1012 : : first_candidate,
1013 : : last_candidate;
1014 : : Oid *current_typeids;
1015 : : Oid current_type;
1016 : : int i;
1017 : : int ncandidates;
1018 : : int nbestMatch,
1019 : : nmatch,
1020 : : nunknowns;
1021 : : Oid input_base_typeids[FUNC_MAX_ARGS];
1022 : : TYPCATEGORY slot_category[FUNC_MAX_ARGS],
1023 : : current_category;
1024 : : bool current_is_preferred;
1025 : : bool slot_has_preferred_type[FUNC_MAX_ARGS];
1026 : : bool resolved_unknowns;
1027 : :
1028 : : /* protect local fixed-size arrays */
6956 tgl@sss.pgh.pa.us 1029 [ - + ]: 5635 : if (nargs > FUNC_MAX_ARGS)
6956 tgl@sss.pgh.pa.us 1030 [ # # ]:UBC 0 : ereport(ERROR,
1031 : : (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
1032 : : errmsg_plural("cannot pass more than %d argument to a function",
1033 : : "cannot pass more than %d arguments to a function",
1034 : : FUNC_MAX_ARGS,
1035 : : FUNC_MAX_ARGS)));
1036 : :
1037 : : /*
1038 : : * If any input types are domains, reduce them to their base types. This
1039 : : * ensures that we will consider functions on the base type to be "exact
1040 : : * matches" in the exact-match heuristic; it also makes it possible to do
1041 : : * something useful with the type-category heuristics. Note that this
1042 : : * makes it difficult, but not impossible, to use functions declared to
1043 : : * take a domain as an input datatype. Such a function will be selected
1044 : : * over the base-type function only if it is an exact match at all
1045 : : * argument positions, and so was already chosen by our caller.
1046 : : *
1047 : : * While we're at it, count the number of unknown-type arguments for use
1048 : : * later.
1049 : : */
4532 tgl@sss.pgh.pa.us 1050 :CBC 5635 : nunknowns = 0;
7629 1051 [ + + ]: 17633 : for (i = 0; i < nargs; i++)
1052 : : {
4532 1053 [ + + ]: 11998 : if (input_typeids[i] != UNKNOWNOID)
1054 : 5958 : input_base_typeids[i] = getBaseType(input_typeids[i]);
1055 : : else
1056 : : {
1057 : : /* no need to call getBaseType on UNKNOWNOID */
1058 : 6040 : input_base_typeids[i] = UNKNOWNOID;
1059 : 6040 : nunknowns++;
1060 : : }
1061 : : }
1062 : :
1063 : : /*
1064 : : * Run through all candidates and keep those with the most matches on
1065 : : * exact types. Keep all candidates if none match.
1066 : : */
9472 lockhart@fourpalms.o 1067 : 5635 : ncandidates = 0;
1068 : 5635 : nbestMatch = 0;
1069 : 5635 : last_candidate = NULL;
1070 : 5635 : for (current_candidate = candidates;
1071 [ + + ]: 25210 : current_candidate != NULL;
1072 : 19575 : current_candidate = current_candidate->next)
1073 : : {
1074 : 19575 : current_typeids = current_candidate->args;
1075 : 19575 : nmatch = 0;
1076 [ + + ]: 60745 : for (i = 0; i < nargs; i++)
1077 : : {
7629 tgl@sss.pgh.pa.us 1078 [ + + ]: 41170 : if (input_base_typeids[i] != UNKNOWNOID &&
1079 [ + + ]: 18668 : current_typeids[i] == input_base_typeids[i])
1080 : 6119 : nmatch++;
1081 : : }
1082 : :
1083 : : /* take this one as the best choice so far? */
9472 lockhart@fourpalms.o 1084 [ + + + + ]: 19575 : if ((nmatch > nbestMatch) || (last_candidate == NULL))
1085 : : {
1086 : 6871 : nbestMatch = nmatch;
1087 : 6871 : candidates = current_candidate;
1088 : 6871 : last_candidate = current_candidate;
1089 : 6871 : ncandidates = 1;
1090 : : }
1091 : : /* no worse than the last choice, so keep this one too? */
1092 [ + + ]: 12704 : else if (nmatch == nbestMatch)
1093 : : {
1094 : 8877 : last_candidate->next = current_candidate;
1095 : 8877 : last_candidate = current_candidate;
1096 : 8877 : ncandidates++;
1097 : : }
1098 : : /* otherwise, don't bother keeping this one... */
1099 : : }
1100 : :
8820 tgl@sss.pgh.pa.us 1101 [ + - ]: 5635 : if (last_candidate) /* terminate rebuilt list */
1102 : 5635 : last_candidate->next = NULL;
1103 : :
9182 lockhart@fourpalms.o 1104 [ + + ]: 5635 : if (ncandidates == 1)
8044 tgl@sss.pgh.pa.us 1105 : 2530 : return candidates;
1106 : :
1107 : : /*
1108 : : * Still too many candidates? Now look for candidates which have either
1109 : : * exact matches or preferred types at the args that will require
1110 : : * coercion. (Restriction added in 7.4: preferred type must be of same
1111 : : * category as input type; give no preference to cross-category
1112 : : * conversions to preferred types.) Keep all candidates if none match.
1113 : : */
7559 bruce@momjian.us 1114 [ + + ]: 9915 : for (i = 0; i < nargs; i++) /* avoid multiple lookups */
7629 tgl@sss.pgh.pa.us 1115 : 6810 : slot_category[i] = TypeCategory(input_base_typeids[i]);
8792 1116 : 3105 : ncandidates = 0;
1117 : 3105 : nbestMatch = 0;
1118 : 3105 : last_candidate = NULL;
1119 : 3105 : for (current_candidate = candidates;
1120 [ + + ]: 13961 : current_candidate != NULL;
1121 : 10856 : current_candidate = current_candidate->next)
1122 : : {
1123 : 10856 : current_typeids = current_candidate->args;
1124 : 10856 : nmatch = 0;
1125 [ + + ]: 34361 : for (i = 0; i < nargs; i++)
1126 : : {
7629 1127 [ + + ]: 23505 : if (input_base_typeids[i] != UNKNOWNOID)
1128 : : {
1129 [ + + + + ]: 9953 : if (current_typeids[i] == input_base_typeids[i] ||
1130 : 3524 : IsPreferredType(slot_category[i], current_typeids[i]))
8792 1131 : 4348 : nmatch++;
1132 : : }
1133 : : }
1134 : :
1135 [ + + + + ]: 10856 : if ((nmatch > nbestMatch) || (last_candidate == NULL))
1136 : : {
1137 : 3851 : nbestMatch = nmatch;
1138 : 3851 : candidates = current_candidate;
1139 : 3851 : last_candidate = current_candidate;
1140 : 3851 : ncandidates = 1;
1141 : : }
1142 [ + + ]: 7005 : else if (nmatch == nbestMatch)
1143 : : {
1144 : 6436 : last_candidate->next = current_candidate;
1145 : 6436 : last_candidate = current_candidate;
1146 : 6436 : ncandidates++;
1147 : : }
1148 : : }
1149 : :
1150 [ + - ]: 3105 : if (last_candidate) /* terminate rebuilt list */
1151 : 3105 : last_candidate->next = NULL;
1152 : :
1153 [ + + ]: 3105 : if (ncandidates == 1)
8044 1154 : 681 : return candidates;
1155 : :
1156 : : /*
1157 : : * Still too many candidates? Try assigning types for the unknown inputs.
1158 : : *
1159 : : * If there are no unknown inputs, we have no more heuristics that apply,
1160 : : * and must fail.
1161 : : */
4532 1162 [ + + ]: 2424 : if (nunknowns == 0)
1163 : 3 : return NULL; /* failed to select a best candidate */
1164 : :
1165 : : /*
1166 : : * The next step examines each unknown argument position to see if we can
1167 : : * determine a "type category" for it. If any candidate has an input
1168 : : * datatype of STRING category, use STRING category (this bias towards
1169 : : * STRING is appropriate since unknown-type literals look like strings).
1170 : : * Otherwise, if all the candidates agree on the type category of this
1171 : : * argument position, use that category. Otherwise, fail because we
1172 : : * cannot determine a category.
1173 : : *
1174 : : * If we are able to determine a type category, also notice whether any of
1175 : : * the candidates takes a preferred datatype within the category.
1176 : : *
1177 : : * Having completed this examination, remove candidates that accept the
1178 : : * wrong category at any unknown position. Also, if at least one
1179 : : * candidate accepted a preferred type at a position, remove candidates
1180 : : * that accept non-preferred types. If just one candidate remains, return
1181 : : * that one. However, if this rule turns out to reject all candidates,
1182 : : * keep them all instead.
1183 : : */
8521 1184 : 2421 : resolved_unknowns = false;
9182 lockhart@fourpalms.o 1185 [ + + ]: 7891 : for (i = 0; i < nargs; i++)
1186 : : {
1187 : : bool have_conflict;
1188 : :
7629 tgl@sss.pgh.pa.us 1189 [ + + ]: 5470 : if (input_base_typeids[i] != UNKNOWNOID)
8521 1190 : 1311 : continue;
2489 1191 : 4159 : resolved_unknowns = true; /* assume we can do it */
5737 1192 : 4159 : slot_category[i] = TYPCATEGORY_INVALID;
8521 1193 : 4159 : slot_has_preferred_type[i] = false;
1194 : 4159 : have_conflict = false;
1195 : 4159 : for (current_candidate = candidates;
1196 [ + + ]: 20498 : current_candidate != NULL;
1197 : 16339 : current_candidate = current_candidate->next)
1198 : : {
1199 : 16339 : current_typeids = current_candidate->args;
1200 : 16339 : current_type = current_typeids[i];
5737 1201 : 16339 : get_type_category_preferred(current_type,
1202 : : ¤t_category,
1203 : : ¤t_is_preferred);
1204 [ + + ]: 16339 : if (slot_category[i] == TYPCATEGORY_INVALID)
1205 : : {
1206 : : /* first candidate */
8521 1207 : 4159 : slot_category[i] = current_category;
5737 1208 : 4159 : slot_has_preferred_type[i] = current_is_preferred;
1209 : : }
8521 1210 [ + + ]: 12180 : else if (current_category == slot_category[i])
1211 : : {
1212 : : /* more candidates in same category */
5737 1213 : 3355 : slot_has_preferred_type[i] |= current_is_preferred;
1214 : : }
1215 : : else
1216 : : {
1217 : : /* category conflict! */
1218 [ + + ]: 8825 : if (current_category == TYPCATEGORY_STRING)
1219 : : {
1220 : : /* STRING always wins if available */
8521 1221 : 1113 : slot_category[i] = current_category;
5737 1222 : 1113 : slot_has_preferred_type[i] = current_is_preferred;
1223 : : }
1224 : : else
1225 : : {
1226 : : /*
1227 : : * Remember conflict, but keep going (might find STRING)
1228 : : */
8521 1229 : 7712 : have_conflict = true;
1230 : : }
1231 : : }
1232 : : }
5737 1233 [ + + - + ]: 4159 : if (have_conflict && slot_category[i] != TYPCATEGORY_STRING)
1234 : : {
1235 : : /* Failed to resolve category conflict at this position */
8521 tgl@sss.pgh.pa.us 1236 :UBC 0 : resolved_unknowns = false;
1237 : 0 : break;
1238 : : }
1239 : : }
1240 : :
8521 tgl@sss.pgh.pa.us 1241 [ + - ]:CBC 2421 : if (resolved_unknowns)
1242 : : {
1243 : : /* Strip non-matching candidates */
1244 : 2421 : ncandidates = 0;
4532 1245 : 2421 : first_candidate = candidates;
8521 1246 : 2421 : last_candidate = NULL;
1247 : 2421 : for (current_candidate = candidates;
1248 [ + + ]: 11061 : current_candidate != NULL;
1249 : 8640 : current_candidate = current_candidate->next)
1250 : : {
8424 bruce@momjian.us 1251 : 8640 : bool keepit = true;
1252 : :
8521 tgl@sss.pgh.pa.us 1253 : 8640 : current_typeids = current_candidate->args;
1254 [ + + ]: 16000 : for (i = 0; i < nargs; i++)
1255 : : {
7629 1256 [ + + ]: 13524 : if (input_base_typeids[i] != UNKNOWNOID)
8521 1257 : 1949 : continue;
1258 : 11575 : current_type = current_typeids[i];
5737 1259 : 11575 : get_type_category_preferred(current_type,
1260 : : ¤t_category,
1261 : : ¤t_is_preferred);
8521 1262 [ + + ]: 11575 : if (current_category != slot_category[i])
1263 : : {
1264 : 5718 : keepit = false;
1265 : 5718 : break;
1266 : : }
5737 1267 [ + + + + ]: 5857 : if (slot_has_preferred_type[i] && !current_is_preferred)
1268 : : {
8521 1269 : 446 : keepit = false;
1270 : 446 : break;
1271 : : }
1272 : : }
1273 [ + + ]: 8640 : if (keepit)
1274 : : {
1275 : : /* keep this candidate */
1276 : 2476 : last_candidate = current_candidate;
1277 : 2476 : ncandidates++;
1278 : : }
1279 : : else
1280 : : {
1281 : : /* forget this candidate */
1282 [ + + ]: 6164 : if (last_candidate)
1283 : 4524 : last_candidate->next = current_candidate->next;
1284 : : else
4532 1285 : 1640 : first_candidate = current_candidate->next;
1286 : : }
1287 : : }
1288 : :
1289 : : /* if we found any matches, restrict our attention to those */
1290 [ + - ]: 2421 : if (last_candidate)
1291 : : {
1292 : 2421 : candidates = first_candidate;
1293 : : /* terminate rebuilt list */
8521 1294 : 2421 : last_candidate->next = NULL;
1295 : : }
1296 : :
4532 1297 [ + + ]: 2421 : if (ncandidates == 1)
1298 : 2396 : return candidates;
1299 : : }
1300 : :
1301 : : /*
1302 : : * Last gasp: if there are both known- and unknown-type inputs, and all
1303 : : * the known types are the same, assume the unknown inputs are also that
1304 : : * type, and see if that gives us a unique match. If so, use that match.
1305 : : *
1306 : : * NOTE: for a binary operator with one unknown and one non-unknown input,
1307 : : * we already tried this heuristic in binary_oper_exact(). However, that
1308 : : * code only finds exact matches, whereas here we will handle matches that
1309 : : * involve coercion, polymorphic type resolution, etc.
1310 : : */
1311 [ + - ]: 25 : if (nunknowns < nargs)
1312 : : {
1313 : 25 : Oid known_type = UNKNOWNOID;
1314 : :
1315 [ + + ]: 75 : for (i = 0; i < nargs; i++)
1316 : : {
1317 [ + + ]: 50 : if (input_base_typeids[i] == UNKNOWNOID)
1318 : 25 : continue;
2489 1319 [ + - ]: 25 : if (known_type == UNKNOWNOID) /* first known arg? */
4532 1320 : 25 : known_type = input_base_typeids[i];
4532 tgl@sss.pgh.pa.us 1321 [ # # ]:UBC 0 : else if (known_type != input_base_typeids[i])
1322 : : {
1323 : : /* oops, not all match */
1324 : 0 : known_type = UNKNOWNOID;
1325 : 0 : break;
1326 : : }
1327 : : }
1328 : :
4532 tgl@sss.pgh.pa.us 1329 [ + - ]:CBC 25 : if (known_type != UNKNOWNOID)
1330 : : {
1331 : : /* okay, just one known type, apply the heuristic */
1332 [ + + ]: 75 : for (i = 0; i < nargs; i++)
1333 : 50 : input_base_typeids[i] = known_type;
1334 : 25 : ncandidates = 0;
1335 : 25 : last_candidate = NULL;
1336 : 25 : for (current_candidate = candidates;
1337 [ + + ]: 105 : current_candidate != NULL;
1338 : 80 : current_candidate = current_candidate->next)
1339 : : {
1340 : 80 : current_typeids = current_candidate->args;
1341 [ + + ]: 80 : if (can_coerce_type(nargs, input_base_typeids, current_typeids,
1342 : : COERCION_IMPLICIT))
1343 : : {
1344 [ - + ]: 25 : if (++ncandidates > 1)
4532 tgl@sss.pgh.pa.us 1345 :UBC 0 : break; /* not unique, give up */
4532 tgl@sss.pgh.pa.us 1346 :CBC 25 : last_candidate = current_candidate;
1347 : : }
1348 : : }
1349 [ + - ]: 25 : if (ncandidates == 1)
1350 : : {
1351 : : /* successfully identified a unique match */
1352 : 25 : last_candidate->next = NULL;
1353 : 25 : return last_candidate;
1354 : : }
1355 : : }
1356 : : }
1357 : :
7629 tgl@sss.pgh.pa.us 1358 :UBC 0 : return NULL; /* failed to select a best candidate */
1359 : : } /* func_select_candidate() */
1360 : :
1361 : :
1362 : : /* func_get_detail()
1363 : : *
1364 : : * Find the named function in the system catalogs.
1365 : : *
1366 : : * Attempt to find the named function in the system catalogs with
1367 : : * arguments exactly as specified, so that the normal case (exact match)
1368 : : * is as quick as possible.
1369 : : *
1370 : : * If an exact match isn't found:
1371 : : * 1) check for possible interpretation as a type coercion request
1372 : : * 2) apply the ambiguous-function resolution rules
1373 : : *
1374 : : * Return values *funcid through *true_typeids receive info about the function.
1375 : : * If argdefaults isn't NULL, *argdefaults receives a list of any default
1376 : : * argument expressions that need to be added to the given arguments.
1377 : : *
1378 : : * When processing a named- or mixed-notation call (ie, fargnames isn't NIL),
1379 : : * the returned true_typeids and argdefaults are ordered according to the
1380 : : * call's argument ordering: first any positional arguments, then the named
1381 : : * arguments, then defaulted arguments (if needed and allowed by
1382 : : * expand_defaults). Some care is needed if this information is to be compared
1383 : : * to the function's pg_proc entry, but in practice the caller can usually
1384 : : * just work with the call's argument ordering.
1385 : : *
1386 : : * We rely primarily on fargnames/nargs/argtypes as the argument description.
1387 : : * The actual expression node list is passed in fargs so that we can check
1388 : : * for type coercion of a constant. Some callers pass fargs == NIL indicating
1389 : : * they don't need that check made. Note also that when fargnames isn't NIL,
1390 : : * the fargs list must be passed if the caller wants actual argument position
1391 : : * information to be returned into the NamedArgExpr nodes.
1392 : : */
1393 : : FuncDetailCode
8041 tgl@sss.pgh.pa.us 1394 :CBC 180859 : func_get_detail(List *funcname,
1395 : : List *fargs,
1396 : : List *fargnames,
1397 : : int nargs,
1398 : : Oid *argtypes,
1399 : : bool expand_variadic,
1400 : : bool expand_defaults,
1401 : : bool include_out_arguments,
1402 : : Oid *funcid, /* return value */
1403 : : Oid *rettype, /* return value */
1404 : : bool *retset, /* return value */
1405 : : int *nvargs, /* return value */
1406 : : Oid *vatype, /* return value */
1407 : : Oid **true_typeids, /* return value */
1408 : : List **argdefaults) /* optional return value */
1409 : : {
1410 : : FuncCandidateList raw_candidates;
1411 : : FuncCandidateList best_candidate;
1412 : :
1413 : : /* initialize output arguments to silence compiler warnings */
5469 1414 : 180859 : *funcid = InvalidOid;
1415 : 180859 : *rettype = InvalidOid;
1416 : 180859 : *retset = false;
1417 : 180859 : *nvargs = 0;
3664 1418 : 180859 : *vatype = InvalidOid;
5469 1419 : 180859 : *true_typeids = NULL;
1420 [ + + ]: 180859 : if (argdefaults)
5421 bruce@momjian.us 1421 : 174731 : *argdefaults = NIL;
1422 : :
1423 : : /* Get list of possible candidates from namespace search */
5302 tgl@sss.pgh.pa.us 1424 : 180859 : raw_candidates = FuncnameGetCandidates(funcname, nargs, fargnames,
1425 : : expand_variadic, expand_defaults,
1426 : : include_out_arguments, false);
1427 : :
1428 : : /*
1429 : : * Quickly check if there is an exact match to the input datatypes (there
1430 : : * can be only one)
1431 : : */
7629 1432 : 180859 : for (best_candidate = raw_candidates;
8044 1433 [ + + ]: 350146 : best_candidate != NULL;
1434 : 169287 : best_candidate = best_candidate->next)
1435 : : {
1436 : : /* if nargs==0, argtypes can be null; don't pass that to memcmp */
1615 1437 [ + + ]: 273195 : if (nargs == 0 ||
1438 [ + + ]: 242572 : memcmp(argtypes, best_candidate->args, nargs * sizeof(Oid)) == 0)
1439 : : break;
1440 : : }
1441 : :
8044 1442 [ + + ]: 180859 : if (best_candidate == NULL)
1443 : : {
1444 : : /*
1445 : : * If we didn't find an exact match, next consider the possibility
1446 : : * that this is really a type-coercion request: a single-argument
1447 : : * function call where the function name is a type name. If so, and
1448 : : * if the coercion path is RELABELTYPE or COERCEVIAIO, then go ahead
1449 : : * and treat the "function call" as a coercion.
1450 : : *
1451 : : * This interpretation needs to be given higher priority than
1452 : : * interpretations involving a type coercion followed by a function
1453 : : * call, otherwise we can produce surprising results. For example, we
1454 : : * want "text(varchar)" to be interpreted as a simple coercion, not as
1455 : : * "text(name(varchar))" which the code below this point is entirely
1456 : : * capable of selecting.
1457 : : *
1458 : : * We also treat a coercion of a previously-unknown-type literal
1459 : : * constant to a specific type this way.
1460 : : *
1461 : : * The reason we reject COERCION_PATH_FUNC here is that we expect the
1462 : : * cast implementation function to be named after the target type.
1463 : : * Thus the function will be found by normal lookup if appropriate.
1464 : : *
1465 : : * The reason we reject COERCION_PATH_ARRAYCOERCE is mainly that you
1466 : : * can't write "foo[] (something)" as a function call. In theory
1467 : : * someone might want to invoke it as "_foo (something)" but we have
1468 : : * never supported that historically, so we can insist that people
1469 : : * write it as a normal cast instead.
1470 : : *
1471 : : * We also reject the specific case of COERCEVIAIO for a composite
1472 : : * source type and a string-category target type. This is a case that
1473 : : * find_coercion_pathway() allows by default, but experience has shown
1474 : : * that it's too commonly invoked by mistake. So, again, insist that
1475 : : * people use cast syntax if they want to do that.
1476 : : *
1477 : : * NB: it's important that this code does not exceed what coerce_type
1478 : : * can do, because the caller will try to apply coerce_type if we
1479 : : * return FUNCDETAIL_COERCION. If we return that result for something
1480 : : * coerce_type can't handle, we'll cause infinite recursion between
1481 : : * this module and coerce_type!
1482 : : */
5302 1483 [ + + + + : 76951 : if (nargs == 1 && fargs != NIL && fargnames == NIL)
+ + ]
1484 : : {
5999 1485 : 27193 : Oid targetType = FuncNameAsType(funcname);
1486 : :
1487 [ + + ]: 27193 : if (OidIsValid(targetType))
1488 : : {
8228 1489 : 330 : Oid sourceType = argtypes[0];
7263 neilc@samurai.com 1490 : 330 : Node *arg1 = linitial(fargs);
1491 : : bool iscoercion;
1492 : :
6158 tgl@sss.pgh.pa.us 1493 [ + + + - ]: 330 : if (sourceType == UNKNOWNOID && IsA(arg1, Const))
1494 : : {
1495 : : /* always treat typename('literal') as coercion */
1496 : 224 : iscoercion = true;
1497 : : }
1498 : : else
1499 : : {
1500 : : CoercionPathType cpathtype;
1501 : : Oid cfuncid;
1502 : :
1503 : 106 : cpathtype = find_coercion_pathway(targetType, sourceType,
1504 : : COERCION_EXPLICIT,
1505 : : &cfuncid);
4907 1506 [ + + + ]: 106 : switch (cpathtype)
1507 : : {
1508 : 4 : case COERCION_PATH_RELABELTYPE:
1509 : 4 : iscoercion = true;
1510 : 4 : break;
1511 : 85 : case COERCION_PATH_COERCEVIAIO:
1512 [ + + + + ]: 164 : if ((sourceType == RECORDOID ||
1513 [ + - ]: 160 : ISCOMPLEX(sourceType)) &&
2489 1514 : 81 : TypeCategory(targetType) == TYPCATEGORY_STRING)
4907 1515 : 81 : iscoercion = false;
1516 : : else
1517 : 4 : iscoercion = true;
1518 : 85 : break;
1519 : 17 : default:
1520 : 17 : iscoercion = false;
1521 : 17 : break;
1522 : : }
1523 : : }
1524 : :
6158 1525 [ + + ]: 330 : if (iscoercion)
1526 : : {
1527 : : /* Treat it as a type coercion */
8228 1528 : 232 : *funcid = InvalidOid;
1529 : 232 : *rettype = targetType;
1530 : 232 : *retset = false;
5751 1531 : 232 : *nvargs = 0;
3664 1532 : 232 : *vatype = InvalidOid;
8228 1533 : 232 : *true_typeids = argtypes;
1534 : 232 : return FUNCDETAIL_COERCION;
1535 : : }
1536 : : }
1537 : : }
1538 : :
1539 : : /*
1540 : : * didn't find an exact match, so now try to match up candidates...
1541 : : */
7629 1542 [ + + ]: 76719 : if (raw_candidates != NULL)
1543 : : {
1544 : : FuncCandidateList current_candidates;
1545 : : int ncandidates;
1546 : :
6931 1547 : 76077 : ncandidates = func_match_argtypes(nargs,
1548 : : argtypes,
1549 : : raw_candidates,
1550 : : ¤t_candidates);
1551 : :
1552 : : /* one match only? then run with it... */
1553 [ + + ]: 76077 : if (ncandidates == 1)
1554 : 72745 : best_candidate = current_candidates;
1555 : :
1556 : : /*
1557 : : * multiple candidates? then better decide or throw an error...
1558 : : */
1559 [ + + ]: 3332 : else if (ncandidates > 1)
1560 : : {
1561 : 3079 : best_candidate = func_select_candidate(nargs,
1562 : : argtypes,
1563 : : current_candidates);
1564 : :
1565 : : /*
1566 : : * If we were able to choose a best candidate, we're done.
1567 : : * Otherwise, ambiguous function call.
1568 : : */
1569 [ - + ]: 3079 : if (!best_candidate)
7590 tgl@sss.pgh.pa.us 1570 :UBC 0 : return FUNCDETAIL_MULTIPLE;
1571 : : }
1572 : : }
1573 : : }
1574 : :
8044 tgl@sss.pgh.pa.us 1575 [ + + ]:CBC 180627 : if (best_candidate)
1576 : : {
1577 : : HeapTuple ftup;
1578 : : Form_pg_proc pform;
1579 : : FuncDetailCode result;
1580 : :
1581 : : /*
1582 : : * If processing named args or expanding variadics or defaults, the
1583 : : * "best candidate" might represent multiple equivalently good
1584 : : * functions; treat this case as ambiguous.
1585 : : */
5596 1586 [ + + ]: 179732 : if (!OidIsValid(best_candidate->oid))
1587 : 15 : return FUNCDETAIL_MULTIPLE;
1588 : :
1589 : : /*
1590 : : * We disallow VARIADIC with named arguments unless the last argument
1591 : : * (the one with VARIADIC attached) actually matched the variadic
1592 : : * parameter. This is mere pedantry, really, but some folks insisted.
1593 : : */
5302 1594 [ + + - + : 179717 : if (fargnames != NIL && !expand_variadic && nargs > 0 &&
- - ]
5302 tgl@sss.pgh.pa.us 1595 [ # # ]:UBC 0 : best_candidate->argnumbers[nargs - 1] != nargs - 1)
1596 : 0 : return FUNCDETAIL_NOTFOUND;
1597 : :
8044 tgl@sss.pgh.pa.us 1598 :CBC 179717 : *funcid = best_candidate->oid;
5751 1599 : 179717 : *nvargs = best_candidate->nvargs;
8044 1600 : 179717 : *true_typeids = best_candidate->args;
1601 : :
1602 : : /*
1603 : : * If processing named args, return actual argument positions into
1604 : : * NamedArgExpr nodes in the fargs list. This is a bit ugly but not
1605 : : * worth the extra notation needed to do it differently.
1606 : : */
5302 1607 [ + + ]: 179717 : if (best_candidate->argnumbers != NULL)
1608 : : {
1609 : 7924 : int i = 0;
1610 : : ListCell *lc;
1611 : :
1612 [ + + + + : 32169 : foreach(lc, fargs)
+ + ]
1613 : : {
1614 : 24245 : NamedArgExpr *na = (NamedArgExpr *) lfirst(lc);
1615 : :
1616 [ + + ]: 24245 : if (IsA(na, NamedArgExpr))
1617 : 23320 : na->argnumber = best_candidate->argnumbers[i];
1618 : 24245 : i++;
1619 : : }
1620 : : }
1621 : :
5173 rhaas@postgresql.org 1622 : 179717 : ftup = SearchSysCache1(PROCOID,
1623 : : ObjectIdGetDatum(best_candidate->oid));
7893 bruce@momjian.us 1624 [ - + ]: 179717 : if (!HeapTupleIsValid(ftup)) /* should not happen */
7576 tgl@sss.pgh.pa.us 1625 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for function %u",
1626 : : best_candidate->oid);
8044 tgl@sss.pgh.pa.us 1627 :CBC 179717 : pform = (Form_pg_proc) GETSTRUCT(ftup);
9637 bruce@momjian.us 1628 : 179717 : *rettype = pform->prorettype;
1629 : 179717 : *retset = pform->proretset;
3923 andrew@dunslane.net 1630 : 179717 : *vatype = pform->provariadic;
1631 : : /* fetch default args if caller wants 'em */
5302 tgl@sss.pgh.pa.us 1632 [ + + + + ]: 179717 : if (argdefaults && best_candidate->ndargs > 0)
1633 : : {
1634 : : Datum proargdefaults;
1635 : : char *str;
1636 : : List *defaults;
1637 : :
1638 : : /* shouldn't happen, FuncnameGetCandidates messed up */
1639 [ - + ]: 6479 : if (best_candidate->ndargs > pform->pronargdefaults)
5302 tgl@sss.pgh.pa.us 1640 [ # # ]:UBC 0 : elog(ERROR, "not enough default arguments");
1641 : :
386 dgustafsson@postgres 1642 :CBC 6479 : proargdefaults = SysCacheGetAttrNotNull(PROCOID, ftup,
1643 : : Anum_pg_proc_proargdefaults);
5302 tgl@sss.pgh.pa.us 1644 : 6479 : str = TextDatumGetCString(proargdefaults);
2609 peter_e@gmx.net 1645 : 6479 : defaults = castNode(List, stringToNode(str));
5302 tgl@sss.pgh.pa.us 1646 : 6479 : pfree(str);
1647 : :
1648 : : /* Delete any unused defaults from the returned list */
1649 [ + + ]: 6479 : if (best_candidate->argnumbers != NULL)
1650 : : {
1651 : : /*
1652 : : * This is a bit tricky in named notation, since the supplied
1653 : : * arguments could replace any subset of the defaults. We
1654 : : * work by making a bitmapset of the argnumbers of defaulted
1655 : : * arguments, then scanning the defaults list and selecting
1656 : : * the needed items. (This assumes that defaulted arguments
1657 : : * should be supplied in their positional order.)
1658 : : */
1659 : : Bitmapset *defargnumbers;
1660 : : int *firstdefarg;
1661 : : List *newdefaults;
1662 : : ListCell *lc;
1663 : : int i;
1664 : :
1665 : 3636 : defargnumbers = NULL;
1666 : 3636 : firstdefarg = &best_candidate->argnumbers[best_candidate->nargs - best_candidate->ndargs];
1667 [ + + ]: 10855 : for (i = 0; i < best_candidate->ndargs; i++)
1668 : 7219 : defargnumbers = bms_add_member(defargnumbers,
1669 : 7219 : firstdefarg[i]);
1670 : 3636 : newdefaults = NIL;
1039 1671 : 3636 : i = best_candidate->nominalnargs - pform->pronargdefaults;
5302 1672 [ + - + + : 20862 : foreach(lc, defaults)
+ + ]
1673 : : {
1674 [ + + ]: 17226 : if (bms_is_member(i, defargnumbers))
1675 : 7219 : newdefaults = lappend(newdefaults, lfirst(lc));
1676 : 17226 : i++;
1677 : : }
1678 [ - + ]: 3636 : Assert(list_length(newdefaults) == best_candidate->ndargs);
1679 : 3636 : bms_free(defargnumbers);
1680 : 3636 : *argdefaults = newdefaults;
1681 : : }
1682 : : else
1683 : : {
1684 : : /*
1685 : : * Defaults for positional notation are lots easier; just
1686 : : * remove any unwanted ones from the front.
1687 : : */
1688 : : int ndelete;
1689 : :
5596 1690 : 2843 : ndelete = list_length(defaults) - best_candidate->ndargs;
1735 1691 [ + + ]: 2843 : if (ndelete > 0)
894 1692 : 105 : defaults = list_delete_first_n(defaults, ndelete);
5596 1693 : 2843 : *argdefaults = defaults;
1694 : : }
1695 : : }
1696 : :
2235 peter_e@gmx.net 1697 [ + + + + : 179717 : switch (pform->prokind)
- ]
1698 : : {
1699 : 21935 : case PROKIND_AGGREGATE:
1700 : 21935 : result = FUNCDETAIL_AGGREGATE;
1701 : 21935 : break;
1702 : 156607 : case PROKIND_FUNCTION:
1703 : 156607 : result = FUNCDETAIL_NORMAL;
1704 : 156607 : break;
1705 : 211 : case PROKIND_PROCEDURE:
1706 : 211 : result = FUNCDETAIL_PROCEDURE;
1707 : 211 : break;
1708 : 964 : case PROKIND_WINDOW:
1709 : 964 : result = FUNCDETAIL_WINDOWFUNC;
1710 : 964 : break;
2235 peter_e@gmx.net 1711 :UBC 0 : default:
1712 [ # # ]: 0 : elog(ERROR, "unrecognized prokind: %c", pform->prokind);
1713 : : result = FUNCDETAIL_NORMAL; /* keep compiler quiet */
1714 : : break;
1715 : : }
1716 : :
8550 tgl@sss.pgh.pa.us 1717 :CBC 179717 : ReleaseSysCache(ftup);
8039 1718 : 179717 : return result;
1719 : : }
1720 : :
8228 1721 : 895 : return FUNCDETAIL_NOTFOUND;
1722 : : }
1723 : :
1724 : :
1725 : : /*
1726 : : * unify_hypothetical_args()
1727 : : *
1728 : : * Ensure that each hypothetical direct argument of a hypothetical-set
1729 : : * aggregate has the same type as the corresponding aggregated argument.
1730 : : * Modify the expressions in the fargs list, if necessary, and update
1731 : : * actual_arg_types[].
1732 : : *
1733 : : * If the agg declared its args non-ANY (even ANYELEMENT), we need only a
1734 : : * sanity check that the declared types match; make_fn_arguments will coerce
1735 : : * the actual arguments to match the declared ones. But if the declaration
1736 : : * is ANY, nothing will happen in make_fn_arguments, so we need to fix any
1737 : : * mismatch here. We use the same type resolution logic as UNION etc.
1738 : : */
1739 : : static void
3765 1740 : 72 : unify_hypothetical_args(ParseState *pstate,
1741 : : List *fargs,
1742 : : int numAggregatedArgs,
1743 : : Oid *actual_arg_types,
1744 : : Oid *declared_arg_types)
1745 : : {
1746 : : int numDirectArgs,
1747 : : numNonHypotheticalArgs;
1748 : : int hargpos;
1749 : :
1750 : 72 : numDirectArgs = list_length(fargs) - numAggregatedArgs;
1751 : 72 : numNonHypotheticalArgs = numDirectArgs - numAggregatedArgs;
1752 : : /* safety check (should only trigger with a misdeclared agg) */
1753 [ - + ]: 72 : if (numNonHypotheticalArgs < 0)
3765 tgl@sss.pgh.pa.us 1754 [ # # ]:UBC 0 : elog(ERROR, "incorrect number of arguments to hypothetical-set aggregate");
1755 : :
1756 : : /* Check each hypothetical arg and corresponding aggregated arg */
1729 tgl@sss.pgh.pa.us 1757 [ + + ]:CBC 165 : for (hargpos = numNonHypotheticalArgs; hargpos < numDirectArgs; hargpos++)
1758 : : {
1759 : 99 : int aargpos = numDirectArgs + (hargpos - numNonHypotheticalArgs);
1760 : 99 : ListCell *harg = list_nth_cell(fargs, hargpos);
1761 : 99 : ListCell *aarg = list_nth_cell(fargs, aargpos);
1762 : : Oid commontype;
1763 : : int32 commontypmod;
1764 : :
1765 : : /* A mismatch means AggregateCreate didn't check properly ... */
1766 [ - + ]: 99 : if (declared_arg_types[hargpos] != declared_arg_types[aargpos])
3765 tgl@sss.pgh.pa.us 1767 [ # # ]:UBC 0 : elog(ERROR, "hypothetical-set aggregate has inconsistent declared argument types");
1768 : :
1769 : : /* No need to unify if make_fn_arguments will coerce */
1729 tgl@sss.pgh.pa.us 1770 [ - + ]:CBC 99 : if (declared_arg_types[hargpos] != ANYOID)
3765 tgl@sss.pgh.pa.us 1771 :UBC 0 : continue;
1772 : :
1773 : : /*
1774 : : * Select common type, giving preference to the aggregated argument's
1775 : : * type (we'd rather coerce the direct argument once than coerce all
1776 : : * the aggregated values).
1777 : : */
3765 tgl@sss.pgh.pa.us 1778 :CBC 99 : commontype = select_common_type(pstate,
1729 1779 : 99 : list_make2(lfirst(aarg), lfirst(harg)),
1780 : : "WITHIN GROUP",
1781 : : NULL);
1265 peter@eisentraut.org 1782 : 96 : commontypmod = select_common_typmod(pstate,
1783 : 96 : list_make2(lfirst(aarg), lfirst(harg)),
1784 : : commontype);
1785 : :
1786 : : /*
1787 : : * Perform the coercions. We don't need to worry about NamedArgExprs
1788 : : * here because they aren't supported with aggregates.
1789 : : */
1729 tgl@sss.pgh.pa.us 1790 : 189 : lfirst(harg) = coerce_type(pstate,
1791 : 96 : (Node *) lfirst(harg),
1792 : 96 : actual_arg_types[hargpos],
1793 : : commontype, commontypmod,
1794 : : COERCION_IMPLICIT,
1795 : : COERCE_IMPLICIT_CAST,
1796 : : -1);
1797 : 93 : actual_arg_types[hargpos] = commontype;
1798 : 186 : lfirst(aarg) = coerce_type(pstate,
1799 : 93 : (Node *) lfirst(aarg),
1800 : 93 : actual_arg_types[aargpos],
1801 : : commontype, commontypmod,
1802 : : COERCION_IMPLICIT,
1803 : : COERCE_IMPLICIT_CAST,
1804 : : -1);
3765 1805 : 93 : actual_arg_types[aargpos] = commontype;
1806 : : }
1807 : 66 : }
1808 : :
1809 : :
1810 : : /*
1811 : : * make_fn_arguments()
1812 : : *
1813 : : * Given the actual argument expressions for a function, and the desired
1814 : : * input types for the function, add any necessary typecasting to the
1815 : : * expression tree. Caller should already have verified that casting is
1816 : : * allowed.
1817 : : *
1818 : : * Caution: given argument list is modified in-place.
1819 : : *
1820 : : * As with coerce_type, pstate may be NULL if no special unknown-Param
1821 : : * processing is wanted.
1822 : : */
1823 : : void
7656 1824 : 478154 : make_fn_arguments(ParseState *pstate,
1825 : : List *fargs,
1826 : : Oid *actual_arg_types,
1827 : : Oid *declared_arg_types)
1828 : : {
1829 : : ListCell *current_fargs;
7677 1830 : 478154 : int i = 0;
1831 : :
1832 [ + + + + : 1357713 : foreach(current_fargs, fargs)
+ + ]
1833 : : {
1834 : : /* types don't match? then force coercion using a function call... */
1835 [ + + ]: 879594 : if (actual_arg_types[i] != declared_arg_types[i])
1836 : : {
5161 bruce@momjian.us 1837 : 232753 : Node *node = (Node *) lfirst(current_fargs);
1838 : :
1839 : : /*
1840 : : * If arg is a NamedArgExpr, coerce its input expr instead --- we
1841 : : * want the NamedArgExpr to stay at the top level of the list.
1842 : : */
5302 tgl@sss.pgh.pa.us 1843 [ + + ]: 232753 : if (IsA(node, NamedArgExpr))
1844 : : {
1845 : 11300 : NamedArgExpr *na = (NamedArgExpr *) node;
1846 : :
1847 : 11300 : node = coerce_type(pstate,
1848 : 11300 : (Node *) na->arg,
1849 : 11300 : actual_arg_types[i],
1850 : 11300 : declared_arg_types[i], -1,
1851 : : COERCION_IMPLICIT,
1852 : : COERCE_IMPLICIT_CAST,
1853 : : -1);
1854 : 11300 : na->arg = (Expr *) node;
1855 : : }
1856 : : else
1857 : : {
1858 : 221453 : node = coerce_type(pstate,
1859 : : node,
1860 : 221453 : actual_arg_types[i],
1861 : 221453 : declared_arg_types[i], -1,
1862 : : COERCION_IMPLICIT,
1863 : : COERCE_IMPLICIT_CAST,
1864 : : -1);
1865 : 221418 : lfirst(current_fargs) = node;
1866 : : }
1867 : : }
7677 1868 : 879559 : i++;
1869 : : }
9637 bruce@momjian.us 1870 : 478119 : }
1871 : :
1872 : : /*
1873 : : * FuncNameAsType -
1874 : : * convenience routine to see if a function name matches a type name
1875 : : *
1876 : : * Returns the OID of the matching type, or InvalidOid if none. We ignore
1877 : : * shell types and complex types.
1878 : : */
1879 : : static Oid
5999 tgl@sss.pgh.pa.us 1880 : 27193 : FuncNameAsType(List *funcname)
1881 : : {
1882 : : Oid result;
1883 : : Type typtup;
1884 : :
1885 : : /*
1886 : : * temp_ok=false protects the <refsect1 id="sql-createfunction-security">
1887 : : * contract for writing SECURITY DEFINER functions safely.
1888 : : */
1714 noah@leadboat.com 1889 : 27193 : typtup = LookupTypeNameExtended(NULL, makeTypeNameFromNameList(funcname),
1890 : : NULL, false, false);
5999 tgl@sss.pgh.pa.us 1891 [ + + ]: 27193 : if (typtup == NULL)
1892 : 26860 : return InvalidOid;
1893 : :
1894 [ + - + + ]: 666 : if (((Form_pg_type) GETSTRUCT(typtup))->typisdefined &&
1895 : 333 : !OidIsValid(typeTypeRelid(typtup)))
1896 : 330 : result = typeTypeId(typtup);
1897 : : else
1898 : 3 : result = InvalidOid;
1899 : :
1900 : 333 : ReleaseSysCache(typtup);
1901 : 333 : return result;
1902 : : }
1903 : :
1904 : : /*
1905 : : * ParseComplexProjection -
1906 : : * handles function calls with a single argument that is of complex type.
1907 : : * If the function call is actually a column projection, return a suitably
1908 : : * transformed expression tree. If not, return NULL.
1909 : : */
1910 : : static Node *
2357 peter_e@gmx.net 1911 : 4669 : ParseComplexProjection(ParseState *pstate, const char *funcname, Node *first_arg,
1912 : : int location)
1913 : : {
1914 : : TupleDesc tupdesc;
1915 : : int i;
1916 : :
1917 : : /*
1918 : : * Special case for whole-row Vars so that we can resolve (foo.*).bar even
1919 : : * when foo is a reference to a subselect, join, or RECORD function. A
1920 : : * bonus is that we avoid generating an unnecessary FieldSelect; our
1921 : : * result can omit the whole-row Var and just be a Var for the selected
1922 : : * field.
1923 : : *
1924 : : * This case could be handled by expandRecordVariable, but it's more
1925 : : * efficient to do it this way when possible.
1926 : : */
7317 tgl@sss.pgh.pa.us 1927 [ + + ]: 4669 : if (IsA(first_arg, Var) &&
1928 [ + + ]: 3623 : ((Var *) first_arg)->varattno == InvalidAttrNumber)
1929 : : {
1930 : : ParseNamespaceItem *nsitem;
1931 : :
1571 1932 : 87 : nsitem = GetNSItemByRangeTablePosn(pstate,
1933 : : ((Var *) first_arg)->varno,
1934 : 87 : ((Var *) first_arg)->varlevelsup);
1935 : : /* Return a Var if funcname matches a column, else NULL */
1936 : 87 : return scanNSItemForColumn(pstate, nsitem,
1937 : 87 : ((Var *) first_arg)->varlevelsup,
1938 : : funcname, location);
1939 : : }
1940 : :
1941 : : /*
1942 : : * Else do it the hard way with get_expr_result_tupdesc().
1943 : : *
1944 : : * If it's a Var of type RECORD, we have to work even harder: we have to
1945 : : * find what the Var refers to, and pass that to get_expr_result_tupdesc.
1946 : : * That task is handled by expandRecordVariable().
1947 : : */
6893 1948 [ + + ]: 4582 : if (IsA(first_arg, Var) &&
1949 [ + + ]: 3536 : ((Var *) first_arg)->vartype == RECORDOID)
1950 : 742 : tupdesc = expandRecordVariable(pstate, (Var *) first_arg, 0);
1951 : : else
2362 1952 : 3840 : tupdesc = get_expr_result_tupdesc(first_arg, true);
1953 [ + + ]: 4582 : if (!tupdesc)
6954 1954 : 1 : return NULL; /* unresolvable RECORD type */
1955 : :
1956 [ + + ]: 51577 : for (i = 0; i < tupdesc->natts; i++)
1957 : : {
2429 andres@anarazel.de 1958 : 51547 : Form_pg_attribute att = TupleDescAttr(tupdesc, i);
1959 : :
6954 tgl@sss.pgh.pa.us 1960 [ + + ]: 51547 : if (strcmp(funcname, NameStr(att->attname)) == 0 &&
1961 [ + - ]: 4551 : !att->attisdropped)
1962 : : {
1963 : : /* Success, so generate a FieldSelect expression */
1964 : 4551 : FieldSelect *fselect = makeNode(FieldSelect);
1965 : :
1966 : 4551 : fselect->arg = (Expr *) first_arg;
1967 : 4551 : fselect->fieldnum = i + 1;
1968 : 4551 : fselect->resulttype = att->atttypid;
1969 : 4551 : fselect->resulttypmod = att->atttypmod;
1970 : : /* save attribute's collation for parse_collate.c */
4775 1971 : 4551 : fselect->resultcollid = att->attcollation;
6954 1972 : 4551 : return (Node *) fselect;
1973 : : }
1974 : : }
1975 : :
1976 : 30 : return NULL; /* funcname does not match any column */
1977 : : }
1978 : :
1979 : : /*
1980 : : * funcname_signature_string
1981 : : * Build a string representing a function name, including arg types.
1982 : : * The result is something like "foo(integer)".
1983 : : *
1984 : : * If argnames isn't NIL, it is a list of C strings representing the actual
1985 : : * arg names for the last N arguments. This must be considered part of the
1986 : : * function signature too, when dealing with named-notation function calls.
1987 : : *
1988 : : * This is typically used in the construction of function-not-found error
1989 : : * messages.
1990 : : */
1991 : : const char *
5302 1992 : 395 : funcname_signature_string(const char *funcname, int nargs,
1993 : : List *argnames, const Oid *argtypes)
1994 : : {
1995 : : StringInfoData argbuf;
1996 : : int numposargs;
1997 : : ListCell *lc;
1998 : : int i;
1999 : :
8003 2000 : 395 : initStringInfo(&argbuf);
2001 : :
7574 2002 : 395 : appendStringInfo(&argbuf, "%s(", funcname);
2003 : :
5302 2004 : 395 : numposargs = nargs - list_length(argnames);
2005 : 395 : lc = list_head(argnames);
2006 : :
9637 bruce@momjian.us 2007 [ + + ]: 995 : for (i = 0; i < nargs; i++)
2008 : : {
2009 [ + + ]: 600 : if (i)
7661 tgl@sss.pgh.pa.us 2010 : 270 : appendStringInfoString(&argbuf, ", ");
5302 2011 [ + + ]: 600 : if (i >= numposargs)
2012 : : {
3271 rhaas@postgresql.org 2013 : 24 : appendStringInfo(&argbuf, "%s => ", (char *) lfirst(lc));
1735 tgl@sss.pgh.pa.us 2014 : 24 : lc = lnext(argnames, lc);
2015 : : }
5068 2016 : 600 : appendStringInfoString(&argbuf, format_type_be(argtypes[i]));
2017 : : }
2018 : :
7590 2019 : 395 : appendStringInfoChar(&argbuf, ')');
2020 : :
2021 : 395 : return argbuf.data; /* return palloc'd string buffer */
2022 : : }
2023 : :
2024 : : /*
2025 : : * func_signature_string
2026 : : * As above, but function name is passed as a qualified name list.
2027 : : */
2028 : : const char *
5302 2029 : 383 : func_signature_string(List *funcname, int nargs,
2030 : : List *argnames, const Oid *argtypes)
2031 : : {
7574 2032 : 383 : return funcname_signature_string(NameListToString(funcname),
2033 : : nargs, argnames, argtypes);
2034 : : }
2035 : :
2036 : : /*
2037 : : * LookupFuncNameInternal
2038 : : * Workhorse for LookupFuncName/LookupFuncWithArgs
2039 : : *
2040 : : * In an error situation, e.g. can't find the function, then we return
2041 : : * InvalidOid and set *lookupError to indicate what went wrong.
2042 : : *
2043 : : * Possible errors:
2044 : : * FUNCLOOKUP_NOSUCHFUNC: we can't find a function of this name.
2045 : : * FUNCLOOKUP_AMBIGUOUS: more than one function matches.
2046 : : */
2047 : : static Oid
1039 2048 : 18052 : LookupFuncNameInternal(ObjectType objtype, List *funcname,
2049 : : int nargs, const Oid *argtypes,
2050 : : bool include_out_arguments, bool missing_ok,
2051 : : FuncLookupError *lookupError)
2052 : : {
2053 : 18052 : Oid result = InvalidOid;
2054 : : FuncCandidateList clist;
2055 : :
2056 : : /* NULL argtypes allowed for nullary functions only */
1615 alvherre@alvh.no-ip. 2057 [ + + - + ]: 18052 : Assert(argtypes != NULL || nargs == 0);
2058 : :
2059 : : /* Always set *lookupError, to forestall uninitialized-variable warnings */
1851 tgl@sss.pgh.pa.us 2060 : 18052 : *lookupError = FUNCLOOKUP_NOSUCHFUNC;
2061 : :
2062 : : /* Get list of candidate objects */
2063 : 18052 : clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false,
2064 : : include_out_arguments, missing_ok);
2065 : :
2066 : : /* Scan list for a match to the arg types (if specified) and the objtype */
1039 2067 [ + + ]: 39889 : for (; clist != NULL; clist = clist->next)
2068 : : {
2069 : : /* Check arg type match, if specified */
2070 [ + + ]: 21879 : if (nargs >= 0)
2071 : : {
2072 : : /* if nargs==0, argtypes can be null; don't pass that to memcmp */
2073 [ + + ]: 21692 : if (nargs > 0 &&
2074 [ + + ]: 12355 : memcmp(argtypes, clist->args, nargs * sizeof(Oid)) != 0)
2075 : 4819 : continue;
2076 : : }
2077 : :
2078 : : /* Check for duplicates reported by FuncnameGetCandidates */
2079 [ + + ]: 17060 : if (!OidIsValid(clist->oid))
2080 : : {
2081 : 3 : *lookupError = FUNCLOOKUP_AMBIGUOUS;
1851 2082 : 3 : return InvalidOid;
2083 : : }
2084 : :
2085 : : /* Check objtype match, if specified */
1039 2086 [ + + + - ]: 17057 : switch (objtype)
2087 : : {
2088 : 10312 : case OBJECT_FUNCTION:
2089 : : case OBJECT_AGGREGATE:
2090 : : /* Ignore procedures */
2091 [ - + ]: 10312 : if (get_func_prokind(clist->oid) == PROKIND_PROCEDURE)
1039 tgl@sss.pgh.pa.us 2092 :UBC 0 : continue;
1039 tgl@sss.pgh.pa.us 2093 :CBC 10312 : break;
2094 : 93 : case OBJECT_PROCEDURE:
2095 : : /* Ignore non-procedures */
2096 [ + + ]: 93 : if (get_func_prokind(clist->oid) != PROKIND_PROCEDURE)
2097 : 6 : continue;
2098 : 87 : break;
2099 : 6652 : case OBJECT_ROUTINE:
2100 : : /* no restriction */
2101 : 6652 : break;
1039 tgl@sss.pgh.pa.us 2102 :UBC 0 : default:
2103 : 0 : Assert(false);
2104 : : }
2105 : :
2106 : : /* Check for multiple matches */
1039 tgl@sss.pgh.pa.us 2107 [ + + ]:CBC 17051 : if (OidIsValid(result))
2108 : : {
2109 : 21 : *lookupError = FUNCLOOKUP_AMBIGUOUS;
2110 : 21 : return InvalidOid;
2111 : : }
2112 : :
2113 : : /* OK, we have a candidate */
2114 : 17030 : result = clist->oid;
2115 : : }
2116 : :
2117 : 18010 : return result;
2118 : : }
2119 : :
2120 : : /*
2121 : : * LookupFuncName
2122 : : *
2123 : : * Given a possibly-qualified function name and optionally a set of argument
2124 : : * types, look up the function. Pass nargs == -1 to indicate that the number
2125 : : * and types of the arguments are unspecified (this is NOT the same as
2126 : : * specifying that there are no arguments).
2127 : : *
2128 : : * If the function name is not schema-qualified, it is sought in the current
2129 : : * namespace search path.
2130 : : *
2131 : : * If the function is not found, we return InvalidOid if missing_ok is true,
2132 : : * else raise an error.
2133 : : *
2134 : : * If nargs == -1 and multiple functions are found matching this function name
2135 : : * we will raise an ambiguous-function error, regardless of what missing_ok is
2136 : : * set to.
2137 : : *
2138 : : * Only functions will be found; procedures will be ignored even if they
2139 : : * match the name and argument types. (However, we don't trouble to reject
2140 : : * aggregates or window functions here.)
2141 : : */
2142 : : Oid
1851 2143 : 11059 : LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
2144 : : {
2145 : : Oid funcoid;
2146 : : FuncLookupError lookupError;
2147 : :
1039 2148 : 11059 : funcoid = LookupFuncNameInternal(OBJECT_FUNCTION,
2149 : : funcname, nargs, argtypes,
2150 : : false, missing_ok,
2151 : : &lookupError);
2152 : :
1851 2153 [ + + ]: 11059 : if (OidIsValid(funcoid))
2154 : 10183 : return funcoid;
2155 : :
2156 [ + - - ]: 876 : switch (lookupError)
2157 : : {
2158 : 876 : case FUNCLOOKUP_NOSUCHFUNC:
2159 : : /* Let the caller deal with it when missing_ok is true */
2160 [ + + ]: 876 : if (missing_ok)
2161 : 856 : return InvalidOid;
2162 : :
2163 [ - + ]: 20 : if (nargs < 0)
1851 tgl@sss.pgh.pa.us 2164 [ # # ]:UBC 0 : ereport(ERROR,
2165 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2166 : : errmsg("could not find a function named \"%s\"",
2167 : : NameListToString(funcname))));
2168 : : else
1851 tgl@sss.pgh.pa.us 2169 [ + - ]:CBC 20 : ereport(ERROR,
2170 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2171 : : errmsg("function %s does not exist",
2172 : : func_signature_string(funcname, nargs,
2173 : : NIL, argtypes))));
2174 : : break;
2175 : :
1851 tgl@sss.pgh.pa.us 2176 :UBC 0 : case FUNCLOOKUP_AMBIGUOUS:
2177 : : /* Raise an error regardless of missing_ok */
2178 [ # # ]: 0 : ereport(ERROR,
2179 : : (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2180 : : errmsg("function name \"%s\" is not unique",
2181 : : NameListToString(funcname)),
2182 : : errhint("Specify the argument list to select the function unambiguously.")));
2183 : : break;
2184 : : }
2185 : :
2186 : 0 : return InvalidOid; /* Keep compiler quiet */
2187 : : }
2188 : :
2189 : : /*
2190 : : * LookupFuncWithArgs
2191 : : *
2192 : : * Like LookupFuncName, but the argument types are specified by an
2193 : : * ObjectWithArgs node. Also, this function can check whether the result is a
2194 : : * function, procedure, or aggregate, based on the objtype argument. Pass
2195 : : * OBJECT_ROUTINE to accept any of them.
2196 : : *
2197 : : * For historical reasons, we also accept aggregates when looking for a
2198 : : * function.
2199 : : *
2200 : : * When missing_ok is true we don't generate any error for missing objects and
2201 : : * return InvalidOid. Other types of errors can still be raised, regardless
2202 : : * of the value of missing_ok.
2203 : : */
2204 : : Oid
1851 tgl@sss.pgh.pa.us 2205 :CBC 6948 : LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool missing_ok)
2206 : : {
2207 : : Oid argoids[FUNC_MAX_ARGS];
2208 : : int argcount;
2209 : : int nargs;
2210 : : int i;
2211 : : ListCell *args_item;
2212 : : Oid oid;
2213 : : FuncLookupError lookupError;
2214 : :
2327 peter_e@gmx.net 2215 [ + + + + : 6948 : Assert(objtype == OBJECT_AGGREGATE ||
+ + - + ]
2216 : : objtype == OBJECT_FUNCTION ||
2217 : : objtype == OBJECT_PROCEDURE ||
2218 : : objtype == OBJECT_ROUTINE);
2219 : :
2664 2220 : 6948 : argcount = list_length(func->objargs);
8041 tgl@sss.pgh.pa.us 2221 [ - + ]: 6948 : if (argcount > FUNC_MAX_ARGS)
2222 : : {
1851 tgl@sss.pgh.pa.us 2223 [ # # ]:UBC 0 : if (objtype == OBJECT_PROCEDURE)
2224 [ # # ]: 0 : ereport(ERROR,
2225 : : (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
2226 : : errmsg_plural("procedures cannot have more than %d argument",
2227 : : "procedures cannot have more than %d arguments",
2228 : : FUNC_MAX_ARGS,
2229 : : FUNC_MAX_ARGS)));
2230 : : else
2231 [ # # ]: 0 : ereport(ERROR,
2232 : : (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
2233 : : errmsg_plural("functions cannot have more than %d argument",
2234 : : "functions cannot have more than %d arguments",
2235 : : FUNC_MAX_ARGS,
2236 : : FUNC_MAX_ARGS)));
2237 : : }
2238 : :
2239 : : /*
2240 : : * First, perform a lookup considering only input arguments (traditional
2241 : : * Postgres rules).
2242 : : */
1872 tgl@sss.pgh.pa.us 2243 :CBC 6948 : i = 0;
2244 [ + + + + : 15175 : foreach(args_item, func->objargs)
+ + ]
2245 : : {
1039 2246 : 8242 : TypeName *t = lfirst_node(TypeName, args_item);
2247 : :
1851 2248 : 8242 : argoids[i] = LookupTypeNameOid(NULL, t, missing_ok);
2249 [ + + ]: 8239 : if (!OidIsValid(argoids[i]))
2250 : 12 : return InvalidOid; /* missing_ok must be true */
2251 : 8227 : i++;
2252 : : }
2253 : :
2254 : : /*
2255 : : * Set nargs for LookupFuncNameInternal. It expects -1 to mean no args
2256 : : * were specified.
2257 : : */
2258 [ + + ]: 6933 : nargs = func->args_unspecified ? -1 : argcount;
2259 : :
2260 : : /*
2261 : : * In args_unspecified mode, also tell LookupFuncNameInternal to consider
2262 : : * the object type, since there seems no reason not to. However, if we
2263 : : * have an argument list, disable the objtype check, because we'd rather
2264 : : * complain about "object is of wrong type" than "object doesn't exist".
2265 : : * (Note that with args, FuncnameGetCandidates will have ensured there's
2266 : : * only one argtype match, so we're not risking an ambiguity failure via
2267 : : * this choice.)
2268 : : */
1039 2269 [ + + ]: 6933 : oid = LookupFuncNameInternal(func->args_unspecified ? objtype : OBJECT_ROUTINE,
2270 : : func->objname, nargs, argoids,
2271 : : false, missing_ok,
2272 : : &lookupError);
2273 : :
2274 : : /*
2275 : : * If PROCEDURE or ROUTINE was specified, and we have an argument list
2276 : : * that contains no parameter mode markers, and we didn't already discover
2277 : : * that there's ambiguity, perform a lookup considering all arguments.
2278 : : * (Note: for a zero-argument procedure, or in args_unspecified mode, the
2279 : : * normal lookup is sufficient; so it's OK to require non-NIL objfuncargs
2280 : : * to perform this lookup.)
2281 : : */
2282 [ + + + + ]: 6915 : if ((objtype == OBJECT_PROCEDURE || objtype == OBJECT_ROUTINE) &&
2283 [ + + ]: 160 : func->objfuncargs != NIL &&
2284 [ + - ]: 75 : lookupError != FUNCLOOKUP_AMBIGUOUS)
2285 : : {
2286 : 75 : bool have_param_mode = false;
2287 : :
2288 : : /*
2289 : : * Check for non-default parameter mode markers. If there are any,
2290 : : * then the command does not conform to SQL-spec syntax, so we may
2291 : : * assume that the traditional Postgres lookup method of considering
2292 : : * only input parameters is sufficient. (Note that because the spec
2293 : : * doesn't have OUT arguments for functions, we also don't need this
2294 : : * hack in FUNCTION or AGGREGATE mode.)
2295 : : */
2296 [ + - + + : 157 : foreach(args_item, func->objfuncargs)
+ + ]
2297 : : {
2298 : 97 : FunctionParameter *fp = lfirst_node(FunctionParameter, args_item);
2299 : :
2300 [ + + ]: 97 : if (fp->mode != FUNC_PARAM_DEFAULT)
2301 : : {
2302 : 15 : have_param_mode = true;
2303 : 15 : break;
2304 : : }
2305 : : }
2306 : :
2307 [ + + ]: 75 : if (!have_param_mode)
2308 : : {
2309 : : Oid poid;
2310 : :
2311 : : /* Without mode marks, objargs surely includes all params */
2312 [ - + ]: 60 : Assert(list_length(func->objfuncargs) == argcount);
2313 : :
2314 : : /* For objtype == OBJECT_PROCEDURE, we can ignore non-procedures */
2315 : 60 : poid = LookupFuncNameInternal(objtype, func->objname,
2316 : : argcount, argoids,
2317 : : true, missing_ok,
2318 : : &lookupError);
2319 : :
2320 : : /* Combine results, handling ambiguity */
2321 [ + + ]: 60 : if (OidIsValid(poid))
2322 : : {
2323 [ + + - + ]: 51 : if (OidIsValid(oid) && oid != poid)
2324 : : {
2325 : : /* oops, we got hits both ways, on different objects */
1039 tgl@sss.pgh.pa.us 2326 :UBC 0 : oid = InvalidOid;
2327 : 0 : lookupError = FUNCLOOKUP_AMBIGUOUS;
2328 : : }
2329 : : else
1039 tgl@sss.pgh.pa.us 2330 :CBC 51 : oid = poid;
2331 : : }
2332 [ + + ]: 9 : else if (lookupError == FUNCLOOKUP_AMBIGUOUS)
2333 : 3 : oid = InvalidOid;
2334 : : }
2335 : : }
2336 : :
1851 2337 [ + + ]: 6915 : if (OidIsValid(oid))
2338 : : {
2339 : : /*
2340 : : * Even if we found the function, perform validation that the objtype
2341 : : * matches the prokind of the found function. For historical reasons
2342 : : * we allow the objtype of FUNCTION to include aggregates and window
2343 : : * functions; but we draw the line if the object is a procedure. That
2344 : : * is a new enough feature that this historical rule does not apply.
2345 : : *
2346 : : * (This check is partially redundant with the objtype check in
2347 : : * LookupFuncNameInternal; but not entirely, since we often don't tell
2348 : : * LookupFuncNameInternal to apply that check at all.)
2349 : : */
2350 [ + + + + ]: 6776 : switch (objtype)
2351 : : {
2352 : 6489 : case OBJECT_FUNCTION:
2353 : : /* Only complain if it's a procedure. */
2354 [ + + ]: 6489 : if (get_func_prokind(oid) == PROKIND_PROCEDURE)
2355 [ + - ]: 9 : ereport(ERROR,
2356 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2357 : : errmsg("%s is not a function",
2358 : : func_signature_string(func->objname, argcount,
2359 : : NIL, argoids))));
2360 : 6480 : break;
2361 : :
2362 : 105 : case OBJECT_PROCEDURE:
2363 : : /* Reject if found object is not a procedure. */
2364 [ + + ]: 105 : if (get_func_prokind(oid) != PROKIND_PROCEDURE)
2365 [ + - ]: 6 : ereport(ERROR,
2366 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2367 : : errmsg("%s is not a procedure",
2368 : : func_signature_string(func->objname, argcount,
2369 : : NIL, argoids))));
2370 : 99 : break;
2371 : :
2372 : 160 : case OBJECT_AGGREGATE:
2373 : : /* Reject if found object is not an aggregate. */
2374 [ + + ]: 160 : if (get_func_prokind(oid) != PROKIND_AGGREGATE)
2375 [ + - ]: 9 : ereport(ERROR,
2376 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2377 : : errmsg("function %s is not an aggregate",
2378 : : func_signature_string(func->objname, argcount,
2379 : : NIL, argoids))));
2380 : 151 : break;
2381 : :
2382 : 22 : default:
2383 : : /* OBJECT_ROUTINE accepts anything. */
2384 : 22 : break;
2385 : : }
2386 : :
2387 : 6752 : return oid; /* All good */
2388 : : }
2389 : : else
2390 : : {
2391 : : /* Deal with cases where the lookup failed */
2392 [ + + - ]: 139 : switch (lookupError)
2393 : : {
2394 : 115 : case FUNCLOOKUP_NOSUCHFUNC:
2395 : : /* Suppress no-such-func errors when missing_ok is true */
2396 [ + + ]: 115 : if (missing_ok)
2397 : 26 : break;
2398 : :
2399 : : switch (objtype)
2400 : : {
2401 : 18 : case OBJECT_PROCEDURE:
2402 [ - + ]: 18 : if (func->args_unspecified)
1851 tgl@sss.pgh.pa.us 2403 [ # # ]:UBC 0 : ereport(ERROR,
2404 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2405 : : errmsg("could not find a procedure named \"%s\"",
2406 : : NameListToString(func->objname))));
2407 : : else
1851 tgl@sss.pgh.pa.us 2408 [ + - ]:CBC 18 : ereport(ERROR,
2409 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2410 : : errmsg("procedure %s does not exist",
2411 : : func_signature_string(func->objname, argcount,
2412 : : NIL, argoids))));
2413 : : break;
2414 : :
2415 : 30 : case OBJECT_AGGREGATE:
2416 [ - + ]: 30 : if (func->args_unspecified)
1851 tgl@sss.pgh.pa.us 2417 [ # # ]:UBC 0 : ereport(ERROR,
2418 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2419 : : errmsg("could not find an aggregate named \"%s\"",
2420 : : NameListToString(func->objname))));
1851 tgl@sss.pgh.pa.us 2421 [ + + ]:CBC 30 : else if (argcount == 0)
2422 [ + - ]: 12 : ereport(ERROR,
2423 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2424 : : errmsg("aggregate %s(*) does not exist",
2425 : : NameListToString(func->objname))));
2426 : : else
2427 [ + - ]: 18 : ereport(ERROR,
2428 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2429 : : errmsg("aggregate %s does not exist",
2430 : : func_signature_string(func->objname, argcount,
2431 : : NIL, argoids))));
2432 : : break;
2433 : :
2434 : 41 : default:
2435 : : /* FUNCTION and ROUTINE */
2436 [ + + ]: 41 : if (func->args_unspecified)
2437 [ + - ]: 3 : ereport(ERROR,
2438 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2439 : : errmsg("could not find a function named \"%s\"",
2440 : : NameListToString(func->objname))));
2441 : : else
2442 [ + - ]: 38 : ereport(ERROR,
2443 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2444 : : errmsg("function %s does not exist",
2445 : : func_signature_string(func->objname, argcount,
2446 : : NIL, argoids))));
2447 : : break;
2448 : : }
2449 : : break;
2450 : :
2451 [ + + - + : 24 : case FUNCLOOKUP_AMBIGUOUS:
- ]
2452 : : switch (objtype)
2453 : : {
2454 : 9 : case OBJECT_FUNCTION:
2455 [ + - + - ]: 9 : ereport(ERROR,
2456 : : (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2457 : : errmsg("function name \"%s\" is not unique",
2458 : : NameListToString(func->objname)),
2459 : : func->args_unspecified ?
2460 : : errhint("Specify the argument list to select the function unambiguously.") : 0));
2461 : : break;
2462 : 12 : case OBJECT_PROCEDURE:
2463 [ + - + + ]: 12 : ereport(ERROR,
2464 : : (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2465 : : errmsg("procedure name \"%s\" is not unique",
2466 : : NameListToString(func->objname)),
2467 : : func->args_unspecified ?
2468 : : errhint("Specify the argument list to select the procedure unambiguously.") : 0));
2469 : : break;
1851 tgl@sss.pgh.pa.us 2470 :UBC 0 : case OBJECT_AGGREGATE:
2471 [ # # # # ]: 0 : ereport(ERROR,
2472 : : (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2473 : : errmsg("aggregate name \"%s\" is not unique",
2474 : : NameListToString(func->objname)),
2475 : : func->args_unspecified ?
2476 : : errhint("Specify the argument list to select the aggregate unambiguously.") : 0));
2477 : : break;
1851 tgl@sss.pgh.pa.us 2478 :CBC 3 : case OBJECT_ROUTINE:
2479 [ + - + - ]: 3 : ereport(ERROR,
2480 : : (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2481 : : errmsg("routine name \"%s\" is not unique",
2482 : : NameListToString(func->objname)),
2483 : : func->args_unspecified ?
2484 : : errhint("Specify the argument list to select the routine unambiguously.") : 0));
2485 : : break;
2486 : :
1851 tgl@sss.pgh.pa.us 2487 :UBC 0 : default:
2488 : 0 : Assert(false); /* Disallowed by Assert above */
2489 : : break;
2490 : : }
2491 : : break;
2492 : : }
2493 : :
1851 tgl@sss.pgh.pa.us 2494 :CBC 26 : return InvalidOid;
2495 : : }
2496 : : }
2497 : :
2498 : : /*
2499 : : * check_srf_call_placement
2500 : : * Verify that a set-returning function is called in a valid place,
2501 : : * and throw a nice error if not.
2502 : : *
2503 : : * A side-effect is to set pstate->p_hasTargetSRFs true if appropriate.
2504 : : *
2505 : : * last_srf should be a copy of pstate->p_last_srf from just before we
2506 : : * started transforming the function's arguments. This allows detection
2507 : : * of whether the SRF's arguments contain any SRFs.
2508 : : */
2509 : : void
2497 2510 : 23251 : check_srf_call_placement(ParseState *pstate, Node *last_srf, int location)
2511 : : {
2512 : : const char *err;
2513 : : bool errkind;
2514 : :
2515 : : /*
2516 : : * Check to see if the set-returning function is in an invalid place
2517 : : * within the query. Basically, we don't allow SRFs anywhere except in
2518 : : * the targetlist (which includes GROUP BY/ORDER BY expressions), VALUES,
2519 : : * and functions in FROM.
2520 : : *
2521 : : * For brevity we support two schemes for reporting an error here: set
2522 : : * "err" to a custom message, or set "errkind" true if the error context
2523 : : * is sufficiently identified by what ParseExprKindName will return, *and*
2524 : : * what it will return is just a SQL keyword. (Otherwise, use a custom
2525 : : * message to avoid creating translation problems.)
2526 : : */
2770 2527 : 23251 : err = NULL;
2528 : 23251 : errkind = false;
2529 [ - - - - : 23251 : switch (pstate->p_expr_kind)
+ - - - -
+ - + + +
- + + + +
- - + - -
- - - - +
+ - + + -
- ]
2530 : : {
2770 tgl@sss.pgh.pa.us 2531 :UBC 0 : case EXPR_KIND_NONE:
2532 : 0 : Assert(false); /* can't happen */
2533 : : break;
2534 : 0 : case EXPR_KIND_OTHER:
2535 : : /* Accept SRF here; caller must throw error if wanted */
2536 : 0 : break;
2537 : 0 : case EXPR_KIND_JOIN_ON:
2538 : : case EXPR_KIND_JOIN_USING:
2539 : 0 : err = _("set-returning functions are not allowed in JOIN conditions");
2540 : 0 : break;
2541 : 0 : case EXPR_KIND_FROM_SUBSELECT:
2542 : : /* can't get here, but just in case, throw an error */
2543 : 0 : errkind = true;
2544 : 0 : break;
2770 tgl@sss.pgh.pa.us 2545 :CBC 18050 : case EXPR_KIND_FROM_FUNCTION:
2546 : : /* okay, but we don't allow nested SRFs here */
2547 : : /* errmsg is chosen to match transformRangeFunction() */
2548 : : /* errposition should point to the inner SRF */
2497 2549 [ + + ]: 18050 : if (pstate->p_last_srf != last_srf)
2550 [ + - ]: 3 : ereport(ERROR,
2551 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2552 : : errmsg("set-returning functions must appear at top level of FROM"),
2553 : : parser_errposition(pstate,
2554 : : exprLocation(pstate->p_last_srf))));
2770 2555 : 18047 : break;
2770 tgl@sss.pgh.pa.us 2556 :UBC 0 : case EXPR_KIND_WHERE:
2557 : 0 : errkind = true;
2558 : 0 : break;
2559 : 0 : case EXPR_KIND_POLICY:
2560 : 0 : err = _("set-returning functions are not allowed in policy expressions");
2561 : 0 : break;
2562 : 0 : case EXPR_KIND_HAVING:
2563 : 0 : errkind = true;
2564 : 0 : break;
2565 : 0 : case EXPR_KIND_FILTER:
2566 : 0 : errkind = true;
2567 : 0 : break;
2770 tgl@sss.pgh.pa.us 2568 :CBC 6 : case EXPR_KIND_WINDOW_PARTITION:
2569 : : case EXPR_KIND_WINDOW_ORDER:
2570 : : /* okay, these are effectively GROUP BY/ORDER BY */
2571 : 6 : pstate->p_hasTargetSRFs = true;
2572 : 6 : break;
2770 tgl@sss.pgh.pa.us 2573 :UBC 0 : case EXPR_KIND_WINDOW_FRAME_RANGE:
2574 : : case EXPR_KIND_WINDOW_FRAME_ROWS:
2575 : : case EXPR_KIND_WINDOW_FRAME_GROUPS:
2576 : 0 : err = _("set-returning functions are not allowed in window definitions");
2577 : 0 : break;
2770 tgl@sss.pgh.pa.us 2578 :CBC 5104 : case EXPR_KIND_SELECT_TARGET:
2579 : : case EXPR_KIND_INSERT_TARGET:
2580 : : /* okay */
2581 : 5104 : pstate->p_hasTargetSRFs = true;
2582 : 5104 : break;
2583 : 3 : case EXPR_KIND_UPDATE_SOURCE:
2584 : : case EXPR_KIND_UPDATE_TARGET:
2585 : : /* disallowed because it would be ambiguous what to do */
2586 : 3 : errkind = true;
2587 : 3 : break;
2588 : 18 : case EXPR_KIND_GROUP_BY:
2589 : : case EXPR_KIND_ORDER_BY:
2590 : : /* okay */
2591 : 18 : pstate->p_hasTargetSRFs = true;
2592 : 18 : break;
2770 tgl@sss.pgh.pa.us 2593 :UBC 0 : case EXPR_KIND_DISTINCT_ON:
2594 : : /* okay */
2595 : 0 : pstate->p_hasTargetSRFs = true;
2596 : 0 : break;
2770 tgl@sss.pgh.pa.us 2597 :CBC 3 : case EXPR_KIND_LIMIT:
2598 : : case EXPR_KIND_OFFSET:
2599 : 3 : errkind = true;
2600 : 3 : break;
2601 : 3 : case EXPR_KIND_RETURNING:
2602 : : case EXPR_KIND_MERGE_RETURNING:
2603 : 3 : errkind = true;
2604 : 3 : break;
2605 : 3 : case EXPR_KIND_VALUES:
2606 : : /* SRFs are presently not supported by nodeValuesscan.c */
2645 2607 : 3 : errkind = true;
2608 : 3 : break;
2609 : 43 : case EXPR_KIND_VALUES_SINGLE:
2610 : : /* okay, since we process this like a SELECT tlist */
2611 : 43 : pstate->p_hasTargetSRFs = true;
2770 2612 : 43 : break;
748 alvherre@alvh.no-ip. 2613 :UBC 0 : case EXPR_KIND_MERGE_WHEN:
2614 : 0 : err = _("set-returning functions are not allowed in MERGE WHEN conditions");
2615 : 0 : break;
2770 tgl@sss.pgh.pa.us 2616 : 0 : case EXPR_KIND_CHECK_CONSTRAINT:
2617 : : case EXPR_KIND_DOMAIN_CHECK:
2618 : 0 : err = _("set-returning functions are not allowed in check constraints");
2619 : 0 : break;
2770 tgl@sss.pgh.pa.us 2620 :CBC 3 : case EXPR_KIND_COLUMN_DEFAULT:
2621 : : case EXPR_KIND_FUNCTION_DEFAULT:
2622 : 3 : err = _("set-returning functions are not allowed in DEFAULT expressions");
2623 : 3 : break;
2770 tgl@sss.pgh.pa.us 2624 :UBC 0 : case EXPR_KIND_INDEX_EXPRESSION:
2625 : 0 : err = _("set-returning functions are not allowed in index expressions");
2626 : 0 : break;
2627 : 0 : case EXPR_KIND_INDEX_PREDICATE:
2628 : 0 : err = _("set-returning functions are not allowed in index predicates");
2629 : 0 : break;
1115 tomas.vondra@postgre 2630 : 0 : case EXPR_KIND_STATS_EXPRESSION:
2631 : 0 : err = _("set-returning functions are not allowed in statistics expressions");
2632 : 0 : break;
2770 tgl@sss.pgh.pa.us 2633 : 0 : case EXPR_KIND_ALTER_COL_TRANSFORM:
2634 : 0 : err = _("set-returning functions are not allowed in transform expressions");
2635 : 0 : break;
2636 : 0 : case EXPR_KIND_EXECUTE_PARAMETER:
2637 : 0 : err = _("set-returning functions are not allowed in EXECUTE parameters");
2638 : 0 : break;
2639 : 0 : case EXPR_KIND_TRIGGER_WHEN:
2640 : 0 : err = _("set-returning functions are not allowed in trigger WHEN conditions");
2641 : 0 : break;
1906 peter@eisentraut.org 2642 :CBC 6 : case EXPR_KIND_PARTITION_BOUND:
2643 : 6 : err = _("set-returning functions are not allowed in partition bound");
2644 : 6 : break;
2685 rhaas@postgresql.org 2645 : 3 : case EXPR_KIND_PARTITION_EXPRESSION:
2497 tgl@sss.pgh.pa.us 2646 : 3 : err = _("set-returning functions are not allowed in partition key expressions");
2685 rhaas@postgresql.org 2647 : 3 : break;
2255 tgl@sss.pgh.pa.us 2648 :UBC 0 : case EXPR_KIND_CALL_ARGUMENT:
2327 peter_e@gmx.net 2649 : 0 : err = _("set-returning functions are not allowed in CALL arguments");
2650 : 0 : break;
1912 tomas.vondra@postgre 2651 :CBC 3 : case EXPR_KIND_COPY_WHERE:
2652 : 3 : err = _("set-returning functions are not allowed in COPY FROM WHERE conditions");
2653 : 3 : break;
1842 peter@eisentraut.org 2654 : 3 : case EXPR_KIND_GENERATED_COLUMN:
2655 : 3 : err = _("set-returning functions are not allowed in column generation expressions");
2656 : 3 : break;
1168 peter@eisentraut.org 2657 :UBC 0 : case EXPR_KIND_CYCLE_MARK:
2658 : 0 : errkind = true;
2659 : 0 : break;
2660 : :
2661 : : /*
2662 : : * There is intentionally no default: case here, so that the
2663 : : * compiler will warn if we add a new ParseExprKind without
2664 : : * extending this switch. If we do see an unrecognized value at
2665 : : * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
2666 : : * which is sane anyway.
2667 : : */
2668 : : }
2770 tgl@sss.pgh.pa.us 2669 [ + + ]:CBC 23248 : if (err)
2670 [ + - ]: 18 : ereport(ERROR,
2671 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2672 : : errmsg_internal("%s", err),
2673 : : parser_errposition(pstate, location)));
2674 [ + + ]: 23230 : if (errkind)
2675 [ + - ]: 12 : ereport(ERROR,
2676 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2677 : : /* translator: %s is name of a SQL construct, eg GROUP BY */
2678 : : errmsg("set-returning functions are not allowed in %s",
2679 : : ParseExprKindName(pstate->p_expr_kind)),
2680 : : parser_errposition(pstate, location)));
2681 : 23218 : }
|