您好,登錄后才能下訂單哦!
本節簡單介紹了PostgreSQL在執行parse中重要的兩個數據結構:SelectStmt&Value.
SelectStmt
“simple” SELECT可轉換為SelectStmt節點.包含集合操作(UNION, INTERSECT, EXCEPT)的查詢通過SelectStmt節點樹來表示,在這棵樹中,葉子節點是SELECTs組件,而內部節點表示UNION, INTERSECT, or EXCEPT操作符.內部節點和葉子節點是相同的節點類型.
/* ----------------------
* 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可轉換為SelectStmt節點.
* 包含集合操作(UNION, INTERSECT, EXCEPT)的查詢通過SelectStmt節點樹來表示,
* 在這棵樹中,葉子節點是SELECTs組件,而內部節點表示UNION, INTERSECT, or EXCEPT操作符.
* 內部節點和葉子節點是相同的節點類型.
* ----------------------
*/
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節點使用的字段
*/
//NULL,DISTINCT ON表達式鏈表,或者所有(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 */
//目標鏈表(元素為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條件表達式
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.
* 如果"葉子"節點表示VALUES鏈表,則上述字段均為NULL,而該字段會存儲相關信息.
*/
List *valuesLists; /* untransformed list of expression lists */
/*
* These fields are used in both "leaf" SelectStmts and upper-level
* SelectStmts.
* 下面這些字段用于"left"節點和上層節點
*/
//排序子句
List *sortClause; /* sort clause (a list of SortBy's) */
//limit偏移
Node *limitOffset; /* # of result tuples to skip */
//limit個數
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結構體用于5中節點類型: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結構體用于5中節點類型: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.
* 整型值實際上通過機器integer來表示,但floats和strings均使用字符串來表示.
* 使用T_Float作為節點類型只是簡單的表示字符串中的內存看似有效的數值字面量.
*
* (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,但會出現精度丟失的問題)
*
* Note that an integer-looking string will get lexed as T_Float if
* the value is too large to fit in an 'int'.
* 注意 : 看似整型字符串在不能使用int存儲的情況下會在語義上視為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
測試SQL語句:
-- 用于測試的查詢語句
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)
樣例數據如下:
...
(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}
###### 實際類型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
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。