溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

PostgreSQL 源碼解讀(19)- 查詢語句#4(ParseTree詳解)

發(fā)布時間:2020-08-11 19:19:07 來源:ITPUB博客 閱讀:253 作者:husthxd 欄目:關(guān)系型數(shù)據(jù)庫
PostgreSQL 源碼解讀(19)- 查詢語句#4(ParseTree詳解)








解析樹

二、數(shù)據(jù)結(jié)構(gòu)

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 schema name, 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;

三、小結(jié)

1、解析樹:通過跟蹤分析源碼,分析解析樹Parsetree的結(jié)構(gòu);
2、其他數(shù)據(jù)結(jié)構(gòu):SelectSmt、RangeSubselect、JoinExpr等數(shù)據(jù)結(jié)構(gòu)。

向AI問一下細(xì)節(jié)
推薦閱讀:
  1. PostgreSQL 源碼解讀(232)- 查詢#125(NOT IN實現(xiàn)#3)
  2. PostgreSQL 源碼解讀(204)- 查詢#117(數(shù)據(jù)結(jié)構(gòu)SelectStmt&Value)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

猜你喜歡

AI