溫馨提示×

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

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

PostgreSQL 源碼解讀(204)- 查詢#117(數(shù)據(jù)結(jié)構(gòu)SelectStmt&Value)

發(fā)布時(shí)間:2020-08-07 16:37:52 來源:ITPUB博客 閱讀:273 作者:husthxd 欄目:關(guān)系型數(shù)據(jù)庫(kù)

本節(jié)簡(jiǎn)單介紹了PostgreSQL在執(zhí)行parse中重要的兩個(gè)數(shù)據(jù)結(jié)構(gòu):SelectStmt&Value.

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

SelectStmt
“simple” SELECT可轉(zhuǎn)換為SelectStmt節(jié)點(diǎn).包含集合操作(UNION, INTERSECT, EXCEPT)的查詢通過SelectStmt節(jié)點(diǎn)樹來表示,在這棵樹中,葉子節(jié)點(diǎn)是SELECTs組件,而內(nèi)部節(jié)點(diǎn)表示UNION, INTERSECT, or EXCEPT操作符.內(nèi)部節(jié)點(diǎn)和葉子節(jié)點(diǎn)是相同的節(jié)點(diǎn)類型.


/* ----------------------
 *    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.
 *
 * "simple" SELECT可轉(zhuǎn)換為SelectStmt節(jié)點(diǎn).
 * 包含集合操作(UNION, INTERSECT, EXCEPT)的查詢通過SelectStmt節(jié)點(diǎn)樹來表示,
 *   在這棵樹中,葉子節(jié)點(diǎn)是SELECTs組件,而內(nèi)部節(jié)點(diǎn)表示UNION, INTERSECT, or EXCEPT操作符.
 * 內(nèi)部節(jié)點(diǎn)和葉子節(jié)點(diǎn)是相同的節(jié)點(diǎn)類型.
 * ----------------------
 */
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.
   * "葉子"SelectStmts節(jié)點(diǎn)使用的字段
   */
  //NULL,DISTINCT ON表達(dá)式鏈表,或者所有(SELECT DISTINCT)的lcons(NIL,NIL)
  List     *distinctClause; /* NULL, list of DISTINCT ON exprs, or
                 * lcons(NIL,NIL) for all (SELECT DISTINCT) */
  //SELECT INTO的target
  IntoClause *intoClause;   /* target for SELECT INTO */
  //目標(biāo)鏈表(元素為ResTarget)
  List     *targetList;   /* the target list (of ResTarget) */
  //FROM子句
  List     *fromClause;   /* the FROM clause */
  //WHERE
  Node     *whereClause;  /* WHERE qualification */
  //GROUP BY 子句
  List     *groupClause;  /* GROUP BY clauses */
  //HAVING條件表達(dá)式
  Node     *havingClause; /* HAVING conditional-expression */
  //窗口函數(shù)鏈表
  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.
   * 如果"葉子"節(jié)點(diǎn)表示VALUES鏈表,則上述字段均為NULL,而該字段會(huì)存儲(chǔ)相關(guān)信息.
   */
  List     *valuesLists;  /* untransformed list of expression lists */
  /*
   * These fields are used in both "leaf" SelectStmts and upper-level
   * SelectStmts.
   * 下面這些字段用于"left"節(jié)點(diǎn)和上層節(jié)點(diǎn)
   */
  //排序子句
  List     *sortClause;   /* sort clause (a list of SortBy's) */
  //limit偏移
  Node     *limitOffset;  /* # of result tuples to skip */
  //limit個(gè)數(shù)
  Node     *limitCount;   /* # of result tuples to return */
  //FOR UPDATE
  List     *lockingClause;  /* FOR UPDATE (list of LockingClause's) */
  //CTE
  WithClause *withClause;   /* WITH clause */
  /*
   * These fields are used only in upper-level SelectStmts.
   * 下面這些字段用于高層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;

Value
相同的Value結(jié)構(gòu)體用于5中節(jié)點(diǎn)類型:T_Integer, T_Float, T_String, T_BitString, T_Null


/*-------------------------------------------------------------------------
 *
 * value.h
 *    interface for Value nodes
 *
 *
 * Copyright (c) 2003-2019, PostgreSQL Global Development Group
 *
 * src/include/nodes/value.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef VALUE_H
#define VALUE_H
#include "nodes/nodes.h"
/*----------------------
 *    Value node
 *
 * The same Value struct is used for five node types: T_Integer,
 * T_Float, T_String, T_BitString, T_Null.
 * 相同的Value結(jié)構(gòu)體用于5中節(jié)點(diǎn)類型:T_Integer, T_Float, T_String, T_BitString, T_Null
 *
 * Integral values are actually represented by a machine integer,
 * but both floats and strings are represented as strings.
 * Using T_Float as the node type simply indicates that
 * the contents of the string look like a valid numeric literal.
 * 整型值實(shí)際上通過機(jī)器integer來表示,但floats和strings均使用字符串來表示.
 * 使用T_Float作為節(jié)點(diǎn)類型只是簡(jiǎn)單的表示字符串中的內(nèi)存看似有效的數(shù)值字面量.
 *
 * (Before Postgres 7.0, we used a double to represent T_Float,
 * but that creates loss-of-precision problems when the value is
 * ultimately destined to be converted to NUMERIC.  Since Value nodes
 * are only used in the parsing process, not for runtime data, it's
 * better to use the more general representation.)
 * (在PG 7.0以前,使用double來表示T_Float,但會(huì)出現(xiàn)精度丟失的問題)
 *
 * Note that an integer-looking string will get lexed as T_Float if
 * the value is too large to fit in an 'int'.
 * 注意 : 看似整型字符串在不能使用int存儲(chǔ)的情況下會(huì)在語義上視為T_Float
 *
 * Nulls, of course, don't need the value part at all.
 * Nulls,不需要值
 *----------------------
 */
typedef struct Value
{
  NodeTag   type;     /* tag appropriately (eg. T_String) */
  union ValUnion
  {
    int     ival;   /* machine integer */
    char     *str;    /* string */
  }     val;
} Value;
#define intVal(v)   (((Value *)(v))->val.ival)
#define floatVal(v)   atof(((Value *)(v))->val.str)
#define strVal(v)   (((Value *)(v))->val.str)
extern Value *makeInteger(int i);
extern Value *makeFloat(char *numericStr);
extern Value *makeString(char *str);
extern Value *makeBitString(char *str);
#endif              /* VALUE_H */

二、源碼解讀

N/A

三、跟蹤分析

測(cè)試SQL語句:


-- 用于測(cè)試的查詢語句
testdb=# select t_dwxx.dwmc,t_grxx.grbh,t_grxx.xm,t_jfxx.ny,t_jfxx.je
testdb-# from t_dwxx,t_grxx,t_jfxx
testdb-# where t_dwxx.dwbh = t_grxx.dwbh 
testdb-# and t_grxx.grbh = t_jfxx.grbh
testdb-# and t_dwxx.dwbh IN ('1001','1002')
testdb-# order by t_grxx.grbh
testdb-# limit 8;
   dwmc    | grbh |  xm  |   ny   |   je   
-----------+------+------+--------+--------
 X有限公司 | 901  | 張三 | 201801 |  401.3
 X有限公司 | 901  | 張三 | 201802 |  401.3
 X有限公司 | 901  | 張三 | 201803 |  401.3
 Y有限公司 | 902  | 李四 | 201801 |  513.1
 Y有限公司 | 902  | 李四 | 201802 |  513.3
 Y有限公司 | 902  | 李四 | 201804 |  513.3
 Y有限公司 | 903  | 王五 | 201801 | 372.22
 Y有限公司 | 903  | 王五 | 201804 | 372.22
(8 rows)

樣例數(shù)據(jù)如下:


...
(gdb) p *(RawStmt *)(raw_parsetree_list->head.data->ptr_value)
$7 = {type = T_RawStmt, stmt = 0x1a48c00, stmt_location = 0, stmt_len = 232}
(gdb) p *((RawStmt *)(raw_parsetree_list->head.data->ptr_value))->stmt
$8 = {type = T_SelectStmt}
###### 實(shí)際類型SelectStmt 
(gdb)  p *(SelectStmt *)((RawStmt *)(raw_parsetree_list->head.data->ptr_value))->stmt
$16 = {type = T_SelectStmt, distinctClause = 0x0, intoClause = 0x0, targetList = 0x1a47b18, 
  fromClause = 0x1a48900, whereClause = 0x1a48b40, groupClause = 0x0, havingClause = 0x0, windowClause = 0x0, 
  valuesLists = 0x0, sortClause = 0x1afd858, limitOffset = 0x0, limitCount = 0x1afd888, lockingClause = 0x0, 
  withClause = 0x0, op = SETOP_NONE, all = false, larg = 0x0, rarg = 0x0}

四、參考資料

N/A

向AI問一下細(xì)節(jié)

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

AI