人大金仓KingbaseES数据库SELECT语句

栏目归类:人大金仓数据库
发布时间:2024-03-26 18:50:34

1概述

simple-select是一条SELECT语句的最核心部分,从simple-select的语法定义可以看出,它由如下子句组成:去除行重复的DISTINCT (标识符opt-distinct)、目标属性(标识符target-list)、 SELECT INTO子句(标识符into-clause)、FROM子句(标识符from-clause)、 WHERE子句(标识符where_clause) 、 CROUP BY子句(标识符group-clause)、HAVING子句(标识符having-clause)和窗口子句(标识符window-clause)。在成功匹配simple-select语法结构后,将创建一个SelectStmt结构体,并将各子句赋值到结构体中相应的字段。

此外, simple-select还可以定义为其他的形式(见文件Gram. y),如VALUES子句、关系表达式以及多个SELECT语句的交并差等,但这些情况最终都会转化成最基本的simple_select形式来处理。而对于simple-select来说,目标属性(标识符target list)、FROM子句(标识符from-clause)、 WHERE子句(标识符where-clause)以及GROUP BY子句(标识符groupclause)是最重要的部分,下面将结合一个具体实例对这些子句的处理加以详细介绍。

1.simple_select:
2.???SELECT?opt_distinct target_list
3.???into_clause?from_clause?where_clause
4.???group_clause?having_clause?window_clause
5.????{
6.?????SelectStmt?*n?=?makeNode(SelectStmt);
7.?????n->targetList?=?$3;
8.?????n->intoClause?=?$4;
9.?????n->fromClause?=?$5;
10.?????n->whereClause?=?$6;
11.?????n->groupClause?=?$7;
12.?????n->havingClause?=?$8;
13.?????n->windowClause?=?$9;
14.?????$$?=?(Node?*)n;
15.????}
16.???|?SELECT?distinct_clause?target_list
17.???into_clause?from_clause?where_clause
18.???group_clause?having_clause?window_clause
19.????{
20.?????SelectStmt?*n?=?makeNode(SelectStmt);
21.?????n->distinctClause?=?$2;
22.?????n->targetList?=?$3;
23.?????n->intoClause?=?$4;
24.?????n->fromClause?=?$5;
25.?????n->whereClause?=?$6;
26.?????n->groupClause?=?$7;
27.?????n->havingClause?=?$8;
28.?????n->windowClause?=?$9;
29.?????$$?=?(Node?*)n;
30.????}
31.???|?values_clause???????{?$$?=?$1;?}

2子句

2.1 DISTINCT子句

DISTINCT子句对应语法定义中的标识符opt_distinct。从opt-distinct的语法结构可以看到,它可以匹配DISTINCT, ALL, DISTINCT ON (表达式列表)或者为空,用来决定SELECT语句是否去除重复的行。

当匹配到DISTINCT时, opt_distinct返回一个List,该链表的第一个ListCell的ptr-value字段置为空。

当匹配到DISTINCT ON时, opt_distinct也返回一个List,这个List中包含了跟在DISTINCTON之后的表达式的列表(星号或者表的属性等)。

当匹配到ALL或者空时, opt_distinct返回NIL,表明没有使用DISTINCT。

2.2 目标属性

目标属性是SELECT语句中所要查询的属性列表,对应着语法定义中的标识符targetList, targetList由若干个target_el组成,target_el定义为取别名的表达式、表达式以及“*”等。

1.target_list:
2.???target_el????????{?$$?=?list_make1($1);?}
3.???|?target_list?','?target_el????{?$$?=?lappend($1,?$3);?}
4.??;
5.
6.target_el:?a_expr?AS?ColLabel
7.????{
8.?????$$?=?makeNode(ResTarget);
9.?????$$->name?=?$3;
10.?????$$->indirection?=?NIL;
11.?????$$->val?=?(Node?*)$1;
12.?????$$->location?=?@1;
13.????}
14.???/*
15.????*?We?support?omitting?AS?only?for?column?labels?that?aren't
16.????*?any?known?keyword.??There?is?an?ambiguity?against?postfix
17.????*?operators:?is?"a?!?b"?an?infix?expression,?or?a?postfix
18.????*?expression?and?a?column?label???We?prefer?to?resolve?this
19.????*?as?an?infix?expression,?which?we?accomplish?by?assigning
20.????*?IDENT?a?precedence?higher?than?POSTFIXOP.
21.????*/
22.???|?a_expr?IDENT
23.????{
24.?????$$?=?makeNode(ResTarget);
25.?????$$->name?=?$2;
26.?????$$->indirection?=?NIL;
27.?????$$->val?=?(Node?*)$1;
28.?????$$->location?=?@1;
29.????}
30.???|?a_expr
31.????{
32.?????$$?=?makeNode(ResTarget);
33.?????$$->name?=?NULL;
34.?????$$->indirection?=?NIL;
35.?????$$->val?=?(Node?*)$1;
36.?????$$->location?=?@1;
37.????}
38.???|?'*'
39.????{
40.?????ColumnRef?*n?=?makeNode(ColumnRef);
41.?????n->fields?=?list_make1(makeNode(A_Star));
42.?????n->location?=?@1;
43.
44.?????$$?=?makeNode(ResTarget);
45.?????$$->name?=?NULL;
46.?????$$->indirection?=?NIL;
47.?????$$->val?=?(Node?*)n;
48.?????$$->location?=?@1;
49.????}
50.??;

当成功匹配一个targetList时,创建一个ResTarget结构体,该结构体中存储了该属性的全部信息。最终targetList将返回一个由ResTarget构成的List。

file

targetList包括若干ListCell节点,每个节点中的data字段指向结构体ResTarget,用来表示目标属性中的一项。下图展示了目标属性在内存中的组织结构。当目标属性中的某项涉及函数调用时, ResTarget中的字段val会指向结构体FunCall, FunCall的字段funcname存储函数的名称,字段args指向结构体ColumnRef构成的链表,每一个ColumnRef存储了函数调用中所使用到的表的一个属性。如果没有函数调用,则结构体ResTarget中的字段val直接指向结构体ColumnRef,存储该项目标属性所涉及的表的字段(此种情况没有在图中展示)。

file

图1 分析树中目标属性的数据组织结构

2.3 FROM子句

文件gram. y中定义的标识符from_clause表示SELECT语句中的FROM子句, from_clause由FROM关键字和fromList组成。而fromlist则由若干个标识符table_ref组成,每一个table_ref表示FROM子句中用逗号分隔的每个子项,它表示在FROM子句中出现的一个表或者一个子查询。

1.from_clause:
2.???FROM?from_list???????{?$$?=?$2;?}
3.???|?/*EMPTY*/????????{?$$?=?NIL;?}
4.??;
5.
6.from_list:
7.???table_ref????????{?$$?=?list_make1($1);?}
8.???|?from_list?','?table_ref????{?$$?=?lappend($1,?$3);?}
9.??;
标识符table_ref可以定义为关系表达式、取别名的关系表达式、带括号的SELECT语句、表连接等形式。
由于FROM子句中子项(标识符table_ref的最简单和基本的形式是关系表达式(标识符relation_expr)。因此,下面分析relation_expr的语法定义。
1.relation_expr:
2.???qualified_name
3.????{
4.?????/*?inheritance?query,?implicitly?*/
5.?????$$?=?$1;
6.?????$$->inh?=?true;
7.?????$$->alias?=?NULL;
8.????}
9.???|?qualified_name?'*'
10.????{
11.?????/*?inheritance?query,?explicitly?*/
12.?????$$?=?$1;
13.?????$$->inh?=?true;
14.?????$$->alias?=?NULL;
15.????}
16.???|?ONLY?qualified_name
17.????{
18.?????/*?no?inheritance?*/
19.?????$$?=?$2;
20.?????$$->inh?=?false;
21.?????$$->alias?=?NULL;
22.????}
23.???|?ONLY?'('?qualified_name?')'
24.????{
25.?????/*?no?inheritance,?SQL99-style?syntax?*/
26.?????$$?=?$3;
27.?????$$->inh?=?false;
28.?????$$->alias?=?NULL;
29.????}
30.??;
31.
32.
33.relation_expr_list:
34.???relation_expr???????{?$$?=?list_make1($1);?}
35.???|?relation_expr_list?','?relation_expr?{?$$?=?lappend($1,?$3);?}
36.??;

关系表达式relation_expr定义成qualified_name、带ONLY关键字的qualified_name等形式,最后qualified_name定义成relation_name。在成功匹配最终的标识符relation_name后,创建一个RangeVar结构体用来存储该关系的信息。 如图2所示, from_clause子句在分析树中同样被组织成一个List,每一个ListCell中包含一个RangeVar结构(或者其他结构)。

file 图2 分析树中from子句的数据结构

2.4 WHERE子句

WHERE子句中定义的是元组约束信息,对应着语法定义中的标识符where_clause。标识符where_clause定义为关键字WHERE和一个表达式(标识符a_expr)。

1.where_clause:
2.???WHERE?a_expr???????{?$$?=?$2;?}
3.???|?/*EMPTY*/????????{?$$?=?NULL;?}
4.??;

由于表达式是递归定义的,因此, A_Expr结构体中字段lexpr和rexpr分别代表操作符的左右两个子表达式,字段A-Expr_kind代表操作的类型。如果该表达式是常量或者属性等(表达式树中的叶子节点),则lexpr和rexpr都为NULL。在WHERE子句中,使用到的表的属性信息用ColumnRef结构体来组织。

2.5 GROUP BY子句

GROUP BY子句的作用是根据所指定的属性进行分组,对应着语法定义中的标识符group_clause, GROUP BY子句的语法结构与WHERE子句非常相似,在此不再详细讨论。Group by子句的语法定义如下:

group_clause:
???GROUP_P?BY?group_by_list????{?$$?=?$3;?}
???|?/*EMPTY*/????????{?$$?=?NIL;?}
??;
expr_list:?a_expr
????{
?????$$?=?list_make1($1);
????}
???|?expr_list?','?a_expr
????{
?????$$?=?lappend($1,?$3);
????}
??;

2.6 HAVING子句和ORDER BY子句

HAVING子句的作用是根据指定的条件对GROUP BY的分组进行过滤,对应于having_clause标识符。ORDER BY子句的作用是根据指定属性对整个查询的结果进行排序,对应于sort_cluse标识符。Having子句和order by子句的语法定义如下:

1.having_clause:
2.???HAVING?a_expr???????{?$$?=?$2;?}
3.???|?/*EMPTY*/????????{?$$?=?NULL;?}
4.??;
5.sort_clause:
6.???ORDER?BY?sortby_list?????{?$$?=?$3;?}
7.??;
8.
9.sortby_list:
10.???sortby?????????{?$$?=?list_make1($1);?}
11.???|?sortby_list?','?sortby????{?$$?=?lappend($1,?$3);?}
12.??;
13.
14.sortby:??a_expr?USING?qual_all_Op?opt_nulls_order
15.????{
16.?????$$?=?makeNode(SortBy);
17.?????$$->node?=?$1;
18.?????$$->sortby_dir?=?SORTBY_USING;
19.?????$$->sortby_nulls?=?$4;
20.?????$$->useOp?=?$3;
21.?????$$->location?=?@3;
22.????}
23.???|?a_expr?opt_asc_desc?opt_nulls_order
24.????{
25.?????$$?=?makeNode(SortBy);
26.?????$$->node?=?$1;
27.?????$$->sortby_dir?=?$2;
28.?????$$->sortby_nulls?=?$3;
29.?????$$->useOp?=?NIL;
30.?????$$->location?=?-1;??/*?no?operator?*/
31.????}
32.??;

更多信息,参见https://help.kingbase.com.cn/v8/index.html

文章来源:https://blog.csdn.net/arthemis_14/article/details/133104818
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
Hotcall 技术分享站