Skip to content

Commit 67cd0ca

Browse files
authored
Merge pull request #79 from mindsdb/union-in-in
UNION can be an expression
2 parents 398f179 + 86ba838 commit 67cd0ca

3 files changed

Lines changed: 43 additions & 26 deletions

File tree

mindsdb_sql_parser/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
__title__ = 'mindsdb_sql_parser'
22
__package_name__ = 'mindsdb_sql_parser'
3-
__version__ = '0.13.3'
3+
__version__ = '0.13.4'
44
__description__ = "Mindsdb SQL parser"
55
__email__ = "jorge@mindsdb.com"
66
__author__ = 'MindsDB Inc'

mindsdb_sql_parser/parser.py

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -667,13 +667,11 @@ def update(self, p):
667667
from_select=p.select)
668668

669669
# INSERT
670-
@_('INSERT INTO identifier LPAREN column_list RPAREN select',
671-
'INSERT INTO identifier LPAREN column_list RPAREN union',
672-
'INSERT INTO identifier select',
670+
@_('INSERT INTO identifier LPAREN column_list RPAREN union',
673671
'INSERT INTO identifier union')
674672
def insert(self, p):
675673
columns = getattr(p, 'column_list', None)
676-
query = p.select if hasattr(p, 'select') else p.union
674+
query = p.union
677675
return Insert(table=p.identifier, columns=columns, from_select=query)
678676

679677
@_('INSERT INTO identifier LPAREN column_list RPAREN VALUES expr_list_set',
@@ -1086,33 +1084,24 @@ def database_engine(self, p):
10861084
return {'identifier':p.identifier, 'engine':engine, 'if_not_exists':p.if_not_exists_or_empty}
10871085

10881086
# Combining
1089-
@_('select UNION select',
1090-
'union UNION select',
1091-
'select UNION ALL select',
1087+
@_('union UNION select',
10921088
'union UNION ALL select',
1093-
'select UNION DISTINCT select',
10941089
'union UNION DISTINCT select')
10951090
def union(self, p):
10961091
unique = not hasattr(p, 'ALL')
10971092
distinct_key = hasattr(p, 'DISTINCT')
10981093
return Union(left=p[0], right=p[-1], unique=unique, distinct_key=distinct_key)
10991094

1100-
@_('select INTERSECT select',
1101-
'union INTERSECT select',
1102-
'select INTERSECT ALL select',
1095+
@_('union INTERSECT select',
11031096
'union INTERSECT ALL select',
1104-
'select INTERSECT DISTINCT select',
11051097
'union INTERSECT DISTINCT select')
11061098
def union(self, p):
11071099
unique = not hasattr(p, 'ALL')
11081100
distinct_key = hasattr(p, 'DISTINCT')
11091101
return Intersect(left=p[0], right=p[-1], unique=unique, distinct_key=distinct_key)
11101102

1111-
@_('select EXCEPT select',
1112-
'union EXCEPT select',
1113-
'select EXCEPT ALL select',
1103+
@_('union EXCEPT select',
11141104
'union EXCEPT ALL select',
1115-
'select EXCEPT DISTINCT select',
11161105
'union EXCEPT DISTINCT select')
11171106
def union(self, p):
11181107
unique = not hasattr(p, 'ALL')
@@ -1121,19 +1110,21 @@ def union(self, p):
11211110

11221111
# tableau
11231112
@_('LPAREN select RPAREN')
1124-
@_('LPAREN union RPAREN')
11251113
def select(self, p):
11261114
return p[1]
11271115

1116+
@_('select')
1117+
def union(self, p):
1118+
return p[0]
1119+
11281120
# WITH
11291121
@_('ctes select')
11301122
def select(self, p):
11311123
select = p.select
11321124
select.cte = p.ctes
11331125
return select
11341126

1135-
@_('ctes COMMA identifier cte_columns_or_nothing AS LPAREN select RPAREN',
1136-
'ctes COMMA identifier cte_columns_or_nothing AS LPAREN union RPAREN')
1127+
@_('ctes COMMA identifier cte_columns_or_nothing AS LPAREN union RPAREN')
11371128
def ctes(self, p):
11381129
ctes = p.ctes
11391130
ctes = ctes + [
@@ -1144,8 +1135,7 @@ def ctes(self, p):
11441135
]
11451136
return ctes
11461137

1147-
@_('WITH identifier cte_columns_or_nothing AS LPAREN select RPAREN',
1148-
'WITH identifier cte_columns_or_nothing AS LPAREN union RPAREN')
1138+
@_('WITH identifier cte_columns_or_nothing AS LPAREN union RPAREN')
11491139
def ctes(self, p):
11501140
return [
11511141
CommonTableExpression(
@@ -1518,11 +1508,11 @@ def window(self, p):
15181508

15191509
# OPERATIONS
15201510

1521-
@_('LPAREN select RPAREN')
1511+
@_('LPAREN union RPAREN')
15221512
def expr(self, p):
1523-
select = p.select
1524-
select.parentheses = True
1525-
return select
1513+
union = p.union
1514+
union.parentheses = True
1515+
return union
15261516

15271517
@_('LPAREN expr RPAREN')
15281518
def expr(self, p):

tests/test_base_sql/test_select_structure.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,33 @@ def test_is_not_precedence(self):
877877
assert str(ast) == str(expected_ast)
878878
assert ast.to_tree() == expected_ast.to_tree()
879879

880+
def test_in_union(self):
881+
sql = f'''
882+
SELECT * FROM tbl1
883+
where col in (
884+
select id from tbl2
885+
union
886+
select id from tbl3
887+
)
888+
'''
889+
ast = parse_sql(sql)
890+
891+
expected_ast = Select(
892+
targets=[Star()],
893+
from_table=Identifier('tbl1'),
894+
where=BinaryOperation(op='in', args=(
895+
Identifier('col'),
896+
Union(
897+
left=Select(targets=[Identifier('id')], from_table=Identifier('tbl2')),
898+
right=Select(targets=[Identifier('id')], from_table=Identifier('tbl3')),
899+
parentheses=True
900+
)
901+
))
902+
)
903+
904+
assert str(ast) == str(expected_ast)
905+
assert ast.to_tree() == expected_ast.to_tree()
906+
880907

881908
class TestSelectStructureNoSqlite:
882909
def test_select_from_plugins(self):

0 commit comments

Comments
 (0)