/* * Parse a function call * * For historical reasons, Postgres tries to treat the notations tab.col * and col(tab) as equivalent: if a single-argument function call has an * argument of complex type and the (unqualified) function name matches * any attribute of the type, we take it as a column projection. Conversely * a function of a single complex-type argument can be written like a * column reference, allowing functions to act like computed columns. * * Hence, both cases come through here. The is_column parameter tells us * which syntactic construct is actually being dealt with, but this is * intended to be used only to deliver an appropriate error message, * not to affect the semantics. When is_column is true, we should have * a single argument (the putative table), unqualified function name * equal to the column name, and no aggregate or variadic decoration. * * The argument expressions (in fargs) must have been transformed already. */ Node * ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, bool agg_star, bool agg_distinct, bool func_variadic, WindowDef *over, bool is_column, int location) { Oid rettype; Oid funcid; ListCell *l; ListCell *nextl; Node *first_arg = NULL; int nargs; int nargsplusdefs; Oid actual_arg_types[FUNC_MAX_ARGS]; Oid *declared_arg_types; List *argdefaults; Node *retval; bool retset; int nvargs; FuncDetailCode fdresult; /* * Most of the rest of the parser just assumes that functions do not have * more than FUNC_MAX_ARGS parameters. We have to test here to protect * against array overruns, etc. Of course, this may not be a function, * but the test doesn't hurt. */ if (list_length(fargs) > FUNC_MAX_ARGS) ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), errmsg_plural("cannot pass more than %d argument to a function", "cannot pass more than %d arguments to a function", FUNC_MAX_ARGS, FUNC_MAX_ARGS), parser_errposition(pstate, location))); /* * Extract arg type info in preparation for function lookup. * * If any arguments are Param markers of type VOID, we discard them from * the parameter list. This is a hack to allow the JDBC driver to not * have to distinguish "input" and "output" parameter symbols while * parsing function-call constructs. We can't use foreach() because we * may modify the list ... */ nargs = 0; for (l = list_head(fargs); l != NULL; l = nextl) { Node *arg = lfirst(l); Oid argtype = exprType(arg); nextl = lnext(l); if (argtype == VOIDOID && IsA(arg, Param) &&!is_column) { fargs = list_delete_ptr(fargs, arg); continue; } actual_arg_types[nargs++] = argtype; } if (fargs) { first_arg = linitial(fargs); Assert(first_arg != NULL); } /* * Check for column projection: if function has one argument, and that * argument is of complex type, and function name is not qualified, then * the "function call" could be a projection. We also check that there * wasn't any aggregate or variadic decoration. */ if (nargs == 1 && !agg_star && !agg_distinct && over == NULL && !func_variadic && list_length(funcname) == 1) { Oid argtype = actual_arg_types[0]; if (argtype == RECORDOID || ISCOMPLEX(argtype)) { retval = ParseComplexProjection(pstate, strVal(linitial(funcname)), first_arg, location); if (retval) return retval; /* * If ParseComplexProjection doesn't recognize it as a projection, * just press on. */ } } /* * Okay, it's not a column projection, so it must really be a function. * func_get_detail looks up the function in the catalogs, does * disambiguation for polymorphic functions, handles inheritance, and * returns the funcid and type and set or singleton status of the * function's return value. It also returns the true argument types to * the function. In the case of a variadic function call, the reported * "true" types aren't really what is in pg_proc: the variadic argument is * replaced by a suitable number of copies of its element type. We'll fix * it up below. We may also have to deal with default arguments. */ fdresult = func_get_detail(funcname, fargs, nargs, actual_arg_types, !func_variadic, true, &funcid, &rettype, &retset, &nvargs, &declared_arg_types, &argdefaults); if (fdresult == FUNCDETAIL_COERCION) { /* * We interpreted it as a type coercion. coerce_type can handle these * cases, so why duplicate code... */ return coerce_type(pstate, linitial(fargs), actual_arg_types[0], rettype, -1, COERCION_EXPLICIT, COERCE_EXPLICIT_CALL, location); } else if (fdresult == FUNCDETAIL_NORMAL) { /* * Normal function found; was there anything indicating it must be an * aggregate? */ if (agg_star) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("%s(*) specified, but %s is not an aggregate function", NameListToString(funcname), NameListToString(funcname)), parser_errposition(pstate, location))); if (agg_distinct) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("DISTINCT specified, but %s is not an aggregate function", NameListToString(funcname)), parser_errposition(pstate, location))); if (over) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("OVER specified, but %s is not a window function nor an aggregate function", NameListToString(funcname)), parser_errposition(pstate, location))); } else if (!(fdresult == FUNCDETAIL_AGGREGATE || fdresult == FUNCDETAIL_WINDOWFUNC)) { /* * Oops. Time to die. * * If we are dealing with the attribute notation rel.function, give an * error message that is appropriate for that case. */ if (is_column) { Assert(nargs == 1); Assert(list_length(funcname) == 1); unknown_attribute(pstate, first_arg, strVal(linitial(funcname)), location); } /* * Else generate a detailed complaint for a function */ if (fdresult == FUNCDETAIL_MULTIPLE) ereport(ERROR, (errcode(ERRCODE_AMBIGUOUS_FUNCTION), errmsg("function %s is not unique", func_signature_string(funcname, nargs, actual_arg_types)), errhint("Could not choose a best candidate function. " "You might need to add explicit type casts."), parser_errposition(pstate, location))); else ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("function %s does not exist", func_signature_string(funcname, nargs, actual_arg_types)), errhint("No function matches the given name and argument types. " "You might need to add explicit type casts."), parser_errposition(pstate, location))); } /* * If there are default arguments, we have to include their types in * actual_arg_types for the purpose of checking generic type consistency. * However, we do NOT put them into the generated parse node, because * their actual values might change before the query gets run. The * planner has to insert the up-to-date values at plan time. */ nargsplusdefs = nargs; foreach(l, argdefaults) { Node *expr = (Node *) lfirst(l); /* probably shouldn't happen ... */ if (nargsplusdefs >= FUNC_MAX_ARGS) ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), errmsg_plural("cannot pass more than %d argument to a function", "cannot pass more than %d arguments to a function", FUNC_MAX_ARGS, FUNC_MAX_ARGS), parser_errposition(pstate, location))); actual_arg_types[nargsplusdefs++] = exprType(expr); }
/* * Parse a function call * * For historical reasons, Postgres tries to treat the notations tab.col * and col(tab) as equivalent: if a single-argument function call has an * argument of complex type and the (unqualified) function name matches * any attribute of the type, we take it as a column projection. Conversely * a function of a single complex-type argument can be written like a * column reference, allowing functions to act like computed columns. * * Hence, both cases come through here. The is_column parameter tells us * which syntactic construct is actually being dealt with, but this is * intended to be used only to deliver an appropriate error message, * not to affect the semantics. When is_column is true, we should have * a single argument (the putative table), unqualified function name * equal to the column name, and no aggregate decoration. * * The argument expressions (in fargs) must have been transformed already. */ Node * ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, bool agg_star, bool agg_distinct, bool is_column) { Oid rettype; Oid funcid; ListCell *l; Node *first_arg = NULL; int nargs = list_length(fargs); int argn; Oid actual_arg_types[FUNC_MAX_ARGS]; Oid *declared_arg_types; Node *retval; bool retset; FuncDetailCode fdresult; /* * Most of the rest of the parser just assumes that functions do not * have more than FUNC_MAX_ARGS parameters. We have to test here to * protect against array overruns, etc. Of course, this may not be a * function, but the test doesn't hurt. */ if (nargs > FUNC_MAX_ARGS) ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), errmsg("cannot pass more than %d arguments to a function", FUNC_MAX_ARGS))); if (fargs) { first_arg = linitial(fargs); Assert(first_arg != NULL); } /* * Check for column projection: if function has one argument, and that * argument is of complex type, and function name is not qualified, * then the "function call" could be a projection. We also check that * there wasn't any aggregate decoration. */ if (nargs == 1 && !agg_star && !agg_distinct && list_length(funcname) == 1) { Oid argtype = exprType(first_arg); if (argtype == RECORDOID || ISCOMPLEX(argtype)) { retval = ParseComplexProjection(pstate, strVal(linitial(funcname)), first_arg); if (retval) return retval; /* * If ParseComplexProjection doesn't recognize it as a * projection, just press on. */ } } /* * Okay, it's not a column projection, so it must really be a * function. Extract arg type info in preparation for function lookup. */ MemSet(actual_arg_types, 0, FUNC_MAX_ARGS * sizeof(Oid)); argn = 0; foreach(l, fargs) { Node *arg = lfirst(l); actual_arg_types[argn++] = exprType(arg); }