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-2025, PostgreSQL Global Development Group
7 : : * Portions Copyright (c) 1994, Regents of the University of California
8 : : *
9 : : *
10 : : * IDENTIFICATION
11 : : * src/backend/parser/parse_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 *
8551 tgl@sss.pgh.pa.us 90 :CBC 188606 : ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
91 : : Node *last_srf, FuncCall *fn, bool proc_call, int location)
92 : : {
4275 93 : 188606 : bool is_column = (fn == NULL);
94 [ + + ]: 188606 : List *agg_order = (fn ? fn->agg_order : NIL);
95 : 188606 : Expr *agg_filter = NULL;
1767 96 [ + + ]: 188606 : WindowDef *over = (fn ? fn->over : NULL);
4275 97 [ + + + + ]: 188606 : bool agg_within_group = (fn ? fn->agg_within_group : false);
98 [ + + + + ]: 188606 : bool agg_star = (fn ? fn->agg_star : false);
99 [ + + + + ]: 188606 : bool agg_distinct = (fn ? fn->agg_distinct : false);
100 [ + + + + ]: 188606 : bool func_variadic = (fn ? fn->func_variadic : false);
1767 101 [ + + ]: 188606 : CoercionForm funcformat = (fn ? fn->funcformat : COERCE_EXPLICIT_CALL);
102 : : bool could_be_projection;
103 : : Oid rettype;
104 : : Oid funcid;
105 : : ListCell *l;
10147 bruce@momjian.us 106 : 188606 : 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;
4275 tgl@sss.pgh.pa.us 118 : 188606 : char aggkind = 0;
119 : : ParseCallbackState pcbstate;
120 : :
121 : : /*
122 : : * If there's an aggregate filter, transform it using transformWhereClause
123 : : */
124 [ + + + + ]: 188606 : if (fn && fn->agg_filter != NULL)
125 : 410 : 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 : : */
7381 135 [ - + ]: 188600 : if (list_length(fargs) > FUNC_MAX_ARGS)
8086 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 : : */
7381 tgl@sss.pgh.pa.us 154 :CBC 188600 : nargs = 0;
2245 155 [ + + + + : 499941 : foreach(l, fargs)
+ + ]
156 : : {
7381 157 : 311341 : Node *arg = lfirst(l);
158 : 311341 : Oid argtype = exprType(arg);
159 : :
4275 160 [ + + - + ]: 311341 : if (argtype == VOIDOID && IsA(arg, Param) &&
4275 tgl@sss.pgh.pa.us 161 [ # # # # ]:UBC 0 : !is_column && !agg_within_group)
162 : : {
2245 163 : 0 : fargs = foreach_delete_current(fargs, l);
7381 164 : 0 : continue;
165 : : }
166 : :
7381 tgl@sss.pgh.pa.us 167 :CBC 311341 : 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 : : */
5812 178 : 188600 : argnames = NIL;
179 [ + + + + : 499935 : foreach(l, fargs)
+ + ]
180 : : {
5671 bruce@momjian.us 181 : 311341 : Node *arg = lfirst(l);
182 : :
5812 tgl@sss.pgh.pa.us 183 [ + + ]: 311341 : if (IsA(arg, NamedArgExpr))
184 : : {
185 : 23654 : NamedArgExpr *na = (NamedArgExpr *) arg;
186 : : ListCell *lc;
187 : :
188 : : /* Reject duplicate arg names */
189 [ + + + + : 51016 : foreach(lc, argnames)
+ + ]
190 : : {
191 [ + + ]: 27365 : 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 : 23651 : argnames = lappend(argnames, na->name);
199 : : }
200 : : else
201 : : {
202 [ + + ]: 287687 : 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 : :
10147 bruce@momjian.us 210 [ + + ]: 188594 : if (fargs)
211 : : {
7773 neilc@samurai.com 212 : 165974 : first_arg = linitial(fargs);
8086 tgl@sss.pgh.pa.us 213 [ - + ]: 165974 : 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 : : */
2637 223 [ + + + + ]: 74372 : could_be_projection = (nargs == 1 && !proc_call &&
224 [ + + ]: 73374 : agg_order == NIL && agg_filter == NULL &&
225 [ + - + + : 73091 : !agg_star && !agg_distinct && over == NULL &&
+ + ]
226 [ + + + + : 142984 : !func_variadic && argnames == NIL &&
+ + ]
227 [ + + ]: 334273 : list_length(funcname) == 1 &&
228 [ + + + + ]: 95142 : (actual_arg_types[0] == RECORDOID ||
229 : 46775 : ISCOMPLEX(actual_arg_types[0])));
230 : :
231 : : /*
232 : : * If it's column syntax, check for column projection case first.
233 : : */
234 [ + + + + ]: 188594 : if (could_be_projection && is_column)
235 : : {
236 : 5769 : retval = ParseComplexProjection(pstate,
237 : 5769 : strVal(linitial(funcname)),
238 : : first_arg,
239 : : location);
240 [ + + ]: 5769 : if (retval)
241 : 5660 : 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 : :
3825 alvherre@alvh.no-ip. 264 : 182934 : setup_parser_errposition_callback(&pcbstate, pstate, location);
265 : :
5812 tgl@sss.pgh.pa.us 266 : 182934 : fdresult = func_get_detail(funcname, fargs, argnames, nargs,
267 : : actual_arg_types,
1549 268 : 182934 : !func_variadic, true, proc_call,
269 : : &funcid, &rettype, &retset,
270 : : &nvargs, &vatype,
6120 peter_e@gmx.net 271 : 182934 : &declared_arg_types, &argdefaults);
272 : :
3825 alvherre@alvh.no-ip. 273 : 182934 : 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 */
2639 tgl@sss.pgh.pa.us 280 [ + + + + ]: 182934 : if (proc_call &&
281 [ + + ]: 250 : (fdresult == FUNCDETAIL_NORMAL ||
282 [ + - ]: 247 : fdresult == FUNCDETAIL_AGGREGATE ||
283 [ - + ]: 247 : 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 [ + + + + ]: 182925 : 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 [ + + + + ]: 182922 : if (fdresult == FUNCDETAIL_NORMAL ||
305 [ + + ]: 23155 : 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 : : */
8549 312 [ - + ]: 160067 : if (agg_star)
8086 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)));
8549 tgl@sss.pgh.pa.us 319 [ - + ]:CBC 160067 : if (agg_distinct)
8086 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)));
4275 tgl@sss.pgh.pa.us 325 [ - + ]:CBC 160067 : if (agg_within_group)
4275 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)));
5744 tgl@sss.pgh.pa.us 331 [ - + ]:CBC 160067 : if (agg_order != NIL)
5744 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)));
4435 noah@leadboat.com 337 [ - + ]:CBC 160067 : if (agg_filter)
4435 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)));
6096 tgl@sss.pgh.pa.us 343 [ + + ]:CBC 160067 : 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 : : */
2639 354 [ + + + + ]: 182919 : if (fdresult == FUNCDETAIL_NORMAL || fdresult == FUNCDETAIL_PROCEDURE)
355 : : {
356 : : /* Nothing special to do for these cases. */
357 : : }
4275 358 [ + + ]: 23155 : 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 : 21617 : tup = SearchSysCache1(AGGFNOID, ObjectIdGetDatum(funcid));
2999 368 [ - + ]: 21617 : if (!HeapTupleIsValid(tup)) /* should not happen */
4275 tgl@sss.pgh.pa.us 369 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for aggregate %u", funcid);
4275 tgl@sss.pgh.pa.us 370 :CBC 21617 : classForm = (Form_pg_aggregate) GETSTRUCT(tup);
371 : 21617 : aggkind = classForm->aggkind;
372 : 21617 : catDirectArgs = classForm->aggnumdirectargs;
373 : 21617 : ReleaseSysCache(tup);
374 : :
375 : : /* Now check various disallowed cases. */
376 [ + + ]: 21617 : 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)
4275 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 */
4275 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)
4275 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 : :
4275 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 */
4275 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 : : */
4275 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 : : {
4275 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 */
4275 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 [ + + ]: 21446 : 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 [ + + ]: 1538 : else if (fdresult == FUNCDETAIL_WINDOWFUNC)
520 : : {
521 : : /*
522 : : * True window functions must be called with a window definition.
523 : : */
524 [ - + ]: 944 : if (!over)
4275 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 */
4275 tgl@sss.pgh.pa.us 531 [ - + ]:CBC 944 : if (agg_within_group)
4275 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 : : }
2639 tgl@sss.pgh.pa.us 538 [ + + ]:CBC 594 : 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 : 300 : return coerce_type(pstate, linitial(fargs),
545 : : actual_arg_types[0], rettype, -1,
546 : : COERCION_EXPLICIT, COERCE_EXPLICIT_CALL, location);
547 : : }
2637 548 [ + + ]: 294 : 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)
2637 tgl@sss.pgh.pa.us 558 :UBC 0 : return NULL;
559 : :
2618 peter_e@gmx.net 560 [ - + ]:CBC 15 : if (proc_call)
2618 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
2618 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 : : */
8570 tgl@sss.pgh.pa.us 586 [ + + ]: 279 : if (is_column)
5789 587 : 52 : return NULL;
588 : :
589 : : /*
590 : : * Check for column projection interpretation, since we didn't before.
591 : : */
2637 592 [ + + ]: 227 : 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 [ - + - - ]: 155 : if (list_length(agg_order) > 1 && !agg_within_group)
607 : : {
608 : : /* It's agg(x, ORDER BY y,z) ... perhaps misplaced ORDER BY */
5511 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 : : }
2618 peter_e@gmx.net 619 [ + + ]:CBC 155 : else if (proc_call)
620 [ + - ]: 7 : 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
8100 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 : : */
6106 646 : 182310 : nargsplusdefs = nargs;
647 [ + + + + : 195723 : foreach(l, argdefaults)
+ + ]
648 : : {
5931 bruce@momjian.us 649 : 13413 : Node *expr = (Node *) lfirst(l);
650 : :
651 : : /* probably shouldn't happen ... */
6106 tgl@sss.pgh.pa.us 652 [ - + ]: 13413 : if (nargsplusdefs >= FUNC_MAX_ARGS)
6106 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 : :
6106 tgl@sss.pgh.pa.us 661 :CBC 13413 : 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 : : */
8187 669 : 182310 : 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 */
8166 676 : 182277 : 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 : : */
4174 683 [ + + ]: 182242 : if (!OidIsValid(vatype))
684 : : {
685 [ - + ]: 177406 : Assert(nvargs == 0);
686 : 177406 : 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 [ + + + + ]: 182242 : if (nvargs > 0 && vatype != ANYOID)
694 : : {
5931 bruce@momjian.us 695 : 1099 : ArrayExpr *newa = makeNode(ArrayExpr);
696 : 1099 : int non_var_args = nargs - nvargs;
697 : : List *vargs;
698 : :
6261 tgl@sss.pgh.pa.us 699 [ - + ]: 1099 : Assert(non_var_args >= 0);
700 : 1099 : vargs = list_copy_tail(fargs, non_var_args);
701 : 1099 : fargs = list_truncate(fargs, non_var_args);
702 : :
703 : 1099 : newa->elements = vargs;
704 : : /* assume all the variadic arguments were coerced to the same type */
705 : 1099 : newa->element_typeid = exprType((Node *) linitial(vargs));
706 : 1099 : newa->array_typeid = get_array_type(newa->element_typeid);
707 [ - + ]: 1099 : if (!OidIsValid(newa->array_typeid))
6261 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 */
6261 tgl@sss.pgh.pa.us 714 :CBC 1099 : newa->multidims = false;
6218 715 : 1099 : newa->location = exprLocation((Node *) vargs);
716 : :
6261 717 : 1099 : fargs = lappend(fargs, newa);
718 : :
719 : : /* We could not have had VARIADIC marking before ... */
4174 720 [ - + ]: 1099 : Assert(!func_variadic);
721 : : /* ... but now, it's a VARIADIC call */
722 : 1099 : 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 : : */
4433 andrew@dunslane.net 729 [ + + + + : 182242 : if (nargs > 0 && vatype == ANYOID && func_variadic)
+ + ]
730 : : {
4174 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)))
4433 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 */
3280 tgl@sss.pgh.pa.us 742 [ + + ]: 182239 : if (retset)
3007 743 : 26462 : check_srf_call_placement(pstate, last_srf, location);
744 : :
745 : : /* build the appropriate output structure */
2837 peter_e@gmx.net 746 [ + + + + ]: 182203 : if (fdresult == FUNCDETAIL_NORMAL || fdresult == FUNCDETAIL_PROCEDURE)
10147 bruce@momjian.us 747 : 159657 : {
8304 tgl@sss.pgh.pa.us 748 : 159657 : FuncExpr *funcexpr = makeNode(FuncExpr);
749 : :
750 : 159657 : funcexpr->funcid = funcid;
751 : 159657 : funcexpr->funcresulttype = rettype;
752 : 159657 : funcexpr->funcretset = retset;
4611 753 : 159657 : funcexpr->funcvariadic = func_variadic;
1767 754 : 159657 : funcexpr->funcformat = funcformat;
755 : : /* funccollid and inputcollid will be set by parse_collate.c */
8304 756 : 159657 : funcexpr->args = fargs;
6218 757 : 159657 : funcexpr->location = location;
758 : :
8304 759 : 159657 : retval = (Node *) funcexpr;
760 : : }
6096 761 [ + + + + ]: 22546 : else if (fdresult == FUNCDETAIL_AGGREGATE && !over)
8876 bruce@momjian.us 762 : 20713 : {
763 : : /* aggregate function */
8549 tgl@sss.pgh.pa.us 764 : 20803 : Aggref *aggref = makeNode(Aggref);
765 : :
766 : 20803 : aggref->aggfnoid = funcid;
3359 767 : 20803 : aggref->aggtype = rettype;
768 : : /* aggcollid and inputcollid will be set by parse_collate.c */
2999 769 : 20803 : 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 */
4435 noah@leadboat.com 773 : 20803 : aggref->aggfilter = agg_filter;
4386 tgl@sss.pgh.pa.us 774 : 20803 : aggref->aggstar = agg_star;
775 : 20803 : aggref->aggvariadic = func_variadic;
4275 776 : 20803 : aggref->aggkind = aggkind;
1131 drowley@postgresql.o 777 : 20803 : aggref->aggpresorted = false;
778 : : /* agglevelsup will be set by transformAggregateCall */
2999 tgl@sss.pgh.pa.us 779 : 20803 : aggref->aggsplit = AGGSPLIT_SIMPLE; /* planner might change this */
1747 heikki.linnakangas@i 780 : 20803 : aggref->aggno = -1; /* planner will set aggno and aggtransno */
781 : 20803 : aggref->aggtransno = -1;
6218 tgl@sss.pgh.pa.us 782 : 20803 : 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 : : */
4275 788 [ + + - + : 20803 : if (fargs == NIL && !agg_star && !agg_within_group)
- - ]
6981 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 : :
6096 tgl@sss.pgh.pa.us 795 [ - + ]:CBC 20803 : if (retset)
6096 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 : : */
5812 tgl@sss.pgh.pa.us 810 [ - + ]:CBC 20803 : if (argnames != NIL)
5812 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 */
5652 tgl@sss.pgh.pa.us 817 :CBC 20803 : transformAggregateCall(pstate, aggref, fargs, agg_order, agg_distinct);
818 : :
8549 819 : 20713 : retval = (Node *) aggref;
820 : : }
821 : : else
822 : : {
823 : : /* window function */
6096 824 : 1743 : WindowFunc *wfunc = makeNode(WindowFunc);
825 : :
4275 826 [ - + ]: 1743 : Assert(over); /* lack of this was checked above */
2999 827 [ - + ]: 1743 : Assert(!agg_within_group); /* also checked above */
828 : :
6096 829 : 1743 : wfunc->winfnoid = funcid;
830 : 1743 : wfunc->wintype = rettype;
831 : : /* wincollid and inputcollid will be set by parse_collate.c */
832 : 1743 : wfunc->args = fargs;
833 : : /* winref will be set by transformWindowFuncCall */
834 : 1743 : wfunc->winstar = agg_star;
835 : 1743 : wfunc->winagg = (fdresult == FUNCDETAIL_AGGREGATE);
4435 noah@leadboat.com 836 : 1743 : wfunc->aggfilter = agg_filter;
489 drowley@postgresql.o 837 : 1743 : wfunc->runCondition = NIL;
6096 tgl@sss.pgh.pa.us 838 : 1743 : wfunc->location = location;
839 : :
840 : : /*
841 : : * agg_star is allowed for aggregate functions but distinct isn't
842 : : */
843 [ - + ]: 1743 : if (agg_distinct)
6096 tgl@sss.pgh.pa.us 844 [ # # ]:UBC 0 : ereport(ERROR,
845 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
846 : : errmsg("DISTINCT is not implemented for window functions"),
847 : : parser_errposition(pstate, location)));
848 : :
849 : : /*
850 : : * Reject attempt to call a parameterless aggregate without (*)
851 : : * syntax. This is mere pedantry but some folks insisted ...
852 : : */
6096 tgl@sss.pgh.pa.us 853 [ + + + + :CBC 1743 : if (wfunc->winagg && fargs == NIL && !agg_star)
+ + ]
854 [ + - ]: 3 : ereport(ERROR,
855 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
856 : : errmsg("%s(*) must be used to call a parameterless aggregate function",
857 : : NameListToString(funcname)),
858 : : parser_errposition(pstate, location)));
859 : :
860 : : /*
861 : : * ordered aggs not allowed in windows yet
862 : : */
4275 863 [ - + ]: 1740 : if (agg_order != NIL)
4435 noah@leadboat.com 864 [ # # ]:UBC 0 : ereport(ERROR,
865 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
866 : : errmsg("aggregate ORDER BY is not implemented for window functions"),
867 : : parser_errposition(pstate, location)));
868 : :
869 : : /*
870 : : * FILTER is not yet supported with true window functions
871 : : */
4275 tgl@sss.pgh.pa.us 872 [ + + - + ]:CBC 1740 : if (!wfunc->winagg && agg_filter)
5744 tgl@sss.pgh.pa.us 873 [ # # ]:UBC 0 : ereport(ERROR,
874 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
875 : : errmsg("FILTER is not implemented for non-aggregate window functions"),
876 : : parser_errposition(pstate, location)));
877 : :
878 : : /*
879 : : * Window functions can't either take or return sets
880 : : */
3007 tgl@sss.pgh.pa.us 881 [ + + ]:CBC 1740 : if (pstate->p_last_srf != last_srf)
882 [ + - ]: 3 : ereport(ERROR,
883 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
884 : : errmsg("window function calls cannot contain set-returning function calls"),
885 : : errhint("You might be able to move the set-returning function into a LATERAL FROM item."),
886 : : parser_errposition(pstate,
887 : : exprLocation(pstate->p_last_srf))));
888 : :
8549 889 [ - + ]: 1737 : if (retset)
8086 tgl@sss.pgh.pa.us 890 [ # # ]:UBC 0 : ereport(ERROR,
891 : : (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
892 : : errmsg("window functions cannot return sets"),
893 : : parser_errposition(pstate, location)));
894 : :
895 : : /* parse_agg.c does additional window-func-specific processing */
6096 tgl@sss.pgh.pa.us 896 :CBC 1737 : transformWindowFuncCall(pstate, wfunc, over);
897 : :
898 : 1710 : retval = (Node *) wfunc;
899 : : }
900 : :
901 : : /* if it returns a set, remember it for error checks at higher levels */
3007 902 [ + + ]: 182080 : if (retset)
903 : 26426 : pstate->p_last_srf = retval;
904 : :
8549 905 : 182080 : return retval;
906 : : }
907 : :
908 : :
909 : : /* func_match_argtypes()
910 : : *
911 : : * Given a list of candidate functions (having the right name and number
912 : : * of arguments) and an array of input datatype OIDs, produce a shortlist of
913 : : * those candidates that actually accept the input datatypes (either exactly
914 : : * or by coercion), and return the number of such candidates.
915 : : *
916 : : * Note that can_coerce_type will assume that UNKNOWN inputs are coercible to
917 : : * anything, so candidates will not be eliminated on that basis.
918 : : *
919 : : * NB: okay to modify input list structure, as long as we find at least
920 : : * one match. If no match at all, the list must remain unmodified.
921 : : */
922 : : int
8139 923 : 96467 : func_match_argtypes(int nargs,
924 : : Oid *input_typeids,
925 : : FuncCandidateList raw_candidates,
926 : : FuncCandidateList *candidates) /* return value */
927 : : {
928 : : FuncCandidateList current_candidate;
929 : : FuncCandidateList next_candidate;
10147 bruce@momjian.us 930 : 96467 : int ncandidates = 0;
931 : :
932 : 96467 : *candidates = NULL;
933 : :
8139 tgl@sss.pgh.pa.us 934 : 96467 : for (current_candidate = raw_candidates;
10147 bruce@momjian.us 935 [ + + ]: 638723 : current_candidate != NULL;
8554 tgl@sss.pgh.pa.us 936 : 542256 : current_candidate = next_candidate)
937 : : {
938 : 542256 : next_candidate = current_candidate->next;
8549 939 [ + + ]: 542256 : if (can_coerce_type(nargs, input_typeids, current_candidate->args,
940 : : COERCION_IMPLICIT))
941 : : {
8554 942 : 111653 : current_candidate->next = *candidates;
943 : 111653 : *candidates = current_candidate;
10147 bruce@momjian.us 944 : 111653 : ncandidates++;
945 : : }
946 : : }
947 : :
948 : 96467 : return ncandidates;
949 : : } /* func_match_argtypes() */
950 : :
951 : :
952 : : /* func_select_candidate()
953 : : * Given the input argtype array and more than one candidate
954 : : * for the function, attempt to resolve the conflict.
955 : : *
956 : : * Returns the selected candidate if the conflict can be resolved,
957 : : * otherwise returns NULL.
958 : : *
959 : : * Note that the caller has already determined that there is no candidate
960 : : * exactly matching the input argtypes, and has pruned away any "candidates"
961 : : * that aren't actually coercion-compatible with the input types.
962 : : *
963 : : * This is also used for resolving ambiguous operator references. Formerly
964 : : * parse_oper.c had its own, essentially duplicate code for the purpose.
965 : : * The following comments (formerly in parse_oper.c) are kept to record some
966 : : * of the history of these heuristics.
967 : : *
968 : : * OLD COMMENTS:
969 : : *
970 : : * This routine is new code, replacing binary_oper_select_candidate()
971 : : * which dates from v4.2/v1.0.x days. It tries very hard to match up
972 : : * operators with types, including allowing type coercions if necessary.
973 : : * The important thing is that the code do as much as possible,
974 : : * while _never_ doing the wrong thing, where "the wrong thing" would
975 : : * be returning an operator when other better choices are available,
976 : : * or returning an operator which is a non-intuitive possibility.
977 : : * - thomas 1998-05-21
978 : : *
979 : : * The comments below came from binary_oper_select_candidate(), and
980 : : * illustrate the issues and choices which are possible:
981 : : * - thomas 1998-05-20
982 : : *
983 : : * current wisdom holds that the default operator should be one in which
984 : : * both operands have the same type (there will only be one such
985 : : * operator)
986 : : *
987 : : * 7.27.93 - I have decided not to do this; it's too hard to justify, and
988 : : * it's easy enough to typecast explicitly - avi
989 : : * [the rest of this routine was commented out since then - ay]
990 : : *
991 : : * 6/23/95 - I don't complete agree with avi. In particular, casting
992 : : * floats is a pain for users. Whatever the rationale behind not doing
993 : : * this is, I need the following special case to work.
994 : : *
995 : : * In the WHERE clause of a query, if a float is specified without
996 : : * quotes, we treat it as float8. I added the float48* operators so
997 : : * that we can operate on float4 and float8. But now we have more than
998 : : * one matching operator if the right arg is unknown (eg. float
999 : : * specified with quotes). This break some stuff in the regression
1000 : : * test where there are floats in quotes not properly casted. Below is
1001 : : * the solution. In addition to requiring the operator operates on the
1002 : : * same type for both operands [as in the code Avi originally
1003 : : * commented out], we also require that the operators be equivalent in
1004 : : * some sense. (see equivalentOpersAfterPromotion for details.)
1005 : : * - ay 6/95
1006 : : */
1007 : : FuncCandidateList
1008 : 6343 : func_select_candidate(int nargs,
1009 : : Oid *input_typeids,
1010 : : FuncCandidateList candidates)
1011 : : {
1012 : : FuncCandidateList current_candidate,
1013 : : first_candidate,
1014 : : last_candidate;
1015 : : Oid *current_typeids;
1016 : : Oid current_type;
1017 : : int i;
1018 : : int ncandidates;
1019 : : int nbestMatch,
1020 : : nmatch,
1021 : : nunknowns;
1022 : : Oid input_base_typeids[FUNC_MAX_ARGS];
1023 : : TYPCATEGORY slot_category[FUNC_MAX_ARGS],
1024 : : current_category;
1025 : : bool current_is_preferred;
1026 : : bool slot_has_preferred_type[FUNC_MAX_ARGS];
1027 : : bool resolved_unknowns;
1028 : :
1029 : : /* protect local fixed-size arrays */
7466 tgl@sss.pgh.pa.us 1030 [ - + ]: 6343 : if (nargs > FUNC_MAX_ARGS)
7466 tgl@sss.pgh.pa.us 1031 [ # # ]:UBC 0 : ereport(ERROR,
1032 : : (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
1033 : : errmsg_plural("cannot pass more than %d argument to a function",
1034 : : "cannot pass more than %d arguments to a function",
1035 : : FUNC_MAX_ARGS,
1036 : : FUNC_MAX_ARGS)));
1037 : :
1038 : : /*
1039 : : * If any input types are domains, reduce them to their base types. This
1040 : : * ensures that we will consider functions on the base type to be "exact
1041 : : * matches" in the exact-match heuristic; it also makes it possible to do
1042 : : * something useful with the type-category heuristics. Note that this
1043 : : * makes it difficult, but not impossible, to use functions declared to
1044 : : * take a domain as an input datatype. Such a function will be selected
1045 : : * over the base-type function only if it is an exact match at all
1046 : : * argument positions, and so was already chosen by our caller.
1047 : : *
1048 : : * While we're at it, count the number of unknown-type arguments for use
1049 : : * later.
1050 : : */
5042 tgl@sss.pgh.pa.us 1051 :CBC 6343 : nunknowns = 0;
8139 1052 [ + + ]: 19826 : for (i = 0; i < nargs; i++)
1053 : : {
5042 1054 [ + + ]: 13483 : if (input_typeids[i] != UNKNOWNOID)
1055 : 6815 : input_base_typeids[i] = getBaseType(input_typeids[i]);
1056 : : else
1057 : : {
1058 : : /* no need to call getBaseType on UNKNOWNOID */
1059 : 6668 : input_base_typeids[i] = UNKNOWNOID;
1060 : 6668 : nunknowns++;
1061 : : }
1062 : : }
1063 : :
1064 : : /*
1065 : : * Run through all candidates and keep those with the most matches on
1066 : : * exact types. Keep all candidates if none match.
1067 : : */
9982 lockhart@fourpalms.o 1068 : 6343 : ncandidates = 0;
1069 : 6343 : nbestMatch = 0;
1070 : 6343 : last_candidate = NULL;
1071 : 6343 : for (current_candidate = candidates;
1072 [ + + ]: 28184 : current_candidate != NULL;
1073 : 21841 : current_candidate = current_candidate->next)
1074 : : {
1075 : 21841 : current_typeids = current_candidate->args;
1076 : 21841 : nmatch = 0;
1077 [ + + ]: 67700 : for (i = 0; i < nargs; i++)
1078 : : {
8139 tgl@sss.pgh.pa.us 1079 [ + + ]: 45859 : if (input_base_typeids[i] != UNKNOWNOID &&
1080 [ + + ]: 21176 : current_typeids[i] == input_base_typeids[i])
1081 : 7030 : nmatch++;
1082 : : }
1083 : :
1084 : : /* take this one as the best choice so far? */
9982 lockhart@fourpalms.o 1085 [ + + + + ]: 21841 : if ((nmatch > nbestMatch) || (last_candidate == NULL))
1086 : : {
1087 : 7687 : nbestMatch = nmatch;
1088 : 7687 : candidates = current_candidate;
1089 : 7687 : last_candidate = current_candidate;
1090 : 7687 : ncandidates = 1;
1091 : : }
1092 : : /* no worse than the last choice, so keep this one too? */
1093 [ + + ]: 14154 : else if (nmatch == nbestMatch)
1094 : : {
1095 : 9870 : last_candidate->next = current_candidate;
1096 : 9870 : last_candidate = current_candidate;
1097 : 9870 : ncandidates++;
1098 : : }
1099 : : /* otherwise, don't bother keeping this one... */
1100 : : }
1101 : :
9330 tgl@sss.pgh.pa.us 1102 [ + - ]: 6343 : if (last_candidate) /* terminate rebuilt list */
1103 : 6343 : last_candidate->next = NULL;
1104 : :
9692 lockhart@fourpalms.o 1105 [ + + ]: 6343 : if (ncandidates == 1)
8554 tgl@sss.pgh.pa.us 1106 : 2822 : return candidates;
1107 : :
1108 : : /*
1109 : : * Still too many candidates? Now look for candidates which have either
1110 : : * exact matches or preferred types at the args that will require
1111 : : * coercion. (Restriction added in 7.4: preferred type must be of same
1112 : : * category as input type; give no preference to cross-category
1113 : : * conversions to preferred types.) Keep all candidates if none match.
1114 : : */
8069 bruce@momjian.us 1115 [ + + ]: 11228 : for (i = 0; i < nargs; i++) /* avoid multiple lookups */
8139 tgl@sss.pgh.pa.us 1116 : 7707 : slot_category[i] = TypeCategory(input_base_typeids[i]);
9302 1117 : 3521 : ncandidates = 0;
1118 : 3521 : nbestMatch = 0;
1119 : 3521 : last_candidate = NULL;
1120 : 3521 : for (current_candidate = candidates;
1121 [ + + ]: 15722 : current_candidate != NULL;
1122 : 12201 : current_candidate = current_candidate->next)
1123 : : {
1124 : 12201 : current_typeids = current_candidate->args;
1125 : 12201 : nmatch = 0;
1126 [ + + ]: 38541 : for (i = 0; i < nargs; i++)
1127 : : {
8139 1128 [ + + ]: 26340 : if (input_base_typeids[i] != UNKNOWNOID)
1129 : : {
1130 [ + + + + ]: 11775 : if (current_typeids[i] == input_base_typeids[i] ||
1131 : 4199 : IsPreferredType(slot_category[i], current_typeids[i]))
9302 1132 : 5146 : nmatch++;
1133 : : }
1134 : : }
1135 : :
1136 [ + + + + ]: 12201 : if ((nmatch > nbestMatch) || (last_candidate == NULL))
1137 : : {
1138 : 4405 : nbestMatch = nmatch;
1139 : 4405 : candidates = current_candidate;
1140 : 4405 : last_candidate = current_candidate;
1141 : 4405 : ncandidates = 1;
1142 : : }
1143 [ + + ]: 7796 : else if (nmatch == nbestMatch)
1144 : : {
1145 : 7147 : last_candidate->next = current_candidate;
1146 : 7147 : last_candidate = current_candidate;
1147 : 7147 : ncandidates++;
1148 : : }
1149 : : }
1150 : :
1151 [ + - ]: 3521 : if (last_candidate) /* terminate rebuilt list */
1152 : 3521 : last_candidate->next = NULL;
1153 : :
1154 [ + + ]: 3521 : if (ncandidates == 1)
8554 1155 : 815 : return candidates;
1156 : :
1157 : : /*
1158 : : * Still too many candidates? Try assigning types for the unknown inputs.
1159 : : *
1160 : : * If there are no unknown inputs, we have no more heuristics that apply,
1161 : : * and must fail.
1162 : : */
5042 1163 [ + + ]: 2706 : if (nunknowns == 0)
1164 : 3 : return NULL; /* failed to select a best candidate */
1165 : :
1166 : : /*
1167 : : * The next step examines each unknown argument position to see if we can
1168 : : * determine a "type category" for it. If any candidate has an input
1169 : : * datatype of STRING category, use STRING category (this bias towards
1170 : : * STRING is appropriate since unknown-type literals look like strings).
1171 : : * Otherwise, if all the candidates agree on the type category of this
1172 : : * argument position, use that category. Otherwise, fail because we
1173 : : * cannot determine a category.
1174 : : *
1175 : : * If we are able to determine a type category, also notice whether any of
1176 : : * the candidates takes a preferred datatype within the category.
1177 : : *
1178 : : * Having completed this examination, remove candidates that accept the
1179 : : * wrong category at any unknown position. Also, if at least one
1180 : : * candidate accepted a preferred type at a position, remove candidates
1181 : : * that accept non-preferred types. If just one candidate remains, return
1182 : : * that one. However, if this rule turns out to reject all candidates,
1183 : : * keep them all instead.
1184 : : */
9031 1185 : 2703 : resolved_unknowns = false;
9692 lockhart@fourpalms.o 1186 [ + + ]: 8808 : for (i = 0; i < nargs; i++)
1187 : : {
1188 : : bool have_conflict;
1189 : :
8139 tgl@sss.pgh.pa.us 1190 [ + + ]: 6105 : if (input_base_typeids[i] != UNKNOWNOID)
9031 1191 : 1524 : continue;
2999 1192 : 4581 : resolved_unknowns = true; /* assume we can do it */
6247 1193 : 4581 : slot_category[i] = TYPCATEGORY_INVALID;
9031 1194 : 4581 : slot_has_preferred_type[i] = false;
1195 : 4581 : have_conflict = false;
1196 : 4581 : for (current_candidate = candidates;
1197 [ + + ]: 22531 : current_candidate != NULL;
1198 : 17950 : current_candidate = current_candidate->next)
1199 : : {
1200 : 17950 : current_typeids = current_candidate->args;
1201 : 17950 : current_type = current_typeids[i];
6247 1202 : 17950 : get_type_category_preferred(current_type,
1203 : : ¤t_category,
1204 : : ¤t_is_preferred);
1205 [ + + ]: 17950 : if (slot_category[i] == TYPCATEGORY_INVALID)
1206 : : {
1207 : : /* first candidate */
9031 1208 : 4581 : slot_category[i] = current_category;
6247 1209 : 4581 : slot_has_preferred_type[i] = current_is_preferred;
1210 : : }
9031 1211 [ + + ]: 13369 : else if (current_category == slot_category[i])
1212 : : {
1213 : : /* more candidates in same category */
6247 1214 : 3682 : slot_has_preferred_type[i] |= current_is_preferred;
1215 : : }
1216 : : else
1217 : : {
1218 : : /* category conflict! */
1219 [ + + ]: 9687 : if (current_category == TYPCATEGORY_STRING)
1220 : : {
1221 : : /* STRING always wins if available */
9031 1222 : 1227 : slot_category[i] = current_category;
6247 1223 : 1227 : slot_has_preferred_type[i] = current_is_preferred;
1224 : : }
1225 : : else
1226 : : {
1227 : : /*
1228 : : * Remember conflict, but keep going (might find STRING)
1229 : : */
9031 1230 : 8460 : have_conflict = true;
1231 : : }
1232 : : }
1233 : : }
6247 1234 [ + + - + ]: 4581 : if (have_conflict && slot_category[i] != TYPCATEGORY_STRING)
1235 : : {
1236 : : /* Failed to resolve category conflict at this position */
9031 tgl@sss.pgh.pa.us 1237 :UBC 0 : resolved_unknowns = false;
1238 : 0 : break;
1239 : : }
1240 : : }
1241 : :
9031 tgl@sss.pgh.pa.us 1242 [ + - ]:CBC 2703 : if (resolved_unknowns)
1243 : : {
1244 : : /* Strip non-matching candidates */
1245 : 2703 : ncandidates = 0;
5042 1246 : 2703 : first_candidate = candidates;
9031 1247 : 2703 : last_candidate = NULL;
1248 : 2703 : for (current_candidate = candidates;
1249 [ + + ]: 12304 : current_candidate != NULL;
1250 : 9601 : current_candidate = current_candidate->next)
1251 : : {
8934 bruce@momjian.us 1252 : 9601 : bool keepit = true;
1253 : :
9031 tgl@sss.pgh.pa.us 1254 : 9601 : current_typeids = current_candidate->args;
1255 [ + + ]: 17655 : for (i = 0; i < nargs; i++)
1256 : : {
8139 1257 [ + + ]: 14897 : if (input_base_typeids[i] != UNKNOWNOID)
9031 1258 : 2183 : continue;
1259 : 12714 : current_type = current_typeids[i];
6247 1260 : 12714 : get_type_category_preferred(current_type,
1261 : : ¤t_category,
1262 : : ¤t_is_preferred);
9031 1263 [ + + ]: 12714 : if (current_category != slot_category[i])
1264 : : {
1265 : 6297 : keepit = false;
1266 : 6297 : break;
1267 : : }
6247 1268 [ + + + + ]: 6417 : if (slot_has_preferred_type[i] && !current_is_preferred)
1269 : : {
9031 1270 : 546 : keepit = false;
1271 : 546 : break;
1272 : : }
1273 : : }
1274 [ + + ]: 9601 : if (keepit)
1275 : : {
1276 : : /* keep this candidate */
1277 : 2758 : last_candidate = current_candidate;
1278 : 2758 : ncandidates++;
1279 : : }
1280 : : else
1281 : : {
1282 : : /* forget this candidate */
1283 [ + + ]: 6843 : if (last_candidate)
1284 : 5005 : last_candidate->next = current_candidate->next;
1285 : : else
5042 1286 : 1838 : first_candidate = current_candidate->next;
1287 : : }
1288 : : }
1289 : :
1290 : : /* if we found any matches, restrict our attention to those */
1291 [ + - ]: 2703 : if (last_candidate)
1292 : : {
1293 : 2703 : candidates = first_candidate;
1294 : : /* terminate rebuilt list */
9031 1295 : 2703 : last_candidate->next = NULL;
1296 : : }
1297 : :
5042 1298 [ + + ]: 2703 : if (ncandidates == 1)
1299 : 2678 : return candidates;
1300 : : }
1301 : :
1302 : : /*
1303 : : * Last gasp: if there are both known- and unknown-type inputs, and all
1304 : : * the known types are the same, assume the unknown inputs are also that
1305 : : * type, and see if that gives us a unique match. If so, use that match.
1306 : : *
1307 : : * NOTE: for a binary operator with one unknown and one non-unknown input,
1308 : : * we already tried this heuristic in binary_oper_exact(). However, that
1309 : : * code only finds exact matches, whereas here we will handle matches that
1310 : : * involve coercion, polymorphic type resolution, etc.
1311 : : */
1312 [ + - ]: 25 : if (nunknowns < nargs)
1313 : : {
1314 : 25 : Oid known_type = UNKNOWNOID;
1315 : :
1316 [ + + ]: 75 : for (i = 0; i < nargs; i++)
1317 : : {
1318 [ + + ]: 50 : if (input_base_typeids[i] == UNKNOWNOID)
1319 : 25 : continue;
2999 1320 [ + - ]: 25 : if (known_type == UNKNOWNOID) /* first known arg? */
5042 1321 : 25 : known_type = input_base_typeids[i];
5042 tgl@sss.pgh.pa.us 1322 [ # # ]:UBC 0 : else if (known_type != input_base_typeids[i])
1323 : : {
1324 : : /* oops, not all match */
1325 : 0 : known_type = UNKNOWNOID;
1326 : 0 : break;
1327 : : }
1328 : : }
1329 : :
5042 tgl@sss.pgh.pa.us 1330 [ + - ]:CBC 25 : if (known_type != UNKNOWNOID)
1331 : : {
1332 : : /* okay, just one known type, apply the heuristic */
1333 [ + + ]: 75 : for (i = 0; i < nargs; i++)
1334 : 50 : input_base_typeids[i] = known_type;
1335 : 25 : ncandidates = 0;
1336 : 25 : last_candidate = NULL;
1337 : 25 : for (current_candidate = candidates;
1338 [ + + ]: 105 : current_candidate != NULL;
1339 : 80 : current_candidate = current_candidate->next)
1340 : : {
1341 : 80 : current_typeids = current_candidate->args;
1342 [ + + ]: 80 : if (can_coerce_type(nargs, input_base_typeids, current_typeids,
1343 : : COERCION_IMPLICIT))
1344 : : {
1345 [ - + ]: 25 : if (++ncandidates > 1)
5042 tgl@sss.pgh.pa.us 1346 :UBC 0 : break; /* not unique, give up */
5042 tgl@sss.pgh.pa.us 1347 :CBC 25 : last_candidate = current_candidate;
1348 : : }
1349 : : }
1350 [ + - ]: 25 : if (ncandidates == 1)
1351 : : {
1352 : : /* successfully identified a unique match */
1353 : 25 : last_candidate->next = NULL;
1354 : 25 : return last_candidate;
1355 : : }
1356 : : }
1357 : : }
1358 : :
8139 tgl@sss.pgh.pa.us 1359 :UBC 0 : return NULL; /* failed to select a best candidate */
1360 : : } /* func_select_candidate() */
1361 : :
1362 : :
1363 : : /* func_get_detail()
1364 : : *
1365 : : * Find the named function in the system catalogs.
1366 : : *
1367 : : * Attempt to find the named function in the system catalogs with
1368 : : * arguments exactly as specified, so that the normal case (exact match)
1369 : : * is as quick as possible.
1370 : : *
1371 : : * If an exact match isn't found:
1372 : : * 1) check for possible interpretation as a type coercion request
1373 : : * 2) apply the ambiguous-function resolution rules
1374 : : *
1375 : : * Return values *funcid through *true_typeids receive info about the function.
1376 : : * If argdefaults isn't NULL, *argdefaults receives a list of any default
1377 : : * argument expressions that need to be added to the given arguments.
1378 : : *
1379 : : * When processing a named- or mixed-notation call (ie, fargnames isn't NIL),
1380 : : * the returned true_typeids and argdefaults are ordered according to the
1381 : : * call's argument ordering: first any positional arguments, then the named
1382 : : * arguments, then defaulted arguments (if needed and allowed by
1383 : : * expand_defaults). Some care is needed if this information is to be compared
1384 : : * to the function's pg_proc entry, but in practice the caller can usually
1385 : : * just work with the call's argument ordering.
1386 : : *
1387 : : * We rely primarily on fargnames/nargs/argtypes as the argument description.
1388 : : * The actual expression node list is passed in fargs so that we can check
1389 : : * for type coercion of a constant. Some callers pass fargs == NIL indicating
1390 : : * they don't need that check made. Note also that when fargnames isn't NIL,
1391 : : * the fargs list must be passed if the caller wants actual argument position
1392 : : * information to be returned into the NamedArgExpr nodes.
1393 : : */
1394 : : FuncDetailCode
8551 tgl@sss.pgh.pa.us 1395 :CBC 189877 : func_get_detail(List *funcname,
1396 : : List *fargs,
1397 : : List *fargnames,
1398 : : int nargs,
1399 : : Oid *argtypes,
1400 : : bool expand_variadic,
1401 : : bool expand_defaults,
1402 : : bool include_out_arguments,
1403 : : Oid *funcid, /* return value */
1404 : : Oid *rettype, /* return value */
1405 : : bool *retset, /* return value */
1406 : : int *nvargs, /* return value */
1407 : : Oid *vatype, /* return value */
1408 : : Oid **true_typeids, /* return value */
1409 : : List **argdefaults) /* optional return value */
1410 : : {
1411 : : FuncCandidateList raw_candidates;
1412 : : FuncCandidateList best_candidate;
1413 : :
1414 : : /* initialize output arguments to silence compiler warnings */
5979 1415 : 189877 : *funcid = InvalidOid;
1416 : 189877 : *rettype = InvalidOid;
1417 : 189877 : *retset = false;
1418 : 189877 : *nvargs = 0;
4174 1419 : 189877 : *vatype = InvalidOid;
5979 1420 : 189877 : *true_typeids = NULL;
1421 [ + + ]: 189877 : if (argdefaults)
5931 bruce@momjian.us 1422 : 182934 : *argdefaults = NIL;
1423 : :
1424 : : /* Get list of possible candidates from namespace search */
5812 tgl@sss.pgh.pa.us 1425 : 189877 : raw_candidates = FuncnameGetCandidates(funcname, nargs, fargnames,
1426 : : expand_variadic, expand_defaults,
1427 : : include_out_arguments, false);
1428 : :
1429 : : /*
1430 : : * Quickly check if there is an exact match to the input datatypes (there
1431 : : * can be only one)
1432 : : */
8139 1433 : 189877 : for (best_candidate = raw_candidates;
8554 1434 [ + + ]: 381236 : best_candidate != NULL;
1435 : 191359 : best_candidate = best_candidate->next)
1436 : : {
1437 : : /* if nargs==0, argtypes can be null; don't pass that to memcmp */
2125 1438 [ + + ]: 292931 : if (nargs == 0 ||
1439 [ + + ]: 269393 : memcmp(argtypes, best_candidate->args, nargs * sizeof(Oid)) == 0)
1440 : : break;
1441 : : }
1442 : :
8554 1443 [ + + ]: 189877 : if (best_candidate == NULL)
1444 : : {
1445 : : /*
1446 : : * If we didn't find an exact match, next consider the possibility
1447 : : * that this is really a type-coercion request: a single-argument
1448 : : * function call where the function name is a type name. If so, and
1449 : : * if the coercion path is RELABELTYPE or COERCEVIAIO, then go ahead
1450 : : * and treat the "function call" as a coercion.
1451 : : *
1452 : : * This interpretation needs to be given higher priority than
1453 : : * interpretations involving a type coercion followed by a function
1454 : : * call, otherwise we can produce surprising results. For example, we
1455 : : * want "text(varchar)" to be interpreted as a simple coercion, not as
1456 : : * "text(name(varchar))" which the code below this point is entirely
1457 : : * capable of selecting.
1458 : : *
1459 : : * We also treat a coercion of a previously-unknown-type literal
1460 : : * constant to a specific type this way.
1461 : : *
1462 : : * The reason we reject COERCION_PATH_FUNC here is that we expect the
1463 : : * cast implementation function to be named after the target type.
1464 : : * Thus the function will be found by normal lookup if appropriate.
1465 : : *
1466 : : * The reason we reject COERCION_PATH_ARRAYCOERCE is mainly that you
1467 : : * can't write "foo[] (something)" as a function call. In theory
1468 : : * someone might want to invoke it as "_foo (something)" but we have
1469 : : * never supported that historically, so we can insist that people
1470 : : * write it as a normal cast instead.
1471 : : *
1472 : : * We also reject the specific case of COERCEVIAIO for a composite
1473 : : * source type and a string-category target type. This is a case that
1474 : : * find_coercion_pathway() allows by default, but experience has shown
1475 : : * that it's too commonly invoked by mistake. So, again, insist that
1476 : : * people use cast syntax if they want to do that.
1477 : : *
1478 : : * NB: it's important that this code does not exceed what coerce_type
1479 : : * can do, because the caller will try to apply coerce_type if we
1480 : : * return FUNCDETAIL_COERCION. If we return that result for something
1481 : : * coerce_type can't handle, we'll cause infinite recursion between
1482 : : * this module and coerce_type!
1483 : : */
5812 1484 [ + + + + : 88305 : if (nargs == 1 && fargs != NIL && fargnames == NIL)
+ + ]
1485 : : {
6509 1486 : 30863 : Oid targetType = FuncNameAsType(funcname);
1487 : :
1488 [ + + ]: 30863 : if (OidIsValid(targetType))
1489 : : {
8738 1490 : 407 : Oid sourceType = argtypes[0];
7773 neilc@samurai.com 1491 : 407 : Node *arg1 = linitial(fargs);
1492 : : bool iscoercion;
1493 : :
6668 tgl@sss.pgh.pa.us 1494 [ + + + - ]: 407 : if (sourceType == UNKNOWNOID && IsA(arg1, Const))
1495 : : {
1496 : : /* always treat typename('literal') as coercion */
1497 : 269 : iscoercion = true;
1498 : : }
1499 : : else
1500 : : {
1501 : : CoercionPathType cpathtype;
1502 : : Oid cfuncid;
1503 : :
1504 : 138 : cpathtype = find_coercion_pathway(targetType, sourceType,
1505 : : COERCION_EXPLICIT,
1506 : : &cfuncid);
5417 1507 [ + + + ]: 138 : switch (cpathtype)
1508 : : {
1509 : 12 : case COERCION_PATH_RELABELTYPE:
1510 : 12 : iscoercion = true;
1511 : 12 : break;
1512 : 100 : case COERCION_PATH_COERCEVIAIO:
1513 [ + + + + ]: 194 : if ((sourceType == RECORDOID ||
1514 [ + - ]: 175 : ISCOMPLEX(sourceType)) &&
2999 1515 : 81 : TypeCategory(targetType) == TYPCATEGORY_STRING)
5417 1516 : 81 : iscoercion = false;
1517 : : else
1518 : 19 : iscoercion = true;
1519 : 100 : break;
1520 : 26 : default:
1521 : 26 : iscoercion = false;
1522 : 26 : break;
1523 : : }
1524 : : }
1525 : :
6668 1526 [ + + ]: 407 : if (iscoercion)
1527 : : {
1528 : : /* Treat it as a type coercion */
8738 1529 : 300 : *funcid = InvalidOid;
1530 : 300 : *rettype = targetType;
1531 : 300 : *retset = false;
6261 1532 : 300 : *nvargs = 0;
4174 1533 : 300 : *vatype = InvalidOid;
8738 1534 : 300 : *true_typeids = argtypes;
1535 : 300 : return FUNCDETAIL_COERCION;
1536 : : }
1537 : : }
1538 : : }
1539 : :
1540 : : /*
1541 : : * didn't find an exact match, so now try to match up candidates...
1542 : : */
8139 1543 [ + + ]: 88005 : if (raw_candidates != NULL)
1544 : : {
1545 : : FuncCandidateList current_candidates;
1546 : : int ncandidates;
1547 : :
7441 1548 : 87307 : ncandidates = func_match_argtypes(nargs,
1549 : : argtypes,
1550 : : raw_candidates,
1551 : : ¤t_candidates);
1552 : :
1553 : : /* one match only? then run with it... */
1554 [ + + ]: 87307 : if (ncandidates == 1)
1555 : 83715 : best_candidate = current_candidates;
1556 : :
1557 : : /*
1558 : : * multiple candidates? then better decide or throw an error...
1559 : : */
1560 [ + + ]: 3592 : else if (ncandidates > 1)
1561 : : {
1562 : 3338 : best_candidate = func_select_candidate(nargs,
1563 : : argtypes,
1564 : : current_candidates);
1565 : :
1566 : : /*
1567 : : * If we were able to choose a best candidate, we're done.
1568 : : * Otherwise, ambiguous function call.
1569 : : */
1570 [ - + ]: 3338 : if (!best_candidate)
8100 tgl@sss.pgh.pa.us 1571 :UBC 0 : return FUNCDETAIL_MULTIPLE;
1572 : : }
1573 : : }
1574 : : }
1575 : :
8554 tgl@sss.pgh.pa.us 1576 [ + + ]:CBC 189577 : if (best_candidate)
1577 : : {
1578 : : HeapTuple ftup;
1579 : : Form_pg_proc pform;
1580 : : FuncDetailCode result;
1581 : :
1582 : : /*
1583 : : * If processing named args or expanding variadics or defaults, the
1584 : : * "best candidate" might represent multiple equivalently good
1585 : : * functions; treat this case as ambiguous.
1586 : : */
6106 1587 [ + + ]: 188625 : if (!OidIsValid(best_candidate->oid))
1588 : 15 : return FUNCDETAIL_MULTIPLE;
1589 : :
1590 : : /*
1591 : : * We disallow VARIADIC with named arguments unless the last argument
1592 : : * (the one with VARIADIC attached) actually matched the variadic
1593 : : * parameter. This is mere pedantry, really, but some folks insisted.
1594 : : */
5812 1595 [ + + - + : 188610 : if (fargnames != NIL && !expand_variadic && nargs > 0 &&
- - ]
5812 tgl@sss.pgh.pa.us 1596 [ # # ]:UBC 0 : best_candidate->argnumbers[nargs - 1] != nargs - 1)
1597 : 0 : return FUNCDETAIL_NOTFOUND;
1598 : :
8554 tgl@sss.pgh.pa.us 1599 :CBC 188610 : *funcid = best_candidate->oid;
6261 1600 : 188610 : *nvargs = best_candidate->nvargs;
8554 1601 : 188610 : *true_typeids = best_candidate->args;
1602 : :
1603 : : /*
1604 : : * If processing named args, return actual argument positions into
1605 : : * NamedArgExpr nodes in the fargs list. This is a bit ugly but not
1606 : : * worth the extra notation needed to do it differently.
1607 : : */
5812 1608 [ + + ]: 188610 : if (best_candidate->argnumbers != NULL)
1609 : : {
1610 : 8151 : int i = 0;
1611 : : ListCell *lc;
1612 : :
1613 [ + + + + : 33153 : foreach(lc, fargs)
+ + ]
1614 : : {
1615 : 25002 : NamedArgExpr *na = (NamedArgExpr *) lfirst(lc);
1616 : :
1617 [ + + ]: 25002 : if (IsA(na, NamedArgExpr))
1618 : 23618 : na->argnumber = best_candidate->argnumbers[i];
1619 : 25002 : i++;
1620 : : }
1621 : : }
1622 : :
5683 rhaas@postgresql.org 1623 : 188610 : ftup = SearchSysCache1(PROCOID,
1624 : : ObjectIdGetDatum(best_candidate->oid));
8403 bruce@momjian.us 1625 [ - + ]: 188610 : if (!HeapTupleIsValid(ftup)) /* should not happen */
8086 tgl@sss.pgh.pa.us 1626 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for function %u",
1627 : : best_candidate->oid);
8554 tgl@sss.pgh.pa.us 1628 :CBC 188610 : pform = (Form_pg_proc) GETSTRUCT(ftup);
10147 bruce@momjian.us 1629 : 188610 : *rettype = pform->prorettype;
1630 : 188610 : *retset = pform->proretset;
4433 andrew@dunslane.net 1631 : 188610 : *vatype = pform->provariadic;
1632 : : /* fetch default args if caller wants 'em */
5812 tgl@sss.pgh.pa.us 1633 [ + + + + ]: 188610 : if (argdefaults && best_candidate->ndargs > 0)
1634 : : {
1635 : : Datum proargdefaults;
1636 : : char *str;
1637 : : List *defaults;
1638 : :
1639 : : /* shouldn't happen, FuncnameGetCandidates messed up */
1640 [ - + ]: 6858 : if (best_candidate->ndargs > pform->pronargdefaults)
5812 tgl@sss.pgh.pa.us 1641 [ # # ]:UBC 0 : elog(ERROR, "not enough default arguments");
1642 : :
896 dgustafsson@postgres 1643 :CBC 6858 : proargdefaults = SysCacheGetAttrNotNull(PROCOID, ftup,
1644 : : Anum_pg_proc_proargdefaults);
5812 tgl@sss.pgh.pa.us 1645 : 6858 : str = TextDatumGetCString(proargdefaults);
3119 peter_e@gmx.net 1646 : 6858 : defaults = castNode(List, stringToNode(str));
5812 tgl@sss.pgh.pa.us 1647 : 6858 : pfree(str);
1648 : :
1649 : : /* Delete any unused defaults from the returned list */
1650 [ + + ]: 6858 : if (best_candidate->argnumbers != NULL)
1651 : : {
1652 : : /*
1653 : : * This is a bit tricky in named notation, since the supplied
1654 : : * arguments could replace any subset of the defaults. We
1655 : : * work by making a bitmapset of the argnumbers of defaulted
1656 : : * arguments, then scanning the defaults list and selecting
1657 : : * the needed items. (This assumes that defaulted arguments
1658 : : * should be supplied in their positional order.)
1659 : : */
1660 : : Bitmapset *defargnumbers;
1661 : : int *firstdefarg;
1662 : : List *newdefaults;
1663 : : ListCell *lc;
1664 : : int i;
1665 : :
1666 : 3821 : defargnumbers = NULL;
1667 : 3821 : firstdefarg = &best_candidate->argnumbers[best_candidate->nargs - best_candidate->ndargs];
1668 [ + + ]: 11647 : for (i = 0; i < best_candidate->ndargs; i++)
1669 : 7826 : defargnumbers = bms_add_member(defargnumbers,
1670 : 7826 : firstdefarg[i]);
1671 : 3821 : newdefaults = NIL;
1549 1672 : 3821 : i = best_candidate->nominalnargs - pform->pronargdefaults;
5812 1673 [ + - + + : 21864 : foreach(lc, defaults)
+ + ]
1674 : : {
1675 [ + + ]: 18043 : if (bms_is_member(i, defargnumbers))
1676 : 7826 : newdefaults = lappend(newdefaults, lfirst(lc));
1677 : 18043 : i++;
1678 : : }
1679 [ - + ]: 3821 : Assert(list_length(newdefaults) == best_candidate->ndargs);
1680 : 3821 : bms_free(defargnumbers);
1681 : 3821 : *argdefaults = newdefaults;
1682 : : }
1683 : : else
1684 : : {
1685 : : /*
1686 : : * Defaults for positional notation are lots easier; just
1687 : : * remove any unwanted ones from the front.
1688 : : */
1689 : : int ndelete;
1690 : :
6106 1691 : 3037 : ndelete = list_length(defaults) - best_candidate->ndargs;
2245 1692 [ + + ]: 3037 : if (ndelete > 0)
1404 1693 : 108 : defaults = list_delete_first_n(defaults, ndelete);
6106 1694 : 3037 : *argdefaults = defaults;
1695 : : }
1696 : : }
1697 : :
2745 peter_e@gmx.net 1698 [ + + + + : 188610 : switch (pform->prokind)
- ]
1699 : : {
1700 : 22580 : case PROKIND_AGGREGATE:
1701 : 22580 : result = FUNCDETAIL_AGGREGATE;
1702 : 22580 : break;
1703 : 164789 : case PROKIND_FUNCTION:
1704 : 164789 : result = FUNCDETAIL_NORMAL;
1705 : 164789 : break;
1706 : 243 : case PROKIND_PROCEDURE:
1707 : 243 : result = FUNCDETAIL_PROCEDURE;
1708 : 243 : break;
1709 : 998 : case PROKIND_WINDOW:
1710 : 998 : result = FUNCDETAIL_WINDOWFUNC;
1711 : 998 : break;
2745 peter_e@gmx.net 1712 :UBC 0 : default:
1713 [ # # ]: 0 : elog(ERROR, "unrecognized prokind: %c", pform->prokind);
1714 : : result = FUNCDETAIL_NORMAL; /* keep compiler quiet */
1715 : : break;
1716 : : }
1717 : :
9060 tgl@sss.pgh.pa.us 1718 :CBC 188610 : ReleaseSysCache(ftup);
8549 1719 : 188610 : return result;
1720 : : }
1721 : :
8738 1722 : 952 : return FUNCDETAIL_NOTFOUND;
1723 : : }
1724 : :
1725 : :
1726 : : /*
1727 : : * unify_hypothetical_args()
1728 : : *
1729 : : * Ensure that each hypothetical direct argument of a hypothetical-set
1730 : : * aggregate has the same type as the corresponding aggregated argument.
1731 : : * Modify the expressions in the fargs list, if necessary, and update
1732 : : * actual_arg_types[].
1733 : : *
1734 : : * If the agg declared its args non-ANY (even ANYELEMENT), we need only a
1735 : : * sanity check that the declared types match; make_fn_arguments will coerce
1736 : : * the actual arguments to match the declared ones. But if the declaration
1737 : : * is ANY, nothing will happen in make_fn_arguments, so we need to fix any
1738 : : * mismatch here. We use the same type resolution logic as UNION etc.
1739 : : */
1740 : : static void
4275 1741 : 72 : unify_hypothetical_args(ParseState *pstate,
1742 : : List *fargs,
1743 : : int numAggregatedArgs,
1744 : : Oid *actual_arg_types,
1745 : : Oid *declared_arg_types)
1746 : : {
1747 : : int numDirectArgs,
1748 : : numNonHypotheticalArgs;
1749 : : int hargpos;
1750 : :
1751 : 72 : numDirectArgs = list_length(fargs) - numAggregatedArgs;
1752 : 72 : numNonHypotheticalArgs = numDirectArgs - numAggregatedArgs;
1753 : : /* safety check (should only trigger with a misdeclared agg) */
1754 [ - + ]: 72 : if (numNonHypotheticalArgs < 0)
4275 tgl@sss.pgh.pa.us 1755 [ # # ]:UBC 0 : elog(ERROR, "incorrect number of arguments to hypothetical-set aggregate");
1756 : :
1757 : : /* Check each hypothetical arg and corresponding aggregated arg */
2239 tgl@sss.pgh.pa.us 1758 [ + + ]:CBC 165 : for (hargpos = numNonHypotheticalArgs; hargpos < numDirectArgs; hargpos++)
1759 : : {
1760 : 99 : int aargpos = numDirectArgs + (hargpos - numNonHypotheticalArgs);
1761 : 99 : ListCell *harg = list_nth_cell(fargs, hargpos);
1762 : 99 : ListCell *aarg = list_nth_cell(fargs, aargpos);
1763 : : Oid commontype;
1764 : : int32 commontypmod;
1765 : :
1766 : : /* A mismatch means AggregateCreate didn't check properly ... */
1767 [ - + ]: 99 : if (declared_arg_types[hargpos] != declared_arg_types[aargpos])
4275 tgl@sss.pgh.pa.us 1768 [ # # ]:UBC 0 : elog(ERROR, "hypothetical-set aggregate has inconsistent declared argument types");
1769 : :
1770 : : /* No need to unify if make_fn_arguments will coerce */
2239 tgl@sss.pgh.pa.us 1771 [ - + ]:CBC 99 : if (declared_arg_types[hargpos] != ANYOID)
4275 tgl@sss.pgh.pa.us 1772 :UBC 0 : continue;
1773 : :
1774 : : /*
1775 : : * Select common type, giving preference to the aggregated argument's
1776 : : * type (we'd rather coerce the direct argument once than coerce all
1777 : : * the aggregated values).
1778 : : */
4275 tgl@sss.pgh.pa.us 1779 :CBC 99 : commontype = select_common_type(pstate,
2239 1780 : 99 : list_make2(lfirst(aarg), lfirst(harg)),
1781 : : "WITHIN GROUP",
1782 : : NULL);
1775 peter@eisentraut.org 1783 : 96 : commontypmod = select_common_typmod(pstate,
1784 : 96 : list_make2(lfirst(aarg), lfirst(harg)),
1785 : : commontype);
1786 : :
1787 : : /*
1788 : : * Perform the coercions. We don't need to worry about NamedArgExprs
1789 : : * here because they aren't supported with aggregates.
1790 : : */
2239 tgl@sss.pgh.pa.us 1791 : 189 : lfirst(harg) = coerce_type(pstate,
1792 : 96 : (Node *) lfirst(harg),
1793 : 96 : actual_arg_types[hargpos],
1794 : : commontype, commontypmod,
1795 : : COERCION_IMPLICIT,
1796 : : COERCE_IMPLICIT_CAST,
1797 : : -1);
1798 : 93 : actual_arg_types[hargpos] = commontype;
1799 : 186 : lfirst(aarg) = coerce_type(pstate,
1800 : 93 : (Node *) lfirst(aarg),
1801 : 93 : actual_arg_types[aargpos],
1802 : : commontype, commontypmod,
1803 : : COERCION_IMPLICIT,
1804 : : COERCE_IMPLICIT_CAST,
1805 : : -1);
4275 1806 : 93 : actual_arg_types[aargpos] = commontype;
1807 : : }
1808 : 66 : }
1809 : :
1810 : :
1811 : : /*
1812 : : * make_fn_arguments()
1813 : : *
1814 : : * Given the actual argument expressions for a function, and the desired
1815 : : * input types for the function, add any necessary typecasting to the
1816 : : * expression tree. Caller should already have verified that casting is
1817 : : * allowed.
1818 : : *
1819 : : * Caution: given argument list is modified in-place.
1820 : : *
1821 : : * As with coerce_type, pstate may be NULL if no special unknown-Param
1822 : : * processing is wanted.
1823 : : */
1824 : : void
8166 1825 : 511810 : make_fn_arguments(ParseState *pstate,
1826 : : List *fargs,
1827 : : Oid *actual_arg_types,
1828 : : Oid *declared_arg_types)
1829 : : {
1830 : : ListCell *current_fargs;
8187 1831 : 511810 : int i = 0;
1832 : :
1833 [ + + + + : 1497050 : foreach(current_fargs, fargs)
+ + ]
1834 : : {
1835 : : /* types don't match? then force coercion using a function call... */
1836 [ + + ]: 985278 : if (actual_arg_types[i] != declared_arg_types[i])
1837 : : {
5671 bruce@momjian.us 1838 : 298106 : Node *node = (Node *) lfirst(current_fargs);
1839 : :
1840 : : /*
1841 : : * If arg is a NamedArgExpr, coerce its input expr instead --- we
1842 : : * want the NamedArgExpr to stay at the top level of the list.
1843 : : */
5812 tgl@sss.pgh.pa.us 1844 [ + + ]: 298106 : if (IsA(node, NamedArgExpr))
1845 : : {
1846 : 11262 : NamedArgExpr *na = (NamedArgExpr *) node;
1847 : :
1848 : 11262 : node = coerce_type(pstate,
1849 : 11262 : (Node *) na->arg,
1850 : 11262 : actual_arg_types[i],
1851 : 11262 : declared_arg_types[i], -1,
1852 : : COERCION_IMPLICIT,
1853 : : COERCE_IMPLICIT_CAST,
1854 : : -1);
1855 : 11262 : na->arg = (Expr *) node;
1856 : : }
1857 : : else
1858 : : {
1859 : 286844 : node = coerce_type(pstate,
1860 : : node,
1861 : 286844 : actual_arg_types[i],
1862 : 286844 : declared_arg_types[i], -1,
1863 : : COERCION_IMPLICIT,
1864 : : COERCE_IMPLICIT_CAST,
1865 : : -1);
1866 : 286806 : lfirst(current_fargs) = node;
1867 : : }
1868 : : }
8187 1869 : 985240 : i++;
1870 : : }
10147 bruce@momjian.us 1871 : 511772 : }
1872 : :
1873 : : /*
1874 : : * FuncNameAsType -
1875 : : * convenience routine to see if a function name matches a type name
1876 : : *
1877 : : * Returns the OID of the matching type, or InvalidOid if none. We ignore
1878 : : * shell types and complex types.
1879 : : */
1880 : : static Oid
6509 tgl@sss.pgh.pa.us 1881 : 30863 : FuncNameAsType(List *funcname)
1882 : : {
1883 : : Oid result;
1884 : : Type typtup;
1885 : :
1886 : : /*
1887 : : * temp_ok=false protects the <refsect1 id="sql-createfunction-security">
1888 : : * contract for writing SECURITY DEFINER functions safely.
1889 : : */
2224 noah@leadboat.com 1890 : 30863 : typtup = LookupTypeNameExtended(NULL, makeTypeNameFromNameList(funcname),
1891 : : NULL, false, false);
6509 tgl@sss.pgh.pa.us 1892 [ + + ]: 30863 : if (typtup == NULL)
1893 : 30453 : return InvalidOid;
1894 : :
1895 [ + - + + ]: 820 : if (((Form_pg_type) GETSTRUCT(typtup))->typisdefined &&
1896 : 410 : !OidIsValid(typeTypeRelid(typtup)))
1897 : 407 : result = typeTypeId(typtup);
1898 : : else
1899 : 3 : result = InvalidOid;
1900 : :
1901 : 410 : ReleaseSysCache(typtup);
1902 : 410 : return result;
1903 : : }
1904 : :
1905 : : /*
1906 : : * ParseComplexProjection -
1907 : : * handles function calls with a single argument that is of complex type.
1908 : : * If the function call is actually a column projection, return a suitably
1909 : : * transformed expression tree. If not, return NULL.
1910 : : */
1911 : : static Node *
2867 peter_e@gmx.net 1912 : 5847 : ParseComplexProjection(ParseState *pstate, const char *funcname, Node *first_arg,
1913 : : int location)
1914 : : {
1915 : : TupleDesc tupdesc;
1916 : : int i;
1917 : :
1918 : : /*
1919 : : * Special case for whole-row Vars so that we can resolve (foo.*).bar even
1920 : : * when foo is a reference to a subselect, join, or RECORD function. A
1921 : : * bonus is that we avoid generating an unnecessary FieldSelect; our
1922 : : * result can omit the whole-row Var and just be a Var for the selected
1923 : : * field.
1924 : : *
1925 : : * This case could be handled by expandRecordVariable, but it's more
1926 : : * efficient to do it this way when possible.
1927 : : */
7827 tgl@sss.pgh.pa.us 1928 [ + + ]: 5847 : if (IsA(first_arg, Var) &&
1929 [ + + ]: 4707 : ((Var *) first_arg)->varattno == InvalidAttrNumber)
1930 : : {
1931 : : ParseNamespaceItem *nsitem;
1932 : :
2081 1933 : 90 : nsitem = GetNSItemByRangeTablePosn(pstate,
1934 : : ((Var *) first_arg)->varno,
1935 : 90 : ((Var *) first_arg)->varlevelsup);
1936 : : /* Return a Var if funcname matches a column, else NULL */
1937 : 90 : return scanNSItemForColumn(pstate, nsitem,
1938 : 90 : ((Var *) first_arg)->varlevelsup,
1939 : : funcname, location);
1940 : : }
1941 : :
1942 : : /*
1943 : : * Else do it the hard way with get_expr_result_tupdesc().
1944 : : *
1945 : : * If it's a Var of type RECORD, we have to work even harder: we have to
1946 : : * find what the Var refers to, and pass that to get_expr_result_tupdesc.
1947 : : * That task is handled by expandRecordVariable().
1948 : : */
7403 1949 [ + + ]: 5757 : if (IsA(first_arg, Var) &&
1950 [ + + ]: 4617 : ((Var *) first_arg)->vartype == RECORDOID)
1951 : 969 : tupdesc = expandRecordVariable(pstate, (Var *) first_arg, 0);
1952 : : else
2872 1953 : 4788 : tupdesc = get_expr_result_tupdesc(first_arg, true);
1954 [ + + ]: 5757 : if (!tupdesc)
7464 1955 : 1 : return NULL; /* unresolvable RECORD type */
1956 : :
1957 [ + + ]: 66608 : for (i = 0; i < tupdesc->natts; i++)
1958 : : {
2939 andres@anarazel.de 1959 : 66578 : Form_pg_attribute att = TupleDescAttr(tupdesc, i);
1960 : :
7464 tgl@sss.pgh.pa.us 1961 [ + + ]: 66578 : if (strcmp(funcname, NameStr(att->attname)) == 0 &&
1962 [ + - ]: 5726 : !att->attisdropped)
1963 : : {
1964 : : /* Success, so generate a FieldSelect expression */
1965 : 5726 : FieldSelect *fselect = makeNode(FieldSelect);
1966 : :
1967 : 5726 : fselect->arg = (Expr *) first_arg;
1968 : 5726 : fselect->fieldnum = i + 1;
1969 : 5726 : fselect->resulttype = att->atttypid;
1970 : 5726 : fselect->resulttypmod = att->atttypmod;
1971 : : /* save attribute's collation for parse_collate.c */
5285 1972 : 5726 : fselect->resultcollid = att->attcollation;
7464 1973 : 5726 : return (Node *) fselect;
1974 : : }
1975 : : }
1976 : :
1977 : 30 : return NULL; /* funcname does not match any column */
1978 : : }
1979 : :
1980 : : /*
1981 : : * funcname_signature_string
1982 : : * Build a string representing a function name, including arg types.
1983 : : * The result is something like "foo(integer)".
1984 : : *
1985 : : * If argnames isn't NIL, it is a list of C strings representing the actual
1986 : : * arg names for the last N arguments. This must be considered part of the
1987 : : * function signature too, when dealing with named-notation function calls.
1988 : : *
1989 : : * This is typically used in the construction of function-not-found error
1990 : : * messages.
1991 : : */
1992 : : const char *
5812 1993 : 396 : funcname_signature_string(const char *funcname, int nargs,
1994 : : List *argnames, const Oid *argtypes)
1995 : : {
1996 : : StringInfoData argbuf;
1997 : : int numposargs;
1998 : : ListCell *lc;
1999 : : int i;
2000 : :
8513 2001 : 396 : initStringInfo(&argbuf);
2002 : :
8084 2003 : 396 : appendStringInfo(&argbuf, "%s(", funcname);
2004 : :
5812 2005 : 396 : numposargs = nargs - list_length(argnames);
2006 : 396 : lc = list_head(argnames);
2007 : :
10147 bruce@momjian.us 2008 [ + + ]: 999 : for (i = 0; i < nargs; i++)
2009 : : {
2010 [ + + ]: 603 : if (i)
8171 tgl@sss.pgh.pa.us 2011 : 272 : appendStringInfoString(&argbuf, ", ");
5812 2012 [ + + ]: 603 : if (i >= numposargs)
2013 : : {
3781 rhaas@postgresql.org 2014 : 24 : appendStringInfo(&argbuf, "%s => ", (char *) lfirst(lc));
2245 tgl@sss.pgh.pa.us 2015 : 24 : lc = lnext(argnames, lc);
2016 : : }
5578 2017 : 603 : appendStringInfoString(&argbuf, format_type_be(argtypes[i]));
2018 : : }
2019 : :
8100 2020 : 396 : appendStringInfoChar(&argbuf, ')');
2021 : :
2022 : 396 : return argbuf.data; /* return palloc'd string buffer */
2023 : : }
2024 : :
2025 : : /*
2026 : : * func_signature_string
2027 : : * As above, but function name is passed as a qualified name list.
2028 : : */
2029 : : const char *
5812 2030 : 384 : func_signature_string(List *funcname, int nargs,
2031 : : List *argnames, const Oid *argtypes)
2032 : : {
8084 2033 : 384 : return funcname_signature_string(NameListToString(funcname),
2034 : : nargs, argnames, argtypes);
2035 : : }
2036 : :
2037 : : /*
2038 : : * LookupFuncNameInternal
2039 : : * Workhorse for LookupFuncName/LookupFuncWithArgs
2040 : : *
2041 : : * In an error situation, e.g. can't find the function, then we return
2042 : : * InvalidOid and set *lookupError to indicate what went wrong.
2043 : : *
2044 : : * Possible errors:
2045 : : * FUNCLOOKUP_NOSUCHFUNC: we can't find a function of this name.
2046 : : * FUNCLOOKUP_AMBIGUOUS: more than one function matches.
2047 : : */
2048 : : static Oid
1549 2049 : 21456 : LookupFuncNameInternal(ObjectType objtype, List *funcname,
2050 : : int nargs, const Oid *argtypes,
2051 : : bool include_out_arguments, bool missing_ok,
2052 : : FuncLookupError *lookupError)
2053 : : {
2054 : 21456 : Oid result = InvalidOid;
2055 : : FuncCandidateList clist;
2056 : :
2057 : : /* NULL argtypes allowed for nullary functions only */
2125 alvherre@alvh.no-ip. 2058 [ + + - + ]: 21456 : Assert(argtypes != NULL || nargs == 0);
2059 : :
2060 : : /* Always set *lookupError, to forestall uninitialized-variable warnings */
2361 tgl@sss.pgh.pa.us 2061 : 21456 : *lookupError = FUNCLOOKUP_NOSUCHFUNC;
2062 : :
2063 : : /* Get list of candidate objects */
2064 : 21456 : clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false,
2065 : : include_out_arguments, missing_ok);
2066 : :
2067 : : /* Scan list for a match to the arg types (if specified) and the objtype */
1549 2068 [ + + ]: 46694 : for (; clist != NULL; clist = clist->next)
2069 : : {
2070 : : /* Check arg type match, if specified */
2071 [ + + ]: 25280 : if (nargs >= 0)
2072 : : {
2073 : : /* if nargs==0, argtypes can be null; don't pass that to memcmp */
2074 [ + + ]: 25064 : if (nargs > 0 &&
2075 [ + + ]: 14170 : memcmp(argtypes, clist->args, nargs * sizeof(Oid)) != 0)
2076 : 4828 : continue;
2077 : : }
2078 : :
2079 : : /* Check for duplicates reported by FuncnameGetCandidates */
2080 [ + + ]: 20452 : if (!OidIsValid(clist->oid))
2081 : : {
2082 : 3 : *lookupError = FUNCLOOKUP_AMBIGUOUS;
2361 2083 : 3 : return InvalidOid;
2084 : : }
2085 : :
2086 : : /* Check objtype match, if specified */
1549 2087 [ + + + - ]: 20449 : switch (objtype)
2088 : : {
2089 : 11229 : case OBJECT_FUNCTION:
2090 : : case OBJECT_AGGREGATE:
2091 : : /* Ignore procedures */
2092 [ - + ]: 11229 : if (get_func_prokind(clist->oid) == PROKIND_PROCEDURE)
1549 tgl@sss.pgh.pa.us 2093 :UBC 0 : continue;
1549 tgl@sss.pgh.pa.us 2094 :CBC 11229 : break;
2095 : 91 : case OBJECT_PROCEDURE:
2096 : : /* Ignore non-procedures */
2097 [ + + ]: 91 : if (get_func_prokind(clist->oid) != PROKIND_PROCEDURE)
2098 : 6 : continue;
2099 : 85 : break;
2100 : 9129 : case OBJECT_ROUTINE:
2101 : : /* no restriction */
2102 : 9129 : break;
1549 tgl@sss.pgh.pa.us 2103 :UBC 0 : default:
2104 : 0 : Assert(false);
2105 : : }
2106 : :
2107 : : /* Check for multiple matches */
1549 tgl@sss.pgh.pa.us 2108 [ + + ]:CBC 20443 : if (OidIsValid(result))
2109 : : {
2110 : 21 : *lookupError = FUNCLOOKUP_AMBIGUOUS;
2111 : 21 : return InvalidOid;
2112 : : }
2113 : :
2114 : : /* OK, we have a candidate */
2115 : 20422 : result = clist->oid;
2116 : : }
2117 : :
2118 : 21414 : return result;
2119 : : }
2120 : :
2121 : : /*
2122 : : * LookupFuncName
2123 : : *
2124 : : * Given a possibly-qualified function name and optionally a set of argument
2125 : : * types, look up the function. Pass nargs == -1 to indicate that the number
2126 : : * and types of the arguments are unspecified (this is NOT the same as
2127 : : * specifying that there are no arguments).
2128 : : *
2129 : : * If the function name is not schema-qualified, it is sought in the current
2130 : : * namespace search path.
2131 : : *
2132 : : * If the function is not found, we return InvalidOid if missing_ok is true,
2133 : : * else raise an error.
2134 : : *
2135 : : * If nargs == -1 and multiple functions are found matching this function name
2136 : : * we will raise an ambiguous-function error, regardless of what missing_ok is
2137 : : * set to.
2138 : : *
2139 : : * Only functions will be found; procedures will be ignored even if they
2140 : : * match the name and argument types. (However, we don't trouble to reject
2141 : : * aggregates or window functions here.)
2142 : : */
2143 : : Oid
2361 2144 : 11959 : LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
2145 : : {
2146 : : Oid funcoid;
2147 : : FuncLookupError lookupError;
2148 : :
1549 2149 : 11959 : funcoid = LookupFuncNameInternal(OBJECT_FUNCTION,
2150 : : funcname, nargs, argtypes,
2151 : : false, missing_ok,
2152 : : &lookupError);
2153 : :
2361 2154 [ + + ]: 11959 : if (OidIsValid(funcoid))
2155 : 11070 : return funcoid;
2156 : :
2157 [ + - - ]: 889 : switch (lookupError)
2158 : : {
2159 : 889 : case FUNCLOOKUP_NOSUCHFUNC:
2160 : : /* Let the caller deal with it when missing_ok is true */
2161 [ + + ]: 889 : if (missing_ok)
2162 : 869 : return InvalidOid;
2163 : :
2164 [ - + ]: 20 : if (nargs < 0)
2361 tgl@sss.pgh.pa.us 2165 [ # # ]:UBC 0 : ereport(ERROR,
2166 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2167 : : errmsg("could not find a function named \"%s\"",
2168 : : NameListToString(funcname))));
2169 : : else
2361 tgl@sss.pgh.pa.us 2170 [ + - ]:CBC 20 : ereport(ERROR,
2171 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2172 : : errmsg("function %s does not exist",
2173 : : func_signature_string(funcname, nargs,
2174 : : NIL, argtypes))));
2175 : : break;
2176 : :
2361 tgl@sss.pgh.pa.us 2177 :UBC 0 : case FUNCLOOKUP_AMBIGUOUS:
2178 : : /* Raise an error regardless of missing_ok */
2179 [ # # ]: 0 : ereport(ERROR,
2180 : : (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2181 : : errmsg("function name \"%s\" is not unique",
2182 : : NameListToString(funcname)),
2183 : : errhint("Specify the argument list to select the function unambiguously.")));
2184 : : break;
2185 : : }
2186 : :
2187 : 0 : return InvalidOid; /* Keep compiler quiet */
2188 : : }
2189 : :
2190 : : /*
2191 : : * LookupFuncWithArgs
2192 : : *
2193 : : * Like LookupFuncName, but the argument types are specified by an
2194 : : * ObjectWithArgs node. Also, this function can check whether the result is a
2195 : : * function, procedure, or aggregate, based on the objtype argument. Pass
2196 : : * OBJECT_ROUTINE to accept any of them.
2197 : : *
2198 : : * For historical reasons, we also accept aggregates when looking for a
2199 : : * function.
2200 : : *
2201 : : * When missing_ok is true we don't generate any error for missing objects and
2202 : : * return InvalidOid. Other types of errors can still be raised, regardless
2203 : : * of the value of missing_ok.
2204 : : */
2205 : : Oid
2361 tgl@sss.pgh.pa.us 2206 :CBC 9454 : LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool missing_ok)
2207 : : {
2208 : : Oid argoids[FUNC_MAX_ARGS];
2209 : : int argcount;
2210 : : int nargs;
2211 : : int i;
2212 : : ListCell *args_item;
2213 : : Oid oid;
2214 : : FuncLookupError lookupError;
2215 : :
2837 peter_e@gmx.net 2216 [ + + + + : 9454 : Assert(objtype == OBJECT_AGGREGATE ||
+ + - + ]
2217 : : objtype == OBJECT_FUNCTION ||
2218 : : objtype == OBJECT_PROCEDURE ||
2219 : : objtype == OBJECT_ROUTINE);
2220 : :
3174 2221 : 9454 : argcount = list_length(func->objargs);
8551 tgl@sss.pgh.pa.us 2222 [ - + ]: 9454 : if (argcount > FUNC_MAX_ARGS)
2223 : : {
2361 tgl@sss.pgh.pa.us 2224 [ # # ]:UBC 0 : if (objtype == OBJECT_PROCEDURE)
2225 [ # # ]: 0 : ereport(ERROR,
2226 : : (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
2227 : : errmsg_plural("procedures cannot have more than %d argument",
2228 : : "procedures cannot have more than %d arguments",
2229 : : FUNC_MAX_ARGS,
2230 : : FUNC_MAX_ARGS)));
2231 : : else
2232 [ # # ]: 0 : ereport(ERROR,
2233 : : (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
2234 : : errmsg_plural("functions cannot have more than %d argument",
2235 : : "functions cannot have more than %d arguments",
2236 : : FUNC_MAX_ARGS,
2237 : : FUNC_MAX_ARGS)));
2238 : : }
2239 : :
2240 : : /*
2241 : : * First, perform a lookup considering only input arguments (traditional
2242 : : * Postgres rules).
2243 : : */
2382 tgl@sss.pgh.pa.us 2244 :CBC 9454 : i = 0;
2245 [ + + + + : 21280 : foreach(args_item, func->objargs)
+ + ]
2246 : : {
1549 2247 : 11841 : TypeName *t = lfirst_node(TypeName, args_item);
2248 : :
2361 2249 : 11841 : argoids[i] = LookupTypeNameOid(NULL, t, missing_ok);
2250 [ + + ]: 11838 : if (!OidIsValid(argoids[i]))
2251 : 12 : return InvalidOid; /* missing_ok must be true */
2252 : 11826 : i++;
2253 : : }
2254 : :
2255 : : /*
2256 : : * Set nargs for LookupFuncNameInternal. It expects -1 to mean no args
2257 : : * were specified.
2258 : : */
2259 [ + + ]: 9439 : nargs = func->args_unspecified ? -1 : argcount;
2260 : :
2261 : : /*
2262 : : * In args_unspecified mode, also tell LookupFuncNameInternal to consider
2263 : : * the object type, since there seems no reason not to. However, if we
2264 : : * have an argument list, disable the objtype check, because we'd rather
2265 : : * complain about "object is of wrong type" than "object doesn't exist".
2266 : : * (Note that with args, FuncnameGetCandidates will have ensured there's
2267 : : * only one argtype match, so we're not risking an ambiguity failure via
2268 : : * this choice.)
2269 : : */
1549 2270 [ + + ]: 9439 : oid = LookupFuncNameInternal(func->args_unspecified ? objtype : OBJECT_ROUTINE,
2271 : : func->objname, nargs, argoids,
2272 : : false, missing_ok,
2273 : : &lookupError);
2274 : :
2275 : : /*
2276 : : * If PROCEDURE or ROUTINE was specified, and we have an argument list
2277 : : * that contains no parameter mode markers, and we didn't already discover
2278 : : * that there's ambiguity, perform a lookup considering all arguments.
2279 : : * (Note: for a zero-argument procedure, or in args_unspecified mode, the
2280 : : * normal lookup is sufficient; so it's OK to require non-NIL objfuncargs
2281 : : * to perform this lookup.)
2282 : : */
2283 [ + + + + ]: 9421 : if ((objtype == OBJECT_PROCEDURE || objtype == OBJECT_ROUTINE) &&
2284 [ + + ]: 160 : func->objfuncargs != NIL &&
2285 [ + - ]: 76 : lookupError != FUNCLOOKUP_AMBIGUOUS)
2286 : : {
2287 : 76 : bool have_param_mode = false;
2288 : :
2289 : : /*
2290 : : * Check for non-default parameter mode markers. If there are any,
2291 : : * then the command does not conform to SQL-spec syntax, so we may
2292 : : * assume that the traditional Postgres lookup method of considering
2293 : : * only input parameters is sufficient. (Note that because the spec
2294 : : * doesn't have OUT arguments for functions, we also don't need this
2295 : : * hack in FUNCTION or AGGREGATE mode.)
2296 : : */
2297 [ + - + + : 152 : foreach(args_item, func->objfuncargs)
+ + ]
2298 : : {
2299 : 94 : FunctionParameter *fp = lfirst_node(FunctionParameter, args_item);
2300 : :
2301 [ + + ]: 94 : if (fp->mode != FUNC_PARAM_DEFAULT)
2302 : : {
2303 : 18 : have_param_mode = true;
2304 : 18 : break;
2305 : : }
2306 : : }
2307 : :
2308 [ + + ]: 76 : if (!have_param_mode)
2309 : : {
2310 : : Oid poid;
2311 : :
2312 : : /* Without mode marks, objargs surely includes all params */
2313 [ - + ]: 58 : Assert(list_length(func->objfuncargs) == argcount);
2314 : :
2315 : : /* For objtype == OBJECT_PROCEDURE, we can ignore non-procedures */
2316 : 58 : poid = LookupFuncNameInternal(objtype, func->objname,
2317 : : argcount, argoids,
2318 : : true, missing_ok,
2319 : : &lookupError);
2320 : :
2321 : : /* Combine results, handling ambiguity */
2322 [ + + ]: 58 : if (OidIsValid(poid))
2323 : : {
2324 [ + + - + ]: 49 : if (OidIsValid(oid) && oid != poid)
2325 : : {
2326 : : /* oops, we got hits both ways, on different objects */
1549 tgl@sss.pgh.pa.us 2327 :UBC 0 : oid = InvalidOid;
2328 : 0 : lookupError = FUNCLOOKUP_AMBIGUOUS;
2329 : : }
2330 : : else
1549 tgl@sss.pgh.pa.us 2331 :CBC 49 : oid = poid;
2332 : : }
2333 [ + + ]: 9 : else if (lookupError == FUNCLOOKUP_AMBIGUOUS)
2334 : 3 : oid = InvalidOid;
2335 : : }
2336 : : }
2337 : :
2361 2338 [ + + ]: 9421 : if (OidIsValid(oid))
2339 : : {
2340 : : /*
2341 : : * Even if we found the function, perform validation that the objtype
2342 : : * matches the prokind of the found function. For historical reasons
2343 : : * we allow the objtype of FUNCTION to include aggregates and window
2344 : : * functions; but we draw the line if the object is a procedure. That
2345 : : * is a new enough feature that this historical rule does not apply.
2346 : : *
2347 : : * (This check is partially redundant with the objtype check in
2348 : : * LookupFuncNameInternal; but not entirely, since we often don't tell
2349 : : * LookupFuncNameInternal to apply that check at all.)
2350 : : */
2351 [ + + + + ]: 9282 : switch (objtype)
2352 : : {
2353 : 9000 : case OBJECT_FUNCTION:
2354 : : /* Only complain if it's a procedure. */
2355 [ + + ]: 9000 : if (get_func_prokind(oid) == PROKIND_PROCEDURE)
2356 [ + - ]: 9 : ereport(ERROR,
2357 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2358 : : errmsg("%s is not a function",
2359 : : func_signature_string(func->objname, argcount,
2360 : : NIL, argoids))));
2361 : 8991 : break;
2362 : :
2363 : 106 : case OBJECT_PROCEDURE:
2364 : : /* Reject if found object is not a procedure. */
2365 [ + + ]: 106 : if (get_func_prokind(oid) != PROKIND_PROCEDURE)
2366 [ + - ]: 6 : ereport(ERROR,
2367 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2368 : : errmsg("%s is not a procedure",
2369 : : func_signature_string(func->objname, argcount,
2370 : : NIL, argoids))));
2371 : 100 : break;
2372 : :
2373 : 155 : case OBJECT_AGGREGATE:
2374 : : /* Reject if found object is not an aggregate. */
2375 [ + + ]: 155 : if (get_func_prokind(oid) != PROKIND_AGGREGATE)
2376 [ + - ]: 9 : ereport(ERROR,
2377 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2378 : : errmsg("function %s is not an aggregate",
2379 : : func_signature_string(func->objname, argcount,
2380 : : NIL, argoids))));
2381 : 146 : break;
2382 : :
2383 : 21 : default:
2384 : : /* OBJECT_ROUTINE accepts anything. */
2385 : 21 : break;
2386 : : }
2387 : :
2388 : 9258 : return oid; /* All good */
2389 : : }
2390 : : else
2391 : : {
2392 : : /* Deal with cases where the lookup failed */
2393 [ + + - ]: 139 : switch (lookupError)
2394 : : {
2395 : 115 : case FUNCLOOKUP_NOSUCHFUNC:
2396 : : /* Suppress no-such-func errors when missing_ok is true */
2397 [ + + ]: 115 : if (missing_ok)
2398 : 26 : break;
2399 : :
2400 [ + + + ]: 89 : switch (objtype)
2401 : : {
2402 : 18 : case OBJECT_PROCEDURE:
2403 [ - + ]: 18 : if (func->args_unspecified)
2361 tgl@sss.pgh.pa.us 2404 [ # # ]:UBC 0 : ereport(ERROR,
2405 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2406 : : errmsg("could not find a procedure named \"%s\"",
2407 : : NameListToString(func->objname))));
2408 : : else
2361 tgl@sss.pgh.pa.us 2409 [ + - ]:CBC 18 : ereport(ERROR,
2410 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2411 : : errmsg("procedure %s does not exist",
2412 : : func_signature_string(func->objname, argcount,
2413 : : NIL, argoids))));
2414 : : break;
2415 : :
2416 : 30 : case OBJECT_AGGREGATE:
2417 [ - + ]: 30 : if (func->args_unspecified)
2361 tgl@sss.pgh.pa.us 2418 [ # # ]:UBC 0 : ereport(ERROR,
2419 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2420 : : errmsg("could not find an aggregate named \"%s\"",
2421 : : NameListToString(func->objname))));
2361 tgl@sss.pgh.pa.us 2422 [ + + ]:CBC 30 : else if (argcount == 0)
2423 [ + - ]: 12 : ereport(ERROR,
2424 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2425 : : errmsg("aggregate %s(*) does not exist",
2426 : : NameListToString(func->objname))));
2427 : : else
2428 [ + - ]: 18 : ereport(ERROR,
2429 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2430 : : errmsg("aggregate %s does not exist",
2431 : : func_signature_string(func->objname, argcount,
2432 : : NIL, argoids))));
2433 : : break;
2434 : :
2435 : 41 : default:
2436 : : /* FUNCTION and ROUTINE */
2437 [ + + ]: 41 : if (func->args_unspecified)
2438 [ + - ]: 3 : ereport(ERROR,
2439 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2440 : : errmsg("could not find a function named \"%s\"",
2441 : : NameListToString(func->objname))));
2442 : : else
2443 [ + - ]: 38 : ereport(ERROR,
2444 : : (errcode(ERRCODE_UNDEFINED_FUNCTION),
2445 : : errmsg("function %s does not exist",
2446 : : func_signature_string(func->objname, argcount,
2447 : : NIL, argoids))));
2448 : : break;
2449 : : }
2450 : : break;
2451 : :
2452 : 24 : case FUNCLOOKUP_AMBIGUOUS:
2453 [ + + - + : 24 : switch (objtype)
- ]
2454 : : {
2455 : 9 : case OBJECT_FUNCTION:
2456 [ + - + - ]: 9 : ereport(ERROR,
2457 : : (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2458 : : errmsg("function name \"%s\" is not unique",
2459 : : NameListToString(func->objname)),
2460 : : func->args_unspecified ?
2461 : : errhint("Specify the argument list to select the function unambiguously.") : 0));
2462 : : break;
2463 : 12 : case OBJECT_PROCEDURE:
2464 [ + - + + ]: 12 : ereport(ERROR,
2465 : : (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2466 : : errmsg("procedure name \"%s\" is not unique",
2467 : : NameListToString(func->objname)),
2468 : : func->args_unspecified ?
2469 : : errhint("Specify the argument list to select the procedure unambiguously.") : 0));
2470 : : break;
2361 tgl@sss.pgh.pa.us 2471 :UBC 0 : case OBJECT_AGGREGATE:
2472 [ # # # # ]: 0 : ereport(ERROR,
2473 : : (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2474 : : errmsg("aggregate name \"%s\" is not unique",
2475 : : NameListToString(func->objname)),
2476 : : func->args_unspecified ?
2477 : : errhint("Specify the argument list to select the aggregate unambiguously.") : 0));
2478 : : break;
2361 tgl@sss.pgh.pa.us 2479 :CBC 3 : case OBJECT_ROUTINE:
2480 [ + - + - ]: 3 : ereport(ERROR,
2481 : : (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2482 : : errmsg("routine name \"%s\" is not unique",
2483 : : NameListToString(func->objname)),
2484 : : func->args_unspecified ?
2485 : : errhint("Specify the argument list to select the routine unambiguously.") : 0));
2486 : : break;
2487 : :
2361 tgl@sss.pgh.pa.us 2488 :UBC 0 : default:
2489 : 0 : Assert(false); /* Disallowed by Assert above */
2490 : : break;
2491 : : }
2492 : : break;
2493 : : }
2494 : :
2361 tgl@sss.pgh.pa.us 2495 :CBC 26 : return InvalidOid;
2496 : : }
2497 : : }
2498 : :
2499 : : /*
2500 : : * check_srf_call_placement
2501 : : * Verify that a set-returning function is called in a valid place,
2502 : : * and throw a nice error if not.
2503 : : *
2504 : : * A side-effect is to set pstate->p_hasTargetSRFs true if appropriate.
2505 : : *
2506 : : * last_srf should be a copy of pstate->p_last_srf from just before we
2507 : : * started transforming the function's arguments. This allows detection
2508 : : * of whether the SRF's arguments contain any SRFs.
2509 : : */
2510 : : void
3007 2511 : 26465 : check_srf_call_placement(ParseState *pstate, Node *last_srf, int location)
2512 : : {
2513 : : const char *err;
2514 : : bool errkind;
2515 : :
2516 : : /*
2517 : : * Check to see if the set-returning function is in an invalid place
2518 : : * within the query. Basically, we don't allow SRFs anywhere except in
2519 : : * the targetlist (which includes GROUP BY/ORDER BY expressions), VALUES,
2520 : : * and functions in FROM.
2521 : : *
2522 : : * For brevity we support two schemes for reporting an error here: set
2523 : : * "err" to a custom message, or set "errkind" true if the error context
2524 : : * is sufficiently identified by what ParseExprKindName will return, *and*
2525 : : * what it will return is just a SQL keyword. (Otherwise, use a custom
2526 : : * message to avoid creating translation problems.)
2527 : : */
3280 2528 : 26465 : err = NULL;
2529 : 26465 : errkind = false;
2530 [ - - - - : 26465 : switch (pstate->p_expr_kind)
+ - - - -
+ - + + +
- + + + +
- - + - -
- - - - +
+ - + + -
- ]
2531 : : {
3280 tgl@sss.pgh.pa.us 2532 :UBC 0 : case EXPR_KIND_NONE:
2533 : 0 : Assert(false); /* can't happen */
2534 : : break;
2535 : 0 : case EXPR_KIND_OTHER:
2536 : : /* Accept SRF here; caller must throw error if wanted */
2537 : 0 : break;
2538 : 0 : case EXPR_KIND_JOIN_ON:
2539 : : case EXPR_KIND_JOIN_USING:
2540 : 0 : err = _("set-returning functions are not allowed in JOIN conditions");
2541 : 0 : break;
2542 : 0 : case EXPR_KIND_FROM_SUBSELECT:
2543 : : /* can't get here, but just in case, throw an error */
2544 : 0 : errkind = true;
2545 : 0 : break;
3280 tgl@sss.pgh.pa.us 2546 :CBC 19366 : case EXPR_KIND_FROM_FUNCTION:
2547 : : /* okay, but we don't allow nested SRFs here */
2548 : : /* errmsg is chosen to match transformRangeFunction() */
2549 : : /* errposition should point to the inner SRF */
3007 2550 [ + + ]: 19366 : if (pstate->p_last_srf != last_srf)
2551 [ + - ]: 3 : ereport(ERROR,
2552 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2553 : : errmsg("set-returning functions must appear at top level of FROM"),
2554 : : parser_errposition(pstate,
2555 : : exprLocation(pstate->p_last_srf))));
3280 2556 : 19363 : break;
3280 tgl@sss.pgh.pa.us 2557 :UBC 0 : case EXPR_KIND_WHERE:
2558 : 0 : errkind = true;
2559 : 0 : break;
2560 : 0 : case EXPR_KIND_POLICY:
2561 : 0 : err = _("set-returning functions are not allowed in policy expressions");
2562 : 0 : break;
2563 : 0 : case EXPR_KIND_HAVING:
2564 : 0 : errkind = true;
2565 : 0 : break;
2566 : 0 : case EXPR_KIND_FILTER:
2567 : 0 : errkind = true;
2568 : 0 : break;
3280 tgl@sss.pgh.pa.us 2569 :CBC 6 : case EXPR_KIND_WINDOW_PARTITION:
2570 : : case EXPR_KIND_WINDOW_ORDER:
2571 : : /* okay, these are effectively GROUP BY/ORDER BY */
2572 : 6 : pstate->p_hasTargetSRFs = true;
2573 : 6 : break;
3280 tgl@sss.pgh.pa.us 2574 :UBC 0 : case EXPR_KIND_WINDOW_FRAME_RANGE:
2575 : : case EXPR_KIND_WINDOW_FRAME_ROWS:
2576 : : case EXPR_KIND_WINDOW_FRAME_GROUPS:
2577 : 0 : err = _("set-returning functions are not allowed in window definitions");
2578 : 0 : break;
3280 tgl@sss.pgh.pa.us 2579 :CBC 6998 : case EXPR_KIND_SELECT_TARGET:
2580 : : case EXPR_KIND_INSERT_TARGET:
2581 : : /* okay */
2582 : 6998 : pstate->p_hasTargetSRFs = true;
2583 : 6998 : break;
2584 : 3 : case EXPR_KIND_UPDATE_SOURCE:
2585 : : case EXPR_KIND_UPDATE_TARGET:
2586 : : /* disallowed because it would be ambiguous what to do */
2587 : 3 : errkind = true;
2588 : 3 : break;
2589 : 18 : case EXPR_KIND_GROUP_BY:
2590 : : case EXPR_KIND_ORDER_BY:
2591 : : /* okay */
2592 : 18 : pstate->p_hasTargetSRFs = true;
2593 : 18 : break;
3280 tgl@sss.pgh.pa.us 2594 :UBC 0 : case EXPR_KIND_DISTINCT_ON:
2595 : : /* okay */
2596 : 0 : pstate->p_hasTargetSRFs = true;
2597 : 0 : break;
3280 tgl@sss.pgh.pa.us 2598 :CBC 3 : case EXPR_KIND_LIMIT:
2599 : : case EXPR_KIND_OFFSET:
2600 : 3 : errkind = true;
2601 : 3 : break;
2602 : 3 : case EXPR_KIND_RETURNING:
2603 : : case EXPR_KIND_MERGE_RETURNING:
2604 : 3 : errkind = true;
2605 : 3 : break;
2606 : 3 : case EXPR_KIND_VALUES:
2607 : : /* SRFs are presently not supported by nodeValuesscan.c */
3155 2608 : 3 : errkind = true;
2609 : 3 : break;
2610 : 44 : case EXPR_KIND_VALUES_SINGLE:
2611 : : /* okay, since we process this like a SELECT tlist */
2612 : 44 : pstate->p_hasTargetSRFs = true;
3280 2613 : 44 : break;
1258 alvherre@alvh.no-ip. 2614 :UBC 0 : case EXPR_KIND_MERGE_WHEN:
2615 : 0 : err = _("set-returning functions are not allowed in MERGE WHEN conditions");
2616 : 0 : break;
3280 tgl@sss.pgh.pa.us 2617 : 0 : case EXPR_KIND_CHECK_CONSTRAINT:
2618 : : case EXPR_KIND_DOMAIN_CHECK:
2619 : 0 : err = _("set-returning functions are not allowed in check constraints");
2620 : 0 : break;
3280 tgl@sss.pgh.pa.us 2621 :CBC 3 : case EXPR_KIND_COLUMN_DEFAULT:
2622 : : case EXPR_KIND_FUNCTION_DEFAULT:
2623 : 3 : err = _("set-returning functions are not allowed in DEFAULT expressions");
2624 : 3 : break;
3280 tgl@sss.pgh.pa.us 2625 :UBC 0 : case EXPR_KIND_INDEX_EXPRESSION:
2626 : 0 : err = _("set-returning functions are not allowed in index expressions");
2627 : 0 : break;
2628 : 0 : case EXPR_KIND_INDEX_PREDICATE:
2629 : 0 : err = _("set-returning functions are not allowed in index predicates");
2630 : 0 : break;
1625 tomas.vondra@postgre 2631 : 0 : case EXPR_KIND_STATS_EXPRESSION:
2632 : 0 : err = _("set-returning functions are not allowed in statistics expressions");
2633 : 0 : break;
3280 tgl@sss.pgh.pa.us 2634 : 0 : case EXPR_KIND_ALTER_COL_TRANSFORM:
2635 : 0 : err = _("set-returning functions are not allowed in transform expressions");
2636 : 0 : break;
2637 : 0 : case EXPR_KIND_EXECUTE_PARAMETER:
2638 : 0 : err = _("set-returning functions are not allowed in EXECUTE parameters");
2639 : 0 : break;
2640 : 0 : case EXPR_KIND_TRIGGER_WHEN:
2641 : 0 : err = _("set-returning functions are not allowed in trigger WHEN conditions");
2642 : 0 : break;
2416 peter@eisentraut.org 2643 :CBC 6 : case EXPR_KIND_PARTITION_BOUND:
2644 : 6 : err = _("set-returning functions are not allowed in partition bound");
2645 : 6 : break;
3195 rhaas@postgresql.org 2646 : 3 : case EXPR_KIND_PARTITION_EXPRESSION:
3007 tgl@sss.pgh.pa.us 2647 : 3 : err = _("set-returning functions are not allowed in partition key expressions");
3195 rhaas@postgresql.org 2648 : 3 : break;
2765 tgl@sss.pgh.pa.us 2649 :UBC 0 : case EXPR_KIND_CALL_ARGUMENT:
2837 peter_e@gmx.net 2650 : 0 : err = _("set-returning functions are not allowed in CALL arguments");
2651 : 0 : break;
2422 tomas.vondra@postgre 2652 :CBC 3 : case EXPR_KIND_COPY_WHERE:
2653 : 3 : err = _("set-returning functions are not allowed in COPY FROM WHERE conditions");
2654 : 3 : break;
2352 peter@eisentraut.org 2655 : 6 : case EXPR_KIND_GENERATED_COLUMN:
2656 : 6 : err = _("set-returning functions are not allowed in column generation expressions");
2657 : 6 : break;
1678 peter@eisentraut.org 2658 :UBC 0 : case EXPR_KIND_CYCLE_MARK:
2659 : 0 : errkind = true;
2660 : 0 : break;
2661 : :
2662 : : /*
2663 : : * There is intentionally no default: case here, so that the
2664 : : * compiler will warn if we add a new ParseExprKind without
2665 : : * extending this switch. If we do see an unrecognized value at
2666 : : * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
2667 : : * which is sane anyway.
2668 : : */
2669 : : }
3280 tgl@sss.pgh.pa.us 2670 [ + + ]:CBC 26462 : if (err)
2671 [ + - ]: 21 : ereport(ERROR,
2672 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2673 : : errmsg_internal("%s", err),
2674 : : parser_errposition(pstate, location)));
2675 [ + + ]: 26441 : if (errkind)
2676 [ + - ]: 12 : ereport(ERROR,
2677 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2678 : : /* translator: %s is name of a SQL construct, eg GROUP BY */
2679 : : errmsg("set-returning functions are not allowed in %s",
2680 : : ParseExprKindName(pstate->p_expr_kind)),
2681 : : parser_errposition(pstate, location)));
2682 : 26429 : }
|