PostgreSQL Source Code interpretation (19)-query statement # 4 (ParseTree detailed explanation)
Analytic tree
2. Data structure
1 、 SelectStmt
/ *-* Select Statement * A "simple" SELECT is represented in the output of gram.y by a single * SelectStmt node; so is a VALUES construct. A query containing set * operators (UNION, INTERSECT, EXCEPT) is represented by a tree of SelectStmt * nodes, in which the leaf nodes are component SELECTs and the internal nodes * represent UNION, INTERSECT, or EXCEPT operators. Using the same node * type for both leaf and internal nodes allows gram.y to stick ORDER BY, * LIMIT, etc, clause values into a SELECT statement without worrying * whether it is a simple or compound SELECT. *-* / typedef enum SetOperation {SETOP_NONE = 0, SETOP_UNION, SETOP_INTERSECT, SETOP_EXCEPT} SetOperation; typedef struct SelectStmt {NodeTag type; / * * These fields are used only in "leaf" SelectStmts. * / List * distinctClause; / * NULL, list of DISTINCT ON exprs, or * lcons (NIL,NIL) for all (SELECT DISTINCT) * / IntoClause * intoClause; / * target for SELECT INTO * / List * targetList; / * the target list (of ResTarget) * / List * fromClause; / * the FROM clause * / Node * whereClause / * WHERE qualification * / List * groupClause; / * GROUP BY clauses * / Node * havingClause; / * HAVING conditional-expression * / List * windowClause; / * WINDOW window_name AS (...),... / * In a "leaf" node representing a VALUES list, the above fields are all * null, and instead this field is set. Note that the elements of the * sublists are just expressions, without ResTarget decoration. Also note * that a list element can be DEFAULT (represented as a SetToDefault * node), regardless of the context of the VALUES list. It's up to parse * analysis to reject that where not valid. * / List * valuesLists; / * untransformed list of expression lists * / / * These fields are used in both "leaf" SelectStmts and upper-level * SelectStmts. * / List * sortClause; / * sort clause (a list of SortBy's) * / Node * limitOffset; / * # of result tuples to skip * / Node * limitCount; / * # of result tuples to return * / List * lockingClause; / * FOR UPDATE (list of LockingClause's) * / WithClause * withClause / * WITH clause * / * * These fields are used only in upper-level SelectStmts. * / SetOperation op; / * type of set op * / bool all; / * ALL specified? * / struct SelectStmt * larg; / * left child * / struct SelectStmt * rarg; / * right child * / / * Eventually add fields for CORRESPONDING spec here * /} SelectStmt
2 、 RangeSubselect
/ * * RangeSubselect-subquery appearing in a FROM clause * / typedef struct RangeSubselect {NodeTag type; bool lateral; / * does it have LATERAL prefix? * / Node * subquery; / * the untransformed sub-select clause * / Alias * alias; / * table alias & optional column aliases * /} RangeSubselect
3 、 Alias
/ * * Alias-* specifies an alias for a range variable; the alias might also * specify renaming of columns within the table. * * Note: colnames is a list of Value nodes (always strings). In Alias structs * associated with RTEs, there may be entries corresponding to dropped * columns; these are normally empty strings ("). See parsenodes.h for info. * / typedef struct Alias {NodeTag type; char * aliasname; / * aliased rel name (never qualified) * / List * colnames; / * optional list of column aliases * /} Alias
4 、 ResTarget
/ * * ResTarget-* result target (used in target list of pre-transformed parse trees) * * In a SELECT target list, 'name' is the column label from an *' AS ColumnLabel' clause, or NULL if there was none, and 'val' is the * value expression itself. The 'indirection' field is not used. * * INSERT uses ResTarget in its target-column-names list. Here, 'name' is * the name of the destination column,' indirection' stores any subscripts * attached to the destination, and 'val' is not used. * * In an UPDATE target list, 'name' is the name of the destination column, *' indirection' stores any subscripts attached to the destination, and * val' is the expression to assign. * * See A_Indirection for more info about what can appear in 'indirection'. * / typedef struct ResTarget {NodeTag type; char * name; / * column name or NULL * / List * indirection; / * subscripts, field names, and'*', or NIL * / Node * val; / * the value expression to compute or assign * / int location; / * token location, or-1 if unknown * /} ResTarget
5 、 FromExpr
/ *-* FromExpr-represents a FROM WHERE... Construct * * This is both more flexible than a JoinExpr (it can have any number of * children, including zero) and less so-we don't need to deal with * aliases and so on. The output column set is implicitly just the union * of the outputs of the children. *-* / typedef struct FromExpr {NodeTag type; List * fromlist; / * List of join subtrees * / Node * quals; / * qualifiers on join, if any * /} FromExpr
6 、 JoinExpr
/ *-* JoinExpr-for SQL JOIN expressions * * isNatural, usingClause, and quals are interdependent. The user can write * only one of NATURAL, USING (), or ON () (this is enforced by the grammar). * If he writes NATURAL then parse analysis generates the equivalent USING () * list, and from that fills in "quals" with the right equality comparisons. * If he writes USING () then "quals" is filled with equality comparisons. * If he writes ON () then only "quals" is set. Note that NATURAL/USING * are not equivalent to ON () since they also affect the output column list. * alias is an Alias node representing the AS alias-clause attached to the * join expression, or NULL if no clause. NB: presence or absence of the * alias has a critical impact on semantics, because a join with an alias * restricts visibility of the tables/columns inside it. * * During parse analysis, an RTE is created for the Join, and its index * is filled into rtindex. This RTE is present mainly so that Vars can * be created that refer to the outputs of the join. The planner sometimes * generates JoinExprs internally; these can have rtindex = 0 if there are * no join alias variables referencing such joins. *-* / typedef struct JoinExpr {NodeTag type; JoinType jointype; / * type of join * / bool isNatural; / * Natural join? Will need to shape table * / Node * larg; / * left subtree * / Node * rarg; / * right subtree * / List * usingClause; / * USING clause, if any (list of String) * / Node * quals; / * qualifiers on join, if any * / Alias * alias / * user-written alias clause, if any * / int rtindex; / * RT index assigned for join, or 0 * /} JoinExpr
7 、 RangeVar
/ * RangeVar-range variable, used in FROM clauses * * Also used to represent table names in utility statements; there, the alias * field is not used, and inh tells whether to apply the operation * recursively to child tables. In some contexts it is also useful to carry * a TEMP table indication here. * / typedef struct RangeVar {NodeTag type; char * catalogname; / * the catalog (database) name, or NULL * / char * schemaname; / * the schemaname, or NULL * / char * relname; / * the relation/sequence name * / bool inh; / * expand rel by inheritance? Recursively act * on children? * / char relpersistence; / * see RELPERSISTENCE_* in pg_class.h * / Alias * alias; / * table alias & optional column aliases * / int location; / * token location, or-1 if unknown * /} RangeVar
8 、 ColumnRef
/ * ColumnRef-specifies a reference to a column, or possibly a whole tuple * * The "fields" list must be nonempty. It can contain string Value nodes * (representing names) and A_Star nodes (representing occurrence of a'*). * Currently, A_Star must appear only as the last list element-the grammar * is responsible for enforcing this! * * Note: any array subscripting or selection of fields from composite columns * is represented by an A_Indirection node above the ColumnRef. However, * for simplicity in the normal case, initial field selection from a table * name is represented within ColumnRef and not by adding A_Indirection. * / typedef struct ColumnRef {NodeTag type; List * fields; / * field names (Value strings) or A_Star * / int location; / * token location, or-1 if unknown * /} ColumnRef; III. Summary
1. Parse tree: analyze the structure of parse tree Parsetree by tracking and analyzing the source code.
2. Other data structures: SelectSmt, RangeSubselect, JoinExpr and other data structures.