Skip to content

Commit 82e09c9

Browse files
committed
TABLE statemtnet
1 parent fd402aa commit 82e09c9

File tree

4 files changed

+119
-0
lines changed

4 files changed

+119
-0
lines changed

mindsdb_sql_parser/ast/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@
1515
from .drop import *
1616
from .create import *
1717
from .variable import *
18+
from .table import Table
1819

1920
from .mindsdb.latest import Latest

mindsdb_sql_parser/ast/table.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
from typing import Optional, List, Any
2+
3+
from mindsdb_sql_parser.ast.base import ASTNode
4+
5+
6+
class Table(ASTNode):
7+
"""AST node representing a TABLE statement with optional ORDER BY, LIMIT, and OFFSET clauses.
8+
https://dev.mysql.com/doc/refman/8.4/en/table.html
9+
10+
Args:
11+
name: The name of the table (Identifier).
12+
order_by: Optional list of ORDER BY terms.
13+
limit: Optional LIMIT value (Constant).
14+
offset: Optional OFFSET value (Constant).
15+
*args: Additional positional arguments for ASTNode.
16+
**kwargs: Additional keyword arguments for ASTNode.
17+
"""
18+
def __init__(
19+
self,
20+
name: Any,
21+
order_by: Optional[List[Any]] = None,
22+
limit: Optional[Any] = None,
23+
offset: Optional[Any] = None,
24+
*args,
25+
**kwargs
26+
):
27+
super().__init__(*args, **kwargs)
28+
self.name = name
29+
self.order_by = order_by
30+
self.limit = limit
31+
self.offset = offset
32+
33+
def to_tree(self, *args, level: int = 0, **kwargs) -> str:
34+
"""Returns a string representation of the AST tree for this node.
35+
36+
Args:
37+
level: Indentation level for pretty printing.
38+
*args: Additional positional arguments.
39+
**kwargs: Additional keyword arguments.
40+
41+
Returns:
42+
str: The tree representation of the node.
43+
"""
44+
ind = ' ' * level
45+
out = f'{ind}Table(\n'
46+
out += f'{ind} name={self.name},\n'
47+
if self.order_by:
48+
out += f'{ind} order_by={self.order_by},\n'
49+
if self.limit:
50+
out += f'{ind} limit={self.limit},\n'
51+
if self.offset:
52+
out += f'{ind} offset={self.offset},\n'
53+
out += f'{ind})'
54+
return out
55+
56+
def to_string(self, *args, **kwargs) -> str:
57+
"""Returns a SQL string representation of the TABLE statement.
58+
59+
Args:
60+
*args: Additional positional arguments.
61+
**kwargs: Additional keyword arguments.
62+
63+
Returns:
64+
str: The SQL string representation.
65+
"""
66+
s = f'TABLE {self.name}'
67+
if self.order_by:
68+
s += ' ORDER BY ' + ', '.join([o.to_string() for o in self.order_by])
69+
if self.limit:
70+
s += f' LIMIT {self.limit.to_string()}'
71+
if self.offset:
72+
s += f' OFFSET {self.offset.to_string()}'
73+
return s

mindsdb_sql_parser/parser.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class MindsDBParser(Parser):
103103
'update_agent',
104104
'create_index',
105105
'drop_index',
106+
'table',
106107
)
107108
def query(self, p):
108109
return p[0]
@@ -2083,3 +2084,39 @@ def error(self, p, expected_tokens=None):
20832084
)
20842085
# don't raise exception
20852086
return
2087+
2088+
# region TABLE https://dev.mysql.com/doc/refman/8.4/en/table.html
2089+
@_('TABLE identifier table_opt_order_by table_opt_limit table_opt_offset')
2090+
def table(self, p):
2091+
from mindsdb_sql_parser.ast.table import Table
2092+
return Table(
2093+
name=p.identifier,
2094+
order_by=p.table_opt_order_by,
2095+
limit=p.table_opt_limit,
2096+
offset=p.table_opt_offset
2097+
)
2098+
2099+
@_('empty')
2100+
def table_opt_order_by(self, p):
2101+
return None
2102+
2103+
@_('ORDER_BY ordering_terms')
2104+
def table_opt_order_by(self, p):
2105+
return p.ordering_terms
2106+
2107+
@_('empty')
2108+
def table_opt_limit(self, p):
2109+
return None
2110+
2111+
@_('LIMIT constant')
2112+
def table_opt_limit(self, p):
2113+
return p.constant
2114+
2115+
@_('empty')
2116+
def table_opt_offset(self, p):
2117+
return None
2118+
2119+
@_('OFFSET constant')
2120+
def table_opt_offset(self, p):
2121+
return p.constant
2122+
# endregion

tests/test_base_sql/test_misc_sql_queries.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ def test_autocommit(self):
7777
assert ast.to_tree() == expected_ast.to_tree()
7878
assert str(ast) == str(expected_ast)
7979

80+
def test_table_with_order_by_limit_offset(self):
81+
sql = "TABLE my_table ORDER BY id LIMIT 10 OFFSET 5"
82+
ast = parse_sql(sql)
83+
assert isinstance(ast, Table)
84+
assert ast.name.to_string() == 'my_table'
85+
assert ast.order_by[0].field.to_string() == 'id'
86+
assert ast.limit.value == 10
87+
assert ast.offset.value == 5
8088

8189

8290
class TestMiscQueriesNoSqlite:

0 commit comments

Comments
 (0)