老叶茶馆|ClickHouse和他的朋友们(8)纯手工打造的SQL解析器( 三 )
if(!parser.parse(pos, list_node, expected))
returnfalse;
...
parser.parse 里又调用 第四层ParserSelectQuery::parseImpl 状态空间:
bool ParserSelectQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
auto select_query = std::make_shared<ASTSelectQuery>;
node = select_query;
ParserKeyword s_select( "SELECT");
ParserKeyword s_distinct( "DISTINCT");
ParserKeyword s_from( "FROM");
ParserKeyword s_prewhere( "PREWHERE");
ParserKeyword s_where( "WHERE");
ParserKeyword s_group_by( "GROUP BY");
ParserKeyword s_with( "WITH");
ParserKeyword s_totals( "TOTALS");
ParserKeyword s_having( "HAVING");
ParserKeyword s_order_by( "ORDER BY");
ParserKeyword s_limit( "LIMIT");
ParserKeyword s_settings( "SETTINGS");
ParserKeyword s_by( "BY");
ParserKeyword s_rollup( "ROLLUP");
ParserKeyword s_cube( "CUBE");
ParserKeyword s_top( "TOP");
ParserKeyword s_with_ties( "WITH TIES");
ParserKeyword s_offset( "OFFSET");
ParserNotEmptyExpressionList exp_list( false);
ParserNotEmptyExpressionList exp_list_for_with_clause( false);
ParserNotEmptyExpressionList exp_list_for_select_clause( true);
...
if(!exp_list_for_select_clause.parse(pos, select_expression_list, expected))
returnfalse;
第五层exp_list_for_select_clause.parse ParserExpressionList::parseImpl状态空间继续:
bool ParserExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
returnParserList(
std::make_unique<ParserExpressionWithOptionalAlias>(allow_alias_without_as_keyword),
std::make_unique<ParserToken>(TokenType::Comma))
.parse(pos, node, expected);
}
... ... 写不下去个鸟!
可以发现 , ast parser 的时候 , 预先构造好状态空间 , 比如 select 的状态空间:
- expression list
- from tables
- where
- group by
- with ...
- order by
- limit
总结
手工 parser 的好处是代码清晰简洁 , 每个细节可防可控 , 以及友好的错误处理 , 改动起来不会一发动全身 。 缺点是手工成本太高 , 需要大量的测试来保证其正确性 , 还需要一些fuzz来保证可靠性 。 好在ClickHouse 已经实现的比较全面 , 即使有新的需求 , 在现有基础上修修补补即可 。
文内链接
- https://github.com/ClickHouse/ClickHouse/blob/558f9c76306ffc4e6add8fd34c2071b64e914103/src/Parsers/ParserQuery.cpp#L26
- https://github.com/ClickHouse/ClickHouse/blob/558f9c76306ffc4e6add8fd34c2071b64e914103/src/Parsers/ParserQueryWithOutput.cpp#L31
- https://github.com/ClickHouse/ClickHouse/blob/558f9c76306ffc4e6add8fd34c2071b64e914103/src/Parsers/ParserExplainQuery.cpp#L10
- https://github.com/ClickHouse/ClickHouse/blob/558f9c76306ffc4e6add8fd34c2071b64e914103/src/Parsers/ParserSelectWithUnionQuery.cpp#L26
推荐阅读
- 老叶|植物花卉缺啥元素,11种症状对应11种元素
- 植株|多肉出现老叶子,要不要摘掉?熟知2个后果,你就知道了!
- 多肉植物|砍头的多肉植物爆芽后,老叶片该不该摘掉
- 养护|多肉出现老叶子,要不要摘掉?熟知2个后果,你就知道了!
- 叶子|养金钱树做好两件事,一年“撑破盆”,新芽比老叶还多
- 春季养虎皮兰的正确方法,让你的虎皮兰长满新芽,老叶肥厚硬挺
- 砍头的多肉植物爆芽后,老叶片该不该摘掉
- 朋友家的盆栽龙吐珠老叶黄不开花,为啥我的爬满围墙,每年都开花
- 盆栽的幸福树发新芽后,老叶全部脱落,手一碰就掉,是什么情况?
- 天冷了建兰最下面的老叶发黄了什么原因