ClickHouse源码分析——SQL解析

时间:2024-04-01 09:53:34

SQL解析函数

ClickHouse的SQL解析入口函数:parseQuery, 函数原型:

ASTPtr parseQuery(

    IParser & parser,

    const char * begin,

    const char * end,

    const std::string & query_description,

    size_t max_query_size)

具体的功能实现是通过调用tryParseQuery函数完成。

tryParseQuery函数

函数原型:

ASTPtr tryParseQuery(

    IParser & parser,

    const char * & pos,

    const char * end,

    std::string & out_error_message,

    bool hilite,

    const std::string & query_description,

    bool allow_multi_statements,

    size_t max_query_size)

该函数主要实现了两种功能:词法分析和语法解析。

ClickHouse词法解析

词法解析的主要任务是读入源程序的输入字符、将它们组成词素,生成并输出一个词法单元(Token)序列,每个词法单元对应于一个词素。

ClickHouse中的每个词法单元(Token)使用一个struct Tocken结构体对象来进行存储,结构体中存储了词法单元的type和value。

ClickHouse中token的种类列表:

name

description

Whitespace

{‘ ’|‘\t’|‘\n’|‘\r’|‘\f’| ‘\v’}+

Comment

 //     /*…*/

BareWord

{‘a’… ‘z’| ‘A’ … ‘Z’| ‘_’}+

Number

 二进制、八进制、十进制、十六进制等

StringLiteral

 \’

QuotedIdentifier

‘    “

OpeningRoundBracket

 (

ClosingRoundBracket

 )

OpeningSquareBracket

 [

ClosingSquareBracket

 ]

Comma

 ,

Semicolon

 ;

Dot

 .

Asterisk

 *

Plus

 +

Minus

 -

Slash

 /

Percent

 %

Arrow

 ->

QuestionMark

 ?

Colon

 :

Equals

 ==

NotEquals

 !=    <>

Less

 <

Creater

 >

LessOrEquals

 <=

GreaterOrEquals

 >=

Concatenation

 ||

 

ClickHouse词法分析器是由Tokens和Lexer类来实现, DB::Lexer::nextTokenImpl()函数用来对SQL语句进行词法分析的具体实现。

ClickHouse语法分析

语法分析器的作用是根据给定的形式文法对由词法单元(Token)序列构成的输入进行语法检查、并构建由输入的词法单元(Token)组成的数据结构(一般是语法分析树抽象语法树等层次化的数据结构)。

 

ClickHouse中定义了不同的Parser用来对不同类型的SQL语句进行语法分析,例如:ParserInsertQuery(Insert语法分析器)、ParserCreateQuery(Create语法分析器)、ParserAlterQuery(Alter语法分析器)等等。

Parser首先判断输入的Token序列是否是该类型的SQL,若是该类型的SQL,则继续检查语法的正确性,正确则生成AST返回,语法错误的则抛出语法错误异常,否则直接返回空AST语法树。

ClickHouse语法分析器的入口类:ParserQuery。该函数接收词法分析器传递的Token序列,将其传递给具体的Parser进行语法分析,并接受Parser产生的AST结果。

ClickHouse中Parser间的调用关系如下图所示:

ClickHouse源码分析——SQL解析