mirror of
https://git.postgresql.org/git/postgresql.git
synced 2026-02-07 12:17:34 +08:00
All expression nodes now have an explicit output-collation field, unless they are known to only return a noncollatable data type (such as boolean or record). Also, nodes that can invoke collation-aware functions store a separate field that is the collation value to pass to the function. This avoids confusion that arises when a function has collatable inputs and noncollatable output type, or vice versa. Also, replace the parser's on-the-fly collation assignment method with a post-pass over the completed expression tree. This allows us to use a more complex (and hopefully more nearly spec-compliant) assignment rule without paying for it in extra storage in every expression node. Fix assorted bugs in the planner's handling of collations by making collation one of the defining properties of an EquivalenceClass and by converting CollateExprs into discardable RelabelType nodes during expression preprocessing.
154 lines
6.1 KiB
C
154 lines
6.1 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* parse_node.h
|
|
* Internal definitions for parser
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/parser/parse_node.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef PARSE_NODE_H
|
|
#define PARSE_NODE_H
|
|
|
|
#include "nodes/parsenodes.h"
|
|
#include "utils/relcache.h"
|
|
|
|
|
|
/*
|
|
* Function signatures for parser hooks
|
|
*/
|
|
typedef struct ParseState ParseState;
|
|
|
|
typedef Node *(*PreParseColumnRefHook) (ParseState *pstate, ColumnRef *cref);
|
|
typedef Node *(*PostParseColumnRefHook) (ParseState *pstate, ColumnRef *cref, Node *var);
|
|
typedef Node *(*ParseParamRefHook) (ParseState *pstate, ParamRef *pref);
|
|
typedef Node *(*CoerceParamHook) (ParseState *pstate, Param *param,
|
|
Oid targetTypeId, int32 targetTypeMod,
|
|
int location);
|
|
|
|
|
|
/*
|
|
* State information used during parse analysis
|
|
*
|
|
* parentParseState: NULL in a top-level ParseState. When parsing a subquery,
|
|
* links to current parse state of outer query.
|
|
*
|
|
* p_sourcetext: source string that generated the raw parsetree being
|
|
* analyzed, or NULL if not available. (The string is used only to
|
|
* generate cursor positions in error messages: we need it to convert
|
|
* byte-wise locations in parse structures to character-wise cursor
|
|
* positions.)
|
|
*
|
|
* p_rtable: list of RTEs that will become the rangetable of the query.
|
|
* Note that neither relname nor refname of these entries are necessarily
|
|
* unique; searching the rtable by name is a bad idea.
|
|
*
|
|
* p_joinexprs: list of JoinExpr nodes associated with p_rtable entries.
|
|
* This is one-for-one with p_rtable, but contains NULLs for non-join
|
|
* RTEs, and may be shorter than p_rtable if the last RTE(s) aren't joins.
|
|
*
|
|
* p_joinlist: list of join items (RangeTblRef and JoinExpr nodes) that
|
|
* will become the fromlist of the query's top-level FromExpr node.
|
|
*
|
|
* p_relnamespace: list of RTEs that represents the current namespace for
|
|
* table lookup, ie, those RTEs that are accessible by qualified names.
|
|
* This may be just a subset of the rtable + joinlist, and/or may contain
|
|
* entries that are not yet added to the main joinlist.
|
|
*
|
|
* p_varnamespace: list of RTEs that represents the current namespace for
|
|
* column lookup, ie, those RTEs that are accessible by unqualified names.
|
|
* This is different from p_relnamespace because a JOIN without an alias does
|
|
* not hide the contained tables (so they must still be in p_relnamespace)
|
|
* but it does hide their columns (unqualified references to the columns must
|
|
* refer to the JOIN, not the member tables). Other special RTEs such as
|
|
* NEW/OLD for rules may also appear in just one of these lists.
|
|
*
|
|
* p_ctenamespace: list of CommonTableExprs (WITH items) that are visible
|
|
* at the moment. This is different from p_relnamespace because you have
|
|
* to make an RTE before you can access a CTE.
|
|
*
|
|
* p_future_ctes: list of CommonTableExprs (WITH items) that are not yet
|
|
* visible due to scope rules. This is used to help improve error messages.
|
|
*
|
|
* p_parent_cte: CommonTableExpr that immediately contains the current query,
|
|
* if any.
|
|
*
|
|
* p_windowdefs: list of WindowDefs representing WINDOW and OVER clauses.
|
|
* We collect these while transforming expressions and then transform them
|
|
* afterwards (so that any resjunk tlist items needed for the sort/group
|
|
* clauses end up at the end of the query tlist). A WindowDef's location in
|
|
* this list, counting from 1, is the winref number to use to reference it.
|
|
*/
|
|
struct ParseState
|
|
{
|
|
struct ParseState *parentParseState; /* stack link */
|
|
const char *p_sourcetext; /* source text, or NULL if not available */
|
|
List *p_rtable; /* range table so far */
|
|
List *p_joinexprs; /* JoinExprs for RTE_JOIN p_rtable entries */
|
|
List *p_joinlist; /* join items so far (will become FromExpr
|
|
* node's fromlist) */
|
|
List *p_relnamespace; /* current namespace for relations */
|
|
List *p_varnamespace; /* current namespace for columns */
|
|
List *p_ctenamespace; /* current namespace for common table exprs */
|
|
List *p_future_ctes; /* common table exprs not yet in namespace */
|
|
CommonTableExpr *p_parent_cte; /* this query's containing CTE */
|
|
List *p_windowdefs; /* raw representations of window clauses */
|
|
int p_next_resno; /* next targetlist resno to assign */
|
|
List *p_locking_clause; /* raw FOR UPDATE/FOR SHARE info */
|
|
Node *p_value_substitute; /* what to replace VALUE with, if any */
|
|
bool p_hasAggs;
|
|
bool p_hasWindowFuncs;
|
|
bool p_hasSubLinks;
|
|
bool p_hasModifyingCTE;
|
|
bool p_is_insert;
|
|
bool p_is_update;
|
|
bool p_locked_from_parent;
|
|
Relation p_target_relation;
|
|
RangeTblEntry *p_target_rangetblentry;
|
|
|
|
/*
|
|
* Optional hook functions for parser callbacks. These are null unless
|
|
* set up by the caller of make_parsestate.
|
|
*/
|
|
PreParseColumnRefHook p_pre_columnref_hook;
|
|
PostParseColumnRefHook p_post_columnref_hook;
|
|
ParseParamRefHook p_paramref_hook;
|
|
CoerceParamHook p_coerce_param_hook;
|
|
void *p_ref_hook_state; /* common passthrough link for above */
|
|
};
|
|
|
|
/* Support for parser_errposition_callback function */
|
|
typedef struct ParseCallbackState
|
|
{
|
|
ParseState *pstate;
|
|
int location;
|
|
ErrorContextCallback errcontext;
|
|
} ParseCallbackState;
|
|
|
|
|
|
extern ParseState *make_parsestate(ParseState *parentParseState);
|
|
extern void free_parsestate(ParseState *pstate);
|
|
extern int parser_errposition(ParseState *pstate, int location);
|
|
|
|
extern void setup_parser_errposition_callback(ParseCallbackState *pcbstate,
|
|
ParseState *pstate, int location);
|
|
extern void cancel_parser_errposition_callback(ParseCallbackState *pcbstate);
|
|
|
|
extern Var *make_var(ParseState *pstate, RangeTblEntry *rte, int attrno,
|
|
int location);
|
|
extern Oid transformArrayType(Oid *arrayType, int32 *arrayTypmod);
|
|
extern ArrayRef *transformArraySubscripts(ParseState *pstate,
|
|
Node *arrayBase,
|
|
Oid arrayType,
|
|
Oid elementType,
|
|
int32 arrayTypMod,
|
|
List *indirection,
|
|
Node *assignFrom);
|
|
extern Const *make_const(ParseState *pstate, Value *value, int location);
|
|
|
|
#endif /* PARSE_NODE_H */
|