老叶茶馆|ClickHouse和他的朋友们(8)纯手工打造的SQL解析器( 二 )


EXPLAIN -- TokenType::BareWord
逻辑首先会进入Parsers/ParserQuery.cpp 的 ParserQuery::parseImpl 方法:
bool res = query_with_output_p.parse(pos, node, expected)
|| insert_p.parse(pos, node, expected)
|| use_p.parse(pos, node, expected)
|| set_role_p.parse(pos, node, expected)
|| set_p.parse(pos, node, expected)
|| system_p.parse(pos, node, expected)
|| create_user_p.parse(pos, node, expected)
|| create_role_p.parse(pos, node, expected)
|| create_quota_p.parse(pos, node, expected)
|| create_row_policy_p.parse(pos, node, expected)
|| create_settings_profile_p.parse(pos, node, expected)
|| drop_access_entity_p.parse(pos, node, expected)
|| grant_p.parse(pos, node, expected);
这里会对所有 query 类型进行 parse 方法的调用 , 直到有分支返回 true 。
我们来看 第一层query_with_output_p.parse Parsers/ParserQueryWithOutput.cpp:
bool parsed =
explain_p.parse(pos, query, expected)
|| select_p.parse(pos, query, expected)
|| show_create_access_entity_p.parse(pos, query, expected)
|| show_tables_p.parse(pos, query, expected)
|| table_p.parse(pos, query, expected)
|| describe_table_p.parse(pos, query, expected)
|| show_processlist_p.parse(pos, query, expected)
|| create_p.parse(pos, query, expected)
|| alter_p.parse(pos, query, expected)
|| rename_p.parse(pos, query, expected)
|| drop_p.parse(pos, query, expected)
|| check_p.parse(pos, query, expected)
|| kill_query_p.parse(pos, query, expected)
|| optimize_p.parse(pos, query, expected)
|| watch_p.parse(pos, query, expected)
|| show_access_p.parse(pos, query, expected)
|| show_access_entities_p.parse(pos, query, expected)
|| show_grants_p.parse(pos, query, expected)
|| show_privileges_p.parse(pos, query, expected
跳进 第二层explain_p.parse ParserExplainQuery::parseImpl状态空间:
bool ParserExplainQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ASTExplainQuery::ExplainKind kind;
bool old_syntax = false;
ParserKeyword s_ast( "AST");
ParserKeyword s_analyze( "ANALYZE");
ParserKeyword s_explain( "EXPLAIN");
ParserKeyword s_syntax( "SYNTAX");
ParserKeyword s_pipeline( "PIPELINE");
ParserKeyword s_plan( "PLAN");
... ...
elseif(s_explain.ignore(pos, expected))
{
... ...
}
... ...
ParserSelectWithUnionQuery select_p;
ASTPtr query;
if(!select_p.parse(pos, query, expected))
returnfalse;
... ...
s_explain.ignore 方法会进行一个 keyword 解析 , 解析出 ast node:
EXPLAIN -- keyword
跃进 第三层select_p.parse ParserSelectWithUnionQuery::parseImpl状态空间:
bool ParserSelectWithUnionQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ASTPtr list_node;
ParserList parser(std::make_unique<ParserUnionQueryElement>, std::make_unique<ParserKeyword>( "UNION ALL"), false);


推荐阅读