从表达式中可以看到,OceanBase支持直接传入日期时间,OceanBase也支持Time和Timestamp类型。具体如下表:
| 类型 | 格式(不区分大小写) | 表达式 |
|---|---|---|
| Date | Date 'YYYY-MM-DD' | Date{whitespace} '[0-9]{4}(-[0-9]{2}){2}' |
| Time | Time 'HH:MI:SS.FF'或Time 'HH:MI:SS | Time{whitespace} '[0-9]{2}(:[0-9]{2}){2}[.][0-9]{1,6}',Time{whitespace} '[0-9]{2}(:[0-9]{2}){2}[.] ' |
| Timestamp | Timestamp 'YYYY-MM-DD HH:MI:SS.FF'或 Timestamp 'YYYY-MM-DD HH:MI:SS' | Timestamp{whitespace} '[0-9]{4}(-[0-9]{2}){2}[ ][0-9]{2}(:[0-9]{2}){2}[.][0-9]{1,6}',Timestamp{whitespace} '[0-9]{4}(-[0-9]{2}){2}[ ][0-9]{2}(:[0-9]{2}){2}[.] ' |
如下是一个使用日期的示例:
select id,name from student where createtime <= date '2014-09-12';
语法树中存在日期类型的节点,其str_value_存储时间的字面值,value_存储该时间与基准时间(1970年1月1日0时0分0秒)之差的毫秒值。
OceanBase通过拓展标准的SQL语法支持直接在SQL语句中写入时间 ,在词法分析阶段就识别到时间类型,而 PostgreSQL 是在语法分析阶段才会识别时间 。 相比而言 , OceanBase 这种方式更直观,方便。
在0.4版本的OceanBase中,增加了预编译的功能,需要识别占位符" ",系统变量和用户变量。对应性质如下:
| 名称 | 表达式 | 动作代码返回值 |
|---|---|---|
| 占位符( ) | " " | QUESTIONMARK |
| 系统变量(system_variable) | (@@[A-Za-z_][A_Za-z0-9_]*) | SYSTEM_VARIABLE |
| 用户变量(temp_variable) | (@[A-Za-z_][A_Za-z0-9_]*) | TEMP_VARIABLE |
语法分析
OceanBase的SQL语法文件为sql_parser.y。.y语法文件最终由Bison转为可编译的.c文件。其结构与Flex的.l文件类似,分为选项部分,规则部分和代码部分。下面的代码都是去掉了关联的动作代码的规则语法,这样有助于更专注的理解语法的实现。
select语法
在SQL的语句语法中,最复杂的语法莫过于Select语句。我们先来看其在OceanBase中的语法。一个select语句可以使带括号的select语句,也可以使不带括号的select语句:
select_stmt:
select_no_parens %prec UMINUS /* 不到括号的select语句 */
| select_with_parens %prec UMINUS /* 带括号的select语句 */
;
%prec用于交换左右两个标记的优先级和结合性。即select_no_parens与UMINUS互换优先级和结核性,select_with_parens 与UMINUS互换优先级和结核性。UMINUS的定义为%right UMINUS。所有上面两句的结果是select_no_parens和select_with_parens都变成了右结合。
带括号的select语句可以是只带一个括号,也可以带多对括号:
select_with_parens:
'(' select_no_parens ')' /*只带一个括号*/
| '(' select_with_parens ')' /*带多对括号*/
;
不带括号的select语句包括简单的select,带order by排序,带order by排序和limit限制的select语句3种:
select_no_parens:
simple_select
| select_clause order_by
| select_clause opt_order_by select_limit
;
select子句包括简单slect和带括号的select:
select_clause:
simple_select
| select_with_parens
;
为什么不包括不带括号的select,暂时没想通。
简单select语句包括我们常见的select 语句,但没有order by和limit选项;同时还包括UNION,INTERSECT,EXCEPT三种运算:
simple_select:
SELECT opt_distinct select_expr_list
FROM from_list
opt_where opt_groupby opt_having
| select_clause UNION opt_distinct select_clause
| select_clause INTERSECT opt_distinct select_clause
| select_clause EXCEPT opt_distinct select_clause
;
select语句的定义相对其他语句很复杂,而且上面这段代码还没有包括无表的select和for update的select。(这两项在0.4版本的OceanBase中已经实现)。
下面这段是从PostgreSQL9.2