1997-11-25 23:07:18 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* parse_func.h
|
1997-11-25 23:07:18 +01:00
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
2021-01-02 19:06:25 +01:00
|
|
|
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1997-11-25 23:07:18 +01:00
|
|
|
*
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/include/parser/parse_func.h
|
1997-11-25 23:07:18 +01:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2019-08-05 05:14:58 +02:00
|
|
|
#ifndef PARSE_FUNC_H
|
|
|
|
#define PARSE_FUNC_H
|
1997-11-25 23:07:18 +01:00
|
|
|
|
2003-05-26 02:11:29 +02:00
|
|
|
#include "catalog/namespace.h"
|
1999-07-16 01:04:24 +02:00
|
|
|
#include "parser/parse_node.h"
|
1997-11-25 23:07:18 +01:00
|
|
|
|
2003-04-30 00:13:11 +02:00
|
|
|
|
2001-10-05 00:06:46 +02:00
|
|
|
/* Result codes for func_get_detail */
|
|
|
|
typedef enum
|
|
|
|
{
|
2003-07-04 04:51:34 +02:00
|
|
|
FUNCDETAIL_NOTFOUND, /* no matching function */
|
|
|
|
FUNCDETAIL_MULTIPLE, /* too many matching functions */
|
2002-04-11 22:00:18 +02:00
|
|
|
FUNCDETAIL_NORMAL, /* found a matching regular function */
|
2017-11-30 14:46:13 +01:00
|
|
|
FUNCDETAIL_PROCEDURE, /* found a matching procedure */
|
2002-04-11 22:00:18 +02:00
|
|
|
FUNCDETAIL_AGGREGATE, /* found a matching aggregate function */
|
2008-12-28 19:54:01 +01:00
|
|
|
FUNCDETAIL_WINDOWFUNC, /* found a matching window function */
|
2001-10-28 07:26:15 +01:00
|
|
|
FUNCDETAIL_COERCION /* it's a type coercion request */
|
2001-10-05 00:06:46 +02:00
|
|
|
} FuncDetailCode;
|
|
|
|
|
|
|
|
|
2013-07-17 02:15:36 +02:00
|
|
|
extern Node *ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
|
2019-05-22 19:04:48 +02:00
|
|
|
Node *last_srf, FuncCall *fn, bool proc_call,
|
|
|
|
int location);
|
1997-11-25 23:07:18 +01:00
|
|
|
|
2009-10-08 04:39:25 +02:00
|
|
|
extern FuncDetailCode func_get_detail(List *funcname,
|
2019-05-22 19:04:48 +02:00
|
|
|
List *fargs, List *fargnames,
|
|
|
|
int nargs, Oid *argtypes,
|
|
|
|
bool expand_variadic, bool expand_defaults,
|
|
|
|
Oid *funcid, Oid *rettype,
|
|
|
|
bool *retset, int *nvargs, Oid *vatype,
|
|
|
|
Oid **true_typeids, List **argdefaults);
|
2000-08-20 02:44:19 +02:00
|
|
|
|
2019-05-22 19:04:48 +02:00
|
|
|
extern int func_match_argtypes(int nargs,
|
|
|
|
Oid *input_typeids,
|
|
|
|
FuncCandidateList raw_candidates,
|
|
|
|
FuncCandidateList *candidates);
|
2003-05-26 02:11:29 +02:00
|
|
|
|
|
|
|
extern FuncCandidateList func_select_candidate(int nargs,
|
2019-05-22 19:04:48 +02:00
|
|
|
Oid *input_typeids,
|
|
|
|
FuncCandidateList candidates);
|
2003-05-26 02:11:29 +02:00
|
|
|
|
2003-04-30 00:13:11 +02:00
|
|
|
extern void make_fn_arguments(ParseState *pstate,
|
2019-05-22 19:04:48 +02:00
|
|
|
List *fargs,
|
|
|
|
Oid *actual_arg_types,
|
|
|
|
Oid *declared_arg_types);
|
2003-04-09 01:20:04 +02:00
|
|
|
|
2009-10-08 04:39:25 +02:00
|
|
|
extern const char *funcname_signature_string(const char *funcname, int nargs,
|
2019-05-22 19:04:48 +02:00
|
|
|
List *argnames, const Oid *argtypes);
|
2009-10-08 04:39:25 +02:00
|
|
|
extern const char *func_signature_string(List *funcname, int nargs,
|
2019-05-22 19:04:48 +02:00
|
|
|
List *argnames, const Oid *argtypes);
|
2001-10-28 07:26:15 +01:00
|
|
|
|
2019-05-22 19:04:48 +02:00
|
|
|
extern Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes,
|
|
|
|
bool missing_ok);
|
|
|
|
extern Oid LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func,
|
|
|
|
bool missing_ok);
|
2002-04-09 22:35:55 +02:00
|
|
|
|
Disallow set-returning functions inside CASE or COALESCE.
When we reimplemented SRFs in commit 69f4b9c85, our initial choice was
to allow the behavior to vary from historical practice in cases where a
SRF call appeared within a conditional-execution construct (currently,
only CASE or COALESCE). But that was controversial to begin with, and
subsequent discussion has resulted in a consensus that it's better to
throw an error instead of executing the query differently from before,
so long as we can provide a reasonably clear error message and a way to
rewrite the query.
Hence, add a parser mechanism to allow detection of such cases during
parse analysis. The mechanism just requires storing, in the ParseState,
a pointer to the set-returning FuncExpr or OpExpr most recently emitted
by parse analysis. Then the parsing functions for CASE and COALESCE can
detect the presence of a SRF in their arguments by noting whether this
pointer changes while analyzing their arguments. Furthermore, if it does,
it provides a suitable error cursor location for the complaint. (This
means that if there's more than one SRF in the arguments, the error will
point at the last one to be analyzed not the first. While connoisseurs of
parsing behavior might find that odd, it's unlikely the average user would
ever notice.)
While at it, we can also provide more specific error messages than before
about some pre-existing restrictions, such as no-SRFs-within-aggregates.
Also, reject at parse time cases where a NULLIF or IS DISTINCT FROM
construct would need to return a set. We've never supported that, but the
restriction is depended on in more subtle ways now, so it seems wise to
detect it at the start.
Also, provide some documentation about how to rewrite a SRF-within-CASE
query using a custom wrapper SRF.
It turns out that the information_schema.user_mapping_options view
contained an instance of exactly the behavior we're now forbidding; but
rewriting it makes it more clear and safer too.
initdb forced because of user_mapping_options change.
Patch by me, with error message suggestions from Alvaro Herrera and
Andres Freund, pursuant to a complaint from Regina Obe.
Discussion: https://postgr.es/m/000001d2d5de$d8d66170$8a832450$@pcorp.us
2017-06-14 05:46:39 +02:00
|
|
|
extern void check_srf_call_placement(ParseState *pstate, Node *last_srf,
|
2019-05-22 19:04:48 +02:00
|
|
|
int location);
|
2016-09-13 19:54:24 +02:00
|
|
|
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
#endif /* PARSE_FUNC_H */
|