codekingpro/portable-devtools
115k
1/*-------------------------------------------------------------------------2 *3 * parse_node.h4 * Internal definitions for parser5 *6 *7 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group8 * Portions Copyright (c) 1994, Regents of the University of California9 *10 * src/include/parser/parse_node.h11 *12 *-------------------------------------------------------------------------13 */14#ifndef PARSE_NODE_H15#define PARSE_NODE_H16 17#include "nodes/parsenodes.h"18#include "utils/queryenvironment.h"19#include "utils/relcache.h"20 21 22/* Forward references for some structs declared below */23typedef struct ParseState ParseState;24typedef struct ParseNamespaceItem ParseNamespaceItem;25typedef struct ParseNamespaceColumn ParseNamespaceColumn;26 27/*28 * Expression kinds distinguished by transformExpr(). Many of these are not29 * semantically distinct so far as expression transformation goes; rather,30 * we distinguish them so that context-specific error messages can be printed.31 *32 * Note: EXPR_KIND_OTHER is not used in the core code, but is left for use33 * by extension code that might need to call transformExpr(). The core code34 * will not enforce any context-driven restrictions on EXPR_KIND_OTHER35 * expressions, so the caller would have to check for sub-selects, aggregates,36 * window functions, SRFs, etc if those need to be disallowed.37 */38typedef enum ParseExprKind39{40 EXPR_KIND_NONE = 0, /* "not in an expression" */41 EXPR_KIND_OTHER, /* reserved for extensions */42 EXPR_KIND_JOIN_ON, /* JOIN ON */43 EXPR_KIND_JOIN_USING, /* JOIN USING */44 EXPR_KIND_FROM_SUBSELECT, /* sub-SELECT in FROM clause */45 EXPR_KIND_FROM_FUNCTION, /* function in FROM clause */46 EXPR_KIND_WHERE, /* WHERE */47 EXPR_KIND_HAVING, /* HAVING */48 EXPR_KIND_FILTER, /* FILTER */49 EXPR_KIND_WINDOW_PARTITION, /* window definition PARTITION BY */50 EXPR_KIND_WINDOW_ORDER, /* window definition ORDER BY */51 EXPR_KIND_WINDOW_FRAME_RANGE, /* window frame clause with RANGE */52 EXPR_KIND_WINDOW_FRAME_ROWS, /* window frame clause with ROWS */53 EXPR_KIND_WINDOW_FRAME_GROUPS, /* window frame clause with GROUPS */54 EXPR_KIND_SELECT_TARGET, /* SELECT target list item */55 EXPR_KIND_INSERT_TARGET, /* INSERT target list item */56 EXPR_KIND_UPDATE_SOURCE, /* UPDATE assignment source item */57 EXPR_KIND_UPDATE_TARGET, /* UPDATE assignment target item */58 EXPR_KIND_MERGE_WHEN, /* MERGE WHEN [NOT] MATCHED condition */59 EXPR_KIND_GROUP_BY, /* GROUP BY */60 EXPR_KIND_ORDER_BY, /* ORDER BY */61 EXPR_KIND_DISTINCT_ON, /* DISTINCT ON */62 EXPR_KIND_LIMIT, /* LIMIT */63 EXPR_KIND_OFFSET, /* OFFSET */64 EXPR_KIND_RETURNING, /* RETURNING */65 EXPR_KIND_VALUES, /* VALUES */66 EXPR_KIND_VALUES_SINGLE, /* single-row VALUES (in INSERT only) */67 EXPR_KIND_CHECK_CONSTRAINT, /* CHECK constraint for a table */68 EXPR_KIND_DOMAIN_CHECK, /* CHECK constraint for a domain */69 EXPR_KIND_COLUMN_DEFAULT, /* default value for a table column */70 EXPR_KIND_FUNCTION_DEFAULT, /* default parameter value for function */71 EXPR_KIND_INDEX_EXPRESSION, /* index expression */72 EXPR_KIND_INDEX_PREDICATE, /* index predicate */73 EXPR_KIND_STATS_EXPRESSION, /* extended statistics expression */74 EXPR_KIND_ALTER_COL_TRANSFORM, /* transform expr in ALTER COLUMN TYPE */75 EXPR_KIND_EXECUTE_PARAMETER, /* parameter value in EXECUTE */76 EXPR_KIND_TRIGGER_WHEN, /* WHEN condition in CREATE TRIGGER */77 EXPR_KIND_POLICY, /* USING or WITH CHECK expr in policy */78 EXPR_KIND_PARTITION_BOUND, /* partition bound expression */79 EXPR_KIND_PARTITION_EXPRESSION, /* PARTITION BY expression */80 EXPR_KIND_CALL_ARGUMENT, /* procedure argument in CALL */81 EXPR_KIND_COPY_WHERE, /* WHERE condition in COPY FROM */82 EXPR_KIND_GENERATED_COLUMN, /* generation expression for a column */83 EXPR_KIND_CYCLE_MARK, /* cycle mark value */84} ParseExprKind;85 86 87/*88 * Function signatures for parser hooks89 */90typedef Node *(*PreParseColumnRefHook) (ParseState *pstate, ColumnRef *cref);91typedef Node *(*PostParseColumnRefHook) (ParseState *pstate, ColumnRef *cref, Node *var);92typedef Node *(*ParseParamRefHook) (ParseState *pstate, ParamRef *pref);93typedef Node *(*CoerceParamHook) (ParseState *pstate, Param *param,94 Oid targetTypeId, int32 targetTypeMod,95 int location);96 97 98/*99 * State information used during parse analysis100 *101 * parentParseState: NULL in a top-level ParseState. When parsing a subquery,102 * links to current parse state of outer query.103 *104 * p_sourcetext: source string that generated the raw parsetree being105 * analyzed, or NULL if not available. (The string is used only to106 * generate cursor positions in error messages: we need it to convert107 * byte-wise locations in parse structures to character-wise cursor108 * positions.)109 *110 * p_rtable: list of RTEs that will become the rangetable of the query.111 * Note that neither relname nor refname of these entries are necessarily112 * unique; searching the rtable by name is a bad idea.113 *114 * p_rteperminfos: list of RTEPermissionInfo containing an entry corresponding115 * to each RTE_RELATION entry in p_rtable.116 *117 * p_joinexprs: list of JoinExpr nodes associated with p_rtable entries.118 * This is one-for-one with p_rtable, but contains NULLs for non-join119 * RTEs, and may be shorter than p_rtable if the last RTE(s) aren't joins.120 *121 * p_nullingrels: list of Bitmapsets associated with p_rtable entries, each122 * containing the set of outer-join RTE indexes that can null that relation123 * at the current point in the parse tree. This is one-for-one with p_rtable,124 * but may be shorter than p_rtable, in which case the missing entries are125 * implicitly empty (NULL). That rule allows us to save work when the query126 * contains no outer joins.127 *128 * p_joinlist: list of join items (RangeTblRef and JoinExpr nodes) that129 * will become the fromlist of the query's top-level FromExpr node.130 *131 * p_namespace: list of ParseNamespaceItems that represents the current132 * namespace for table and column lookup. (The RTEs listed here may be just133 * a subset of the whole rtable. See ParseNamespaceItem comments below.)134 *135 * p_lateral_active: true if we are currently parsing a LATERAL subexpression136 * of this parse level. This makes p_lateral_only namespace items visible,137 * whereas they are not visible when p_lateral_active is FALSE.138 *139 * p_ctenamespace: list of CommonTableExprs (WITH items) that are visible140 * at the moment. This is entirely different from p_namespace because a CTE141 * is not an RTE, rather "visibility" means you could make an RTE from it.142 *143 * p_future_ctes: list of CommonTableExprs (WITH items) that are not yet144 * visible due to scope rules. This is used to help improve error messages.145 *146 * p_parent_cte: CommonTableExpr that immediately contains the current query,147 * if any.148 *149 * p_target_relation: target relation, if query is INSERT/UPDATE/DELETE/MERGE150 *151 * p_target_nsitem: target relation's ParseNamespaceItem.152 *153 * p_is_insert: true to process assignment expressions like INSERT, false154 * to process them like UPDATE. (Note this can change intra-statement, for155 * cases like INSERT ON CONFLICT UPDATE.)156 *157 * p_windowdefs: list of WindowDefs representing WINDOW and OVER clauses.158 * We collect these while transforming expressions and then transform them159 * afterwards (so that any resjunk tlist items needed for the sort/group160 * clauses end up at the end of the query tlist). A WindowDef's location in161 * this list, counting from 1, is the winref number to use to reference it.162 *163 * p_expr_kind: kind of expression we're currently parsing, as per enum above;164 * EXPR_KIND_NONE when not in an expression.165 *166 * p_next_resno: next TargetEntry.resno to assign, starting from 1.167 *168 * p_multiassign_exprs: partially-processed MultiAssignRef source expressions.169 *170 * p_locking_clause: query's FOR UPDATE/FOR SHARE clause, if any.171 *172 * p_locked_from_parent: true if parent query level applies FOR UPDATE/SHARE173 * to this subquery as a whole.174 *175 * p_resolve_unknowns: resolve unknown-type SELECT output columns as type TEXT176 * (this is true by default).177 *178 * p_hasAggs, p_hasWindowFuncs, etc: true if we've found any of the indicated179 * constructs in the query.180 *181 * p_last_srf: the set-returning FuncExpr or OpExpr most recently found in182 * the query, or NULL if none.183 *184 * p_pre_columnref_hook, etc: optional parser hook functions for modifying the185 * interpretation of ColumnRefs and ParamRefs.186 *187 * p_ref_hook_state: passthrough state for the parser hook functions.188 */189struct ParseState190{191 ParseState *parentParseState; /* stack link */192 const char *p_sourcetext; /* source text, or NULL if not available */193 List *p_rtable; /* range table so far */194 List *p_rteperminfos; /* list of RTEPermissionInfo nodes for each195 * RTE_RELATION entry in rtable */196 List *p_joinexprs; /* JoinExprs for RTE_JOIN p_rtable entries */197 List *p_nullingrels; /* Bitmapsets showing nulling outer joins */198 List *p_joinlist; /* join items so far (will become FromExpr199 * node's fromlist) */200 List *p_namespace; /* currently-referenceable RTEs (List of201 * ParseNamespaceItem) */202 bool p_lateral_active; /* p_lateral_only items visible? */203 List *p_ctenamespace; /* current namespace for common table exprs */204 List *p_future_ctes; /* common table exprs not yet in namespace */205 CommonTableExpr *p_parent_cte; /* this query's containing CTE */206 Relation p_target_relation; /* INSERT/UPDATE/DELETE/MERGE target rel */207 ParseNamespaceItem *p_target_nsitem; /* target rel's NSItem, or NULL */208 bool p_is_insert; /* process assignment like INSERT not UPDATE */209 List *p_windowdefs; /* raw representations of window clauses */210 ParseExprKind p_expr_kind; /* what kind of expression we're parsing */211 int p_next_resno; /* next targetlist resno to assign */212 List *p_multiassign_exprs; /* junk tlist entries for multiassign */213 List *p_locking_clause; /* raw FOR UPDATE/FOR SHARE info */214 bool p_locked_from_parent; /* parent has marked this subquery215 * with FOR UPDATE/FOR SHARE */216 bool p_resolve_unknowns; /* resolve unknown-type SELECT outputs as217 * type text */218 219 QueryEnvironment *p_queryEnv; /* curr env, incl refs to enclosing env */220 221 /* Flags telling about things found in the query: */222 bool p_hasAggs;223 bool p_hasWindowFuncs;224 bool p_hasTargetSRFs;225 bool p_hasSubLinks;226 bool p_hasModifyingCTE;227 228 Node *p_last_srf; /* most recent set-returning func/op found */229 230 /*231 * Optional hook functions for parser callbacks. These are null unless232 * set up by the caller of make_parsestate.233 */234 PreParseColumnRefHook p_pre_columnref_hook;235 PostParseColumnRefHook p_post_columnref_hook;236 ParseParamRefHook p_paramref_hook;237 CoerceParamHook p_coerce_param_hook;238 void *p_ref_hook_state; /* common passthrough link for above */239};240 241/*242 * An element of a namespace list.243 *244 * p_names contains the table name and column names exposed by this nsitem.245 * (Typically it's equal to p_rte->eref, but for a JOIN USING alias it's246 * equal to p_rte->join_using_alias. Since the USING columns will be the247 * join's first N columns, the net effect is just that we expose only those248 * join columns via this nsitem.)249 *250 * p_rte and p_rtindex link to the underlying rangetable entry, and251 * p_perminfo to the entry in rteperminfos.252 *253 * The p_nscolumns array contains info showing how to construct Vars254 * referencing the names appearing in the p_names->colnames list.255 *256 * Namespace items with p_rel_visible set define which RTEs are accessible by257 * qualified names, while those with p_cols_visible set define which RTEs are258 * accessible by unqualified names. These sets are different because a JOIN259 * without an alias does not hide the contained tables (so they must be260 * visible for qualified references) but it does hide their columns261 * (unqualified references to the columns refer to the JOIN, not the member262 * tables, so we must not complain that such a reference is ambiguous).263 * Conversely, a subquery without an alias does not hide the columns selected264 * by the subquery, but it does hide the auto-generated relation name (so the265 * subquery columns are visible for unqualified references only). Various266 * special RTEs such as NEW/OLD for rules may also appear with only one flag267 * set.268 *269 * While processing the FROM clause, namespace items may appear with270 * p_lateral_only set, meaning they are visible only to LATERAL271 * subexpressions. (The pstate's p_lateral_active flag tells whether we are272 * inside such a subexpression at the moment.) If p_lateral_ok is not set,273 * it's an error to actually use such a namespace item. One might think it274 * would be better to just exclude such items from visibility, but the wording275 * of SQL:2008 requires us to do it this way. We also use p_lateral_ok to276 * forbid LATERAL references to an UPDATE/DELETE target table.277 *278 * At no time should a namespace list contain two entries that conflict279 * according to the rules in checkNameSpaceConflicts; but note that those280 * are more complicated than "must have different alias names", so in practice281 * code searching a namespace list has to check for ambiguous references.282 */283struct ParseNamespaceItem284{285 Alias *p_names; /* Table and column names */286 RangeTblEntry *p_rte; /* The relation's rangetable entry */287 int p_rtindex; /* The relation's index in the rangetable */288 RTEPermissionInfo *p_perminfo; /* The relation's rteperminfos entry */289 /* array of same length as p_names->colnames: */290 ParseNamespaceColumn *p_nscolumns; /* per-column data */291 bool p_rel_visible; /* Relation name is visible? */292 bool p_cols_visible; /* Column names visible as unqualified refs? */293 bool p_lateral_only; /* Is only visible to LATERAL expressions? */294 bool p_lateral_ok; /* If so, does join type allow use? */295};296 297/*298 * Data about one column of a ParseNamespaceItem.299 *300 * We track the info needed to construct a Var referencing the column301 * (but only for user-defined columns; system column references and302 * whole-row references are handled separately).303 *304 * p_varno and p_varattno identify the semantic referent, which is a305 * base-relation column unless the reference is to a join USING column that306 * isn't semantically equivalent to either join input column (because it is a307 * FULL join or the input column requires a type coercion). In those cases308 * p_varno and p_varattno refer to the JOIN RTE.309 *310 * p_varnosyn and p_varattnosyn are either identical to p_varno/p_varattno,311 * or they specify the column's position in an aliased JOIN RTE that hides312 * the semantic referent RTE's refname. (That could be either the JOIN RTE313 * in which this ParseNamespaceColumn entry exists, or some lower join level.)314 *315 * If an RTE contains a dropped column, its ParseNamespaceColumn struct316 * is all-zeroes. (Conventionally, test for p_varno == 0 to detect this.)317 */318struct ParseNamespaceColumn319{320 Index p_varno; /* rangetable index */321 AttrNumber p_varattno; /* attribute number of the column */322 Oid p_vartype; /* pg_type OID */323 int32 p_vartypmod; /* type modifier value */324 Oid p_varcollid; /* OID of collation, or InvalidOid */325 Index p_varnosyn; /* rangetable index of syntactic referent */326 AttrNumber p_varattnosyn; /* attribute number of syntactic referent */327 bool p_dontexpand; /* not included in star expansion */328};329 330/* Support for parser_errposition_callback function */331typedef struct ParseCallbackState332{333 ParseState *pstate;334 int location;335 ErrorContextCallback errcallback;336} ParseCallbackState;337 338 339extern ParseState *make_parsestate(ParseState *parentParseState);340extern void free_parsestate(ParseState *pstate);341extern int parser_errposition(ParseState *pstate, int location);342 343extern void setup_parser_errposition_callback(ParseCallbackState *pcbstate,344 ParseState *pstate, int location);345extern void cancel_parser_errposition_callback(ParseCallbackState *pcbstate);346 347extern void transformContainerType(Oid *containerType, int32 *containerTypmod);348 349extern SubscriptingRef *transformContainerSubscripts(ParseState *pstate,350 Node *containerBase,351 Oid containerType,352 int32 containerTypMod,353 List *indirection,354 bool isAssignment);355extern Const *make_const(ParseState *pstate, A_Const *aconst);356 357#endif /* PARSE_NODE_H */358 