《PG源码学习--3.查询语义分析》

一.背景说明

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

二.物理代码

2.1 postgres.c

postgres\src\backend\tcop\postgres.c ,exec_simple_query 中调用pg_analyze_and_rewrite

2.2 analyze.c

postgres\src\backend\parser\analyze.c 具体逻辑实现

三.数据结构

核心数据结构ParseState解析状态,Query查询体

3.1 解析状态

代码位置postgres\src\include\parser\parse_node.h

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_namespace;   /* currently-referenceable RTEs (List of
                         * ParseNamespaceItem) */
   bool      p_lateral_active;  /* p_lateral_only items visible? */
   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 */
   Relation   p_target_relation; /* INSERT/UPDATE/DELETE target rel */
   RangeTblEntry *p_target_rangetblentry; /* target rel's RTE */
   bool      p_is_insert;   /* process assignment like INSERT not UPDATE */
   List      *p_windowdefs;  /* raw representations of window clauses */
   ParseExprKind p_expr_kind; /* what kind of expression we're parsing */
   int          p_next_resno;  /* next targetlist resno to assign */
   List      *p_multiassign_exprs;   /* junk tlist entries for multiassign */
   List      *p_locking_clause;  /* raw FOR UPDATE/FOR SHARE info */
   bool      p_locked_from_parent;  /* parent has marked this subquery
                               * with FOR UPDATE/FOR SHARE */
   bool      p_resolve_unknowns; /* resolve unknown-type SELECT outputs as
                            * type text */

   QueryEnvironment *p_queryEnv;  /* curr env, incl refs to enclosing env */

   /* Flags telling about things found in the query: */
   bool      p_hasAggs;
   bool      p_hasWindowFuncs;
   bool      p_hasTargetSRFs;
   bool      p_hasSubLinks;
   bool      p_hasModifyingCTE;

   Node      *p_last_srf;       /* most recent set-returning func/op found */

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

3.2 查询体

代码位置postgres\include\server\nodes\parsenodes.h

typedef struct Query
{
   
   NodeTag       type;

   CmdType       commandType;   /* select|insert|update|delete|utility */

   QuerySource querySource;   /* where did I come from? */

   uint32    queryId;      /* query identifier (can be set by plugins) */

   bool      canSetTag;    /* do I set the command result tag? */

   Node      *utilityStmt;   /* non-null if commandType == CMD_UTILITY */

   int          resultRelation; /* rtable index of target relation for
                         * INSERT/UPDATE/DELETE; 0 for SELECT */

   bool      hasAggs;      /* has aggregates in tlist or havingQual */
   bool      hasWindowFuncs; /* has window functions in tlist */
   bool      hasTargetSRFs; /* has set-returning functions in tlist */
   bool      hasSubLinks;   /* has subquery SubLink */
   bool      hasDistinctOn; /* distinctClause is from DISTINCT ON */
   bool      hasRecursive;  /* WITH RECURSIVE was specified */
   bool      hasModifyingCTE;   /* has INSERT/UPDATE/DELETE in WITH */
   bool      hasForUpdate;  /* FOR [KEY] UPDATE/SHARE was specified */
   bool      hasRowSecurity; /* rewriter has applied some RLS policy */

   List      *cteList;      /* WITH list (of CommonTableExpr's) */

   List      *rtable;          /* list of range table entries */
   FromExpr   *jointree;     /* table join tree (FROM and WHERE clauses) */

   List      *targetList;       /* target list (of TargetEntry) */

   OverridingKind override;   /* OVERRIDING clause */

   OnConflictExpr *onConflict; /* ON CONFLICT DO [NOTHING | UPDATE] */

   List  
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值