Skip to content

Commit

Permalink
Merge pull request #25 from ChangxingJiang/24-dev
Browse files Browse the repository at this point in the history
#24:新增 DELETE 语句解析逻辑
  • Loading branch information
ChangxingJiang authored May 28, 2024
2 parents cecd6aa + 8e5ada4 commit 2c1adc0
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
24 changes: 24 additions & 0 deletions metasequoia_sql/core/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@
"ASTUpdateSetClause", # UPDATE 语句中的 SET 子句
"ASTUpdateStatement", # UPDATE 语句

# ------------------------------ 抽象语法树(AST)节点的 DELETE 语句节点 ------------------------------
"ASTDeleteStatement", # DELETE 语句

# ------------------------------ 抽象语法树(AST)节点的 SHOW 语句节点 ------------------------------
"ASTShowDatabasesStatement", # SHOW DATABASES 语句
"ASTShowTablesStatement", # SHOW TABLES 语句
Expand Down Expand Up @@ -1865,6 +1868,27 @@ def source(self, sql_type: SQLType = SQLType.DEFAULT) -> str:
return result


@dataclasses.dataclass(slots=True, frozen=True, eq=True)
class ASTDeleteStatement(ASTStatementBase):
"""DELETE 语句"""

table_name: ASTTableNameExpression = dataclasses.field(kw_only=True)
where_clause: Optional[ASTWhereClause] = dataclasses.field(kw_only=True)
order_by_clause: Optional[ASTOrderByClause] = dataclasses.field(kw_only=True)
limit_clause: Optional[ASTLimitClause] = dataclasses.field(kw_only=True)

def source(self, sql_type: SQLType = SQLType.DEFAULT) -> str:
"""返回语法节点的 SQL 源码"""
result = f"DELETE FROM {self.table_name.source(sql_type)} "
if self.where_clause is not None:
result += f" {self.where_clause.source(sql_type)}"
if self.order_by_clause is not None:
result += f" {self.order_by_clause.source(sql_type)}"
if self.limit_clause is not None:
result += f" {self.limit_clause.source(sql_type)}"
return result


@dataclasses.dataclass(slots=True, frozen=True, eq=True)
class ASTShowDatabasesStatement(ASTStatementBase):
"""SHOW DATABASES 语句"""
Expand Down
25 changes: 25 additions & 0 deletions metasequoia_sql/core/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2240,6 +2240,27 @@ def _parse_update_statement(cls, scanner: TokenScanner,
limit_clause=limit_clause
)

@classmethod
def parse_delete_statement(cls, scanner_or_string: ScannerOrString,
sql_type: SQLType = SQLType.DEFAULT) -> node.ASTDeleteStatement:
"""解析 UPDATE 语句"""
scanner = cls._unify_input_scanner(scanner_or_string, sql_type=sql_type)
return cls._parse_delete_statement(scanner, sql_type)

@classmethod
def _parse_delete_statement(cls, scanner: TokenScanner, sql_type: SQLType) -> node.ASTDeleteStatement:
scanner.match("DELETE", "FROM")
table_name = cls._parse_table_name_expression(scanner)
where_clause = cls._parse_where_clause(scanner, sql_type)
order_by_clause = cls._parse_order_by_clause(scanner, sql_type)
limit_clause = cls._parse_limit_clause(scanner)
return node.ASTDeleteStatement(
table_name=table_name,
where_clause=where_clause,
order_by_clause=order_by_clause,
limit_clause=limit_clause
)

@classmethod
def parse_show_columns_statement(cls, scanner_or_string: ScannerOrString,
sql_type: SQLType = SQLType.DEFAULT) -> node.ASTShowColumnsStatement:
Expand Down Expand Up @@ -2269,6 +2290,10 @@ def parse_statements(cls, scanner_or_string: ScannerOrString,
if scanner.search_one_type_str_use_upper("SET"):
statement_list.append(cls._parse_set_statement(scanner))

# 解析 DELETE 语句
elif scanner.search_two_type_str_use_upper("DELETE", "FROM"):
statement_list.append(cls._parse_delete_statement(scanner, sql_type))

# 解析 DROP TABLE 语句
elif scanner.search_two_type_str_use_upper("DROP", "TABLE"):
statement_list.append(cls._parse_drop_table_statement(scanner))
Expand Down
15 changes: 15 additions & 0 deletions scripts/tests/test_parse_statement.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
语句级解析样例
"""

import unittest

from metasequoia_sql import SQLParser


class TestDolphinSchedulerMysql(unittest.TestCase):
"""使用海豚调度元数据的测试用例"""

def test_delete_statement(self):
"""测试 DELETE 语句解析"""
SQLParser.parse_statements("DELETE FROM table_1 WHERE column1 = '3'")

0 comments on commit 2c1adc0

Please sign in to comment.