@@ -46,7 +46,7 @@ class MindsDBParser(Parser):
4646 ('nonassoc' , LESS , LEQ , GREATER , GEQ , IN , NOT_IN , BETWEEN , IS , IS_NOT , NOT_LIKE , LIKE ),
4747 ('left' , JSON_GET ),
4848 ('left' , PLUS , MINUS ),
49- ('left' , STAR , DIVIDE , TYPECAST ),
49+ ('left' , STAR , DIVIDE , TYPECAST , MODULO ),
5050 ('right' , UMINUS ), # Unary minus operator, unary not
5151
5252 )
@@ -68,9 +68,9 @@ class MindsDBParser(Parser):
6868 'drop_predictor' ,
6969 'drop_datasource' ,
7070 'drop_dataset' ,
71- 'union' ,
7271 'select' ,
7372 'insert' ,
73+ 'union' ,
7474 'update' ,
7575 'delete' ,
7676 'evaluate' ,
@@ -615,10 +615,13 @@ def update(self, p):
615615
616616 # INSERT
617617 @_ ('INSERT INTO identifier LPAREN column_list RPAREN select' ,
618- 'INSERT INTO identifier select' )
618+ 'INSERT INTO identifier LPAREN column_list RPAREN union' ,
619+ 'INSERT INTO identifier select' ,
620+ 'INSERT INTO identifier union' )
619621 def insert (self , p ):
620622 columns = getattr (p , 'column_list' , None )
621- return Insert (table = p .identifier , columns = columns , from_select = p .select )
623+ query = p .select if hasattr (p , 'select' ) else p .union
624+ return Insert (table = p .identifier , columns = columns , from_select = query )
622625
623626 @_ ('INSERT INTO identifier LPAREN column_list RPAREN VALUES expr_list_set' ,
624627 'INSERT INTO identifier VALUES expr_list_set' )
@@ -999,21 +1002,35 @@ def database_engine(self, p):
9991002 engine = p .string
10001003 return {'identifier' :p .identifier , 'engine' :engine , 'if_not_exists' :p .if_not_exists_or_empty }
10011004
1002- # UNION / UNION ALL
1005+ # Combining
10031006 @_ ('select UNION select' ,
1004- 'union UNION select' )
1007+ 'union UNION select' ,
1008+ 'select UNION ALL select' ,
1009+ 'union UNION ALL select' )
10051010 def union (self , p ):
1006- return Union (left = p [0 ], right = p [2 ], unique = True )
1011+ unique = not hasattr (p , 'ALL' )
1012+ return Union (left = p [0 ], right = p [2 ] if unique else p [3 ], unique = unique )
10071013
1008- @_ ('select UNION ALL select' ,
1009- 'union UNION ALL select' ,)
1014+ @_ ('select INTERSECT select' ,
1015+ 'union INTERSECT select' ,
1016+ 'select INTERSECT ALL select' ,
1017+ 'union INTERSECT ALL select' )
1018+ def union (self , p ):
1019+ unique = not hasattr (p , 'ALL' )
1020+ return Intersect (left = p [0 ], right = p [2 ] if unique else p [3 ], unique = unique )
1021+ @_ ('select EXCEPT select' ,
1022+ 'union EXCEPT select' ,
1023+ 'select EXCEPT ALL select' ,
1024+ 'union EXCEPT ALL select' )
10101025 def union (self , p ):
1011- return Union (left = p [0 ], right = p [3 ], unique = False )
1026+ unique = not hasattr (p , 'ALL' )
1027+ return Except (left = p [0 ], right = p [2 ] if unique else p [3 ], unique = unique )
10121028
10131029 # tableau
10141030 @_ ('LPAREN select RPAREN' )
1031+ @_ ('LPAREN union RPAREN' )
10151032 def select (self , p ):
1016- return p . select
1033+ return p [ 1 ]
10171034
10181035 # WITH
10191036 @_ ('ctes select' )
@@ -1033,13 +1050,14 @@ def ctes(self, p):
10331050 ]
10341051 return ctes
10351052
1036- @_ ('WITH identifier cte_columns_or_nothing AS LPAREN select RPAREN' )
1053+ @_ ('WITH identifier cte_columns_or_nothing AS LPAREN select RPAREN' ,
1054+ 'WITH identifier cte_columns_or_nothing AS LPAREN union RPAREN' )
10371055 def ctes (self , p ):
10381056 return [
10391057 CommonTableExpression (
10401058 name = p .identifier ,
10411059 columns = p .cte_columns_or_nothing ,
1042- query = p . select )
1060+ query = p [ 5 ] )
10431061 ]
10441062
10451063 @_ ('empty' )
@@ -1334,6 +1352,15 @@ def column_list(self, p):
13341352 def case (self , p ):
13351353 return Case (rules = p .case_conditions , default = getattr (p , 'expr' , None ))
13361354
1355+ @_ ('CASE expr case_conditions ELSE expr END' ,
1356+ 'CASE expr case_conditions END' )
1357+ def case (self , p ):
1358+ if hasattr (p , 'expr' ):
1359+ arg , default = p .expr , None
1360+ else :
1361+ arg , default = p .expr0 , p .expr1
1362+ return Case (rules = p .case_conditions , default = default , arg = arg )
1363+
13371364 @_ ('case_condition' ,
13381365 'case_conditions case_condition' )
13391366 def case_conditions (self , p ):
@@ -1346,13 +1373,18 @@ def case_condition(self, p):
13461373 return [p .expr0 , p .expr1 ]
13471374
13481375 # Window function
1349- @_ ('function OVER LPAREN window RPAREN' )
1376+ @_ ('expr OVER LPAREN window RPAREN' ,
1377+ 'expr OVER LPAREN window id BETWEEN id id AND id id RPAREN' )
13501378 def window_function (self , p ):
13511379
1380+ modifier = None
1381+ if hasattr (p , 'BETWEEN' ):
1382+ modifier = f'{ p .id0 } BETWEEN { p .id1 } { p .id2 } AND { p .id3 } { p .id4 } '
13521383 return WindowFunction (
1353- function = p .function ,
1384+ function = p .expr ,
13541385 order_by = p .window .get ('order_by' ),
13551386 partition = p .window .get ('partition' ),
1387+ modifier = modifier ,
13561388 )
13571389
13581390 @_ ('window PARTITION_BY expr_list' )
@@ -1469,8 +1501,13 @@ def expr_list_or_nothing(self, p):
14691501 pass
14701502
14711503 @_ ('CAST LPAREN expr AS id LPAREN integer RPAREN RPAREN' )
1504+ @_ ('CAST LPAREN expr AS id LPAREN integer COMMA integer RPAREN RPAREN' )
14721505 def expr (self , p ):
1473- return TypeCast (arg = p .expr , type_name = str (p .id ), length = p .integer )
1506+ if hasattr (p , 'integer' ):
1507+ precision = [p .integer ]
1508+ else :
1509+ precision = [p .integer0 , p .integer1 ]
1510+ return TypeCast (arg = p .expr , type_name = str (p .id ), precision = precision )
14741511
14751512 @_ ('CAST LPAREN expr AS id RPAREN' )
14761513 def expr (self , p ):
0 commit comments