《PG源码学习--2.查询语法分析》

一.背景说明

数据库的一条普通的查询SQL,首先要通过查询编译,生成数据库识别的数据结构,然后数据库对生成的数据结构进行语义分析解析,最后返回内部的查询结构,共查询重写和查询优化使用。
查询代码如select * from table;类似这样的语句是外部系统和数据库交互的DSL语言。本文通过Postgres的代码学习,来加深对查询编译过程的理解。
Postgres的代码使用 最新的master分支。

二.物理代码

postgres\src\backend\parser\scan.l
postgres\src\backend\parser\gram.y

三.数据结构

3.1 语法入口

simple_select:
         SELECT opt_all_clause opt_target_list
         into_clause from_clause where_clause
         group_clause having_clause window_clause
            {
               SelectStmt *n = makeNode(SelectStmt);
               n->targetList = $3;
               n->intoClause = $4;
               n->fromClause = $5;
               n->whereClause = $6;
               n->groupClause = $7;
               n->havingClause = $8;
               n->windowClause = $9;
               $$ = (Node *)n;
            }
         | SELECT distinct_clause target_list
         into_clause from_clause where_clause
         group_clause having_clause window_clause
            {
               SelectStmt *n = makeNode(SelectStmt);
               n->distinctClause = $2;
               n->targetList = $3;
               n->intoClause = $4;
               n->fromClause = $5;
               n->whereClause = $6;
               n->groupClause = $7;
               n->havingClause = $8;
               n->windowClause = $9;
               $$ = (Node *)n;
            }
         | values_clause                      { $$ = $1; }
         | TABLE relation_expr
            {

3.2 数据结构

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 (...), ... */
    ParseState
   /*
    * 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 */

   /*ParseState
    * 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;

四.其他

不小心被删除了,就先补个骨架信息吧,加油!

发布了6 篇原创文章 · 获赞 1 · 访问量 218

猜你喜欢

转载自blog.csdn.net/weixin_39939108/article/details/104523557