@@ -84,6 +84,7 @@ func setResult(l yyLexer, stmts []SQLStmt) {
8484%token NOT LIKE IF EXISTS IN IS
8585%token AUTO_INCREMENT NULL CAST SCAST
8686%token SHOW DATABASES TABLES USERS
87+ %token BETWEEN
8788%token <id> NPARAM
8889%token <pparam> PPARAM
8990%token <joinType> JOINTYPE
@@ -105,19 +106,20 @@ func setResult(l yyLexer, stmts []SQLStmt) {
105106%left ' ,'
106107%right AS
107108
109+ %nonassoc BETWEEN
110+
108111%left OR
109112%left AND
110113
111- %right NOT_MATCHES_OP
112- %right LIKE
113114%right NOT
114115
115- %left CMPOP
116+ %nonassoc CMPOP LIKE NOT_MATCHES_OP IS
117+
116118%left ' +' ' -'
117119%left ' *' ' /' ' %'
118- %left ' .'
120+ %left ' .'
121+
119122%right STMT_SEPARATOR
120- %left IS
121123
122124%type <stmts> sql sqlstmts
123125%type <stmt> sqlstmt ddlstmt dmlstmt dqlstmt select_stmt
@@ -144,8 +146,8 @@ func setResult(l yyLexer, stmts []SQLStmt) {
144146%type <check> check
145147%type <tableElem> tableElem
146148%type <tableElems> tableElems
147- %type <exp> exp opt_exp opt_where opt_having boundexp opt_else
148- %type <binExp> binExp
149+ %type <exp> exp opt_exp opt_where opt_having boundexp opt_else orExp andExp cmpExp primaryBool addExp notExp
150+ mulExp unaryExp primary
149151%type <cols> opt_groupby
150152%type <exp> opt_limit opt_offset case_when_exp
151153%type <targets> opt_targets targets
@@ -1140,63 +1142,6 @@ opt_exp:
11401142 }
11411143;
11421144
1143- exp:
1144- boundexp
1145- {
1146- $$ = $1
1147- }
1148- |
1149- binExp
1150- {
1151- $$ = $1
1152- }
1153- |
1154- NOT exp
1155- {
1156- $$ = &NotBoolExp{exp: $2 }
1157- }
1158- |
1159- ' -' exp
1160- {
1161- i, isInt := $2 .(*Integer)
1162- if isInt {
1163- i.val = -i.val
1164- $$ = i
1165- } else {
1166- $$ = &NumExp{left: &Integer{val: 0 }, op: SUBSOP, right: $2 }
1167- }
1168- }
1169- |
1170- boundexp opt_not LIKE exp
1171- {
1172- $$ = &LikeBoolExp{val: $1 , notLike: $2 , pattern: $4 }
1173- }
1174- |
1175- boundexp NOT_MATCHES_OP exp
1176- {
1177- $$ = &LikeBoolExp{val: $1 , notLike: true , pattern: $3 }
1178- }
1179- |
1180- EXISTS ' (' dqlstmt ' )'
1181- {
1182- $$ = &ExistsBoolExp{q: ($3 ).(DataSource)}
1183- }
1184- |
1185- boundexp opt_not IN ' (' dqlstmt ' )'
1186- {
1187- $$ = &InSubQueryExp{val: $1 , notIn: $2 , q: $5 .(*SelectStmt)}
1188- }
1189- |
1190- boundexp opt_not IN ' (' values ' )'
1191- {
1192- $$ = &InListExp{val: $1 , notIn: $2 , values: $5 }
1193- }
1194- |
1195- case_when_exp
1196- {
1197- $$ = $1
1198- }
1199-
12001145case_when_exp:
12011146 CASE opt_exp when_then_clauses opt_else END
12021147 {
@@ -1231,6 +1176,91 @@ opt_else:
12311176 }
12321177;
12331178
1179+ exp
1180+ : orExp { $$ = $1 }
1181+ ;
1182+
1183+ orExp
1184+ : orExp OR andExp { $$ = &BinBoolExp{left: $1 , op: Or, right: $3 } }
1185+ | andExp
1186+ ;
1187+
1188+ andExp
1189+ : andExp AND notExp { $$ = &BinBoolExp{left: $1 , op: And, right: $3 } }
1190+ | notExp
1191+ ;
1192+
1193+ notExp
1194+ : NOT notExp { $$ = &NotBoolExp{exp: $2 } }
1195+ | cmpExp
1196+ ;
1197+
1198+ cmpExp
1199+ : addExp CMPOP addExp { $$ = &CmpBoolExp{left: $1 , op: $2 , right: $3 } }
1200+ | addExp IS NULL { $$ = &CmpBoolExp{left: $1 , op: EQ, right: &NullValue{t: AnyType}} }
1201+ | addExp IS NOT NULL { $$ = &CmpBoolExp{left: $1 , op: NE, right: &NullValue{t: AnyType}} }
1202+ | addExp BETWEEN addExp AND addExp
1203+ {
1204+ $$ = &BinBoolExp{
1205+ left: &CmpBoolExp{
1206+ left: $1 ,
1207+ op: GE,
1208+ right: $3 ,
1209+ },
1210+ op: And,
1211+ right: &CmpBoolExp{
1212+ left: $1 ,
1213+ op: LE,
1214+ right: $5 ,
1215+ },
1216+ }
1217+ }
1218+ | addExp opt_not LIKE addExp { $$ = &LikeBoolExp{val: $1 , notLike: $2 , pattern: $4 } }
1219+ | addExp NOT_MATCHES_OP addExp { $$ = &LikeBoolExp{val: $1 , notLike: true , pattern: $3 } }
1220+ | primaryBool
1221+ ;
1222+
1223+ primaryBool
1224+ : EXISTS ' (' dqlstmt ' )' { $$ = &ExistsBoolExp{q: ($3 ).(DataSource)} }
1225+ | addExp opt_not IN ' (' dqlstmt ' )' { $$ = &InSubQueryExp{val: $1 , notIn: $2 , q: $5 .(*SelectStmt)} }
1226+ | addExp opt_not IN ' (' values ' )' { $$ = &InListExp{val: $1 , notIn: $2 , values: $5 } }
1227+ | case_when_exp { $$ = $1 }
1228+ | addExp
1229+ ;
1230+
1231+ addExp
1232+ : addExp ' +' mulExp { $$ = &NumExp{left: $1 , op: ADDOP, right: $3 } }
1233+ | addExp ' -' mulExp { $$ = &NumExp{left: $1 , op: SUBSOP, right: $3 } }
1234+ | mulExp
1235+ ;
1236+
1237+ mulExp
1238+ : mulExp ' *' unaryExp { $$ = &NumExp{left: $1 , op: MULTOP, right: $3 } }
1239+ | mulExp ' /' unaryExp { $$ = &NumExp{left: $1 , op: DIVOP, right: $3 } }
1240+ | mulExp ' %' unaryExp { $$ = &NumExp{left: $1 , op: MODOP, right: $3 } }
1241+ | unaryExp
1242+ ;
1243+
1244+ unaryExp
1245+ : ' -' unaryExp
1246+ {
1247+ i, isInt := $2 .(*Integer)
1248+ if isInt {
1249+ i.val = -i.val
1250+ $$ = i
1251+ } else {
1252+ $$ = &NumExp{left: &Integer{val: 0 }, op: SUBSOP, right: $2 }
1253+ }
1254+ }
1255+ |
1256+ primary
1257+ ;
1258+
1259+ primary
1260+ : ' (' exp ' )' { $$ = $2 }
1261+ | boundexp
1262+ ;
1263+
12341264boundexp:
12351265 selector
12361266 {
@@ -1241,11 +1271,6 @@ boundexp:
12411271 {
12421272 $$ = $1
12431273 }
1244- |
1245- ' (' exp ' )'
1246- {
1247- $$ = $2
1248- }
12491274|
12501275 boundexp SCAST TYPE
12511276 {
@@ -1262,53 +1287,3 @@ opt_not:
12621287 $$ = true
12631288 }
12641289
1265- binExp:
1266- exp ' +' exp
1267- {
1268- $$ = &NumExp{left: $1 , op: ADDOP, right: $3 }
1269- }
1270- |
1271- exp ' -' exp
1272- {
1273- $$ = &NumExp{left: $1 , op: SUBSOP, right: $3 }
1274- }
1275- |
1276- exp ' /' exp
1277- {
1278- $$ = &NumExp{left: $1 , op: DIVOP, right: $3 }
1279- }
1280- |
1281- exp ' *' exp
1282- {
1283- $$ = &NumExp{left: $1 , op: MULTOP, right: $3 }
1284- }
1285- |
1286- exp ' %' exp
1287- {
1288- $$ = &NumExp{left: $1 , op: MODOP, right: $3 }
1289- }
1290- |
1291- exp AND exp
1292- {
1293- $$ = &BinBoolExp{left: $1 , op: And, right: $3 }
1294- }
1295- |
1296- exp OR exp
1297- {
1298- $$ = &BinBoolExp{left: $1 , op: Or, right: $3 }
1299- }
1300- |
1301- exp CMPOP exp
1302- {
1303- $$ = &CmpBoolExp{left: $1 , op: $2 , right: $3 }
1304- }
1305- |
1306- exp IS NULL
1307- {
1308- $$ = &CmpBoolExp{left: $1 , op: EQ, right: &NullValue{t: AnyType}}
1309- }
1310- |
1311- exp IS NOT NULL
1312- {
1313- $$ = &CmpBoolExp{left: $1 , op: NE, right: &NullValue{t: AnyType}}
1314- }
0 commit comments