Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 4 additions & 12 deletions docs/docs/design/miniob-sql-expression.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,13 @@ expression 的规则会比较简单,加减乘除,以及负号取反。这里
%left '*' '/'
```

%left 表示左结合,就是遇到指定的符号,先跟左边的符号结合。而定义的顺序就是优先级的顺序,越靠后的优先级越高。
%left 表示左结合,就是遇到指定的符号,先跟左边的符号结合,比如 `1+2+3` 会被解析为 `(1+2)+3`。而定义的顺序就是优先级的顺序,越靠后的优先级越高。

负号运算符的特殊性除了它的优先级,还有它的结合性。普通的运算,比如 `1+2`,是两个数字即两个表达式,一个运算符。而负号的表示形式是 `-(1+2)`,即一个符号,一个表达式。
```yacc
%nonassoc UMINUS
%right UMINUS
```
表示 `UMINUS` 是一个一元运算符,没有结合性。在.y中,放到了 `%left '*' '/'` 的后面,说明优先级比乘除运算符高。
表示 `UMINUS` 是一个一元运算符,%right 表示右结合,作用与左结合类似,保证 `- -5` 等类似表达式可以被正确识别为 `-(-5)`。在.y中,放到了 `%left '*' '/'` 的后面,说明优先级比乘除运算符高。

expression 的规则如下:
```yacc
Expand Down Expand Up @@ -161,12 +161,4 @@ expression '+' expression {
## 抽象表达式类型
上面语法分析中描述的都是算术表达式,但是真实的SQL语句中,像字段名、常量、比较运算、函数、子查询等都是表达式。我们需要定义一个基类,然后派生出各种表达式类型。

这些表达式的定义已经在expression.h中定义,但是没有在语法解析中体现。更完善的做法是在 select 的属性列表、where 条件、insert 的 values等语句中,都使用表达式来表示。

## '-' 缺陷
由于在词法分析中,负号'-'与数字放在一起时,会被认为是一个负值数字,作为一个完整的token返回给语法分析,所以当前的语法分析无法正确的解析下面的表达式:
```
1 -2;
```
这个表达式的结果应该是 -1,但是当前的语法分析会认为是两个表达式,一个是1,一个是-2,这样就无法正确的计算出结果。
当前修复此问题的成本较高,需要修改词法分析的规则,所以暂时不做处理。
这些表达式的定义已经在expression.h中定义,但是没有在语法解析中体现。更完善的做法是在 select 的属性列表、where 条件、insert 的 values等语句中,都使用表达式来表示。
4 changes: 2 additions & 2 deletions src/observer/sql/parser/lex_sql.l
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ QUOTE [\'\"]
{WHITE_SPACE} // ignore whitespace
\n ;

[\-]?{DIGIT}+ yylval->number=atoi(yytext); RETURN_TOKEN(NUMBER);
[\-]?{DIGIT}+{DOT}{DIGIT}+ yylval->floats=(float)(atof(yytext)); RETURN_TOKEN(FLOAT);
{DIGIT}+ yylval->number=atoi(yytext); RETURN_TOKEN(NUMBER);
{DIGIT}+{DOT}{DIGIT}+ yylval->floats=(float)(atof(yytext)); RETURN_TOKEN(FLOAT);

";" RETURN_TOKEN(SEMICOLON);
{DOT} RETURN_TOKEN(DOT);
Expand Down
2 changes: 1 addition & 1 deletion src/observer/sql/parser/yacc_sql.y
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ UnboundAggregateExpr *create_aggregate_expression(const char *aggregate_name,

%left '+' '-'
%left '*' '/'
%nonassoc UMINUS
%right UMINUS
%%

commands: command_wrapper opt_semicolon //commands or sqls. parser starts here.
Expand Down