使用 ANTLR4 解析 T-SQL 查询

Parsing a T-SQL query using ANTLR4

我目前正在开发一个 T-SQL 解析器,它将能够为我的学校项目映射数据库中的查询。到目前为止,我已经设法解析了其中的大部分内容,但我遇到了一个似乎无法解决的问题。我正在使用 C# 和 tsql.g4 语法和 ANTLR4。

如何访问表达式?我想知道我在 select 中并且我有某种表达方式,但是表达方式是什么?是否可以从 select_statement?

中仅提取列名、模式(如果有)和数据库(如果有)

每当我尝试从 c# 代码访问 expression 时:

上下文:GrammarSQLParser.Dml_clauseContext context context.select_statement().query_expression().query_specification().select_list().select_list_elem().expression()

我只得到方法 CopyFrom(),我没有任何 full_column_name() 方法可以进一步访问 table_name() 等等..

edit1: 仔细检查后,表达式是 column_ref_expression,但如何从表达式访问它?它们是不同的对象..

这是查询:

select p.BusinessEntityID,p.FirstName,p.LastName,adresstbl.* from person.Person as p 
join (select bea.BusinessEntityID, adr.AddressLine1, adr.AddressLine2, adr.City, adr.PostalCode from person.BusinessEntityAddress as bea 
join person.Address as adr
on bea.AddressID = adr.AddressID )
as adresstbl 
on not p.BusinessEntityID != adresstbl.BusinessEntityID order by p.BusinessEntityID

这是我的解析树:

Lisp Parse Tree: (tsql_file (batch (sql_clauses (sql_clause (dml_clause (select_statement (query_expression (query_specification select (select_list (select_list_elem (expression (full_column_name (table_name (id (simple_id p))) . (id (simple_id BusinessEntityID))))) , (select_list_elem (expression (full_column_name (table_name (id (simple_id p))) . (id (simple_id FirstName))))) , (select_list_elem (expression (full_column_name (table_name (id (simple_id p))) . (id (simple_id LastName))))) , (select_list_elem (table_name (id (simple_id adresstbl))) . *)) from (table_sources (table_source (table_source_item_joined (table_source_item (table_name_with_hint (table_name (id (simple_id person)) . (id (simple_id Person)))) (as_table_alias as (table_alias (id (simple_id p))))) (join_part join (table_source (table_source_item_joined (table_source_item (derived_table (subquery (select_statement (query_expression ( (query_expression (query_specification select (select_list (select_list_elem (expression (full_column_name (table_name (id (simple_id bea))) . (id (simple_id BusinessEntityID))))) , (select_list_elem (expression (full_column_name (table_name (id (simple_id adr))) . (id (simple_id AddressLine1))))) , (select_list_elem (expression (full_column_name (table_name (id (simple_id adr))) . (id (simple_id AddressLine2))))) , (select_list_elem (expression (full_column_name (table_name (id (simple_id adr))) . (id (simple_id City))))) , (select_list_elem (expression (full_column_name (table_name (id (simple_id adr))) . (id (simple_id PostalCode)))))) from (table_sources (table_source (table_source_item_joined (table_source_item (table_name_with_hint (table_name (id (simple_id person)) . (id (simple_id BusinessEntityAddress)))) (as_table_alias as (table_alias (id (simple_id bea))))) (join_part join (table_source (table_source_item_joined (table_source_item (table_name_with_hint (table_name (id (simple_id person)) . (id (simple_id Address)))) (as_table_alias as (table_alias (id (simple_id adr))))))) on (search_condition (search_condition_and (search_condition_not (predicate (expression (full_column_name (table_name (id (simple_id bea))) . (id (simple_id AddressID)))) (comparison_operator =) (expression (full_column_name (table_name (id (simple_id adr))) . (id (simple_id AddressID)))))))))))))) ))))) (as_table_alias as (table_alias (id (simple_id adresstbl))))))) on (search_condition (search_condition_and (search_condition_not not (predicate (expression (full_column_name (table_name (id (simple_id p))) . (id (simple_id BusinessEntityID)))) (comparison_operator ! =) (expression (full_column_name (table_name (id (simple_id adresstbl))) . (id (simple_id BusinessEntityID)))))))))))))) (order_by_clause order by (order_by_expression (expression (full_column_name (table_name (id (simple_id p))) . (id (simple_id BusinessEntityID))))))))))) )

expression 可能是许多事情之一。如果你看语法,你会看到

expression
    : DEFAULT                                                  #primitive_expression
    | NULL                                                     #primitive_expression
    | LOCAL_ID                                                 #primitive_expression
    | constant                                                 #primitive_expression
    | function_call                                            #function_call_expression
    | expression COLLATE id                                    #function_call_expression
    | case_expr                                                #case_expression
    | full_column_name                                         #column_ref_expression
    | '(' expression ')'                                       #bracket_expression
    | '(' subquery ')'                                         #subquery_expression
    | '~' expression                                           #unary_operator_expression

    | expression op=('*' | '/' | '%') expression               #binary_operator_expression
    | op=('+' | '-') expression                                #unary_operator_expression
    | expression op=('+' | '-' | '&' | '^' | '|') expression   #binary_operator_expression
    | expression comparison_operator expression                #binary_operator_expression
    ;

你需要弄清楚是哪一个。在你的情况下,它是一个 column_ref_expression,在这种情况下你需要将它转换为 Column_ref_expressionContext 然后你将能够访问 full_column_name.

有多种方法可以确定它是哪个,或者如果您只想支持语法的有限子集,您可以假设。