@@ -68,6 +68,9 @@ static Node *ParseComplexProjection(ParseState *pstate, const char *funcname,
68
68
*last_srf should be a copy of pstate->p_last_srf from just before we
69
69
*started transforming fargs. If the caller knows that fargs couldn't
70
70
*contain any SRF calls, last_srf can just be pstate->p_last_srf.
71
+ *
72
+ *proc_call is true if we are considering a CALL statement, so that the
73
+ *name must resolve to a procedure name, not anything else.
71
74
*/
72
75
Node *
73
76
ParseFuncOrColumn (ParseState * pstate ,List * funcname ,List * fargs ,
@@ -204,7 +207,8 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
204
207
* the "function call" could be a projection. We also check that there
205
208
* wasn't any aggregate or variadic decoration, nor an argument name.
206
209
*/
207
- if (nargs == 1 && agg_order == NIL && agg_filter == NULL && !agg_star &&
210
+ if (nargs == 1 && !proc_call &&
211
+ agg_order == NIL && agg_filter == NULL && !agg_star &&
208
212
!agg_distinct && over == NULL && !func_variadic && argnames == NIL &&
209
213
list_length (funcname )== 1 )
210
214
{
@@ -253,21 +257,42 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
253
257
254
258
cancel_parser_errposition_callback (& pcbstate );
255
259
256
- if (fdresult == FUNCDETAIL_COERCION )
257
- {
258
- /*
259
- * We interpreted it as a type coercion. coerce_type can handle these
260
- * cases, so why duplicate code...
261
- */
262
- return coerce_type (pstate ,linitial (fargs ),
263
- actual_arg_types [0 ],rettype ,-1 ,
264
- COERCION_EXPLICIT ,COERCE_EXPLICIT_CALL ,location );
265
- }
266
- else if (fdresult == FUNCDETAIL_NORMAL || fdresult == FUNCDETAIL_PROCEDURE )
260
+ /*
261
+ * Check for various wrong-kind-of-routine cases.
262
+ */
263
+
264
+ /* If this is a CALL, reject things that aren't procedures */
265
+ if (proc_call &&
266
+ (fdresult == FUNCDETAIL_NORMAL ||
267
+ fdresult == FUNCDETAIL_AGGREGATE ||
268
+ fdresult == FUNCDETAIL_WINDOWFUNC ||
269
+ fdresult == FUNCDETAIL_COERCION ))
270
+ ereport (ERROR ,
271
+ (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
272
+ errmsg ("%s is not a procedure" ,
273
+ func_signature_string (funcname ,nargs ,
274
+ argnames ,
275
+ actual_arg_types )),
276
+ errhint ("To call a function, use SELECT." ),
277
+ parser_errposition (pstate ,location )));
278
+ /* Conversely, if not a CALL, reject procedures */
279
+ if (fdresult == FUNCDETAIL_PROCEDURE && !proc_call )
280
+ ereport (ERROR ,
281
+ (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
282
+ errmsg ("%s is a procedure" ,
283
+ func_signature_string (funcname ,nargs ,
284
+ argnames ,
285
+ actual_arg_types )),
286
+ errhint ("To call a procedure, use CALL." ),
287
+ parser_errposition (pstate ,location )));
288
+
289
+ if (fdresult == FUNCDETAIL_NORMAL ||
290
+ fdresult == FUNCDETAIL_PROCEDURE ||
291
+ fdresult == FUNCDETAIL_COERCION )
267
292
{
268
293
/*
269
- *Normal function found; was there anything indicating it must be an
270
- * aggregate?
294
+ *In these cases, complain if therewas anything indicating it must
295
+ *be an aggregate or window function.
271
296
*/
272
297
if (agg_star )
273
298
ereport (ERROR ,
@@ -306,26 +331,14 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
306
331
errmsg ("OVER specified, but %s is not a window function nor an aggregate function" ,
307
332
NameListToString (funcname )),
308
333
parser_errposition (pstate ,location )));
334
+ }
309
335
310
- if (fdresult == FUNCDETAIL_NORMAL && proc_call )
311
- ereport (ERROR ,
312
- (errcode (ERRCODE_UNDEFINED_FUNCTION ),
313
- errmsg ("%s is not a procedure" ,
314
- func_signature_string (funcname ,nargs ,
315
- argnames ,
316
- actual_arg_types )),
317
- errhint ("To call a function, use SELECT." ),
318
- parser_errposition (pstate ,location )));
319
-
320
- if (fdresult == FUNCDETAIL_PROCEDURE && !proc_call )
321
- ereport (ERROR ,
322
- (errcode (ERRCODE_UNDEFINED_FUNCTION ),
323
- errmsg ("%s is a procedure" ,
324
- func_signature_string (funcname ,nargs ,
325
- argnames ,
326
- actual_arg_types )),
327
- errhint ("To call a procedure, use CALL." ),
328
- parser_errposition (pstate ,location )));
336
+ /*
337
+ * So far so good, so do some routine-type-specific processing.
338
+ */
339
+ if (fdresult == FUNCDETAIL_NORMAL || fdresult == FUNCDETAIL_PROCEDURE )
340
+ {
341
+ /* Nothing special to do for these cases. */
329
342
}
330
343
else if (fdresult == FUNCDETAIL_AGGREGATE )
331
344
{
@@ -336,15 +349,6 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
336
349
Form_pg_aggregate classForm ;
337
350
int catDirectArgs ;
338
351
339
- if (proc_call )
340
- ereport (ERROR ,
341
- (errcode (ERRCODE_UNDEFINED_FUNCTION ),
342
- errmsg ("%s is not a procedure" ,
343
- func_signature_string (funcname ,nargs ,
344
- argnames ,
345
- actual_arg_types )),
346
- parser_errposition (pstate ,location )));
347
-
348
352
tup = SearchSysCache1 (AGGFNOID ,ObjectIdGetDatum (funcid ));
349
353
if (!HeapTupleIsValid (tup ))/* should not happen */
350
354
elog (ERROR ,"cache lookup failed for aggregate %u" ,funcid );
@@ -510,6 +514,16 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
510
514
NameListToString (funcname )),
511
515
parser_errposition (pstate ,location )));
512
516
}
517
+ else if (fdresult == FUNCDETAIL_COERCION )
518
+ {
519
+ /*
520
+ * We interpreted it as a type coercion. coerce_type can handle these
521
+ * cases, so why duplicate code...
522
+ */
523
+ return coerce_type (pstate ,linitial (fargs ),
524
+ actual_arg_types [0 ],rettype ,-1 ,
525
+ COERCION_EXPLICIT ,COERCE_EXPLICIT_CALL ,location );
526
+ }
513
527
else
514
528
{
515
529
/*