Merge branch 'master' into inconsisteny

This commit is contained in:
Kseniia Sumarokova 2021-07-04 02:29:56 +03:00 committed by GitHub
commit 705e839390
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
141 changed files with 356 additions and 35494 deletions

3
.gitmodules vendored
View File

@ -168,9 +168,6 @@
[submodule "contrib/fmtlib"]
path = contrib/fmtlib
url = https://github.com/fmtlib/fmt.git
[submodule "contrib/antlr4-runtime"]
path = contrib/antlr4-runtime
url = https://github.com/ClickHouse-Extras/antlr4-runtime.git
[submodule "contrib/sentry-native"]
path = contrib/sentry-native
url = https://github.com/ClickHouse-Extras/sentry-native.git

View File

@ -34,7 +34,6 @@ endif()
set_property(DIRECTORY PROPERTY EXCLUDE_FROM_ALL 1)
add_subdirectory (abseil-cpp-cmake)
add_subdirectory (antlr4-runtime-cmake)
add_subdirectory (boost-cmake)
add_subdirectory (cctz-cmake)
add_subdirectory (consistent-hashing)

@ -1 +0,0 @@
Subproject commit 672643e9a427ef803abf13bc8cb4989606553d64

View File

@ -1,156 +0,0 @@
set (LIBRARY_DIR "${ClickHouse_SOURCE_DIR}/contrib/antlr4-runtime")
set (SRCS
"${LIBRARY_DIR}/ANTLRErrorListener.cpp"
"${LIBRARY_DIR}/ANTLRErrorStrategy.cpp"
"${LIBRARY_DIR}/ANTLRFileStream.cpp"
"${LIBRARY_DIR}/ANTLRInputStream.cpp"
"${LIBRARY_DIR}/atn/AbstractPredicateTransition.cpp"
"${LIBRARY_DIR}/atn/ActionTransition.cpp"
"${LIBRARY_DIR}/atn/AmbiguityInfo.cpp"
"${LIBRARY_DIR}/atn/ArrayPredictionContext.cpp"
"${LIBRARY_DIR}/atn/ATN.cpp"
"${LIBRARY_DIR}/atn/ATNConfig.cpp"
"${LIBRARY_DIR}/atn/ATNConfigSet.cpp"
"${LIBRARY_DIR}/atn/ATNDeserializationOptions.cpp"
"${LIBRARY_DIR}/atn/ATNDeserializer.cpp"
"${LIBRARY_DIR}/atn/ATNSerializer.cpp"
"${LIBRARY_DIR}/atn/ATNSimulator.cpp"
"${LIBRARY_DIR}/atn/ATNState.cpp"
"${LIBRARY_DIR}/atn/AtomTransition.cpp"
"${LIBRARY_DIR}/atn/BasicBlockStartState.cpp"
"${LIBRARY_DIR}/atn/BasicState.cpp"
"${LIBRARY_DIR}/atn/BlockEndState.cpp"
"${LIBRARY_DIR}/atn/BlockStartState.cpp"
"${LIBRARY_DIR}/atn/ContextSensitivityInfo.cpp"
"${LIBRARY_DIR}/atn/DecisionEventInfo.cpp"
"${LIBRARY_DIR}/atn/DecisionInfo.cpp"
"${LIBRARY_DIR}/atn/DecisionState.cpp"
"${LIBRARY_DIR}/atn/EmptyPredictionContext.cpp"
"${LIBRARY_DIR}/atn/EpsilonTransition.cpp"
"${LIBRARY_DIR}/atn/ErrorInfo.cpp"
"${LIBRARY_DIR}/atn/LexerAction.cpp"
"${LIBRARY_DIR}/atn/LexerActionExecutor.cpp"
"${LIBRARY_DIR}/atn/LexerATNConfig.cpp"
"${LIBRARY_DIR}/atn/LexerATNSimulator.cpp"
"${LIBRARY_DIR}/atn/LexerChannelAction.cpp"
"${LIBRARY_DIR}/atn/LexerCustomAction.cpp"
"${LIBRARY_DIR}/atn/LexerIndexedCustomAction.cpp"
"${LIBRARY_DIR}/atn/LexerModeAction.cpp"
"${LIBRARY_DIR}/atn/LexerMoreAction.cpp"
"${LIBRARY_DIR}/atn/LexerPopModeAction.cpp"
"${LIBRARY_DIR}/atn/LexerPushModeAction.cpp"
"${LIBRARY_DIR}/atn/LexerSkipAction.cpp"
"${LIBRARY_DIR}/atn/LexerTypeAction.cpp"
"${LIBRARY_DIR}/atn/LL1Analyzer.cpp"
"${LIBRARY_DIR}/atn/LookaheadEventInfo.cpp"
"${LIBRARY_DIR}/atn/LoopEndState.cpp"
"${LIBRARY_DIR}/atn/NotSetTransition.cpp"
"${LIBRARY_DIR}/atn/OrderedATNConfigSet.cpp"
"${LIBRARY_DIR}/atn/ParseInfo.cpp"
"${LIBRARY_DIR}/atn/ParserATNSimulator.cpp"
"${LIBRARY_DIR}/atn/PlusBlockStartState.cpp"
"${LIBRARY_DIR}/atn/PlusLoopbackState.cpp"
"${LIBRARY_DIR}/atn/PrecedencePredicateTransition.cpp"
"${LIBRARY_DIR}/atn/PredicateEvalInfo.cpp"
"${LIBRARY_DIR}/atn/PredicateTransition.cpp"
"${LIBRARY_DIR}/atn/PredictionContext.cpp"
"${LIBRARY_DIR}/atn/PredictionMode.cpp"
"${LIBRARY_DIR}/atn/ProfilingATNSimulator.cpp"
"${LIBRARY_DIR}/atn/RangeTransition.cpp"
"${LIBRARY_DIR}/atn/RuleStartState.cpp"
"${LIBRARY_DIR}/atn/RuleStopState.cpp"
"${LIBRARY_DIR}/atn/RuleTransition.cpp"
"${LIBRARY_DIR}/atn/SemanticContext.cpp"
"${LIBRARY_DIR}/atn/SetTransition.cpp"
"${LIBRARY_DIR}/atn/SingletonPredictionContext.cpp"
"${LIBRARY_DIR}/atn/StarBlockStartState.cpp"
"${LIBRARY_DIR}/atn/StarLoopbackState.cpp"
"${LIBRARY_DIR}/atn/StarLoopEntryState.cpp"
"${LIBRARY_DIR}/atn/TokensStartState.cpp"
"${LIBRARY_DIR}/atn/Transition.cpp"
"${LIBRARY_DIR}/atn/WildcardTransition.cpp"
"${LIBRARY_DIR}/BailErrorStrategy.cpp"
"${LIBRARY_DIR}/BaseErrorListener.cpp"
"${LIBRARY_DIR}/BufferedTokenStream.cpp"
"${LIBRARY_DIR}/CharStream.cpp"
"${LIBRARY_DIR}/CommonToken.cpp"
"${LIBRARY_DIR}/CommonTokenFactory.cpp"
"${LIBRARY_DIR}/CommonTokenStream.cpp"
"${LIBRARY_DIR}/ConsoleErrorListener.cpp"
"${LIBRARY_DIR}/DefaultErrorStrategy.cpp"
"${LIBRARY_DIR}/dfa/DFA.cpp"
"${LIBRARY_DIR}/dfa/DFASerializer.cpp"
"${LIBRARY_DIR}/dfa/DFAState.cpp"
"${LIBRARY_DIR}/dfa/LexerDFASerializer.cpp"
"${LIBRARY_DIR}/DiagnosticErrorListener.cpp"
"${LIBRARY_DIR}/Exceptions.cpp"
"${LIBRARY_DIR}/FailedPredicateException.cpp"
"${LIBRARY_DIR}/InputMismatchException.cpp"
"${LIBRARY_DIR}/InterpreterRuleContext.cpp"
"${LIBRARY_DIR}/IntStream.cpp"
"${LIBRARY_DIR}/Lexer.cpp"
"${LIBRARY_DIR}/LexerInterpreter.cpp"
"${LIBRARY_DIR}/LexerNoViableAltException.cpp"
"${LIBRARY_DIR}/ListTokenSource.cpp"
"${LIBRARY_DIR}/misc/InterpreterDataReader.cpp"
"${LIBRARY_DIR}/misc/Interval.cpp"
"${LIBRARY_DIR}/misc/IntervalSet.cpp"
"${LIBRARY_DIR}/misc/MurmurHash.cpp"
"${LIBRARY_DIR}/misc/Predicate.cpp"
"${LIBRARY_DIR}/NoViableAltException.cpp"
"${LIBRARY_DIR}/Parser.cpp"
"${LIBRARY_DIR}/ParserInterpreter.cpp"
"${LIBRARY_DIR}/ParserRuleContext.cpp"
"${LIBRARY_DIR}/ProxyErrorListener.cpp"
"${LIBRARY_DIR}/RecognitionException.cpp"
"${LIBRARY_DIR}/Recognizer.cpp"
"${LIBRARY_DIR}/RuleContext.cpp"
"${LIBRARY_DIR}/RuleContextWithAltNum.cpp"
"${LIBRARY_DIR}/RuntimeMetaData.cpp"
"${LIBRARY_DIR}/support/Any.cpp"
"${LIBRARY_DIR}/support/Arrays.cpp"
"${LIBRARY_DIR}/support/CPPUtils.cpp"
"${LIBRARY_DIR}/support/guid.cpp"
"${LIBRARY_DIR}/support/StringUtils.cpp"
"${LIBRARY_DIR}/Token.cpp"
"${LIBRARY_DIR}/TokenSource.cpp"
"${LIBRARY_DIR}/TokenStream.cpp"
"${LIBRARY_DIR}/TokenStreamRewriter.cpp"
"${LIBRARY_DIR}/tree/ErrorNode.cpp"
"${LIBRARY_DIR}/tree/ErrorNodeImpl.cpp"
"${LIBRARY_DIR}/tree/IterativeParseTreeWalker.cpp"
"${LIBRARY_DIR}/tree/ParseTree.cpp"
"${LIBRARY_DIR}/tree/ParseTreeListener.cpp"
"${LIBRARY_DIR}/tree/ParseTreeVisitor.cpp"
"${LIBRARY_DIR}/tree/ParseTreeWalker.cpp"
"${LIBRARY_DIR}/tree/pattern/Chunk.cpp"
"${LIBRARY_DIR}/tree/pattern/ParseTreeMatch.cpp"
"${LIBRARY_DIR}/tree/pattern/ParseTreePattern.cpp"
"${LIBRARY_DIR}/tree/pattern/ParseTreePatternMatcher.cpp"
"${LIBRARY_DIR}/tree/pattern/RuleTagToken.cpp"
"${LIBRARY_DIR}/tree/pattern/TagChunk.cpp"
"${LIBRARY_DIR}/tree/pattern/TextChunk.cpp"
"${LIBRARY_DIR}/tree/pattern/TokenTagToken.cpp"
"${LIBRARY_DIR}/tree/TerminalNode.cpp"
"${LIBRARY_DIR}/tree/TerminalNodeImpl.cpp"
"${LIBRARY_DIR}/tree/Trees.cpp"
"${LIBRARY_DIR}/tree/xpath/XPath.cpp"
"${LIBRARY_DIR}/tree/xpath/XPathElement.cpp"
"${LIBRARY_DIR}/tree/xpath/XPathLexer.cpp"
"${LIBRARY_DIR}/tree/xpath/XPathLexerErrorListener.cpp"
"${LIBRARY_DIR}/tree/xpath/XPathRuleAnywhereElement.cpp"
"${LIBRARY_DIR}/tree/xpath/XPathRuleElement.cpp"
"${LIBRARY_DIR}/tree/xpath/XPathTokenAnywhereElement.cpp"
"${LIBRARY_DIR}/tree/xpath/XPathTokenElement.cpp"
"${LIBRARY_DIR}/tree/xpath/XPathWildcardAnywhereElement.cpp"
"${LIBRARY_DIR}/tree/xpath/XPathWildcardElement.cpp"
"${LIBRARY_DIR}/UnbufferedCharStream.cpp"
"${LIBRARY_DIR}/UnbufferedTokenStream.cpp"
"${LIBRARY_DIR}/Vocabulary.cpp"
"${LIBRARY_DIR}/WritableToken.cpp"
)
add_library (antlr4-runtime ${SRCS})
target_include_directories (antlr4-runtime SYSTEM PUBLIC ${LIBRARY_DIR})

View File

@ -160,7 +160,6 @@ function clone_submodules
SUBMODULES_TO_UPDATE=(
contrib/abseil-cpp
contrib/antlr4-runtime
contrib/boost
contrib/zlib-ng
contrib/libxml2

View File

@ -35,7 +35,7 @@ if [ "$NUM_TRIES" -gt "1" ]; then
# simpliest way to forward env variables to server
sudo -E -u clickhouse /usr/bin/clickhouse-server --config /etc/clickhouse-server/config.xml --daemon
else
service clickhouse-server start
sudo clickhouse start
fi
if [[ -n "$USE_DATABASE_REPLICATED" ]] && [[ "$USE_DATABASE_REPLICATED" -eq 1 ]]; then

View File

@ -1,39 +1,42 @@
---
toc_priority: 31
toc_title: SQL语法
---
# SQL语法 {#syntax}
CH有2类解析器完整SQL解析器递归式解析器以及数据格式解析器快速流式解析器
ClickHouse有2类解析器完整SQL解析器递归式解析器以及数据格式解析器快速流式解析器
除了 `INSERT` 查询其它情况下仅使用完整SQL解析器。
`INSERT`查询会同时使用2种解析器
``` sql
INSERT INTO t VALUES (1, 'Hello, world'), (2, 'abc'), (3, 'def')
```
含`INSERT INTO t VALUES` 的部分由完整SQL解析器处理包含数据的部分 `(1, 'Hello, world'), (2, 'abc'), (3, 'def')` 交给快速流式解析器解析。通过设置参数 [input_format_values_interpret_expressions](../operations/settings/settings.md#settings-input_format_values_interpret_expressions)你也可以对数据部分开启完整SQL解析器。当 `input_format_values_interpret_expressions = 1`CH优先采用快速流式解析器来解析数据。如果失败CH再尝试用完整SQL解析器来处理就像处理SQL [expression](#syntax-expressions) 一样。
含`INSERT INTO t VALUES` 的部分由完整SQL解析器处理包含数据的部分 `(1, 'Hello, world'), (2, 'abc'), (3, 'def')` 交给快速流式解析器解析。通过设置参数 [input_format_values_interpret_expressions](../operations/settings/settings.md#settings-input_format_values_interpret_expressions)你也可以对数据部分开启完整SQL解析器。当 `input_format_values_interpret_expressions = 1`ClickHouse优先采用快速流式解析器来解析数据。如果失败ClickHouse再尝试用完整SQL解析器来处理就像处理SQL [expression](#syntax-expressions) 一样。
数据可以采用任何格式。当CH接收到请求时服务端先在内存中计算不超过 [max_query_size](../operations/settings/settings.md#settings-max_query_size) 字节的请求数据默认1 mb然后剩下部分交给快速流式解析器。
这将避免在处理大型的 `INSERT`语句时出现问题
`INSERT` 语句中使用 `Values` 格式时,看起来数据部分的解析和解析`SELECT` 中的表达式相同,但并不是这样的。 `Values` 格式有非常多的限制
`INSERT` 语句中使用 `Values` 形式时,看起来 数据部分的解析和解析`SELECT` 中的表达式相同,但并不是这样的。 `Values` 形式非常有限。
该篇的剩余部分涵盖了完整SQL解析器。关于格式解析的更多信息参见 [Formats](../interfaces/formats.md) 章节。
本文的剩余部分涵盖了完整SQL解析器。关于格式解析的更多信息参见 [Formats](../interfaces/formats.md) 章节。
## 空字符 {#spaces}
## 空{#spaces}
sql语句包含sql的起始和结束可以有任意的空字符这些空字符类型包括空格字符tab制表符换行符CR符换页符等。
sql语句的语法结构部分之间标识符之间、部分符号之间、包括sql的起始和结束可以有任意的空白字符这些空字符类型包括空格字符tab制表符换行符CR符换页符等。
## 注释 {#comments}
CH支持SQL风格或C语言风格的注释
ClickHouse支持SQL风格或C语言风格的注释
- SQL风格的注释以 `--` 开始,直到行末,`--` 后紧跟的空格可以忽略
- C语言风格的注释以 `/*` 开始,以 `*/` 结束,支持多行形式,同样可以省略 `/*` 后的空格
- C语言风格的注释以 `/*` 开始,以 `*/` 结束,可以跨行,同样可以省略 `/*` 后的空格
## 关键字 {#syntax-keywords}
以下场景的关键字是大小写不敏感的:
- 标准SQL。例如`SELECT`, `select``SeLeCt` 都是允许的
- 在某些流行的RDBMS中被实现的关键字例如`DateTime` 和 `datetime`是一样的
@ -41,38 +44,36 @@ CH支持SQL风格或C语言风格的注释
你可以在系统表 [system.data_type_families](../operations/system-tables/data_type_families.md#system_tables-data_type_families) 中检查某个数据类型的名称是否是大小写敏感型。
和标准SQL相反所有其它的关键字都是 **大小写敏感的**,包括函数名称。
In contrast to standard SQL, all other keywords (including functions names) are **case-sensitive**.
关键字不是保留的;它们仅在相应的上下文中才会被处理。如果你使用和关键字同名的 [变量名](#syntax-identifiers) ,需要使用双引号或转移符将它们包含起来。例如:如果表 `table_name` 包含列 `"FROM"`,那么 `SELECT "FROM" FROM table_name` 是合法的
关键字不是保留的;它们仅在相应的上下文中才会被认为是关键字。如果你使用和关键字同名的 [标识符](#syntax-identifiers) ,需要使用双引号或反引号将它们包含起来。例如:如果表 `table_name` 包含列 `"FROM"`,那么 `SELECT "FROM" FROM table_name` 是合法的
## 变量名 {#syntax-identifiers}
## 标识符 {#syntax-identifiers}
变量包括:
Identifiers are:
标识符包括:
- 集群,数据库,表,分区,列名称
- 集群、数据库、表、分区、列的名称
- 函数
- 数据类型
- 表达式别名
- [表达式别名](https://clickhouse.tech/docs/zh/sql-reference/syntax/#syntax-expression_aliases)
变量名可以使用反引号包含起来
变量名可以被括起或不括起,后者是推荐做法。
没有使用反引号包含的变量名,必须匹配正则表达式 `^[a-zA-Z_][0-9a-zA-Z_]*$`,并且不能和 [关键字]相同
没有括起的变量名,必须匹配正则表达式 `^[a-zA-Z_][0-9a-zA-Z_]*$`,并且不能和 [关键字](#syntax-keywords)相同,合法的标识符名称:`x``_1``X_y__Z123_`等。
如果想使用和关键字同名的变量名称,或者在变量名称中包含其它符号,你需要通过双引号或转义符号,例如: `"id"`, `` `id` ``
如果想使用和关键字同名的变量名称,或者在变量名称中包含其它符号,你需要通过双引号或反引号,例如: `"id"`, `` `id` ``
## 字符 {#literals}
CH包含数字字母括号NULL值等字符
字符包含数字字母括号NULL值等字符。
### 数字 {#numeric}
数字类型字符会被做如下解析:
- 首先当做64位的有符号整数使用该函数 [strtoull](https://en.cppreference.com/w/cpp/string/byte/strtoul)
- 首先当做64位的有符号整数使用函数 [strtoull](https://en.cppreference.com/w/cpp/string/byte/strtoul)
- 如果失败解析成64位无符号整数同样使用函数 [strtoull](https://en.cppreference.com/w/cpp/string/byte/strtoul)
- 如果还失败了,试图解析成浮点型数值,使用函数 [strtod](https://en.cppreference.com/w/cpp/string/byte/strtof)
Numeric literal tries to be parsed:
- 最后,以上情形都不符合时,返回异常
@ -82,13 +83,14 @@ Numeric literal tries to be parsed:
例如: `1`, `18446744073709551615`, `0xDEADBEEF`, `01`, `0.1`, `1e100`, `-1e-100`, `inf`, `nan`.
### 字母 {#syntax-string-literal}
CH只支持用单引号包含的字母。特殊字符可通过反斜杠进行转义。下列转义字符都有相应的实际值 `\b`, `\f`, `\r`, `\n`, `\t`, `\0`, `\a`, `\v`, `\xHH`。其它情况下,以 `\c`形式出现的转义字符,当`c`表示任意字符时,转义字符会转换成`c`。这意味着你可以使用 `\'`和`\\`。该值将拥有[String](../sql-reference/data-types/string.md)类型。
### 字符串 {#syntax-string-literal}
ClickHouse只支持用单引号包含的字符串。特殊字符可通过反斜杠进行转义。下列转义字符都有相应的实际值 `\b`, `\f`, `\r`, `\n`, `\t`, `\0`, `\a`, `\v`, `\xHH`。其它情况下,以 `\c`形式出现的转义字符,当`c`表示任意字符时,转义字符会转换成`c`。这意味着你可以使用 `\'`和`\\`。该值将拥有[String](../sql-reference/data-types/string.md)类型。
在字符串中,你至少需要对 `'``\` 进行转义。单引号可以使用单引号转义,例如 `'It\'s'``'It''s'` 是相同的。
### 括号 {#compound}
### 复合字符串 {#compound}
数组都是使用方括号进行构造 `[1, 2, 3]`,元组则使用圆括号 `(1, 'Hello, world!', 2)`
从技术上来讲,这些都不是字符串,而是包含创建数组和元组运算符的表达式。
@ -97,17 +99,18 @@ CH只支持用单引号包含的字母。特殊字符可通过反斜杠进行转
### NULL值 {#null-literal}
代表不存在的值
代表不存在的值
为了能在表字段中存储NULL值该字段必须声明为 [空值](../sql-reference/data-types/nullable.md) 类型
为了能在表字段中存储NULL值该字段必须声明为 [空值](../sql-reference/data-types/nullable.md) 类型
根据数据的格式输入或输出NULL值有不同的表现形式。更多信息参见文档 [数据格式](../interfaces/formats.md#formats)
在处理 `NULL`时存在很多细微差别。例如,比较运算的至少一个参数为 `NULL` ,该结果也是 `NULL` 。与之类似的还有乘法运算, 加法运算,以及其它运算。更多信息,请参阅每种运算的文档部分。
在处理 `NULL`时存在很多细微差别。例如,比较运算的至少一个参数为 `NULL` 该结果也是 `NULL` 。与之类似的还有乘法运算, 加法运算,以及其它运算。更多信息,请参阅每种运算的文档部分。
在语句中,可以通过 [是否为NULL](operators/index.md#operator-is-null) 以及 [是否不为NULL](operators/index.md) 运算符,以及 `isNull``isNotNull` 函数来检查 `NULL`
在语句中,可以通过 [IS NULL](operators/index.md#operator-is-null) 以及 [IS NOT NULL](operators/index.md) 运算符,以及 `isNull``isNotNull` 函数来检查 `NULL`
## 函数 {#functions}
函数调用的写法类似于变量并带有被圆括号包含的参数列表可能为空。与标准SQL不同圆括号是必须的不管参数列表是否为空。例如 `now()`
函数调用的写法类似于一个标识符后接被圆括号包含的参数列表可能为空。与标准SQL不同圆括号是必须的不管参数列表是否为空。例如 `now()`
函数分为常规函数和聚合函数参见“Aggregate functions”一章。有些聚合函数包含2个参数列表第一个参数列表中的参数被称为“parameters”。不包含“parameters”的聚合函数语法和常规函数是一样的。
@ -116,12 +119,12 @@ CH只支持用单引号包含的字母。特殊字符可通过反斜杠进行转
在查询解析阶段,运算符会被转换成对应的函数,使用时请注意它们的优先级。例如:
表达式 `1 + 2 * 3 + 4` 会被解析成 `plus(plus(1, multiply(2, 3)), 4)`.
## 数据类型及数据库/表引擎 {#data_types-and-database-table-engines}
`CREATE` 语句中的数据类型和表引擎写法与变量或函数类似。
换句话说,它们可以用括号包含参数列表。更多信息,参见“数据类型,” “数据表引擎” 和 “CREATE语句”等章节
换句话说,它们可以包含或不包含用括号包含参数列表。更多信息,参见“数据类型,” “数据表引擎” 和 “CREATE语句”等章节
## 表达式别名 {#syntax-expression_aliases}
@ -131,29 +134,30 @@ CH只支持用单引号包含的字母。特殊字符可通过反斜杠进行转
expr AS alias
```
- `AS` — 用于定义别名的关键字。可以对表或select语句中的列定义别名(`AS` 可以省略)
例如, `SELECT table_name_alias.column_name FROM table_name table_name_alias`.
- `AS` — 用于定义别名的关键字。可以对表或select语句中的列定义别名(`AS` 可以省略)
例如, `SELECT table_name_alias.column_name FROM table_name table_name_alias`.
在 [CAST函数](sql_reference/functions/type_conversion_functions.md#type_conversion_function-cast) 中,`AS`有其它含义。请参见该函数的说明部分。
在 [CAST函数](../sql-reference/functions/type-conversion-functions.md#type_conversion_function-cast) 中,`AS`有其它含义。请参见该函数的说明部分。
- `expr` — 任意CH支持的表达式.
- `expr` — 任意CH支持的表达式.
例如, `SELECT column_name * 2 AS double FROM some_table`.
例如, `SELECT column_name * 2 AS double FROM some_table`.
- `alias``expr` 的名称。别名必须符合 [变量名]](#syntax-identifiers) 语法.
- `alias``expr` 的名称。别名必须符合 [标识符](#syntax-identifiers) 语法.
例如, `SELECT "table t".column_name FROM table_name AS "table t"`.
例如, `SELECT "table t".column_name FROM table_name AS "table t"`.
### 用法注意 {#notes-on-usage}
别名在当前查询或子查询中是全局可见的,你可以在查询语句的任何位置对表达式定义别名
别名在当前查询的子查询及不同子查询中是不可见的。例如执行如下查询SQL: `SELECT (SELECT sum(b.a) + num FROM b) - a.a AS num FROM a` ,CH会提示异常 `Unknown identifier: num`.
别名在当前查询的子查询及不同子查询中是不可见的。例如执行如下查询SQL: `SELECT (SELECT sum(b.a) + num FROM b) - a.a AS num FROM a` ,ClickHouse会提示异常 `Unknown identifier: num`.
如果给select子查询语句的结果列定义其别名那么在外层可以使用该别名。例如, `SELECT n + m FROM (SELECT 1 AS n, 2 AS m)`.
注意列的别名和表的别名相同时的情形,考虑如下示例:
``` sql
CREATE TABLE t
(
@ -175,7 +179,7 @@ Received exception from server (version 18.14.17):
Code: 184. DB::Exception: Received from localhost:9000, 127.0.0.1. DB::Exception: Aggregate function sum(b) is found inside another aggregate function in query.
```
在这个示例中,先声明了表 `t` 以及列 `b`。然后,在查询数据时,又定义了别名 `sum(b) AS b`。由于别名是全局的CH使用表达式 `sum(b)` 来替换表达式 `argMax(a, b)` 中的变量 `b`。这种替换导致出现异常。
在这个示例中,先声明了表 `t` 以及列 `b`。然后,在查询数据时,又定义了别名 `sum(b) AS b`。由于别名是全局的ClickHouse使用表达式 `sum(b)` 来替换表达式 `argMax(a, b)` 中的变量 `b`。这种替换导致出现异常。
## 星号 {#asterisk}
@ -184,7 +188,7 @@ select查询中星号可以代替表达式使用。详情请参见“select
## 表达式 {#syntax-expressions}
表达式是函数、标识符、字符、运算符的应用程序、括号中的表达式、子查询或星号。它也可以包含别名。
表达式是函数、标识符、字符、使用运算符的语句、括号中的表达式、子查询或星号。它也可以包含别名。
表达式列表是用逗号分隔的一个或多个表达式。
反过来,函数和运算符可以将表达式作为参数。

View File

@ -66,7 +66,7 @@ enum class AccessType
M(ALTER_TTL, "ALTER MODIFY TTL, MODIFY TTL", TABLE, ALTER_TABLE) /* allows to execute ALTER MODIFY TTL */\
M(ALTER_MATERIALIZE_TTL, "MATERIALIZE TTL", TABLE, ALTER_TABLE) /* allows to execute ALTER MATERIALIZE TTL;
enabled implicitly by the grant ALTER_TABLE */\
M(ALTER_SETTINGS, "ALTER SETTING, ALTER MODIFY SETTING, MODIFY SETTING", TABLE, ALTER_TABLE) /* allows to execute ALTER MODIFY SETTING */\
M(ALTER_SETTINGS, "ALTER SETTING, ALTER MODIFY SETTING, MODIFY SETTING, RESET SETTING", TABLE, ALTER_TABLE) /* allows to execute ALTER MODIFY SETTING */\
M(ALTER_MOVE_PARTITION, "ALTER MOVE PART, MOVE PARTITION, MOVE PART", TABLE, ALTER_TABLE) \
M(ALTER_FETCH_PARTITION, "ALTER FETCH PART, FETCH PARTITION", TABLE, ALTER_TABLE) \
M(ALTER_FREEZE_PARTITION, "FREEZE PARTITION, UNFREEZE", TABLE, ALTER_TABLE) \

View File

@ -54,7 +54,6 @@ add_subdirectory (Dictionaries)
add_subdirectory (Disks)
add_subdirectory (Storages)
add_subdirectory (Parsers)
add_subdirectory (Parsers/New)
add_subdirectory (IO)
add_subdirectory (Functions)
add_subdirectory (Interpreters)
@ -222,12 +221,12 @@ endif()
if (MAKE_STATIC_LIBRARIES OR NOT SPLIT_SHARED_LIBRARIES)
add_library (dbms STATIC ${dbms_headers} ${dbms_sources})
target_link_libraries (dbms PRIVATE clickhouse_parsers_new jemalloc libdivide ${DBMS_COMMON_LIBRARIES})
target_link_libraries (dbms PRIVATE jemalloc libdivide ${DBMS_COMMON_LIBRARIES})
set (all_modules dbms)
else()
add_library (dbms SHARED ${dbms_headers} ${dbms_sources})
target_link_libraries (dbms PUBLIC ${all_modules} ${DBMS_COMMON_LIBRARIES})
target_link_libraries (clickhouse_interpreters PRIVATE clickhouse_parsers_new jemalloc libdivide)
target_link_libraries (clickhouse_interpreters PRIVATE jemalloc libdivide)
list (APPEND all_modules dbms)
# force all split libs to be linked
if (OS_DARWIN)

View File

@ -445,7 +445,6 @@ class IColumn;
M(Bool, allow_experimental_window_functions, false, "Allow experimental window functions", 0) \
M(Bool, allow_experimental_projection_optimization, false, "Enable projection optimization when processing SELECT queries", 0) \
M(Bool, force_optimize_projection, false, "If projection optimization is enabled, SELECT queries need to use projection", 0) \
M(Bool, use_antlr_parser, false, "Parse incoming queries using ANTLR-generated experimental parser", 0) \
M(Bool, async_socket_for_remote, true, "Asynchronously read from socket executing remote query", 0) \
M(Bool, insert_null_as_default, true, "Insert DEFAULT values instead of NULL in INSERT SELECT (UNION ALL)", 0) \
\

View File

@ -269,6 +269,7 @@ AccessRightsElements InterpreterAlterQuery::getRequiredAccessForCommand(const AS
required_access.emplace_back(AccessType::ALTER_MATERIALIZE_TTL, database, table);
break;
}
case ASTAlterCommand::RESET_SETTING: [[fallthrough]];
case ASTAlterCommand::MODIFY_SETTING:
{
required_access.emplace_back(AccessType::ALTER_SETTINGS, database, table);

View File

@ -5,6 +5,8 @@
#include <Interpreters/InJoinSubqueriesPreprocessor.h>
#include <Interpreters/TableJoin.h>
#include <Interpreters/getTableExpressions.h>
#include <Parsers/ASTAsterisk.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTQualifiedAsterisk.h>
@ -12,8 +14,7 @@
#include <Parsers/ASTSelectWithUnionQuery.h>
#include <Parsers/ASTSubquery.h>
#include <Parsers/ASTTablesInSelectQuery.h>
#include <Parsers/ParserTablesInSelectQuery.h>
#include <Parsers/parseQuery.h>
#include <Storages/ColumnsDescription.h>
#include <Storages/IStorage.h>
#include <Storages/StorageDictionary.h>
@ -33,6 +34,23 @@ namespace ErrorCodes
namespace
{
template <typename T, typename ... Args>
std::shared_ptr<T> addASTChildrenTo(IAST & node, ASTPtr & children, Args && ... args)
{
auto new_children = std::make_shared<T>(std::forward<Args>(args)...);
children = new_children;
node.children.push_back(children);
return new_children;
}
template <typename T>
std::shared_ptr<T> addASTChildren(IAST & node)
{
auto children = std::make_shared<T>();
node.children.push_back(children);
return children;
}
void replaceJoinedTable(const ASTSelectQuery & select_query)
{
const ASTTablesInSelectQueryElement * join = select_query.join();
@ -48,15 +66,30 @@ void replaceJoinedTable(const ASTSelectQuery & select_query)
if (table_expr.database_and_table_name)
{
const auto & table_id = table_expr.database_and_table_name->as<ASTTableIdentifier &>();
String expr = "(SELECT * FROM " + backQuote(table_id.name()) + ") AS " + backQuote(table_id.shortName());
String table_name = table_id.name();
String table_short_name = table_id.shortName();
// FIXME: since the expression "a as b" exposes both "a" and "b" names, which is not equivalent to "(select * from a) as b",
// we can't replace aliased tables.
// FIXME: long table names include database name, which we can't save within alias.
if (table_id.alias.empty() && table_id.isShort())
{
ParserTableExpression parser;
table_expr = parseQuery(parser, expr, 0, DBMS_DEFAULT_MAX_PARSER_DEPTH)->as<ASTTableExpression &>();
/// Build query of form '(SELECT * FROM table_name) AS table_short_name'
table_expr = ASTTableExpression();
auto subquery = addASTChildrenTo<ASTSubquery>(table_expr, table_expr.subquery);
subquery->setAlias(table_short_name);
auto sub_select_with_union = addASTChildren<ASTSelectWithUnionQuery>(*subquery);
auto list_of_selects = addASTChildrenTo<ASTExpressionList>(*sub_select_with_union, sub_select_with_union->list_of_selects);
auto new_select = addASTChildren<ASTSelectQuery>(*list_of_selects);
new_select->setExpression(ASTSelectQuery::Expression::SELECT, std::make_shared<ASTExpressionList>());
addASTChildren<ASTAsterisk>(*new_select->select());
new_select->setExpression(ASTSelectQuery::Expression::TABLES, std::make_shared<ASTTablesInSelectQuery>());
auto tables_elem = addASTChildren<ASTTablesInSelectQueryElement>(*new_select->tables());
auto sub_table_expr = addASTChildrenTo<ASTTableExpression>(*tables_elem, tables_elem->table_expression);
addASTChildrenTo<ASTTableIdentifier>(*sub_table_expr, sub_table_expr->database_and_table_name, table_name);
}
}
}

View File

@ -18,7 +18,7 @@ namespace
if (!func.arguments || (func.arguments->children.size() <= argument_pos))
return;
auto arg = func.arguments->children[argument_pos];
auto identifier = arg->as<ASTIdentifier>();
auto * identifier = arg->as<ASTIdentifier>();
if (!identifier)
return;
if (aliases.contains(identifier->name()))

View File

@ -388,7 +388,6 @@ ASTPtr MutationsInterpreter::prepare(bool dry_run)
if (commands.empty())
throw Exception("Empty mutation commands list", ErrorCodes::LOGICAL_ERROR);
const ColumnsDescription & columns_desc = metadata_snapshot->getColumns();
const IndicesDescription & indices_desc = metadata_snapshot->getSecondaryIndices();
const ProjectionsDescription & projections_desc = metadata_snapshot->getProjections();
@ -425,8 +424,7 @@ ASTPtr MutationsInterpreter::prepare(bool dry_run)
validateUpdateColumns(storage, metadata_snapshot, updated_columns, column_to_affected_materialized);
}
/// Columns, that we need to read for calculation of skip indices, projections or TTL expressions.
auto dependencies = getAllColumnDependencies(metadata_snapshot, updated_columns);
dependencies = getAllColumnDependencies(metadata_snapshot, updated_columns);
/// First, break a sequence of commands into stages.
for (auto & command : commands)
@ -921,6 +919,10 @@ const Block & MutationsInterpreter::getUpdatedHeader() const
return *updated_header;
}
const ColumnDependencies & MutationsInterpreter::getColumnDependencies() const
{
return dependencies;
}
size_t MutationsInterpreter::evaluateCommandsSize()
{

View File

@ -56,6 +56,8 @@ public:
/// Only changed columns.
const Block & getUpdatedHeader() const;
const ColumnDependencies & getColumnDependencies() const;
/// Latest mutation stage affects all columns in storage
bool isAffectingAllColumns() const;
@ -148,6 +150,9 @@ private:
NameSet materialized_projections;
MutationKind mutation_kind; /// Do we meet any index or projection mutation.
/// Columns, that we need to read for calculation of skip indices, projections or TTL expressions.
ColumnDependencies dependencies;
};
}

View File

@ -26,11 +26,6 @@
#include <Parsers/ASTShowProcesslistQuery.h>
#include <Parsers/ASTWatchQuery.h>
#include <Parsers/Lexer.h>
#if !defined(ARCADIA_BUILD)
# include <Parsers/New/parseQuery.h> // Y_IGNORE
#endif
#include <Parsers/parseQuery.h>
#include <Parsers/ParserQuery.h>
#include <Parsers/queryNormalization.h>
@ -166,11 +161,10 @@ static void logQuery(const String & query, ContextPtr context, bool internal)
if (!comment.empty())
comment = fmt::format(" (comment: {})", comment);
LOG_DEBUG(&Poco::Logger::get("executeQuery"), "(from {}{}{}, using {} parser){} {}",
LOG_DEBUG(&Poco::Logger::get("executeQuery"), "(from {}{}{}){} {}",
client_info.current_address.toString(),
(current_user != "default" ? ", user: " + current_user : ""),
(!initial_query_id.empty() && current_query_id != initial_query_id ? ", initial_query_id: " + initial_query_id : std::string()),
(context->getSettingsRef().use_antlr_parser ? "experimental" : "production"),
comment,
joinLines(query));
@ -386,24 +380,10 @@ static std::tuple<ASTPtr, BlockIO> executeQueryImpl(
String query_table;
try
{
#if !defined(ARCADIA_BUILD)
if (settings.use_antlr_parser)
{
ast = parseQuery(begin, end, max_query_size, settings.max_parser_depth, context->getCurrentDatabase());
}
else
{
ParserQuery parser(end);
/// TODO: parser should fail early when max_query_size limit is reached.
ast = parseQuery(parser, begin, end, "", max_query_size, settings.max_parser_depth);
}
#else
ParserQuery parser(end);
/// TODO: parser should fail early when max_query_size limit is reached.
ast = parseQuery(parser, begin, end, "", max_query_size, settings.max_parser_depth);
#endif
/// Interpret SETTINGS clauses as early as possible (before invoking the corresponding interpreter),
/// to allow settings to take effect.

View File

@ -52,6 +52,11 @@ ASTPtr ASTAlterCommand::clone() const
res->settings_changes = settings_changes->clone();
res->children.push_back(res->settings_changes);
}
if (settings_resets)
{
res->settings_resets = settings_resets->clone();
res->children.push_back(res->settings_resets);
}
if (values)
{
res->values = values->clone();
@ -379,6 +384,11 @@ void ASTAlterCommand::formatImpl(
settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "MODIFY SETTING " << (settings.hilite ? hilite_none : "");
settings_changes->formatImpl(settings, state, frame);
}
else if (type == ASTAlterCommand::RESET_SETTING)
{
settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "RESET SETTING " << (settings.hilite ? hilite_none : "");
settings_resets->formatImpl(settings, state, frame);
}
else if (type == ASTAlterCommand::MODIFY_QUERY)
{
settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "MODIFY QUERY " << settings.nl_or_ws << (settings.hilite ? hilite_none : "");

View File

@ -36,6 +36,7 @@ public:
MODIFY_TTL,
MATERIALIZE_TTL,
MODIFY_SETTING,
RESET_SETTING,
MODIFY_QUERY,
REMOVE_TTL,
@ -141,6 +142,9 @@ public:
/// FOR MODIFY_SETTING
ASTPtr settings_changes;
/// FOR RESET_SETTING
ASTPtr settings_resets;
/// For MODIFY_QUERY
ASTPtr select;

View File

@ -1,814 +0,0 @@
#include <Parsers/New/AST/AlterTableQuery.h>
#include <Interpreters/StorageID.h>
#include <Parsers/ASTAlterQuery.h>
#include <Parsers/ASTAssignment.h>
#include <Parsers/ASTColumnDeclaration.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTPartition.h>
#include <Parsers/New/AST/ColumnExpr.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/AST/TableElementExpr.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
AssignmentExpr::AssignmentExpr(PtrTo<Identifier> identifier, PtrTo<ColumnExpr> expr) : INode{identifier, expr}
{
}
ASTPtr AssignmentExpr::convertToOld() const
{
auto expr = std::make_shared<ASTAssignment>();
expr->column_name = get(IDENTIFIER)->convertToOld()->getColumnName();
expr->children.push_back(get(EXPR)->convertToOld());
return expr;
}
PartitionClause::PartitionClause(PtrTo<Literal> id) : PartitionClause(ClauseType::ID, {id})
{
}
PartitionClause::PartitionClause(PtrTo<List<Literal>> list) : PartitionClause(ClauseType::LIST, {list})
{
}
PartitionClause::PartitionClause(ClauseType type, PtrList exprs) : INode(exprs), clause_type(type)
{
}
ASTPtr PartitionClause::convertToOld() const
{
auto partition = std::make_shared<ASTPartition>();
switch(clause_type)
{
case ClauseType::ID:
partition->id = get<StringLiteral>(ID)->as<String>();
break;
case ClauseType::LIST:
{
auto tuple = std::make_shared<ASTFunction>();
tuple->name = "tuple";
tuple->arguments = std::make_shared<ASTExpressionList>();
for (const auto & child : get(LIST)->as<List<Literal> &>())
tuple->arguments->children.push_back(child->convertToOld());
tuple->children.push_back(tuple->arguments);
partition->value = tuple;
partition->children.push_back(partition->value);
partition->fields_count = get<List<Literal>>(LIST)->size();
partition->fields_str = get(LIST)->toString();
}
break;
}
return partition;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createAddColumn(bool if_not_exists, PtrTo<TableElementExpr> element, PtrTo<Identifier> after)
{
assert(element->getType() == TableElementExpr::ExprType::COLUMN);
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::ADD_COLUMN, {element, after}));
query->if_not_exists = if_not_exists;
return query;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createAddIndex(bool if_not_exists, PtrTo<TableElementExpr> element, PtrTo<Identifier> after)
{
assert(element->getType() == TableElementExpr::ExprType::INDEX);
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::ADD_INDEX, {element, after}));
query->if_not_exists = if_not_exists;
return query;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createAddProjection(bool if_not_exists, PtrTo<TableElementExpr> element, PtrTo<Identifier> after)
{
assert(element->getType() == TableElementExpr::ExprType::PROJECTION);
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::ADD_PROJECTION, {element, after}));
query->if_not_exists = if_not_exists;
return query;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createAttach(PtrTo<PartitionClause> clause, PtrTo<TableIdentifier> from)
{
return PtrTo<AlterTableClause>(new AlterTableClause(ClauseType::ATTACH, {clause, from}));
}
// static
PtrTo<AlterTableClause> AlterTableClause::createClearColumn(bool if_exists, PtrTo<Identifier> identifier, PtrTo<PartitionClause> in)
{
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::CLEAR_COLUMN, {identifier, in}));
query->if_exists = if_exists;
return query;
}
PtrTo<AlterTableClause> AlterTableClause::createClearIndex(bool if_exists, PtrTo<Identifier> identifier, PtrTo<PartitionClause> in)
{
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::CLEAR_INDEX, {identifier, in}));
query->if_exists = if_exists;
return query;
}
PtrTo<AlterTableClause> AlterTableClause::createClearProjection(bool if_exists, PtrTo<Identifier> identifier, PtrTo<PartitionClause> in)
{
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::CLEAR_PROJECTION, {identifier, in}));
query->if_exists = if_exists;
return query;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createCodec(bool if_exists, PtrTo<Identifier> identifier, PtrTo<CodecExpr> codec)
{
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::CODEC, {identifier, codec}));
query->if_exists = if_exists;
return query;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createComment(bool if_exists, PtrTo<Identifier> identifier, PtrTo<StringLiteral> comment)
{
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::COMMENT, {identifier, comment}));
query->if_exists = if_exists;
return query;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createDelete(PtrTo<ColumnExpr> expr)
{
return PtrTo<AlterTableClause>(new AlterTableClause(ClauseType::DELETE, {expr}));
}
// static
PtrTo<AlterTableClause> AlterTableClause::createDetach(PtrTo<PartitionClause> clause)
{
return PtrTo<AlterTableClause>(new AlterTableClause(ClauseType::DETACH, {clause}));
}
// static
PtrTo<AlterTableClause> AlterTableClause::createDropColumn(bool if_exists, PtrTo<Identifier> identifier)
{
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::DROP_COLUMN, {identifier}));
query->if_exists = if_exists;
return query;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createDropIndex(bool if_exists, PtrTo<Identifier> identifier)
{
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::DROP_INDEX, {identifier}));
query->if_exists = if_exists;
return query;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createDropProjection(bool if_exists, PtrTo<Identifier> identifier)
{
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::DROP_PROJECTION, {identifier}));
query->if_exists = if_exists;
return query;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createDropPartition(PtrTo<PartitionClause> clause)
{
return PtrTo<AlterTableClause>(new AlterTableClause(ClauseType::DROP_PARTITION, {clause}));
}
// static
PtrTo<AlterTableClause> AlterTableClause::createFreezePartition(PtrTo<PartitionClause> clause)
{
return PtrTo<AlterTableClause>(new AlterTableClause(ClauseType::FREEZE_PARTITION, {clause}));
}
// static
PtrTo<AlterTableClause> AlterTableClause::createMaterializeIndex(bool if_exists, PtrTo<Identifier> identifier, PtrTo<PartitionClause> in)
{
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::MATERIALIZE_INDEX, {identifier, in}));
query->if_exists = if_exists;
return query;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createMaterializeProjection(bool if_exists, PtrTo<Identifier> identifier, PtrTo<PartitionClause> in)
{
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::MATERIALIZE_PROJECTION, {identifier, in}));
query->if_exists = if_exists;
return query;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createModify(bool if_exists, PtrTo<TableElementExpr> element)
{
// TODO: assert(element->getType() == TableElementExpr::ExprType::COLUMN);
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::MODIFY, {element}));
query->if_exists = if_exists;
return query;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createMovePartitionToDisk(PtrTo<PartitionClause> clause, PtrTo<StringLiteral> literal)
{
return PtrTo<AlterTableClause>(new AlterTableClause(ClauseType::MOVE_PARTITION_TO_DISK, {clause, literal}));
}
// static
PtrTo<AlterTableClause> AlterTableClause::createMovePartitionToTable(PtrTo<PartitionClause> clause, PtrTo<TableIdentifier> identifier)
{
return PtrTo<AlterTableClause>(new AlterTableClause(ClauseType::MOVE_PARTITION_TO_TABLE, {clause, identifier}));
}
// static
PtrTo<AlterTableClause> AlterTableClause::createMovePartitionToVolume(PtrTo<PartitionClause> clause, PtrTo<StringLiteral> literal)
{
return PtrTo<AlterTableClause>(new AlterTableClause(ClauseType::MOVE_PARTITION_TO_VOLUME, {clause, literal}));
}
// static
PtrTo<AlterTableClause> AlterTableClause::createOrderBy(PtrTo<ColumnExpr> expr)
{
return PtrTo<AlterTableClause>(new AlterTableClause(ClauseType::ORDER_BY, {expr}));
}
// static
PtrTo<AlterTableClause> AlterTableClause::createRemove(bool if_exists, PtrTo<Identifier> identifier, TableColumnPropertyType type)
{
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::REMOVE, {identifier}));
query->if_exists = if_exists;
query->property_type = type;
return query;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createRemoveTTL()
{
return PtrTo<AlterTableClause>(new AlterTableClause(ClauseType::REMOVE_TTL, {}));
}
// static
PtrTo<AlterTableClause> AlterTableClause::createRename(bool if_exists, PtrTo<Identifier> identifier, PtrTo<Identifier> to)
{
PtrTo<AlterTableClause> query(new AlterTableClause(ClauseType::RENAME, {identifier, to}));
query->if_exists = if_exists;
return query;
}
// static
PtrTo<AlterTableClause> AlterTableClause::createReplace(PtrTo<PartitionClause> clause, PtrTo<TableIdentifier> from)
{
return PtrTo<AlterTableClause>(new AlterTableClause(ClauseType::REPLACE, {clause, from}));
}
// static
PtrTo<AlterTableClause> AlterTableClause::createTTL(PtrTo<TTLClause> clause)
{
return PtrTo<AlterTableClause>(new AlterTableClause(ClauseType::TTL, {clause}));
}
// static
PtrTo<AlterTableClause> AlterTableClause::createUpdate(PtrTo<AssignmentExprList> list, PtrTo<WhereClause> where)
{
return PtrTo<AlterTableClause>(new AlterTableClause(ClauseType::UPDATE, {list, where}));
}
ASTPtr AlterTableClause::convertToOld() const
{
auto command = std::make_shared<ASTAlterCommand>();
switch(clause_type)
{
case ClauseType::ADD_COLUMN:
command->type = ASTAlterCommand::ADD_COLUMN;
command->if_not_exists = if_not_exists;
// TODO: command->first
command->col_decl = get(ELEMENT)->convertToOld();
if (has(AFTER)) command->column = get(AFTER)->convertToOld();
break;
case ClauseType::ADD_INDEX:
command->type = ASTAlterCommand::ADD_INDEX;
command->if_not_exists = if_not_exists;
command->index_decl = get(ELEMENT)->convertToOld();
if (has(AFTER)) command->index = get(AFTER)->convertToOld();
break;
case ClauseType::ADD_PROJECTION:
command->type = ASTAlterCommand::ADD_PROJECTION;
command->if_not_exists = if_not_exists;
command->projection_decl = get(ELEMENT)->convertToOld();
if (has(AFTER)) command->projection = get(AFTER)->convertToOld();
break;
case ClauseType::ATTACH:
command->type = ASTAlterCommand::ATTACH_PARTITION;
command->partition = get(PARTITION)->convertToOld();
if (has(FROM))
{
auto table = get(FROM)->convertToOld();
command->from_database = table->as<ASTTableIdentifier>()->getDatabaseName();
command->from_table = table->as<ASTTableIdentifier>()->shortName();
command->replace = false;
command->type = ASTAlterCommand::REPLACE_PARTITION;
}
break;
case ClauseType::CLEAR_COLUMN:
command->type = ASTAlterCommand::DROP_COLUMN;
command->if_exists = if_exists;
command->clear_column = true;
command->detach = false;
command->column = get(ELEMENT)->convertToOld();
if (has(IN)) command->partition = get(IN)->convertToOld();
break;
case ClauseType::CLEAR_INDEX:
command->type = ASTAlterCommand::DROP_INDEX;
command->if_exists = if_exists;
command->clear_index = true;
command->detach = false;
command->index = get(ELEMENT)->convertToOld();
if (has(IN)) command->partition = get(IN)->convertToOld();
break;
case ClauseType::CLEAR_PROJECTION:
command->type = ASTAlterCommand::DROP_PROJECTION;
command->if_exists = if_exists;
command->clear_projection = true;
command->detach = false;
command->projection = get(ELEMENT)->convertToOld();
if (has(IN)) command->partition = get(IN)->convertToOld();
break;
case ClauseType::CODEC:
command->type = ASTAlterCommand::MODIFY_COLUMN;
command->if_exists = if_exists;
{
auto column = std::make_shared<ASTColumnDeclaration>();
column->name = get(COLUMN)->toString();
column->codec = get(CODEC)->convertToOld();
command->col_decl = column;
}
break;
case ClauseType::COMMENT:
command->type = ASTAlterCommand::COMMENT_COLUMN;
command->if_exists = if_exists;
command->column = get(COLUMN)->convertToOld();
command->comment = get(COMMENT)->convertToOld();
break;
case ClauseType::DELETE:
command->type = ASTAlterCommand::DELETE;
command->predicate = get(EXPR)->convertToOld();
break;
case ClauseType::DETACH:
command->type = ASTAlterCommand::DROP_PARTITION;
command->detach = true;
command->partition = get(PARTITION)->convertToOld();
break;
case ClauseType::DROP_COLUMN:
command->type = ASTAlterCommand::DROP_COLUMN;
command->if_exists = if_exists;
command->detach = false;
command->column = get(ELEMENT)->convertToOld();
break;
case ClauseType::DROP_INDEX:
command->type = ASTAlterCommand::DROP_INDEX;
command->if_exists = if_exists;
command->detach = false;
command->index = get(ELEMENT)->convertToOld();
break;
case ClauseType::DROP_PROJECTION:
command->type = ASTAlterCommand::DROP_PROJECTION;
command->if_exists = if_exists;
command->detach = false;
command->projection = get(ELEMENT)->convertToOld();
break;
case ClauseType::DROP_PARTITION:
command->type = ASTAlterCommand::DROP_PARTITION;
command->partition = get(PARTITION)->convertToOld();
break;
case ClauseType::FREEZE_PARTITION:
if (has(PARTITION))
{
command->type = ASTAlterCommand::FREEZE_PARTITION;
command->partition = get(PARTITION)->convertToOld();
}
else
command->type = ASTAlterCommand::FREEZE_ALL;
break;
case ClauseType::MATERIALIZE_INDEX:
command->type = ASTAlterCommand::MATERIALIZE_INDEX;
command->if_exists = if_exists;
command->index = get(ELEMENT)->convertToOld();
if (has(IN)) command->partition = get(IN)->convertToOld();
break;
case ClauseType::MATERIALIZE_PROJECTION:
command->type = ASTAlterCommand::MATERIALIZE_PROJECTION;
command->if_exists = if_exists;
command->projection = get(ELEMENT)->convertToOld();
if (has(IN)) command->partition = get(IN)->convertToOld();
break;
case ClauseType::MODIFY:
command->type = ASTAlterCommand::MODIFY_COLUMN;
command->if_exists = if_exists;
command->col_decl = get(ELEMENT)->convertToOld();
break;
case ClauseType::MOVE_PARTITION_TO_DISK:
command->type = ASTAlterCommand::MOVE_PARTITION;
command->partition = get(PARTITION)->convertToOld();
command->move_destination_type = DataDestinationType::DISK;
command->move_destination_name = get(TO)->convertToOld()->as<ASTLiteral>()->value.get<String>();
break;
case ClauseType::MOVE_PARTITION_TO_TABLE:
command->type = ASTAlterCommand::MOVE_PARTITION;
command->partition = get(PARTITION)->convertToOld();
command->move_destination_type = DataDestinationType::TABLE;
{
auto table = get(TO)->convertToOld();
command->to_database = table->as<ASTTableIdentifier>()->getDatabaseName();
command->to_table = table->as<ASTTableIdentifier>()->shortName();
}
break;
case ClauseType::MOVE_PARTITION_TO_VOLUME:
command->type = ASTAlterCommand::MOVE_PARTITION;
command->partition = get(PARTITION)->convertToOld();
command->move_destination_type = DataDestinationType::VOLUME;
command->move_destination_name = get(TO)->convertToOld()->as<ASTLiteral>()->value.get<String>();
break;
case ClauseType::REMOVE:
command->type = ASTAlterCommand::MODIFY_COLUMN;
command->if_exists = if_exists;
{
auto col_decl = std::make_shared<ASTColumnDeclaration>();
col_decl->name = get(ELEMENT)->convertToOld()->getColumnName();
command->col_decl = col_decl;
}
switch(property_type)
{
case TableColumnPropertyType::ALIAS:
command->remove_property = "ALIAS";
break;
case TableColumnPropertyType::CODEC:
command->remove_property = "CODEC";
break;
case TableColumnPropertyType::COMMENT:
command->remove_property = "COMMENT";
break;
case TableColumnPropertyType::DEFAULT:
command->remove_property = "DEFAULT";
break;
case TableColumnPropertyType::MATERIALIZED:
command->remove_property = "MATERIALIZED";
break;
case TableColumnPropertyType::TTL:
command->remove_property = "TTL";
break;
}
break;
case ClauseType::REMOVE_TTL:
command->type = ASTAlterCommand::REMOVE_TTL;
break;
case ClauseType::RENAME:
command->type = ASTAlterCommand::RENAME_COLUMN;
command->column = get(COLUMN)->convertToOld();
command->rename_to = get(TO)->convertToOld();
break;
case ClauseType::ORDER_BY:
command->type = ASTAlterCommand::MODIFY_ORDER_BY;
command->order_by = get(EXPR)->convertToOld();
break;
case ClauseType::REPLACE:
command->type = ASTAlterCommand::REPLACE_PARTITION;
command->replace = true;
command->partition = get(PARTITION)->convertToOld();
{
auto table = get(FROM)->convertToOld();
command->from_database = table->as<ASTTableIdentifier>()->getDatabaseName();
command->from_table = table->as<ASTTableIdentifier>()->shortName();
}
break;
case ClauseType::TTL:
command->type = ASTAlterCommand::MODIFY_TTL;
command->ttl = get(CLAUSE)->convertToOld();
break;
case ClauseType::UPDATE:
command->type = ASTAlterCommand::UPDATE;
command->update_assignments = get(ASSIGNMENTS)->convertToOld();
command->predicate = get(WHERE)->convertToOld();
break;
}
if (command->col_decl)
command->children.push_back(command->col_decl);
if (command->column)
command->children.push_back(command->column);
if (command->partition)
command->children.push_back(command->partition);
if (command->order_by)
command->children.push_back(command->order_by);
if (command->sample_by)
command->children.push_back(command->sample_by);
if (command->predicate)
command->children.push_back(command->predicate);
if (command->update_assignments)
command->children.push_back(command->update_assignments);
if (command->values)
command->children.push_back(command->values);
if (command->comment)
command->children.push_back(command->comment);
if (command->ttl)
command->children.push_back(command->ttl);
if (command->settings_changes)
command->children.push_back(command->settings_changes);
return command;
}
AlterTableClause::AlterTableClause(ClauseType type, PtrList exprs) : INode(exprs), clause_type(type)
{
}
AlterTableQuery::AlterTableQuery(PtrTo<ClusterClause> cluster, PtrTo<TableIdentifier> identifier, PtrTo<List<AlterTableClause>> clauses)
: DDLQuery(cluster, {identifier, clauses})
{
}
ASTPtr AlterTableQuery::convertToOld() const
{
auto query = std::make_shared<ASTAlterQuery>();
{
auto table = get(TABLE)->convertToOld();
query->database = table->as<ASTTableIdentifier>()->getDatabaseName();
query->table = table->as<ASTTableIdentifier>()->shortName();
}
query->cluster = cluster_name;
query->set(query->command_list, get(CLAUSES)->convertToOld());
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseAddColumn(ClickHouseParser::AlterTableClauseAddColumnContext * ctx)
{
auto after = ctx->AFTER() ? visit(ctx->nestedIdentifier()).as<PtrTo<Identifier>>() : nullptr;
return AlterTableClause::createAddColumn(!!ctx->IF(), visit(ctx->tableColumnDfnt()), after);
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseAddIndex(ClickHouseParser::AlterTableClauseAddIndexContext * ctx)
{
auto after = ctx->AFTER() ? visit(ctx->nestedIdentifier()).as<PtrTo<Identifier>>() : nullptr;
return AlterTableClause::createAddIndex(!!ctx->IF(), visit(ctx->tableIndexDfnt()), after);
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseAddProjection(ClickHouseParser::AlterTableClauseAddProjectionContext * ctx)
{
auto after = ctx->AFTER() ? visit(ctx->nestedIdentifier()).as<PtrTo<Identifier>>() : nullptr;
return AlterTableClause::createAddProjection(!!ctx->IF(), visit(ctx->tableProjectionDfnt()), after);
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseAttach(ClickHouseParser::AlterTableClauseAttachContext *ctx)
{
auto from = ctx->tableIdentifier() ? visit(ctx->tableIdentifier()).as<PtrTo<TableIdentifier>>() : nullptr;
return AlterTableClause::createAttach(visit(ctx->partitionClause()), from);
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseClearColumn(ClickHouseParser::AlterTableClauseClearColumnContext * ctx)
{
auto partition = ctx->partitionClause() ? visit(ctx->partitionClause()).as<PtrTo<PartitionClause>>() : nullptr;
return AlterTableClause::createClearColumn(!!ctx->IF(), visit(ctx->nestedIdentifier()), partition);
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseClearIndex(ClickHouseParser::AlterTableClauseClearIndexContext * ctx)
{
auto partition = ctx->partitionClause() ? visit(ctx->partitionClause()).as<PtrTo<PartitionClause>>() : nullptr;
return AlterTableClause::createClearIndex(!!ctx->IF(), visit(ctx->nestedIdentifier()), partition);
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseClearProjection(ClickHouseParser::AlterTableClauseClearProjectionContext * ctx)
{
auto partition = ctx->partitionClause() ? visit(ctx->partitionClause()).as<PtrTo<PartitionClause>>() : nullptr;
return AlterTableClause::createClearProjection(!!ctx->IF(), visit(ctx->nestedIdentifier()), partition);
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseComment(ClickHouseParser::AlterTableClauseCommentContext * ctx)
{
return AlterTableClause::createComment(!!ctx->IF(), visit(ctx->nestedIdentifier()), Literal::createString(ctx->STRING_LITERAL()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseDelete(ClickHouseParser::AlterTableClauseDeleteContext *ctx)
{
return AlterTableClause::createDelete(visit(ctx->columnExpr()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseDetach(ClickHouseParser::AlterTableClauseDetachContext *ctx)
{
return AlterTableClause::createDetach(visit(ctx->partitionClause()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseDropColumn(ClickHouseParser::AlterTableClauseDropColumnContext * ctx)
{
return AlterTableClause::createDropColumn(!!ctx->IF(), visit(ctx->nestedIdentifier()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseDropIndex(ClickHouseParser::AlterTableClauseDropIndexContext * ctx)
{
return AlterTableClause::createDropIndex(!!ctx->IF(), visit(ctx->nestedIdentifier()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseDropProjection(ClickHouseParser::AlterTableClauseDropProjectionContext * ctx)
{
return AlterTableClause::createDropProjection(!!ctx->IF(), visit(ctx->nestedIdentifier()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseDropPartition(ClickHouseParser::AlterTableClauseDropPartitionContext *ctx)
{
return AlterTableClause::createDropPartition(visit(ctx->partitionClause()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseFreezePartition(ClickHouseParser::AlterTableClauseFreezePartitionContext *ctx)
{
auto clause = ctx->partitionClause() ? visit(ctx->partitionClause()).as<PtrTo<PartitionClause>>() : nullptr;
return AlterTableClause::createFreezePartition(clause);
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseMaterializeIndex(ClickHouseParser::AlterTableClauseMaterializeIndexContext * ctx)
{
auto partition = ctx->partitionClause() ? visit(ctx->partitionClause()).as<PtrTo<PartitionClause>>() : nullptr;
return AlterTableClause::createMaterializeIndex(!!ctx->IF(), visit(ctx->nestedIdentifier()), partition);
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseMaterializeProjection(ClickHouseParser::AlterTableClauseMaterializeProjectionContext * ctx)
{
auto partition = ctx->partitionClause() ? visit(ctx->partitionClause()).as<PtrTo<PartitionClause>>() : nullptr;
return AlterTableClause::createMaterializeProjection(!!ctx->IF(), visit(ctx->nestedIdentifier()), partition);
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseModify(ClickHouseParser::AlterTableClauseModifyContext * ctx)
{
return AlterTableClause::createModify(!!ctx->IF(), visit(ctx->tableColumnDfnt()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseModifyCodec(ClickHouseParser::AlterTableClauseModifyCodecContext * ctx)
{
return AlterTableClause::createCodec(!!ctx->IF(), visit(ctx->nestedIdentifier()), visit(ctx->codecExpr()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseModifyComment(ClickHouseParser::AlterTableClauseModifyCommentContext *ctx)
{
return AlterTableClause::createComment(!!ctx->IF(), visit(ctx->nestedIdentifier()), Literal::createString(ctx->STRING_LITERAL()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseModifyOrderBy(ClickHouseParser::AlterTableClauseModifyOrderByContext * ctx)
{
return AlterTableClause::createOrderBy(visit(ctx->columnExpr()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseModifyRemove(ClickHouseParser::AlterTableClauseModifyRemoveContext *ctx)
{
return AlterTableClause::createRemove(!!ctx->IF(), visit(ctx->nestedIdentifier()), visit(ctx->tableColumnPropertyType()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseModifyTTL(ClickHouseParser::AlterTableClauseModifyTTLContext *ctx)
{
return AlterTableClause::createTTL(visit(ctx->ttlClause()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseMovePartition(ClickHouseParser::AlterTableClauseMovePartitionContext *ctx)
{
if (ctx->DISK())
return AlterTableClause::createMovePartitionToDisk(visit(ctx->partitionClause()), Literal::createString(ctx->STRING_LITERAL()));
if (ctx->TABLE())
return AlterTableClause::createMovePartitionToTable(visit(ctx->partitionClause()), visit(ctx->tableIdentifier()));
if (ctx->VOLUME())
return AlterTableClause::createMovePartitionToVolume(visit(ctx->partitionClause()), Literal::createString(ctx->STRING_LITERAL()));
__builtin_unreachable();
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseRemoveTTL(ClickHouseParser::AlterTableClauseRemoveTTLContext *)
{
return AlterTableClause::createRemoveTTL();
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseRename(ClickHouseParser::AlterTableClauseRenameContext *ctx)
{
return AlterTableClause::createRename(!!ctx->IF(), visit(ctx->nestedIdentifier(0)), visit(ctx->nestedIdentifier(1)));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseReplace(ClickHouseParser::AlterTableClauseReplaceContext *ctx)
{
return AlterTableClause::createReplace(visit(ctx->partitionClause()), visit(ctx->tableIdentifier()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableClauseUpdate(ClickHouseParser::AlterTableClauseUpdateContext *ctx)
{
return AlterTableClause::createUpdate(visit(ctx->assignmentExprList()), visit(ctx->whereClause()));
}
antlrcpp::Any ParseTreeVisitor::visitAlterTableStmt(ClickHouseParser::AlterTableStmtContext * ctx)
{
auto cluster = ctx->clusterClause() ? visit(ctx->clusterClause()).as<PtrTo<ClusterClause>>() : nullptr;
auto list = std::make_shared<List<AlterTableClause>>();
for (auto * clause : ctx->alterTableClause()) list->push(visit(clause));
return std::make_shared<AlterTableQuery>(cluster, visit(ctx->tableIdentifier()), list);
}
antlrcpp::Any ParseTreeVisitor::visitAssignmentExpr(ClickHouseParser::AssignmentExprContext *ctx)
{
return std::make_shared<AssignmentExpr>(visit(ctx->nestedIdentifier()), visit(ctx->columnExpr()));
}
antlrcpp::Any ParseTreeVisitor::visitAssignmentExprList(ClickHouseParser::AssignmentExprListContext *ctx)
{
auto list = std::make_shared<AssignmentExprList>();
for (auto * expr : ctx->assignmentExpr()) list->push(visit(expr));
return list;
}
antlrcpp::Any ParseTreeVisitor::visitTableColumnPropertyType(ClickHouseParser::TableColumnPropertyTypeContext *ctx)
{
if (ctx->ALIAS()) return TableColumnPropertyType::ALIAS;
if (ctx->CODEC()) return TableColumnPropertyType::CODEC;
if (ctx->COMMENT()) return TableColumnPropertyType::COMMENT;
if (ctx->DEFAULT()) return TableColumnPropertyType::DEFAULT;
if (ctx->MATERIALIZED()) return TableColumnPropertyType::MATERIALIZED;
if (ctx->TTL()) return TableColumnPropertyType::TTL;
__builtin_unreachable();
}
antlrcpp::Any ParseTreeVisitor::visitPartitionClause(ClickHouseParser::PartitionClauseContext *ctx)
{
if (ctx->STRING_LITERAL())
return std::make_shared<PartitionClause>(Literal::createString(ctx->STRING_LITERAL()));
auto expr = visit(ctx->columnExpr()).as<PtrTo<ColumnExpr>>();
if (expr->getType() == ColumnExpr::ExprType::LITERAL)
return std::make_shared<PartitionClause>(PtrTo<List<Literal>>(new List<Literal>{expr->getLiteral()}));
if (expr->getType() == ColumnExpr::ExprType::FUNCTION && expr->getFunctionName() == "tuple")
{
auto list = std::make_shared<List<Literal>>();
for (auto it = expr->argumentsBegin(); it != expr->argumentsEnd(); ++it)
{
auto * literal = (*it)->as<ColumnExpr>();
if (literal->getType() == ColumnExpr::ExprType::LITERAL)
list->push(literal->getLiteral());
else
{
// TODO: 'Expected tuple of literals as Partition Expression'.
}
}
return std::make_shared<PartitionClause>(list);
}
// TODO: 'Expected tuple of literals as Partition Expression'.
__builtin_unreachable();
}
}

View File

@ -1,191 +0,0 @@
#pragma once
#include <Parsers/New/AST/DDLQuery.h>
namespace DB::AST
{
class AssignmentExpr : public INode
{
public:
AssignmentExpr(PtrTo<Identifier> identifier, PtrTo<ColumnExpr> expr);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
IDENTIFIER = 0, // Identifier
EXPR = 1, // ColumnExpr
};
};
enum class TableColumnPropertyType
{
ALIAS,
CODEC,
COMMENT,
DEFAULT,
MATERIALIZED,
TTL,
};
class PartitionClause : public INode
{
public:
explicit PartitionClause(PtrTo<Literal> id);
explicit PartitionClause(PtrTo<List<Literal>> list);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
ID = 0, // Literal
LIST = 0, // List<Literal>
};
enum class ClauseType
{
ID,
LIST,
};
const ClauseType clause_type;
PartitionClause(ClauseType type, PtrList exprs);
};
class AlterTableClause : public INode
{
public:
static PtrTo<AlterTableClause> createAddColumn(bool if_not_exists, PtrTo<TableElementExpr> element, PtrTo<Identifier> after);
static PtrTo<AlterTableClause> createAddIndex(bool if_not_exists, PtrTo<TableElementExpr> element, PtrTo<Identifier> after);
static PtrTo<AlterTableClause> createAddProjection(bool if_not_exists, PtrTo<TableElementExpr> element, PtrTo<Identifier> after);
static PtrTo<AlterTableClause> createAttach(PtrTo<PartitionClause> clause, PtrTo<TableIdentifier> from);
static PtrTo<AlterTableClause> createClearColumn(bool if_exists, PtrTo<Identifier> identifier, PtrTo<PartitionClause> in);
static PtrTo<AlterTableClause> createClearIndex(bool if_exists, PtrTo<Identifier> identifier, PtrTo<PartitionClause> in);
static PtrTo<AlterTableClause> createClearProjection(bool if_exists, PtrTo<Identifier> identifier, PtrTo<PartitionClause> in);
static PtrTo<AlterTableClause> createCodec(bool if_exists, PtrTo<Identifier> identifier, PtrTo<CodecExpr> codec);
static PtrTo<AlterTableClause> createComment(bool if_exists, PtrTo<Identifier> identifier, PtrTo<StringLiteral> comment);
static PtrTo<AlterTableClause> createDelete(PtrTo<ColumnExpr> expr);
static PtrTo<AlterTableClause> createDetach(PtrTo<PartitionClause> clause);
static PtrTo<AlterTableClause> createDropColumn(bool if_exists, PtrTo<Identifier> identifier);
static PtrTo<AlterTableClause> createDropIndex(bool if_exists, PtrTo<Identifier> identifier);
static PtrTo<AlterTableClause> createDropProjection(bool if_exists, PtrTo<Identifier> identifier);
static PtrTo<AlterTableClause> createDropPartition(PtrTo<PartitionClause> clause);
static PtrTo<AlterTableClause> createFreezePartition(PtrTo<PartitionClause> clause);
static PtrTo<AlterTableClause> createMaterializeIndex(bool if_exists, PtrTo<Identifier> identifier, PtrTo<PartitionClause> in);
static PtrTo<AlterTableClause> createMaterializeProjection(bool if_exists, PtrTo<Identifier> identifier, PtrTo<PartitionClause> in);
static PtrTo<AlterTableClause> createModify(bool if_exists, PtrTo<TableElementExpr> element);
static PtrTo<AlterTableClause> createMovePartitionToDisk(PtrTo<PartitionClause> clause, PtrTo<StringLiteral> literal);
static PtrTo<AlterTableClause> createMovePartitionToTable(PtrTo<PartitionClause> clause, PtrTo<TableIdentifier> identifier);
static PtrTo<AlterTableClause> createMovePartitionToVolume(PtrTo<PartitionClause> clause, PtrTo<StringLiteral> literal);
static PtrTo<AlterTableClause> createRemove(bool if_exists, PtrTo<Identifier> identifier, TableColumnPropertyType type);
static PtrTo<AlterTableClause> createRemoveTTL();
static PtrTo<AlterTableClause> createRename(bool if_exists, PtrTo<Identifier> identifier, PtrTo<Identifier> to);
static PtrTo<AlterTableClause> createOrderBy(PtrTo<ColumnExpr> expr);
static PtrTo<AlterTableClause> createReplace(PtrTo<PartitionClause> clause, PtrTo<TableIdentifier> from);
static PtrTo<AlterTableClause> createTTL(PtrTo<TTLClause> clause);
static PtrTo<AlterTableClause> createUpdate(PtrTo<AssignmentExprList> list, PtrTo<WhereClause> where);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
// ADD COLUMN, INDEX or PROJECTION
ELEMENT = 0, // TableElementExpr (COLUMN, CONSTRAINT, INDEX, PROJECTION)
AFTER = 1, // Identifier (optional)
// ATTACH/REPLACE
PARTITION = 0, // PartitionClause
FROM = 1, // TableIdentifier (optional)
// CLEAR COLUMN, INDEX or PROJECTION
IN = 1, // PartitionClause
// CODEC, COMMENT and RENAME
COLUMN = 0, // Identifier
CODEC = 1, // CodecExpr
// COMMENT
COMMENT = 1, // StringLiteral
// DELETE
EXPR = 0, // ColumnExpr
// MOVE
// TO = 1, // TableIdentifier or StringLiteral
// RENAME
TO = 1, // Identifier
// TTL
CLAUSE = 0, // TTLClause
// UPDATE
ASSIGNMENTS = 0, // AssignmentExprList
WHERE = 1, // WhereClause
};
enum class ClauseType
{
ADD_COLUMN,
ADD_INDEX,
ADD_PROJECTION,
ATTACH,
CLEAR_COLUMN,
CLEAR_INDEX,
CLEAR_PROJECTION,
CODEC,
COMMENT,
DELETE,
DETACH,
DROP_COLUMN,
DROP_INDEX,
DROP_PROJECTION,
DROP_PARTITION,
FREEZE_PARTITION,
MATERIALIZE_INDEX,
MATERIALIZE_PROJECTION,
MODIFY,
MOVE_PARTITION_TO_DISK,
MOVE_PARTITION_TO_TABLE,
MOVE_PARTITION_TO_VOLUME,
ORDER_BY,
REMOVE,
REMOVE_TTL,
RENAME,
REPLACE,
TTL,
UPDATE,
};
const ClauseType clause_type;
TableColumnPropertyType property_type = TableColumnPropertyType::ALIAS; // default value to silence PVS-Studio
union
{
bool if_exists;
bool if_not_exists;
};
AlterTableClause(ClauseType type, PtrList exprs);
};
class AlterTableQuery : public DDLQuery
{
public:
AlterTableQuery(PtrTo<ClusterClause> cluster, PtrTo<TableIdentifier> identifier, PtrTo<List<AlterTableClause>> clauses);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
TABLE = 0, // TableIdentifier
CLAUSES = 1, // List<AlterTableClause>
};
};
}

View File

@ -1,57 +0,0 @@
#include <Parsers/New/AST/AttachQuery.h>
#include <Parsers/ASTCreateQuery.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
// static
PtrTo<AttachQuery> AttachQuery::createDictionary(PtrTo<ClusterClause> clause, PtrTo<TableIdentifier> identifier)
{
return PtrTo<AttachQuery>(new AttachQuery(clause, QueryType::DICTIONARY, {identifier}));
}
AttachQuery::AttachQuery(PtrTo<ClusterClause> clause, QueryType type, PtrList exprs) : DDLQuery(clause, exprs), query_type(type)
{
}
ASTPtr AttachQuery::convertToOld() const
{
auto query = std::make_shared<ASTCreateQuery>();
query->attach = true;
switch(query_type)
{
case QueryType::DICTIONARY:
query->is_dictionary = true;
{
auto table = get(NAME)->convertToOld();
query->database = table->as<ASTTableIdentifier>()->getDatabaseName();
query->table = table->as<ASTTableIdentifier>()->shortName();
}
break;
}
query->cluster = cluster_name;
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitAttachDictionaryStmt(ClickHouseParser::AttachDictionaryStmtContext *ctx)
{
auto cluster = ctx->clusterClause() ? visit(ctx->clusterClause()).as<PtrTo<ClusterClause>>() : nullptr;
return AttachQuery::createDictionary(cluster, visit(ctx->tableIdentifier()));
}
}

View File

@ -1,32 +0,0 @@
#pragma once
#include <Parsers/New/AST/DDLQuery.h>
namespace DB::AST
{
class AttachQuery : public DDLQuery
{
public:
static PtrTo<AttachQuery> createDictionary(PtrTo<ClusterClause> clause, PtrTo<TableIdentifier> identifier);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // TableIdentifier
};
enum class QueryType
{
DICTIONARY,
};
const QueryType query_type;
AttachQuery(PtrTo<ClusterClause> clause, QueryType type, PtrList exprs);
};
}

View File

@ -1,44 +0,0 @@
#include <Parsers/New/AST/CheckQuery.h>
#include <Interpreters/StorageID.h>
#include <Parsers/ASTCheckQuery.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/New/AST/AlterTableQuery.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
CheckQuery::CheckQuery(PtrTo<TableIdentifier> identifier, PtrTo<PartitionClause> clause) : Query{identifier, clause}
{
}
ASTPtr CheckQuery::convertToOld() const
{
auto query = std::make_shared<ASTCheckQuery>();
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(NAME)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->shortName();
if (has(PARTITION)) query->partition = get(PARTITION)->convertToOld();
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitCheckStmt(ClickHouseParser::CheckStmtContext *ctx)
{
auto partition = ctx->partitionClause() ? visit(ctx->partitionClause()).as<PtrTo<PartitionClause>>() : nullptr;
return std::make_shared<CheckQuery>(visit(ctx->tableIdentifier()), partition);
}
}

View File

@ -1,24 +0,0 @@
#pragma once
#include <Parsers/New/AST/Query.h>
namespace DB::AST
{
class CheckQuery : public Query
{
public:
CheckQuery(PtrTo<TableIdentifier> identifier, PtrTo<PartitionClause> clause);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // TableIdentifier
PARTITION = 1, // PartitionClause (optional)
};
};
}

View File

@ -1,588 +0,0 @@
#include <Parsers/New/AST/ColumnExpr.h>
#include <Parsers/ASTAsterisk.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTQualifiedAsterisk.h>
#include <Parsers/ASTSubquery.h>
#include <Parsers/New/AST/ColumnTypeExpr.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/AST/SelectUnionQuery.h>
#include <Parsers/New/ClickHouseLexer.h>
#include <Parsers/New/ClickHouseParser.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::ErrorCodes
{
extern int SYNTAX_ERROR;
}
namespace DB::AST
{
// static
PtrTo<ColumnExpr> ColumnExpr::createAlias(PtrTo<ColumnExpr> expr, PtrTo<Identifier> alias)
{
return PtrTo<ColumnExpr>(new ColumnExpr(ExprType::ALIAS, {expr, alias}));
}
// static
PtrTo<ColumnExpr> ColumnExpr::createAsterisk(PtrTo<TableIdentifier> identifier, bool single_column)
{
auto expr = PtrTo<ColumnExpr>(new ColumnExpr(ExprType::ASTERISK, {identifier}));
expr->expect_single_column = single_column;
return expr;
}
// static
PtrTo<ColumnExpr> ColumnExpr::createFunction(PtrTo<Identifier> name, PtrTo<ColumnParamList> params, PtrTo<ColumnExprList> args)
{
// FIXME: make sure that all function names are camel-case.
// Flatten some consequent binary operators to a single multi-operator, because they are left-associative.
if ((name->getName() == "or" || name->getName() == "and") && args && args->size() == 2)
{
const auto * left = (*args->begin())->as<ColumnExpr>();
const auto * right = (*++args->begin())->as<ColumnExpr>();
if (left && left->getType() == ExprType::FUNCTION && left->getFunctionName() == name->getName())
{
auto new_args = std::make_shared<ColumnExprList>();
for (const auto & arg : left->get(ARGS)->as<ColumnExprList &>())
new_args->push(std::static_pointer_cast<ColumnExpr>(arg));
new_args->push(std::static_pointer_cast<ColumnExpr>(*++args->begin()));
args = new_args;
}
else if (right && right->getType() == ExprType::FUNCTION && right->getFunctionName() == name->getName())
{
auto new_args = std::make_shared<ColumnExprList>();
new_args->push(std::static_pointer_cast<ColumnExpr>(*args->begin()));
for (const auto & arg : right->get(ARGS)->as<ColumnExprList &>())
new_args->push(std::static_pointer_cast<ColumnExpr>(arg));
args = new_args;
}
}
return PtrTo<ColumnExpr>(new ColumnExpr(ExprType::FUNCTION, {name, params, args}));
}
// static
PtrTo<ColumnExpr> ColumnExpr::createIdentifier(PtrTo<ColumnIdentifier> identifier)
{
return PtrTo<ColumnExpr>(new ColumnExpr(ExprType::IDENTIFIER, {identifier}));
}
// static
PtrTo<ColumnExpr> ColumnExpr::createLambda(PtrTo<List<Identifier>> params, PtrTo<ColumnExpr> expr)
{
return PtrTo<ColumnExpr>(new ColumnExpr(ExprType::LAMBDA, {params, expr}));
}
// static
PtrTo<ColumnExpr> ColumnExpr::createLiteral(PtrTo<Literal> literal)
{
return PtrTo<ColumnExpr>(new ColumnExpr(ExprType::LITERAL, {literal}));
}
// static
PtrTo<ColumnExpr> ColumnExpr::createSubquery(PtrTo<SelectUnionQuery> query, bool scalar)
{
if (scalar) query->shouldBeScalar();
return PtrTo<ColumnExpr>(new ColumnExpr(ExprType::SUBQUERY, {query}));
}
ColumnExpr::ColumnExpr(ColumnExpr::ExprType type, PtrList exprs) : INode(exprs), expr_type(type)
{
}
ASTPtr ColumnExpr::convertToOld() const
{
switch (expr_type)
{
case ExprType::ALIAS:
{
ASTPtr expr = get(EXPR)->convertToOld();
if (auto * expr_with_alias = dynamic_cast<ASTWithAlias*>(expr.get()))
expr_with_alias->setAlias(get<Identifier>(ALIAS)->getName());
else
throw std::runtime_error("Trying to convert new expression with alias to old one without alias support: " + expr->getID());
return expr;
}
case ExprType::ASTERISK:
if (has(TABLE))
{
auto expr = std::make_shared<ASTQualifiedAsterisk>();
expr->children.push_back(get(TABLE)->convertToOld());
return expr;
}
return std::make_shared<ASTAsterisk>();
case ExprType::FUNCTION:
{
auto func = std::make_shared<ASTFunction>();
func->name = get<Identifier>(NAME)->getName();
if (has(ARGS))
{
func->arguments = get(ARGS)->convertToOld();
func->children.push_back(func->arguments);
}
if (has(PARAMS))
{
func->parameters = get(PARAMS)->convertToOld();
func->children.push_back(func->parameters);
}
return func;
}
case ExprType::IDENTIFIER:
return get(IDENTIFIER)->convertToOld();
case ExprType::LAMBDA:
{
auto func = std::make_shared<ASTFunction>();
auto tuple = std::make_shared<ASTFunction>();
func->name = "lambda";
func->arguments = std::make_shared<ASTExpressionList>();
func->arguments->children.push_back(tuple);
func->arguments->children.push_back(get(LAMBDA_EXPR)->convertToOld());
func->children.push_back(func->arguments);
tuple->name = "tuple";
tuple->arguments = get(LAMBDA_ARGS)->convertToOld();
tuple->children.push_back(tuple->arguments);
return func;
}
case ExprType::LITERAL:
return get(LITERAL)->convertToOld();
case ExprType::SUBQUERY:
{
auto subquery = std::make_shared<ASTSubquery>();
subquery->children.push_back(get(SUBQUERY)->convertToOld());
return subquery;
}
}
__builtin_unreachable();
}
String ColumnExpr::toString() const
{
switch(expr_type)
{
case ExprType::LITERAL: return get(LITERAL)->toString();
default: return {};
}
__builtin_unreachable();
}
String ColumnExpr::dumpInfo() const
{
switch(expr_type)
{
case ExprType::ALIAS: return "ALIAS";
case ExprType::ASTERISK: return "ASTERISK";
case ExprType::FUNCTION: return "FUNCTION";
case ExprType::IDENTIFIER: return "IDENTIFIER";
case ExprType::LAMBDA: return "LAMBDA";
case ExprType::LITERAL: return "LITERAL";
case ExprType::SUBQUERY: return "SUBQUERY";
}
__builtin_unreachable();
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitColumnArgExpr(ClickHouseParser::ColumnArgExprContext *ctx)
{
if (ctx->columnExpr()) return visit(ctx->columnExpr());
if (ctx->columnLambdaExpr()) return visit(ctx->columnLambdaExpr());
__builtin_unreachable();
}
antlrcpp::Any ParseTreeVisitor::visitColumnArgList(ClickHouseParser::ColumnArgListContext *ctx)
{
auto list = std::make_shared<ColumnExprList>();
for (auto * arg : ctx->columnArgExpr()) list->push(visit(arg));
return list;
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprAlias(ClickHouseParser::ColumnExprAliasContext *ctx)
{
if (ctx->AS()) return ColumnExpr::createAlias(visit(ctx->columnExpr()), visit(ctx->identifier()));
else return ColumnExpr::createAlias(visit(ctx->columnExpr()), visit(ctx->alias()));
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprAnd(ClickHouseParser::ColumnExprAndContext *ctx)
{
auto name = std::make_shared<Identifier>("and");
auto args = std::make_shared<ColumnExprList>();
for (auto * expr : ctx->columnExpr()) args->push(visit(expr));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprArray(ClickHouseParser::ColumnExprArrayContext *ctx)
{
auto name = std::make_shared<Identifier>("array");
auto args = ctx->columnExprList() ? visit(ctx->columnExprList()).as<PtrTo<ColumnExprList>>() : nullptr;
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprArrayAccess(ClickHouseParser::ColumnExprArrayAccessContext *ctx)
{
auto name = std::make_shared<Identifier>("arrayElement");
auto args = std::make_shared<ColumnExprList>();
for (auto * expr : ctx->columnExpr()) args->push(visit(expr));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprAsterisk(ClickHouseParser::ColumnExprAsteriskContext *ctx)
{
auto table = ctx->tableIdentifier() ? visit(ctx->tableIdentifier()).as<PtrTo<TableIdentifier>>() : nullptr;
return ColumnExpr::createAsterisk(table, true);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprBetween(ClickHouseParser::ColumnExprBetweenContext *ctx)
{
PtrTo<ColumnExpr> expr1, expr2;
{
auto name = std::make_shared<Identifier>(ctx->NOT() ? "lessOrEquals" : "greaterOrEquals");
auto args = std::make_shared<ColumnExprList>();
args->push(visit(ctx->columnExpr(0)));
args->push(visit(ctx->columnExpr(1)));
expr1 = ColumnExpr::createFunction(name, nullptr, args);
}
{
auto name = std::make_shared<Identifier>(ctx->NOT() ? "greaterOrEquals" : "lessOrEquals");
auto args = std::make_shared<ColumnExprList>();
args->push(visit(ctx->columnExpr(0)));
args->push(visit(ctx->columnExpr(2)));
expr2 = ColumnExpr::createFunction(name, nullptr, args);
}
auto name = std::make_shared<Identifier>("and");
auto args = std::make_shared<ColumnExprList>();
args->push(expr1);
args->push(expr2);
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprCase(ClickHouseParser::ColumnExprCaseContext *ctx)
{
auto has_case_expr = (ctx->ELSE() && ctx->columnExpr().size() % 2 == 0) || (!ctx->ELSE() && ctx->columnExpr().size() % 2 == 1);
auto name = std::make_shared<Identifier>(has_case_expr ? "caseWithExpression" : "multiIf");
auto args = std::make_shared<ColumnExprList>();
for (auto * expr : ctx->columnExpr()) args->push(visit(expr));
if (!ctx->ELSE()) args->push(ColumnExpr::createLiteral(Literal::createNull()));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprCast(ClickHouseParser::ColumnExprCastContext *ctx)
{
auto args = std::make_shared<ColumnExprList>();
args->push(visit(ctx->columnExpr()));
args->push(ColumnExpr::createLiteral(Literal::createString(visit(ctx->columnTypeExpr()).as<PtrTo<ColumnTypeExpr>>()->toString())));
return ColumnExpr::createFunction(std::make_shared<Identifier>("cast"), nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprDate(ClickHouseParser::ColumnExprDateContext *ctx)
{
auto name = std::make_shared<Identifier>("toDate");
auto args = std::make_shared<ColumnExprList>();
args->push(ColumnExpr::createLiteral(Literal::createString(ctx->STRING_LITERAL())));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprExtract(ClickHouseParser::ColumnExprExtractContext *ctx)
{
String name;
auto args = std::make_shared<ColumnExprList>();
if (ctx->interval()->SECOND()) name = "toSecond";
else if (ctx->interval()->MINUTE()) name = "toMinute";
else if (ctx->interval()->HOUR()) name = "toHour";
else if (ctx->interval()->DAY()) name = "toDayOfMonth";
else if (ctx->interval()->WEEK())
throw Exception(
"The syntax 'EXTRACT(WEEK FROM date)' is not supported, cannot extract the number of a week", ErrorCodes::SYNTAX_ERROR);
else if (ctx->interval()->MONTH()) name = "toMonth";
else if (ctx->interval()->QUARTER()) name = "toQuarter";
else if (ctx->interval()->YEAR()) name = "toYear";
else __builtin_unreachable();
args->push(visit(ctx->columnExpr()));
return ColumnExpr::createFunction(std::make_shared<Identifier>(name), nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprFunction(ClickHouseParser::ColumnExprFunctionContext *ctx)
{
auto name = visit(ctx->identifier()).as<PtrTo<Identifier>>();
auto params = ctx->columnExprList() ? visit(ctx->columnExprList()).as<PtrTo<ColumnExprList>>() : nullptr;
auto args = ctx->columnArgList() ? visit(ctx->columnArgList()).as<PtrTo<ColumnExprList>>() : nullptr;
if (ctx->DISTINCT()) name = std::make_shared<Identifier>(name->getName() + "Distinct");
return ColumnExpr::createFunction(name, params, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprIdentifier(ClickHouseParser::ColumnExprIdentifierContext *ctx)
{
return ColumnExpr::createIdentifier(visit(ctx->columnIdentifier()));
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprInterval(ClickHouseParser::ColumnExprIntervalContext *ctx)
{
PtrTo<Identifier> name;
auto args = std::make_shared<ColumnExprList>();
if (ctx->interval()->SECOND()) name = std::make_shared<Identifier>("toIntervalSecond");
else if (ctx->interval()->MINUTE()) name = std::make_shared<Identifier>("toIntervalMinute");
else if (ctx->interval()->HOUR()) name = std::make_shared<Identifier>("toIntervalHour");
else if (ctx->interval()->DAY()) name = std::make_shared<Identifier>("toIntervalDay");
else if (ctx->interval()->WEEK()) name = std::make_shared<Identifier>("toIntervalWeek");
else if (ctx->interval()->MONTH()) name = std::make_shared<Identifier>("toIntervalMonth");
else if (ctx->interval()->QUARTER()) name = std::make_shared<Identifier>("toIntervalQuarter");
else if (ctx->interval()->YEAR()) name = std::make_shared<Identifier>("toIntervalYear");
else __builtin_unreachable();
args->push(visit(ctx->columnExpr()));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprIsNull(ClickHouseParser::ColumnExprIsNullContext *ctx)
{
auto name = std::make_shared<Identifier>(ctx->NOT() ? "isNotNull" : "isNull");
auto args = std::make_shared<ColumnExprList>();
args->push(visit(ctx->columnExpr()));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprList(ClickHouseParser::ColumnExprListContext *ctx)
{
auto list = std::make_shared<ColumnExprList>();
for (auto * expr : ctx->columnsExpr()) list->push(visit(expr));
return list;
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprLiteral(ClickHouseParser::ColumnExprLiteralContext *ctx)
{
return ColumnExpr::createLiteral(visit(ctx->literal()).as<PtrTo<Literal>>());
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprNegate(ClickHouseParser::ColumnExprNegateContext *ctx)
{
auto name = std::make_shared<Identifier>("negate");
auto args = std::make_shared<ColumnExprList>();
args->push(visit(ctx->columnExpr()));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprNot(ClickHouseParser::ColumnExprNotContext *ctx)
{
auto name = std::make_shared<Identifier>("not");
auto args = std::make_shared<ColumnExprList>();
args->push(visit(ctx->columnExpr()));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprOr(ClickHouseParser::ColumnExprOrContext *ctx)
{
auto name = std::make_shared<Identifier>("or");
auto args = std::make_shared<ColumnExprList>();
for (auto * expr : ctx->columnExpr()) args->push(visit(expr));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprParens(ClickHouseParser::ColumnExprParensContext *ctx)
{
return visit(ctx->columnExpr());
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprPrecedence1(ClickHouseParser::ColumnExprPrecedence1Context *ctx)
{
PtrTo<Identifier> name;
if (ctx->ASTERISK()) name = std::make_shared<Identifier>("multiply");
else if (ctx->SLASH()) name = std::make_shared<Identifier>("divide");
else if (ctx->PERCENT()) name = std::make_shared<Identifier>("modulo");
auto args = std::make_shared<ColumnExprList>();
for (auto * expr : ctx->columnExpr()) args->push(visit(expr));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprPrecedence2(ClickHouseParser::ColumnExprPrecedence2Context *ctx)
{
PtrTo<Identifier> name;
if (ctx->PLUS()) name = std::make_shared<Identifier>("plus");
else if (ctx->DASH()) name = std::make_shared<Identifier>("minus");
else if (ctx->CONCAT()) name = std::make_shared<Identifier>("concat");
auto args = std::make_shared<ColumnExprList>();
for (auto * expr : ctx->columnExpr()) args->push(visit(expr));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprPrecedence3(ClickHouseParser::ColumnExprPrecedence3Context *ctx)
{
PtrTo<Identifier> name;
if (ctx->EQ_DOUBLE() || ctx->EQ_SINGLE()) name = std::make_shared<Identifier>("equals");
else if (ctx->NOT_EQ()) name = std::make_shared<Identifier>("notEquals");
else if (ctx->LE()) name = std::make_shared<Identifier>("lessOrEquals");
else if (ctx->GE()) name = std::make_shared<Identifier>("greaterOrEquals");
else if (ctx->LT()) name = std::make_shared<Identifier>("less");
else if (ctx->GT()) name = std::make_shared<Identifier>("greater");
else if (ctx->LIKE())
{
if (ctx->NOT()) name = std::make_shared<Identifier>("notLike");
else name = std::make_shared<Identifier>("like");
}
else if (ctx->ILIKE())
{
if (ctx->NOT()) name = std::make_shared<Identifier>("notILike");
else name = std::make_shared<Identifier>("ilike");
}
else if (ctx->IN())
{
if (ctx->GLOBAL())
{
if (ctx->NOT()) name = std::make_shared<Identifier>("globalNotIn");
else name = std::make_shared<Identifier>("globalIn");
}
else
{
if (ctx->NOT()) name = std::make_shared<Identifier>("notIn");
else name = std::make_shared<Identifier>("in");
}
}
auto args = std::make_shared<ColumnExprList>();
for (auto * expr : ctx->columnExpr()) args->push(visit(expr));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprSubquery(ClickHouseParser::ColumnExprSubqueryContext *ctx)
{
// IN-operator is special since it accepts non-scalar subqueries on the right side.
auto * parent = dynamic_cast<ClickHouseParser::ColumnExprPrecedence3Context*>(ctx->parent);
return ColumnExpr::createSubquery(visit(ctx->selectUnionStmt()), !(parent && parent->IN()));
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprSubstring(ClickHouseParser::ColumnExprSubstringContext *ctx)
{
auto name = std::make_shared<Identifier>("substring");
auto args = std::make_shared<ColumnExprList>();
for (auto * expr : ctx->columnExpr()) args->push(visit(expr));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprTernaryOp(ClickHouseParser::ColumnExprTernaryOpContext *ctx)
{
auto name = std::make_shared<Identifier>("if");
auto args = std::make_shared<ColumnExprList>();
for (auto * expr : ctx->columnExpr()) args->push(visit(expr));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprTimestamp(ClickHouseParser::ColumnExprTimestampContext *ctx)
{
auto name = std::make_shared<Identifier>("toDateTime");
auto args = std::make_shared<ColumnExprList>();
args->push(ColumnExpr::createLiteral(Literal::createString(ctx->STRING_LITERAL())));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprTrim(ClickHouseParser::ColumnExprTrimContext *ctx)
{
auto name = std::make_shared<Identifier>("trim");
auto args = std::make_shared<ColumnExprList>();
auto params = std::make_shared<ColumnParamList>();
args->push(visit(ctx->columnExpr()));
// TODO: params->append(Literal::createString(???));
params->push(ColumnExpr::createLiteral(Literal::createString(ctx->STRING_LITERAL())));
return ColumnExpr::createFunction(name, params, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprTuple(ClickHouseParser::ColumnExprTupleContext *ctx)
{
auto name = std::make_shared<Identifier>("tuple");
auto args = visit(ctx->columnExprList()).as<PtrTo<ColumnExprList>>();
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnExprTupleAccess(ClickHouseParser::ColumnExprTupleAccessContext *ctx)
{
auto name = std::make_shared<Identifier>("tupleElement");
auto args = std::make_shared<ColumnExprList>();
args->push(visit(ctx->columnExpr()));
args->push(ColumnExpr::createLiteral(Literal::createNumber(ctx->DECIMAL_LITERAL())));
return ColumnExpr::createFunction(name, nullptr, args);
}
antlrcpp::Any ParseTreeVisitor::visitColumnLambdaExpr(ClickHouseParser::ColumnLambdaExprContext *ctx)
{
auto params = std::make_shared<List<Identifier>>();
for (auto * id : ctx->identifier()) params->push(visit(id));
return ColumnExpr::createLambda(params, visit(ctx->columnExpr()));
}
antlrcpp::Any ParseTreeVisitor::visitColumnsExprAsterisk(ClickHouseParser::ColumnsExprAsteriskContext *ctx)
{
auto table = ctx->tableIdentifier() ? visit(ctx->tableIdentifier()).as<PtrTo<TableIdentifier>>() : nullptr;
return ColumnExpr::createAsterisk(table, false);
}
antlrcpp::Any ParseTreeVisitor::visitColumnsExprSubquery(ClickHouseParser::ColumnsExprSubqueryContext *ctx)
{
return ColumnExpr::createSubquery(visit(ctx->selectUnionStmt()), false);
}
antlrcpp::Any ParseTreeVisitor::visitColumnsExprColumn(ClickHouseParser::ColumnsExprColumnContext *ctx)
{
return visit(ctx->columnExpr());
}
}

View File

@ -1,82 +0,0 @@
#pragma once
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/Literal.h>
namespace DB::AST
{
class ColumnExpr : public INode
{
public:
static PtrTo<ColumnExpr> createAlias(PtrTo<ColumnExpr> expr, PtrTo<Identifier> alias);
static PtrTo<ColumnExpr> createAsterisk(PtrTo<TableIdentifier> identifier, bool single_column);
static PtrTo<ColumnExpr> createFunction(PtrTo<Identifier> name, PtrTo<ColumnParamList> params, PtrTo<ColumnExprList> args);
static PtrTo<ColumnExpr> createIdentifier(PtrTo<ColumnIdentifier> identifier);
static PtrTo<ColumnExpr> createLambda(PtrTo<List<Identifier>> params, PtrTo<ColumnExpr> expr);
static PtrTo<ColumnExpr> createLiteral(PtrTo<Literal> literal);
static PtrTo<ColumnExpr> createSubquery(PtrTo<SelectUnionQuery> query, bool scalar);
enum class ExprType
{
ALIAS,
ASTERISK,
FUNCTION,
IDENTIFIER,
LAMBDA,
LITERAL,
SUBQUERY,
};
auto getType() const { return expr_type; };
// FUNCTION
auto getFunctionName() const { return get<Identifier>(NAME)->getName(); }
auto argumentsBegin() const { return has(ARGS) ? get<ColumnExprList>(ARGS)->begin() : end(); }
auto argumentsEnd() const { return has(ARGS) ? get<ColumnExprList>(ARGS)->end() : end(); }
// LITERAL
auto getLiteral() const { return std::static_pointer_cast<Literal>(get(LITERAL)); }
ASTPtr convertToOld() const override;
String toString() const override;
private:
enum ChildIndex : UInt8
{
// ALIAS
EXPR = 0, // ColumnExpr
ALIAS = 1, // Identifier
// ASTERISK
TABLE = 0, // TableIdentifier (optional)
// IDENTIFIER
IDENTIFIER = 0, // ColumnIdentifier
// FUNCTION
NAME = 0, // Identifier
PARAMS = 1, // ColumnParamList (optional)
ARGS = 2, // ColumnExprList (optional)
// LAMBDA
LAMBDA_ARGS = 0,
LAMBDA_EXPR = 1,
// LITERAL
LITERAL = 0,
// SUBQUERY
SUBQUERY = 0,
};
const ExprType expr_type;
bool expect_single_column = false;
ColumnExpr(ExprType type, PtrList exprs);
String dumpInfo() const override;
};
}

View File

@ -1,166 +0,0 @@
#include <Parsers/New/AST/ColumnTypeExpr.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTNameTypePair.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
EnumValue::EnumValue(PtrTo<StringLiteral> name, PtrTo<NumberLiteral> value) : INode{name, value}
{
}
ASTPtr EnumValue::convertToOld() const
{
auto func = std::make_shared<ASTFunction>();
func->name = "equals";
func->arguments = std::make_shared<ASTExpressionList>();
func->arguments->children.push_back(get(NAME)->convertToOld());
func->arguments->children.push_back(get(VALUE)->convertToOld());
func->children.push_back(func->arguments);
return func;
}
String EnumValue::toString() const
{
return fmt::format("{} = {}", get(NAME)->toString(), get(VALUE)->toString());
}
// static
PtrTo<ColumnTypeExpr> ColumnTypeExpr::createSimple(PtrTo<Identifier> identifier)
{
return PtrTo<ColumnTypeExpr>(new ColumnTypeExpr(ExprType::SIMPLE, {identifier}));
}
// static
PtrTo<ColumnTypeExpr> ColumnTypeExpr::createNamed(PtrTo<Identifier> identifier, PtrTo<ColumnTypeExpr> type)
{
return PtrTo<ColumnTypeExpr>(new ColumnTypeExpr(ExprType::NAMED, {identifier, type}));
}
// static
PtrTo<ColumnTypeExpr> ColumnTypeExpr::createComplex(PtrTo<Identifier> identifier, PtrTo<ColumnTypeExprList> list)
{
return PtrTo<ColumnTypeExpr>(new ColumnTypeExpr(ExprType::COMPLEX, {identifier, list}));
}
// static
PtrTo<ColumnTypeExpr> ColumnTypeExpr::createEnum(PtrTo<Identifier> identifier, PtrTo<EnumValueList> list)
{
return PtrTo<ColumnTypeExpr>(new ColumnTypeExpr(ExprType::ENUM, {identifier, list}));
}
// static
PtrTo<ColumnTypeExpr> ColumnTypeExpr::createParam(PtrTo<Identifier> identifier, PtrTo<ColumnParamList> list)
{
return PtrTo<ColumnTypeExpr>(new ColumnTypeExpr(ExprType::PARAM, {identifier, list}));
}
// static
PtrTo<ColumnTypeExpr> ColumnTypeExpr::createNested(PtrTo<Identifier> identifier, PtrTo<ColumnTypeExprList> list)
{
// TODO: assert that |list| must contain only expressions of NAMED type
return PtrTo<ColumnTypeExpr>(new ColumnTypeExpr(ExprType::NESTED, {identifier, list}));
}
ColumnTypeExpr::ColumnTypeExpr(ExprType type, PtrList exprs) : INode(exprs), expr_type(type)
{
}
ASTPtr ColumnTypeExpr::convertToOld() const
{
if (expr_type == ExprType::NAMED)
{
auto pair = std::make_shared<ASTNameTypePair>();
pair->name = get<Identifier>(NAME)->getName();
pair->type = get(TYPE)->convertToOld();
pair->children.push_back(pair->type);
return pair;
}
auto func = std::make_shared<ASTFunction>();
func->name = get<Identifier>(NAME)->getName();
func->no_empty_args = true;
if (expr_type != ExprType::SIMPLE && has(LIST))
{
func->arguments = get(LIST)->convertToOld();
func->children.push_back(func->arguments);
}
return func;
}
String ColumnTypeExpr::toString() const
{
switch(expr_type)
{
case ExprType::SIMPLE:
return get(NAME)->toString();
case ExprType::NAMED:
return get(NAME)->toString() + " " + get(TYPE)->toString();
case ExprType::COMPLEX:
case ExprType::ENUM:
case ExprType::PARAM:
case ExprType::NESTED:
return get(NAME)->toString() + "(" + (has(LIST) ? get(LIST)->toString() : "") + ")";
}
__builtin_unreachable();
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitColumnTypeExprSimple(ClickHouseParser::ColumnTypeExprSimpleContext *ctx)
{
return ColumnTypeExpr::createSimple(visit(ctx->identifier()));
}
antlrcpp::Any ParseTreeVisitor::visitColumnTypeExprParam(ClickHouseParser::ColumnTypeExprParamContext *ctx)
{
auto list = ctx->columnExprList() ? visit(ctx->columnExprList()).as<PtrTo<ColumnExprList>>() : nullptr;
return ColumnTypeExpr::createParam(visit(ctx->identifier()), list);
}
antlrcpp::Any ParseTreeVisitor::visitColumnTypeExprEnum(ClickHouseParser::ColumnTypeExprEnumContext *ctx)
{
auto list = std::make_shared<EnumValueList>();
for (auto * value : ctx->enumValue()) list->push(visit(value));
return ColumnTypeExpr::createEnum(visit(ctx->identifier()), list);
}
antlrcpp::Any ParseTreeVisitor::visitColumnTypeExprComplex(ClickHouseParser::ColumnTypeExprComplexContext *ctx)
{
auto list = std::make_shared<ColumnTypeExprList>();
for (auto * expr : ctx->columnTypeExpr()) list->push(visit(expr));
return ColumnTypeExpr::createComplex(visit(ctx->identifier()), list);
}
antlrcpp::Any ParseTreeVisitor::visitColumnTypeExprNested(ClickHouseParser::ColumnTypeExprNestedContext *ctx)
{
auto list = std::make_shared<ColumnTypeExprList>();
for (size_t i = 0; i < ctx->columnTypeExpr().size(); ++i)
list->push(ColumnTypeExpr::createNamed(visit(ctx->identifier(i + 1)), visit(ctx->columnTypeExpr(i))));
return ColumnTypeExpr::createNested(visit(ctx->identifier(0)), list);
}
antlrcpp::Any ParseTreeVisitor::visitEnumValue(ClickHouseParser::EnumValueContext *ctx)
{
return std::make_shared<EnumValue>(Literal::createString(ctx->STRING_LITERAL()), visit(ctx->numberLiteral()));
}
}

View File

@ -1,62 +0,0 @@
#pragma once
#include <Parsers/New/AST/INode.h>
#include <list>
namespace DB::AST
{
class EnumValue : public INode
{
public:
EnumValue(PtrTo<StringLiteral> name, PtrTo<NumberLiteral> value);
ASTPtr convertToOld() const override;
String toString() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // StringLiteral
VALUE = 1, // NumberLiteral
};
};
class ColumnTypeExpr : public INode
{
public:
static PtrTo<ColumnTypeExpr> createSimple(PtrTo<Identifier> identifier);
static PtrTo<ColumnTypeExpr> createNamed(PtrTo<Identifier> identifier, PtrTo<ColumnTypeExpr> type);
static PtrTo<ColumnTypeExpr> createComplex(PtrTo<Identifier> identifier, PtrTo<ColumnTypeExprList> list);
static PtrTo<ColumnTypeExpr> createEnum(PtrTo<Identifier> identifier, PtrTo<EnumValueList> list);
static PtrTo<ColumnTypeExpr> createParam(PtrTo<Identifier> identifier, PtrTo<ColumnParamList> list);
static PtrTo<ColumnTypeExpr> createNested(PtrTo<Identifier> identifier, PtrTo<ColumnTypeExprList> list);
ASTPtr convertToOld() const override;
String toString() const override;
private:
enum class ExprType
{
SIMPLE,
NAMED,
COMPLEX,
ENUM,
PARAM,
NESTED,
};
enum ChildIndex : UInt8
{
NAME = 0, // Identifier
TYPE = 1, // ColumnTypeExpr
LIST = 1, // depends on |expr_type|
};
ExprType expr_type;
ColumnTypeExpr(ExprType type, PtrList exprs);
};
}

View File

@ -1,51 +0,0 @@
#include <Parsers/New/AST/CreateDatabaseQuery.h>
#include <Parsers/ASTCreateQuery.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/New/AST/EngineExpr.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
CreateDatabaseQuery::CreateDatabaseQuery(
PtrTo<ClusterClause> cluster, bool if_not_exists_, PtrTo<DatabaseIdentifier> identifier, PtrTo<EngineExpr> expr)
: DDLQuery(cluster, {identifier, expr}), if_not_exists(if_not_exists_)
{
}
ASTPtr CreateDatabaseQuery::convertToOld() const
{
auto query = std::make_shared<ASTCreateQuery>();
query->if_not_exists = if_not_exists;
query->database = get<DatabaseIdentifier>(NAME)->getName();
query->cluster = cluster_name;
if (has(ENGINE))
{
auto engine = std::make_shared<ASTStorage>();
engine->set(engine->engine, get(ENGINE)->convertToOld());
query->set(query->storage, engine);
}
// TODO: query->uuid
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitCreateDatabaseStmt(ClickHouseParser::CreateDatabaseStmtContext *ctx)
{
auto engine = ctx->engineExpr() ? visit(ctx->engineExpr()).as<PtrTo<EngineExpr>>() : nullptr;
auto cluster = ctx->clusterClause() ? visit(ctx->clusterClause()).as<PtrTo<ClusterClause>>() : nullptr;
return std::make_shared<CreateDatabaseQuery>(cluster, !!ctx->IF(), visit(ctx->databaseIdentifier()), engine);
}
}

View File

@ -1,26 +0,0 @@
#pragma once
#include <Parsers/New/AST/DDLQuery.h>
namespace DB::AST
{
class CreateDatabaseQuery: public DDLQuery
{
public:
CreateDatabaseQuery(PtrTo<ClusterClause> cluster, bool if_not_exists, PtrTo<DatabaseIdentifier> identifier, PtrTo<EngineExpr> expr);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // DatabaseIdentifier
ENGINE = 1, // EngineExpr (optional)
};
const bool if_not_exists;
};
}

View File

@ -1,361 +0,0 @@
#include <Parsers/New/AST/CreateDictionaryQuery.h>
#include <Parsers/ASTCreateQuery.h>
#include <Parsers/New/AST/ColumnExpr.h>
#include <Parsers/New/AST/ColumnTypeExpr.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/AST/SelectUnionQuery.h>
#include <Parsers/New/AST/SettingExpr.h>
#include <Parsers/New/ParseTreeVisitor.h>
#include <Poco/String.h>
namespace DB::ErrorCodes
{
extern const int SYNTAX_ERROR;
}
namespace DB::AST
{
// DictionaryAttributeExpr
DictionaryAttributeExpr::DictionaryAttributeExpr(PtrTo<Identifier> identifier, PtrTo<ColumnTypeExpr> type) : INode(MAX_INDEX)
{
set(NAME, identifier);
set(TYPE, type);
}
void DictionaryAttributeExpr::setDefaultClause(PtrTo<Literal> literal)
{
set(DEFAULT, literal);
}
void DictionaryAttributeExpr::setExpressionClause(PtrTo<ColumnExpr> expr)
{
set(EXPRESSION, expr);
}
ASTPtr DictionaryAttributeExpr::convertToOld() const
{
auto expr = std::make_shared<ASTDictionaryAttributeDeclaration>();
expr->name = get<Identifier>(NAME)->getName();
if (has(TYPE))
{
expr->type = get(TYPE)->convertToOld();
expr->children.push_back(expr->type);
}
if (has(DEFAULT))
{
expr->default_value = get(DEFAULT)->convertToOld();
expr->children.push_back(expr->default_value);
}
if (has(EXPRESSION))
{
expr->expression = get(EXPRESSION)->convertToOld();
expr->children.push_back(expr->expression);
}
expr->hierarchical = hierarchical;
expr->injective = injective;
expr->is_object_id = is_object_id;
return expr;
}
// DictionaryArgExpr
DictionaryArgExpr::DictionaryArgExpr(PtrTo<Identifier> identifier, PtrTo<ColumnExpr> expr) : INode{identifier, expr}
{
if (expr->getType() != ColumnExpr::ExprType::LITERAL && expr->getType() != ColumnExpr::ExprType::IDENTIFIER
&& expr->getType() != ColumnExpr::ExprType::FUNCTION)
throw DB::Exception(ErrorCodes::SYNTAX_ERROR, "Expected literal, identifier or function");
}
ASTPtr DictionaryArgExpr::convertToOld() const
{
auto expr = std::make_shared<ASTPair>(false); // FIXME: always true?
// TODO: probably there are more variants to parse.
expr->first = Poco::toLower(get<Identifier>(KEY)->getName());
expr->set(expr->second, get(VALUE)->convertToOld());
return expr;
}
// SourceClause
SourceClause::SourceClause(PtrTo<Identifier> identifier, PtrTo<DictionaryArgList> list) : INode{identifier, list}
{
}
ASTPtr SourceClause::convertToOld() const
{
auto clause = std::make_shared<ASTFunctionWithKeyValueArguments>(true); // FIXME: always true?
clause->name = Poco::toLower(get<Identifier>(NAME)->getName());
if (has(ARGS))
{
clause->elements = get(ARGS)->convertToOld();
clause->children.push_back(clause->elements);
}
return clause;
}
// LifetimeClause
LifetimeClause::LifetimeClause(PtrTo<NumberLiteral> max, PtrTo<NumberLiteral> min) : INode{max, min}
{
}
ASTPtr LifetimeClause::convertToOld() const
{
auto clause = std::make_shared<ASTDictionaryLifetime>();
clause->max_sec = get(MAX)->convertToOld()->as<ASTLiteral>()->value.get<UInt64>();
if (has(MIN)) clause->min_sec = get(MIN)->convertToOld()->as<ASTLiteral>()->value.get<UInt64>();
return clause;
}
// LayoutClause
LayoutClause::LayoutClause(PtrTo<Identifier> identifier, PtrTo<DictionaryArgList> list) : INode{identifier, list}
{
}
ASTPtr LayoutClause::convertToOld() const
{
auto clause = std::make_shared<ASTDictionaryLayout>();
clause->layout_type = Poco::toLower(get<Identifier>(NAME)->getName());
clause->has_brackets = true; // FIXME: maybe not?
if (has(ARGS)) clause->set(clause->parameters, get(ARGS)->convertToOld());
return clause;
}
// RangeClause
RangeClause::RangeClause(PtrTo<Identifier> max, PtrTo<Identifier> min) : INode{max, min}
{
}
ASTPtr RangeClause::convertToOld() const
{
auto clause = std::make_shared<ASTDictionaryRange>();
clause->max_attr_name = get<Identifier>(MAX)->getName();
clause->min_attr_name = get<Identifier>(MIN)->getName();
return clause;
}
// DictionarySettingsClause
DictionarySettingsClause::DictionarySettingsClause(PtrTo<SettingExprList> list) : INode{list}
{
}
ASTPtr DictionarySettingsClause::convertToOld() const
{
auto clause = std::make_shared<ASTDictionarySettings>();
for (const auto & child : get(LIST)->as<SettingExprList &>())
{
const auto * setting = child->as<SettingExpr>();
clause->changes.emplace_back(setting->getName()->getName(), setting->getValue()->convertToOld()->as<ASTLiteral>()->value);
}
return clause;
}
// DictionaryEngineClause
DictionaryEngineClause::DictionaryEngineClause(PtrTo<DictionaryPrimaryKeyClause> clause) : INode(MAX_INDEX)
{
set(PRIMARY_KEY, clause);
}
void DictionaryEngineClause::setSourceClause(PtrTo<SourceClause> clause)
{
set(SOURCE, clause);
}
void DictionaryEngineClause::setLifetimeClause(PtrTo<LifetimeClause> clause)
{
set(LIFETIME, clause);
}
void DictionaryEngineClause::setLayoutClause(PtrTo<LayoutClause> clause)
{
set(LAYOUT, clause);
}
void DictionaryEngineClause::setRangeClause(PtrTo<RangeClause> clause)
{
set(RANGE, clause);
}
void DictionaryEngineClause::setSettingsClause(PtrTo<DictionarySettingsClause> clause)
{
set(SETTINGS, clause);
}
ASTPtr DictionaryEngineClause::convertToOld() const
{
auto clause = std::make_shared<ASTDictionary>();
if (has(PRIMARY_KEY)) clause->set(clause->primary_key, get(PRIMARY_KEY)->convertToOld());
if (has(SOURCE)) clause->set(clause->source, get(SOURCE)->convertToOld());
if (has(LIFETIME)) clause->set(clause->lifetime, get(LIFETIME)->convertToOld());
if (has(LAYOUT)) clause->set(clause->layout, get(LAYOUT)->convertToOld());
if (has(RANGE)) clause->set(clause->range, get(RANGE)->convertToOld());
if (has(SETTINGS)) clause->set(clause->dict_settings, get(SETTINGS)->convertToOld());
return clause;
}
// CreateDictionaryQuery
CreateDictionaryQuery::CreateDictionaryQuery(
PtrTo<ClusterClause> cluster,
bool attach_,
bool if_not_exists_,
PtrTo<TableIdentifier> identifier,
PtrTo<UUIDClause> uuid,
PtrTo<DictionarySchemaClause> schema,
PtrTo<DictionaryEngineClause> engine)
: DDLQuery(cluster, {identifier, uuid, schema, engine}), attach(attach_), if_not_exists(if_not_exists_)
{
}
ASTPtr CreateDictionaryQuery::convertToOld() const
{
auto query = std::make_shared<ASTCreateQuery>();
{
auto table = get(NAME)->convertToOld();
query->database = table->as<ASTTableIdentifier>()->getDatabaseName();
query->table = table->as<ASTTableIdentifier>()->shortName();
query->uuid = has(UUID) ? parseFromString<DB::UUID>(get(UUID)->convertToOld()->as<ASTLiteral>()->value.get<String>())
: table->as<ASTTableIdentifier>()->uuid;
}
query->cluster = cluster_name;
query->is_dictionary = true;
query->attach = attach;
query->if_not_exists = if_not_exists;
query->set(query->dictionary_attributes_list, get(SCHEMA)->convertToOld());
query->set(query->dictionary, get(ENGINE)->convertToOld());
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitCreateDictionaryStmt(ClickHouseParser::CreateDictionaryStmtContext *ctx)
{
auto uuid = ctx->uuidClause() ? visit(ctx->uuidClause()).as<PtrTo<UUIDClause>>() : nullptr;
auto cluster = ctx->clusterClause() ? visit(ctx->clusterClause()).as<PtrTo<ClusterClause>>() : nullptr;
auto schema = ctx->dictionarySchemaClause() ? visit(ctx->dictionarySchemaClause()).as<PtrTo<DictionarySchemaClause>>() : nullptr;
auto engine = ctx->dictionaryEngineClause() ? visit(ctx->dictionaryEngineClause()).as<PtrTo<DictionaryEngineClause>>() : nullptr;
return std::make_shared<CreateDictionaryQuery>(
cluster, !!ctx->ATTACH(), !!ctx->IF(), visit(ctx->tableIdentifier()), uuid, schema, engine);
}
antlrcpp::Any ParseTreeVisitor::visitDictionaryArgExpr(ClickHouseParser::DictionaryArgExprContext *ctx)
{
PtrTo<ColumnExpr> expr;
if (ctx->literal()) expr = ColumnExpr::createLiteral(visit(ctx->literal()));
else if (ctx->LPAREN()) expr = ColumnExpr::createFunction(visit(ctx->identifier(1)), nullptr, nullptr);
else expr = ColumnExpr::createIdentifier(visit(ctx->identifier(1)));
return std::make_shared<DictionaryArgExpr>(visit(ctx->identifier(0)), expr);
}
antlrcpp::Any ParseTreeVisitor::visitDictionaryAttrDfnt(ClickHouseParser::DictionaryAttrDfntContext *ctx)
{
auto expr = std::make_shared<DictionaryAttributeExpr>(visit(ctx->identifier()), visit(ctx->columnTypeExpr()));
if (!ctx->DEFAULT().empty()) expr->setDefaultClause(visit(ctx->literal(0)));
if (!ctx->EXPRESSION().empty()) expr->setExpressionClause(visit(ctx->columnExpr(0)));
if (!ctx->HIERARCHICAL().empty()) expr->setHierarchicalFlag();
if (!ctx->INJECTIVE().empty()) expr->setInjectiveFlag();
if (!ctx->IS_OBJECT_ID().empty()) expr->setIsObjectIdFlag();
return expr;
}
antlrcpp::Any ParseTreeVisitor::visitDictionaryEngineClause(ClickHouseParser::DictionaryEngineClauseContext *ctx)
{
auto primary_key
= ctx->dictionaryPrimaryKeyClause() ? visit(ctx->dictionaryPrimaryKeyClause()).as<PtrTo<DictionaryPrimaryKeyClause>>() : nullptr;
auto clause = std::make_shared<DictionaryEngineClause>(primary_key);
if (!ctx->sourceClause().empty()) clause->setSourceClause(visit(ctx->sourceClause(0)));
if (!ctx->lifetimeClause().empty()) clause->setLifetimeClause(visit(ctx->lifetimeClause(0)));
if (!ctx->layoutClause().empty()) clause->setLayoutClause(visit(ctx->layoutClause(0)));
if (!ctx->rangeClause().empty()) clause->setRangeClause(visit(ctx->rangeClause(0)));
if (!ctx->dictionarySettingsClause().empty()) clause->setSettingsClause(visit(ctx->dictionarySettingsClause(0)));
return clause;
}
antlrcpp::Any ParseTreeVisitor::visitDictionaryPrimaryKeyClause(ClickHouseParser::DictionaryPrimaryKeyClauseContext *ctx)
{
return std::make_shared<DictionaryPrimaryKeyClause>(visit(ctx->columnExprList()).as<PtrTo<ColumnExprList>>());
}
antlrcpp::Any ParseTreeVisitor::visitDictionarySchemaClause(ClickHouseParser::DictionarySchemaClauseContext *ctx)
{
auto list = std::make_shared<DictionaryAttributeList>();
for (auto * attr : ctx->dictionaryAttrDfnt()) list->push(visit(attr));
return std::make_shared<DictionarySchemaClause>(list);
}
antlrcpp::Any ParseTreeVisitor::visitDictionarySettingsClause(ClickHouseParser::DictionarySettingsClauseContext *ctx)
{
return std::make_shared<DictionarySettingsClause>(visit(ctx->settingExprList()).as<PtrTo<SettingExprList>>());
}
antlrcpp::Any ParseTreeVisitor::visitLayoutClause(ClickHouseParser::LayoutClauseContext *ctx)
{
auto list = ctx->dictionaryArgExpr().empty() ? nullptr : std::make_shared<DictionaryArgList>();
for (auto * arg : ctx->dictionaryArgExpr()) list->push(visit(arg));
return std::make_shared<LayoutClause>(visit(ctx->identifier()), list);
}
antlrcpp::Any ParseTreeVisitor::visitLifetimeClause(ClickHouseParser::LifetimeClauseContext *ctx)
{
if (ctx->DECIMAL_LITERAL().size() == 1) return std::make_shared<LifetimeClause>(Literal::createNumber(ctx->DECIMAL_LITERAL(0)));
if (ctx->MAX()->getSymbol()->getTokenIndex() < ctx->MIN()->getSymbol()->getTokenIndex())
return std::make_shared<LifetimeClause>(
Literal::createNumber(ctx->DECIMAL_LITERAL(0)), Literal::createNumber(ctx->DECIMAL_LITERAL(1)));
else
return std::make_shared<LifetimeClause>(
Literal::createNumber(ctx->DECIMAL_LITERAL(1)), Literal::createNumber(ctx->DECIMAL_LITERAL(0)));
}
antlrcpp::Any ParseTreeVisitor::visitRangeClause(ClickHouseParser::RangeClauseContext *ctx)
{
if (ctx->MAX()->getSymbol()->getTokenIndex() < ctx->MIN()->getSymbol()->getTokenIndex())
return std::make_shared<RangeClause>(visit(ctx->identifier(0)), visit(ctx->identifier(1)));
else
return std::make_shared<RangeClause>(visit(ctx->identifier(1)), visit(ctx->identifier(0)));
}
antlrcpp::Any ParseTreeVisitor::visitSourceClause(ClickHouseParser::SourceClauseContext *ctx)
{
auto list = ctx->dictionaryArgExpr().empty() ? nullptr : std::make_shared<DictionaryArgList>();
for (auto * arg : ctx->dictionaryArgExpr()) list->push(visit(arg));
return std::make_shared<SourceClause>(visit(ctx->identifier()), list);
}
}

View File

@ -1,183 +0,0 @@
#pragma once
#include <Parsers/New/AST/DDLQuery.h>
namespace DB::AST
{
class DictionaryAttributeExpr : public INode
{
public:
DictionaryAttributeExpr(PtrTo<Identifier> identifier, PtrTo<ColumnTypeExpr> type);
void setDefaultClause(PtrTo<Literal> literal);
void setExpressionClause(PtrTo<ColumnExpr> expr);
void setHierarchicalFlag() { hierarchical = true; }
void setInjectiveFlag() { injective = true; }
void setIsObjectIdFlag() { is_object_id = true; }
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // Identifier
TYPE, // ColumnTypeExpr
DEFAULT, // Literal (optional)
EXPRESSION, // ColumnExpr (optional)
MAX_INDEX,
};
bool hierarchical = false, injective = false, is_object_id = false;
};
using DictionaryPrimaryKeyClause = SimpleClause<ColumnExprList>;
using DictionarySchemaClause = SimpleClause<DictionaryAttributeList>;
class DictionaryArgExpr : public INode
{
public:
explicit DictionaryArgExpr(PtrTo<Identifier> identifier, PtrTo<ColumnExpr> expr);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
KEY = 0, // Identifier
VALUE, // ColumnExpr: literal, identifier or function
};
};
class SourceClause : public INode
{
public:
SourceClause(PtrTo<Identifier> identifier, PtrTo<DictionaryArgList> list);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // Identifier
ARGS = 1, // DictionaryArgList (optional)
};
};
class LifetimeClause : public INode
{
public:
explicit LifetimeClause(PtrTo<NumberLiteral> max, PtrTo<NumberLiteral> min = nullptr);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
MAX = 0, // NumberLiteral
MIN, // NumberLiteral (optional)
};
};
class LayoutClause : public INode
{
public:
LayoutClause(PtrTo<Identifier> identifier, PtrTo<DictionaryArgList> list);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // Identifier
ARGS = 1, // DictionaryArgList (optional)
};
};
class RangeClause : public INode
{
public:
RangeClause(PtrTo<Identifier> max, PtrTo<Identifier> min);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
MAX = 0, // Identifier
MIN, // Identifier
};
};
class DictionarySettingsClause : public INode
{
public:
explicit DictionarySettingsClause(PtrTo<SettingExprList> list);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
LIST = 0, // SettingExprList
};
};
class DictionaryEngineClause : public INode
{
public:
explicit DictionaryEngineClause(PtrTo<DictionaryPrimaryKeyClause> clause);
void setSourceClause(PtrTo<SourceClause> clause);
void setLifetimeClause(PtrTo<LifetimeClause> clause);
void setLayoutClause(PtrTo<LayoutClause> clause);
void setRangeClause(PtrTo<RangeClause> clause);
void setSettingsClause(PtrTo<DictionarySettingsClause> clause);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
PRIMARY_KEY = 0, // DictionaryPrimaryKeyClause
SOURCE, // SourceClause (optional)
LIFETIME, // LifetimeClause (optional)
LAYOUT, // LayoutClause (optional)
RANGE, // RangeClause (optional)
SETTINGS, // DictionarySettingsClause (optional)
MAX_INDEX,
};
};
class CreateDictionaryQuery : public DDLQuery
{
public:
CreateDictionaryQuery(
PtrTo<ClusterClause> cluster,
bool attach,
bool if_not_exists,
PtrTo<TableIdentifier> identifier,
PtrTo<UUIDClause> uuid,
PtrTo<DictionarySchemaClause> schema,
PtrTo<DictionaryEngineClause> engine);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // TableIdentifier
UUID, // UUIDClause (optional)
SCHEMA, // DictionarySchemaClause
ENGINE, // DictionaryEngineClause
};
const bool attach, if_not_exists;
};
}

View File

@ -1,86 +0,0 @@
#include <Parsers/New/AST/CreateLiveViewQuery.h>
#include <Parsers/ASTCreateQuery.h>
#include <Parsers/New/AST/CreateTableQuery.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/AST/SelectUnionQuery.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
CreateLiveViewQuery::CreateLiveViewQuery(
PtrTo<ClusterClause> cluster,
bool attach_,
bool if_not_exists_,
PtrTo<TableIdentifier> identifier,
PtrTo<UUIDClause> uuid,
PtrTo<NumberLiteral> timeout,
PtrTo<DestinationClause> destination,
PtrTo<TableSchemaClause> schema,
PtrTo<SelectUnionQuery> query)
: DDLQuery(cluster, {identifier, uuid, timeout, destination, schema, query}), attach(attach_), if_not_exists(if_not_exists_)
{
}
ASTPtr CreateLiveViewQuery::convertToOld() const
{
auto query = std::make_shared<ASTCreateQuery>();
{
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(NAME)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->shortName();
query->uuid = has(UUID) ? parseFromString<DB::UUID>(get(UUID)->convertToOld()->as<ASTLiteral>()->value.get<String>()) : table->uuid;
}
if (has(TIMEOUT))
query->live_view_timeout.emplace(get(TIMEOUT)->convertToOld()->as<ASTLiteral>()->value.get<UInt64>());
if (has(DESTINATION))
query->to_table_id = get(DESTINATION)->convertToOld()->as<ASTTableIdentifier>()->getTableId();
if (has(SCHEMA))
{
assert(get<TableSchemaClause>(SCHEMA)->getType() == TableSchemaClause::ClauseType::DESCRIPTION);
query->set(query->columns_list, get(SCHEMA)->convertToOld());
}
query->attach = attach;
query->if_not_exists = if_not_exists;
query->is_live_view = true;
query->set(query->select, get(SUBQUERY)->convertToOld());
query->cluster = cluster_name;
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitCreateLiveViewStmt(ClickHouseParser::CreateLiveViewStmtContext *ctx)
{
auto uuid = ctx->uuidClause() ? visit(ctx->uuidClause()).as<PtrTo<UUIDClause>>() : nullptr;
auto cluster = ctx->clusterClause() ? visit(ctx->clusterClause()).as<PtrTo<ClusterClause>>() : nullptr;
auto timeout = ctx->DECIMAL_LITERAL() ? Literal::createNumber(ctx->DECIMAL_LITERAL()) : nullptr;
auto destination = ctx->destinationClause() ? visit(ctx->destinationClause()).as<PtrTo<DestinationClause>>() : nullptr;
auto schema = ctx->tableSchemaClause() ? visit(ctx->tableSchemaClause()).as<PtrTo<TableSchemaClause>>() : nullptr;
if (ctx->TIMEOUT() && !timeout) timeout = Literal::createNumber(std::to_string(DEFAULT_TEMPORARY_LIVE_VIEW_TIMEOUT_SEC));
return std::make_shared<CreateLiveViewQuery>(
cluster,
!!ctx->ATTACH(),
!!ctx->IF(),
visit(ctx->tableIdentifier()),
uuid,
timeout,
destination,
schema,
visit(ctx->subqueryClause()));
}
}

View File

@ -1,39 +0,0 @@
#pragma once
#include <Parsers/New/AST/DDLQuery.h>
namespace DB::AST
{
class CreateLiveViewQuery : public DDLQuery
{
public:
CreateLiveViewQuery(
PtrTo<ClusterClause> cluster,
bool attach,
bool if_not_exists,
PtrTo<TableIdentifier> identifier,
PtrTo<UUIDClause> uuid,
PtrTo<NumberLiteral> timeout,
PtrTo<DestinationClause> destination,
PtrTo<TableSchemaClause> schema,
PtrTo<SelectUnionQuery> query);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // TableIdentifier
UUID, // UUIDClause (optional)
TIMEOUT, // NumberLiteral (optional)
DESTINATION, // DestinationClause (optional)
SCHEMA, // TableSchemaClause (optional)
SUBQUERY, // SelectUnionQuery
};
const bool attach, if_not_exists;
};
}

View File

@ -1,99 +0,0 @@
#include <Parsers/New/AST/CreateMaterializedViewQuery.h>
#include <IO/ReadHelpers.h>
#include <Parsers/ASTCreateQuery.h>
#include <Parsers/New/AST/CreateTableQuery.h>
#include <Parsers/New/AST/EngineExpr.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/SelectUnionQuery.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
CreateMaterializedViewQuery::CreateMaterializedViewQuery(
PtrTo<ClusterClause> cluster,
bool attach_,
bool if_not_exists_,
bool populate_,
PtrTo<TableIdentifier> identifier,
PtrTo<UUIDClause> uuid,
PtrTo<TableSchemaClause> schema,
PtrTo<DestinationClause> destination,
PtrTo<EngineClause> engine,
PtrTo<SelectUnionQuery> query)
: DDLQuery(cluster, {identifier, uuid, schema, destination, engine, query})
, attach(attach_)
, if_not_exists(if_not_exists_)
, populate(populate_)
{
assert(!destination != !engine);
}
ASTPtr CreateMaterializedViewQuery::convertToOld() const
{
auto query = std::make_shared<ASTCreateQuery>();
{
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(NAME)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->shortName();
query->uuid = has(UUID) ? parseFromString<DB::UUID>(get(UUID)->convertToOld()->as<ASTLiteral>()->value.get<String>()) : table->uuid;
}
if (has(DESTINATION))
query->to_table_id = get(DESTINATION)->convertToOld()->as<ASTTableIdentifier>()->getTableId();
else if (has(ENGINE))
{
query->set(query->storage, get(ENGINE)->convertToOld());
query->is_populate = populate;
}
if (has(SCHEMA))
{
assert(get<TableSchemaClause>(SCHEMA)->getType() == TableSchemaClause::ClauseType::DESCRIPTION);
query->set(query->columns_list, get(SCHEMA)->convertToOld());
}
query->attach = attach;
query->if_not_exists = if_not_exists;
query->is_materialized_view = true;
query->set(query->select, get(SUBQUERY)->convertToOld());
query->cluster = cluster_name;
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitCreateMaterializedViewStmt(ClickHouseParser::CreateMaterializedViewStmtContext *ctx)
{
auto uuid = ctx->uuidClause() ? visit(ctx->uuidClause()).as<PtrTo<UUIDClause>>() : nullptr;
auto cluster = ctx->clusterClause() ? visit(ctx->clusterClause()).as<PtrTo<ClusterClause>>() : nullptr;
auto schema = ctx->tableSchemaClause() ? visit(ctx->tableSchemaClause()).as<PtrTo<TableSchemaClause>>() : nullptr;
auto engine = ctx->engineClause() ? visit(ctx->engineClause()).as<PtrTo<EngineClause>>() : nullptr;
auto destination = ctx->destinationClause() ? visit(ctx->destinationClause()).as<PtrTo<DestinationClause>>() : nullptr;
return std::make_shared<CreateMaterializedViewQuery>(
cluster,
!!ctx->ATTACH(),
!!ctx->IF(),
!!ctx->POPULATE(),
visit(ctx->tableIdentifier()),
uuid,
schema,
destination,
engine,
visit(ctx->subqueryClause()));
}
antlrcpp::Any ParseTreeVisitor::visitDestinationClause(ClickHouseParser::DestinationClauseContext *ctx)
{
return std::make_shared<DestinationClause>(visit(ctx->tableIdentifier()).as<PtrTo<TableIdentifier>>());
}
}

View File

@ -1,40 +0,0 @@
#pragma once
#include <Parsers/New/AST/DDLQuery.h>
namespace DB::AST
{
class CreateMaterializedViewQuery : public DDLQuery
{
public:
CreateMaterializedViewQuery(
PtrTo<ClusterClause> cluster,
bool attach,
bool if_not_exists,
bool populate,
PtrTo<TableIdentifier> identifier,
PtrTo<UUIDClause> uuid,
PtrTo<TableSchemaClause> schema,
PtrTo<DestinationClause> destination,
PtrTo<EngineClause> engine,
PtrTo<SelectUnionQuery> query);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // TableIdentifier
UUID, // UUIDClause (optional)
SCHEMA, // TableSchemaClause (optional)
DESTINATION, // DestinationClause (optional)
ENGINE, // EngineClause (optional)
SUBQUERY, // SelectUnionQuery
};
const bool attach, if_not_exists, populate;
};
}

View File

@ -1,224 +0,0 @@
#include <Parsers/New/AST/CreateTableQuery.h>
#include <IO/ReadHelpers.h>
#include <Parsers/ASTCreateQuery.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/New/AST/EngineExpr.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/AST/SelectUnionQuery.h>
#include <Parsers/New/AST/TableElementExpr.h>
#include <Parsers/New/AST/TableExpr.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
// static
PtrTo<TableSchemaClause> TableSchemaClause::createDescription(PtrTo<TableElementList> list)
{
return PtrTo<TableSchemaClause>(new TableSchemaClause(ClauseType::DESCRIPTION, {list}));
}
// static
PtrTo<TableSchemaClause> TableSchemaClause::createAsTable(PtrTo<TableIdentifier> identifier)
{
return PtrTo<TableSchemaClause>(new TableSchemaClause(ClauseType::TABLE, {identifier}));
}
// static
PtrTo<TableSchemaClause> TableSchemaClause::createAsFunction(PtrTo<TableFunctionExpr> expr)
{
return PtrTo<TableSchemaClause>(new TableSchemaClause(ClauseType::FUNCTION, {expr}));
}
TableSchemaClause::TableSchemaClause(ClauseType type, PtrList exprs) : INode(exprs), clause_type(type)
{
}
ASTPtr TableSchemaClause::convertToOld() const
{
switch(clause_type)
{
case ClauseType::DESCRIPTION:
{
auto columns = std::make_shared<ASTColumns>();
auto column_list = std::make_shared<ASTExpressionList>();
auto constraint_list = std::make_shared<ASTExpressionList>();
auto index_list = std::make_shared<ASTExpressionList>();
auto projection_list = std::make_shared<ASTExpressionList>();
for (const auto & element : get(ELEMENTS)->as<TableElementList &>())
{
switch(element->as<TableElementExpr>()->getType())
{
case TableElementExpr::ExprType::COLUMN:
column_list->children.push_back(element->convertToOld());
break;
case TableElementExpr::ExprType::CONSTRAINT:
constraint_list->children.push_back(element->convertToOld());
break;
case TableElementExpr::ExprType::INDEX:
index_list->children.push_back(element->convertToOld());
break;
case TableElementExpr::ExprType::PROJECTION:
projection_list->children.push_back(element->convertToOld());
break;
}
}
if (!column_list->children.empty()) columns->set(columns->columns, column_list);
if (!constraint_list->children.empty()) columns->set(columns->constraints, constraint_list);
if (!index_list->children.empty()) columns->set(columns->indices, index_list);
if (!projection_list->children.empty()) columns->set(columns->projections, projection_list);
return columns;
}
case ClauseType::FUNCTION:
case ClauseType::TABLE:
return get(EXPR)->convertToOld();
}
__builtin_unreachable(); // FIXME: old gcc compilers complain about reaching end of non-void function
}
String TableSchemaClause::dumpInfo() const
{
switch(clause_type)
{
case ClauseType::DESCRIPTION: return "Description";
case ClauseType::FUNCTION: return "Function";
case ClauseType::TABLE: return "Table";
}
__builtin_unreachable(); // FIXME: old gcc compilers complain about reaching end of non-void function
}
CreateTableQuery::CreateTableQuery(
PtrTo<ClusterClause> cluster,
bool attach_,
bool temporary_,
bool if_not_exists_,
PtrTo<TableIdentifier> identifier,
PtrTo<UUIDClause> uuid,
PtrTo<TableSchemaClause> schema,
PtrTo<EngineClause> engine,
PtrTo<SelectUnionQuery> query)
: DDLQuery(cluster, {identifier, uuid, schema, engine, query}), attach(attach_), temporary(temporary_), if_not_exists(if_not_exists_)
{
}
ASTPtr CreateTableQuery::convertToOld() const
{
auto query = std::make_shared<ASTCreateQuery>();
{
auto table = get(NAME)->convertToOld();
query->database = table->as<ASTTableIdentifier>()->getDatabaseName();
query->table = table->as<ASTTableIdentifier>()->shortName();
query->uuid = has(UUID) ? parseFromString<DB::UUID>(get(UUID)->convertToOld()->as<ASTLiteral>()->value.get<String>())
: table->as<ASTTableIdentifier>()->uuid;
}
query->cluster = cluster_name;
query->attach = attach;
query->if_not_exists = if_not_exists;
query->temporary = temporary;
if (has(SCHEMA))
{
switch(get<TableSchemaClause>(SCHEMA)->getType())
{
case TableSchemaClause::ClauseType::DESCRIPTION:
{
query->set(query->columns_list, get(SCHEMA)->convertToOld());
break;
}
case TableSchemaClause::ClauseType::TABLE:
{
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(SCHEMA)->convertToOld());
query->as_database = table->getDatabaseName();
query->as_table = table->shortName();
break;
}
case TableSchemaClause::ClauseType::FUNCTION:
{
query->as_table_function = get(SCHEMA)->convertToOld();
break;
}
}
}
if (has(ENGINE)) query->set(query->storage, get(ENGINE)->convertToOld());
if (has(SUBQUERY)) query->set(query->select, get(SUBQUERY)->convertToOld());
return query;
}
String CreateTableQuery::dumpInfo() const
{
String info;
if (attach) info += "attach=true, ";
else info += "attach=false, ";
if (temporary) info += "temporary=true, ";
else info += "temporary=false, ";
if (if_not_exists) info += "if_not_exists=true";
else info += "if_not_exists=false";
return info;
}
}
namespace DB
{
using namespace AST;
// TODO: assert(!(ctx->parent->TEMPORARY() ^ ctx->engineClause()))
antlrcpp::Any ParseTreeVisitor::visitClusterClause(ClickHouseParser::ClusterClauseContext *ctx)
{
auto literal = ctx->STRING_LITERAL() ? Literal::createString(ctx->STRING_LITERAL())
: Literal::createString(ctx->identifier()->getText());
return std::make_shared<ClusterClause>(literal);
}
antlrcpp::Any ParseTreeVisitor::visitCreateTableStmt(ClickHouseParser::CreateTableStmtContext *ctx)
{
auto uuid = ctx->uuidClause() ? visit(ctx->uuidClause()).as<PtrTo<UUIDClause>>() : nullptr;
auto cluster = ctx->clusterClause() ? visit(ctx->clusterClause()).as<PtrTo<ClusterClause>>() : nullptr;
auto schema = ctx->tableSchemaClause() ? visit(ctx->tableSchemaClause()).as<PtrTo<TableSchemaClause>>() : nullptr;
auto engine = ctx->engineClause() ? visit(ctx->engineClause()).as<PtrTo<EngineClause>>() : nullptr;
auto query = ctx->subqueryClause() ? visit(ctx->subqueryClause()).as<PtrTo<SelectUnionQuery>>() : nullptr;
return std::make_shared<CreateTableQuery>(
cluster, !!ctx->ATTACH(), !!ctx->TEMPORARY(), !!ctx->IF(), visit(ctx->tableIdentifier()), uuid, schema, engine, query);
}
antlrcpp::Any ParseTreeVisitor::visitSchemaDescriptionClause(ClickHouseParser::SchemaDescriptionClauseContext *ctx)
{
auto elems = std::make_shared<TableElementList>();
for (auto * elem : ctx->tableElementExpr()) elems->push(visit(elem));
return TableSchemaClause::createDescription(elems);
}
antlrcpp::Any ParseTreeVisitor::visitSchemaAsTableClause(ClickHouseParser::SchemaAsTableClauseContext *ctx)
{
return TableSchemaClause::createAsTable(visit(ctx->tableIdentifier()));
}
antlrcpp::Any ParseTreeVisitor::visitSchemaAsFunctionClause(ClickHouseParser::SchemaAsFunctionClauseContext *ctx)
{
return TableSchemaClause::createAsFunction(visit(ctx->tableFunctionExpr()));
}
antlrcpp::Any ParseTreeVisitor::visitSubqueryClause(ClickHouseParser::SubqueryClauseContext *ctx)
{
return visit(ctx->selectUnionStmt());
}
antlrcpp::Any ParseTreeVisitor::visitUuidClause(ClickHouseParser::UuidClauseContext *ctx)
{
return std::make_shared<UUIDClause>(Literal::createString(ctx->STRING_LITERAL()));
}
}

View File

@ -1,76 +0,0 @@
#pragma once
#include <Parsers/New/AST/DDLQuery.h>
#include "Parsers/New/AST/SelectUnionQuery.h"
namespace DB::AST
{
class TableSchemaClause : public INode
{
public:
static PtrTo<TableSchemaClause> createDescription(PtrTo<TableElementList> list);
static PtrTo<TableSchemaClause> createAsTable(PtrTo<TableIdentifier> identifier);
static PtrTo<TableSchemaClause> createAsFunction(PtrTo<TableFunctionExpr> expr);
enum class ClauseType
{
DESCRIPTION,
TABLE,
FUNCTION,
};
auto getType() const { return clause_type; }
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
// DESCRIPTION
ELEMENTS = 0, // TableElementList
// TABLE and FUNCTION
EXPR = 0, // TableIdentifier or TableFunctionExpr
};
ClauseType clause_type;
TableSchemaClause(ClauseType type, PtrList exprs);
String dumpInfo() const override;
};
class CreateTableQuery : public DDLQuery
{
public:
CreateTableQuery(
PtrTo<ClusterClause> cluster,
bool attach,
bool temporary,
bool if_not_exists,
PtrTo<TableIdentifier> identifier,
PtrTo<UUIDClause> uuid,
PtrTo<TableSchemaClause> schema,
PtrTo<EngineClause> engine,
PtrTo<SelectUnionQuery> query);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // TableIdentifier
UUID, // UUIDClause (optional)
SCHEMA, // TableSchemaClause
ENGINE, // EngineClause
SUBQUERY, // SelectUnionQuery
};
const bool attach, temporary, if_not_exists;
String dumpInfo() const override;
};
}

View File

@ -1,62 +0,0 @@
#include <Parsers/New/AST/CreateViewQuery.h>
#include <Parsers/ASTCreateQuery.h>
#include <Parsers/New/AST/CreateTableQuery.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/SelectUnionQuery.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
CreateViewQuery::CreateViewQuery(
PtrTo<ClusterClause> cluster,
bool attach_,
bool replace_,
bool if_not_exists_,
PtrTo<TableIdentifier> identifier,
PtrTo<TableSchemaClause> clause,
PtrTo<SelectUnionQuery> query)
: DDLQuery(cluster, {identifier, clause, query}), attach(attach_), replace(replace_), if_not_exists(if_not_exists_)
{
}
ASTPtr CreateViewQuery::convertToOld() const
{
auto query = std::make_shared<ASTCreateQuery>();
{
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(NAME)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->shortName();
query->uuid = table->uuid;
}
query->attach = attach;
query->replace_view = replace;
query->if_not_exists = if_not_exists;
query->is_ordinary_view = true;
query->cluster = cluster_name;
if (has(SCHEMA)) query->set(query->columns_list, get(SCHEMA)->convertToOld());
query->set(query->select, get(SUBQUERY)->convertToOld());
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitCreateViewStmt(ClickHouseParser::CreateViewStmtContext *ctx)
{
auto cluster = ctx->clusterClause() ? visit(ctx->clusterClause()).as<PtrTo<ClusterClause>>() : nullptr;
auto schema = ctx->tableSchemaClause() ? visit(ctx->tableSchemaClause()).as<PtrTo<TableSchemaClause>>() : nullptr;
return std::make_shared<CreateViewQuery>(
cluster, !!ctx->ATTACH(), !!ctx->REPLACE(), !!ctx->IF(), visit(ctx->tableIdentifier()), schema, visit(ctx->subqueryClause()));
}
}

View File

@ -1,34 +0,0 @@
#pragma once
#include <Parsers/New/AST/DDLQuery.h>
namespace DB::AST
{
class CreateViewQuery : public DDLQuery
{
public:
CreateViewQuery(
PtrTo<ClusterClause> cluster,
bool attach,
bool replace,
bool if_not_exists,
PtrTo<TableIdentifier> identifier,
PtrTo<TableSchemaClause> clause,
PtrTo<SelectUnionQuery> query);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // TableIdentifier
SCHEMA = 1, // TableSchemaClause (optional)
SUBQUERY = 2, // SelectUnionQuery
};
const bool attach, replace, if_not_exists;
};
}

View File

@ -1,6 +0,0 @@
#include <Parsers/New/AST/DDLQuery.h>
namespace DB::AST
{
}

View File

@ -1,29 +0,0 @@
#pragma once
#include <Parsers/New/AST/Query.h>
#include <Parsers/ASTLiteral.h>
#include <Parsers/ASTQueryWithOnCluster.h>
#include <Parsers/New/AST/Identifier.h>
namespace DB::AST
{
class DDLQuery : public Query
{
protected:
DDLQuery(PtrTo<ClusterClause> cluster, std::initializer_list<Ptr> list)
: Query(list), cluster_name(cluster ? cluster->convertToOld()->as<ASTLiteral>()->value.get<String>() : String{})
{
}
DDLQuery(PtrTo<ClusterClause> cluster, PtrList list)
: Query(list), cluster_name(cluster ? cluster->convertToOld()->as<ASTLiteral>()->value.get<String>() : String{})
{
}
const String cluster_name;
};
}

View File

@ -1,36 +0,0 @@
#include <Parsers/New/AST/DescribeQuery.h>
#include <Parsers/TablePropertiesQueriesASTs.h>
#include <Parsers/New/AST/TableExpr.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
DescribeQuery::DescribeQuery(PtrTo<TableExpr> expr) : Query{expr}
{
}
ASTPtr DescribeQuery::convertToOld() const
{
auto query = std::make_shared<ASTDescribeQuery>();
query->table_expression = get(EXPR)->convertToOld();
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitDescribeStmt(ClickHouseParser::DescribeStmtContext *ctx)
{
return std::make_shared<DescribeQuery>(visit(ctx->tableExpr()).as<PtrTo<TableExpr>>());
}
}

View File

@ -1,27 +0,0 @@
#pragma once
#include <Parsers/New/AST/Query.h>
namespace DB::AST
{
// TODO: rewrite to
// `SELECT name, type, default_type, default_expression, comment, codec_expression, ttl_expression FROM system.columns
// WHERE database=db AND table=table`
class DescribeQuery : public Query
{
public:
explicit DescribeQuery(PtrTo<TableExpr> expr);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
EXPR = 0,
};
};
}

View File

@ -1,126 +0,0 @@
#include <Parsers/New/AST/DropQuery.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/ParseTreeVisitor.h>
#include <Parsers/ASTDropQuery.h>
namespace DB::AST
{
// static
PtrTo<DropQuery>
DropQuery::createDropDatabase(bool detach, bool if_exists, PtrTo<DatabaseIdentifier> identifier, PtrTo<ClusterClause> cluster)
{
auto query = PtrTo<DropQuery>(new DropQuery(cluster, QueryType::DATABASE, {identifier}));
query->detach = detach;
query->if_exists = if_exists;
return query;
}
// static
PtrTo<DropQuery>
DropQuery::createDropDictionary(bool detach, bool if_exists, PtrTo<TableIdentifier> identifier, PtrTo<ClusterClause> cluster)
{
auto query = PtrTo<DropQuery>(new DropQuery(cluster, QueryType::DICTIONARY, {identifier}));
query->detach = detach;
query->if_exists = if_exists;
return query;
}
// static
PtrTo<DropQuery>
DropQuery::createDropTable(bool detach, bool if_exists, bool temporary, PtrTo<TableIdentifier> identifier, PtrTo<ClusterClause> cluster)
{
auto query = PtrTo<DropQuery>(new DropQuery(cluster, QueryType::TABLE, {identifier}));
query->detach = detach;
query->if_exists = if_exists;
query->temporary = temporary;
return query;
}
// static
PtrTo<DropQuery>
DropQuery::createDropView(bool detach, bool if_exists, PtrTo<TableIdentifier> identifier, PtrTo<ClusterClause> cluster)
{
auto query = PtrTo<DropQuery>(new DropQuery(cluster, QueryType::VIEW, {identifier}));
query->detach = detach;
query->if_exists = if_exists;
return query;
}
DropQuery::DropQuery(PtrTo<ClusterClause> cluster, QueryType type, PtrList exprs) : DDLQuery(cluster, exprs), query_type(type)
{
}
ASTPtr DropQuery::convertToOld() const
{
auto query = std::make_shared<ASTDropQuery>();
query->kind = detach ? ASTDropQuery::Detach : ASTDropQuery::Drop;
query->if_exists = if_exists;
query->temporary = temporary;
query->cluster = cluster_name;
// TODO: refactor |ASTQueryWithTableAndOutput| to accept |ASTIdentifier|
switch(query_type)
{
case QueryType::DATABASE:
query->database = get<DatabaseIdentifier>(NAME)->getName();
break;
case QueryType::DICTIONARY:
query->is_dictionary = true;
query->table = get<TableIdentifier>(NAME)->getName();
if (auto database = get<TableIdentifier>(NAME)->getDatabase())
query->database = database->getName();
break;
case QueryType::TABLE:
{
query->table = get<TableIdentifier>(NAME)->getName();
if (auto database = get<TableIdentifier>(NAME)->getDatabase())
query->database = database->getName();
break;
}
case QueryType::VIEW:
{
query->is_view = true;
query->table = get<TableIdentifier>(NAME)->getName();
if (auto database = get<TableIdentifier>(NAME)->getDatabase())
query->database = database->getName();
break;
}
}
convertToOldPartially(query);
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitDropDatabaseStmt(ClickHouseParser::DropDatabaseStmtContext *ctx)
{
auto cluster = ctx->clusterClause() ? visit(ctx->clusterClause()).as<PtrTo<ClusterClause>>() : nullptr;
return DropQuery::createDropDatabase(!!ctx->DETACH(), !!ctx->EXISTS(), visit(ctx->databaseIdentifier()), cluster);
}
antlrcpp::Any ParseTreeVisitor::visitDropTableStmt(ClickHouseParser::DropTableStmtContext *ctx)
{
auto cluster = ctx->clusterClause() ? visit(ctx->clusterClause()).as<PtrTo<ClusterClause>>() : nullptr;
if (ctx->TABLE())
return DropQuery::createDropTable(!!ctx->DETACH(), !!ctx->EXISTS(), !!ctx->TEMPORARY(), visit(ctx->tableIdentifier()), cluster);
if (ctx->DICTIONARY())
return DropQuery::createDropDictionary(!!ctx->DETACH(), !!ctx->EXISTS(), visit(ctx->tableIdentifier()), cluster);
if (ctx->VIEW())
return DropQuery::createDropView(!!ctx->DETACH(), !!ctx->EXISTS(), visit(ctx->tableIdentifier()), cluster);
__builtin_unreachable();
}
}

View File

@ -1,46 +0,0 @@
#pragma once
#include <Parsers/New/AST/DDLQuery.h>
namespace DB::AST
{
class DropQuery : public DDLQuery
{
public:
static PtrTo<DropQuery>
createDropDatabase(bool detach, bool if_exists, PtrTo<DatabaseIdentifier> identifier, PtrTo<ClusterClause> cluster);
static PtrTo<DropQuery>
createDropTable(bool detach, bool if_exists, bool temporary, PtrTo<TableIdentifier> identifier, PtrTo<ClusterClause> cluster);
static PtrTo<DropQuery>
createDropDictionary(bool detach, bool if_exists, PtrTo<TableIdentifier> identifier, PtrTo<ClusterClause> cluster);
static PtrTo<DropQuery>
createDropView(bool detach, bool if_exists, PtrTo<TableIdentifier> identifier, PtrTo<ClusterClause> cluster);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0,
};
enum class QueryType
{
DATABASE,
DICTIONARY,
TABLE,
VIEW,
};
const QueryType query_type;
bool detach = false;
bool if_exists = false;
bool temporary = false;
DropQuery(PtrTo<ClusterClause> cluster, QueryType type, PtrList exprs);
};
}

View File

@ -1,199 +0,0 @@
#include <Parsers/New/AST/EngineExpr.h>
#include <Parsers/ASTCreateQuery.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTTTLElement.h>
#include <Parsers/New/AST/ColumnExpr.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/AST/SelectUnionQuery.h>
#include <Parsers/New/ParseTreeVisitor.h>
#include <Storages/DataDestinationType.h>
#include <Storages/TTLMode.h>
namespace DB::ErrorCodes
{
extern const int UNEXPECTED_AST_STRUCTURE;
}
namespace DB::AST
{
EngineClause::EngineClause(PtrTo<EngineExpr> expr) : INode(MAX_INDEX)
{
set(ENGINE, expr);
}
void EngineClause::setOrderByClause(PtrTo<OrderByClause> clause)
{
set(ORDER_BY, clause);
}
void EngineClause::setPartitionByClause(PtrTo<PartitionByClause> clause)
{
set(PARTITION_BY, clause);
}
void EngineClause::setPrimaryKeyClause(PtrTo<PrimaryKeyClause> clause)
{
set(PRIMARY_KEY, clause);
}
void EngineClause::setSampleByClause(PtrTo<SampleByClause> clause)
{
set(SAMPLE_BY, clause);
}
void EngineClause::setTTLClause(PtrTo<TTLClause> clause)
{
set(TTL, clause);
}
void EngineClause::setSettingsClause(PtrTo<SettingsClause> clause)
{
set(SETTINGS, clause);
}
ASTPtr EngineClause::convertToOld() const
{
auto storage = std::make_shared<ASTStorage>();
storage->set(storage->engine, get(ENGINE)->convertToOld());
if (has(PARTITION_BY)) storage->set(storage->partition_by, get(PARTITION_BY)->convertToOld());
if (has(PRIMARY_KEY)) storage->set(storage->primary_key, get(PRIMARY_KEY)->convertToOld());
if (has(ORDER_BY))
{
/// XXX: old parser used very strange grammar for this case, instead of using OrderByElement's.
auto expr_list = get(ORDER_BY)->convertToOld();
if (expr_list->children.size() > 1)
throw DB::Exception(ErrorCodes::UNEXPECTED_AST_STRUCTURE, "Cannot convert multiple ORDER expression to old AST");
storage->set(storage->order_by, expr_list->children[0]->children[0]);
}
if (has(SAMPLE_BY)) storage->set(storage->sample_by, get(SAMPLE_BY)->convertToOld());
if (has(TTL)) storage->set(storage->ttl_table, get(TTL)->convertToOld());
if (has(SETTINGS))
{
storage->set(storage->settings, get(SETTINGS)->convertToOld());
storage->settings->is_standalone = false;
}
return storage;
}
EngineExpr::EngineExpr(PtrTo<Identifier> identifier, PtrTo<ColumnExprList> args) : INode{identifier, args}
{
}
ASTPtr EngineExpr::convertToOld() const
{
auto expr = std::make_shared<ASTFunction>();
expr->name = get<Identifier>(NAME)->getName();
expr->no_empty_args = true;
if (has(ARGS))
{
expr->arguments = get(ARGS)->convertToOld();
expr->children.push_back(expr->arguments);
}
return expr;
}
TTLExpr::TTLExpr(PtrTo<ColumnExpr> expr, TTLType type, PtrTo<StringLiteral> literal) : INode{expr, literal}, ttl_type(type)
{
}
ASTPtr TTLExpr::convertToOld() const
{
TTLMode mode = TTLMode::DELETE;
DataDestinationType destination_type = DataDestinationType::DELETE;
String destination_name;
switch(ttl_type)
{
case TTLType::DELETE:
mode = TTLMode::DELETE;
destination_type = DataDestinationType::DELETE;
break;
case TTLType::TO_DISK:
mode = TTLMode::MOVE;
destination_type = DataDestinationType::DISK;
destination_name = get(TYPE)->convertToOld()->as<ASTLiteral>()->value.get<String>();
break;
case TTLType::TO_VOLUME:
mode = TTLMode::MOVE;
destination_type = DataDestinationType::VOLUME;
destination_name = get(TYPE)->convertToOld()->as<ASTLiteral>()->value.get<String>();
break;
}
auto expr = std::make_shared<ASTTTLElement>(mode, destination_type, destination_name);
expr->setTTL(get(EXPR)->convertToOld());
return expr;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitEngineClause(ClickHouseParser::EngineClauseContext *ctx)
{
auto clause = std::make_shared<EngineClause>(visit(ctx->engineExpr()).as<PtrTo<EngineExpr>>());
if (!ctx->orderByClause().empty()) clause->setOrderByClause(visit(ctx->orderByClause(0)));
if (!ctx->partitionByClause().empty()) clause->setPartitionByClause(visit(ctx->partitionByClause(0)));
if (!ctx->primaryKeyClause().empty()) clause->setPrimaryKeyClause(visit(ctx->primaryKeyClause(0)));
if (!ctx->sampleByClause().empty()) clause->setSampleByClause(visit(ctx->sampleByClause(0)));
if (!ctx->ttlClause().empty()) clause->setTTLClause(visit(ctx->ttlClause(0)));
if (!ctx->settingsClause().empty()) clause->setSettingsClause(visit(ctx->settingsClause(0)));
return clause;
}
antlrcpp::Any ParseTreeVisitor::visitEngineExpr(ClickHouseParser::EngineExprContext *ctx)
{
auto list = ctx->columnExprList() ? visit(ctx->columnExprList()).as<PtrTo<ColumnExprList>>() : nullptr;
return std::make_shared<EngineExpr>(visit(ctx->identifierOrNull()), list);
}
antlrcpp::Any ParseTreeVisitor::visitPartitionByClause(ClickHouseParser::PartitionByClauseContext *ctx)
{
return std::make_shared<PartitionByClause>(visit(ctx->columnExpr()).as<PtrTo<ColumnExpr>>());
}
antlrcpp::Any ParseTreeVisitor::visitPrimaryKeyClause(ClickHouseParser::PrimaryKeyClauseContext *ctx)
{
return std::make_shared<PrimaryKeyClause>(visit(ctx->columnExpr()).as<PtrTo<ColumnExpr>>());
}
antlrcpp::Any ParseTreeVisitor::visitSampleByClause(ClickHouseParser::SampleByClauseContext *ctx)
{
return std::make_shared<SampleByClause>(visit(ctx->columnExpr()).as<PtrTo<ColumnExpr>>());
}
antlrcpp::Any ParseTreeVisitor::visitTtlClause(ClickHouseParser::TtlClauseContext *ctx)
{
auto list = std::make_shared<TTLExprList>();
for (auto * expr : ctx->ttlExpr()) list->push(visit(expr));
return std::make_shared<TTLClause>(list);
}
antlrcpp::Any ParseTreeVisitor::visitTtlExpr(ClickHouseParser::TtlExprContext *ctx)
{
TTLExpr::TTLType type;
PtrTo<StringLiteral> literal;
if (ctx->DISK()) type = TTLExpr::TTLType::TO_DISK;
else if (ctx->VOLUME()) type = TTLExpr::TTLType::TO_VOLUME;
else type = TTLExpr::TTLType::DELETE;
if (ctx->STRING_LITERAL()) literal = Literal::createString(ctx->STRING_LITERAL());
return std::make_shared<TTLExpr>(visit(ctx->columnExpr()), type, literal);
}
}

View File

@ -1,85 +0,0 @@
#pragma once
#include <Parsers/New/AST/INode.h>
namespace DB::AST
{
// Clauses
using PartitionByClause = SimpleClause<ColumnExpr>;
using SampleByClause = SimpleClause<ColumnExpr>;
class EngineClause : public INode
{
public:
explicit EngineClause(PtrTo<EngineExpr> expr);
void setOrderByClause(PtrTo<OrderByClause> clause);
void setPartitionByClause(PtrTo<PartitionByClause> clause);
void setPrimaryKeyClause(PtrTo<PrimaryKeyClause> clause);
void setSampleByClause(PtrTo<SampleByClause> clause);
void setTTLClause(PtrTo<TTLClause> clause);
void setSettingsClause(PtrTo<SettingsClause> clause);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
ENGINE = 0, // EngineExpr
ORDER_BY, // OrderByClause (optional)
PARTITION_BY, // PartitionByClause (optional)
PRIMARY_KEY, // PrimaryKeyClause (optional)
SAMPLE_BY, // SampleByClause (optional)
TTL, // TTLClause (optional)
SETTINGS, // SettingsClause (optional)
MAX_INDEX,
};
};
// Expressions
class EngineExpr : public INode
{
public:
EngineExpr(PtrTo<Identifier> identifier, PtrTo<ColumnExprList> args);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // Identifier
ARGS, // ColumnExprList (optional)
};
};
class TTLExpr : public INode
{
public:
enum class TTLType
{
DELETE,
TO_DISK,
TO_VOLUME,
};
TTLExpr(PtrTo<ColumnExpr> expr, TTLType type, PtrTo<StringLiteral> literal);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
EXPR = 0, // ColumnExpr
TYPE = 1, // StringLiteral (optional)
};
TTLType ttl_type;
};
}

View File

@ -1,87 +0,0 @@
#include <Parsers/New/AST/ExistsQuery.h>
#include <Interpreters/StorageID.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/ParseTreeVisitor.h>
#include <Parsers/TablePropertiesQueriesASTs.h>
namespace DB::AST
{
ExistsQuery::ExistsQuery(QueryType type, bool temporary_, PtrList exprs)
: Query(exprs), query_type(type), temporary(temporary_)
{
}
// static
PtrTo<ExistsQuery> ExistsQuery::createTable(QueryType type, bool temporary, PtrTo<TableIdentifier> identifier)
{
return PtrTo<ExistsQuery>(new ExistsQuery(type, temporary, {identifier}));
}
// static
PtrTo<ExistsQuery> ExistsQuery::createDatabase(PtrTo<DatabaseIdentifier> identifier)
{
return PtrTo<ExistsQuery>(new ExistsQuery(QueryType::DATABASE, false, {identifier}));
}
ASTPtr ExistsQuery::convertToOld() const
{
std::shared_ptr<ASTQueryWithTableAndOutput> query;
switch(query_type)
{
case QueryType::DATABASE:
query = std::make_shared<ASTExistsDatabaseQuery>();
tryGetIdentifierNameInto(get<DatabaseIdentifier>(IDENTIFIER)->convertToOld(), query->database);
return query;
case QueryType::DICTIONARY:
query = std::make_shared<ASTExistsDictionaryQuery>();
break;
case QueryType::TABLE:
query = std::make_shared<ASTExistsTableQuery>();
break;
case QueryType::VIEW:
query = std::make_shared<ASTExistsViewQuery>();
break;
}
// FIXME: this won't work if table doesn't exist
auto table_id = std::static_pointer_cast<ASTTableIdentifier>(get<TableIdentifier>(IDENTIFIER)->convertToOld());
query->database = table_id->getDatabaseName();
query->table = table_id->shortName();
query->uuid = table_id->uuid;
query->temporary = temporary;
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitExistsTableStmt(ClickHouseParser::ExistsTableStmtContext *ctx)
{
ExistsQuery::QueryType type;
if (ctx->DICTIONARY())
type = ExistsQuery::QueryType::DICTIONARY;
else if (ctx->VIEW())
type = ExistsQuery::QueryType::VIEW;
else // Query 'EXISTS <table_name>' is interptered as 'EXISTS TABLE <table_name>'
type = ExistsQuery::QueryType::TABLE;
return ExistsQuery::createTable(type, !!ctx->TEMPORARY(), visit(ctx->tableIdentifier()));
}
antlrcpp::Any ParseTreeVisitor::visitExistsDatabaseStmt(ClickHouseParser::ExistsDatabaseStmtContext *ctx)
{
return ExistsQuery::createDatabase(visit(ctx->databaseIdentifier()));
}
}

View File

@ -1,37 +0,0 @@
#pragma once
#include <Parsers/New/AST/Query.h>
namespace DB::AST
{
class ExistsQuery : public Query
{
public:
enum class QueryType
{
DICTIONARY,
TABLE,
VIEW,
DATABASE,
};
static PtrTo<ExistsQuery> createTable(QueryType type, bool temporary, PtrTo<TableIdentifier> identifier);
static PtrTo<ExistsQuery> createDatabase(PtrTo<DatabaseIdentifier> identifier);
ExistsQuery(QueryType type, bool temporary, PtrList exprs);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
IDENTIFIER = 0, // DatabaseIdentifier or TableIdentifier
};
const QueryType query_type;
const bool temporary;
};
}

View File

@ -1,62 +0,0 @@
#include <Parsers/New/AST/ExplainQuery.h>
#include <Parsers/ASTExplainQuery.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
// static
PtrTo<ExplainQuery> ExplainQuery::createExplainAST(PtrTo<Query> query)
{
return PtrTo<ExplainQuery>(new ExplainQuery(QueryType::AST, {query}));
}
// static
PtrTo<ExplainQuery> ExplainQuery::createExplainSyntax(PtrTo<Query> query)
{
return PtrTo<ExplainQuery>(new ExplainQuery(QueryType::SYNTAX, {query}));
}
ExplainQuery::ExplainQuery(QueryType type, PtrList exprs) : Query{exprs}, query_type(type)
{
}
ASTPtr ExplainQuery::convertToOld() const
{
ASTPtr query;
switch (query_type)
{
case QueryType::AST:
query = std::make_shared<ASTExplainQuery>(ASTExplainQuery::ParsedAST);
break;
case QueryType::SYNTAX:
query = std::make_shared<ASTExplainQuery>(ASTExplainQuery::AnalyzedSyntax);
break;
}
query->as<ASTExplainQuery>()->setExplainedQuery(get(QUERY)->convertToOld());
return query;
}
}
namespace DB
{
using namespace DB::AST;
antlrcpp::Any ParseTreeVisitor::visitExplainASTStmt(ClickHouseParser::ExplainASTStmtContext *ctx)
{
return ExplainQuery::createExplainAST(visit(ctx->query()).as<PtrTo<Query>>());
}
antlrcpp::Any ParseTreeVisitor::visitExplainSyntaxStmt(ClickHouseParser::ExplainSyntaxStmtContext *ctx)
{
return ExplainQuery::createExplainSyntax(visit(ctx->query()).as<PtrTo<Query>>());
}
}

View File

@ -1,34 +0,0 @@
#pragma once
#include <Parsers/New/AST/Query.h>
namespace DB::AST
{
class ExplainQuery : public Query
{
public:
static PtrTo<ExplainQuery> createExplainAST(PtrTo<Query> query);
static PtrTo<ExplainQuery> createExplainSyntax(PtrTo<Query> query);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
QUERY = 0, // Query
};
enum class QueryType
{
AST,
SYNTAX,
};
const QueryType query_type;
ExplainQuery(QueryType type, PtrList exprs);
};
}

View File

@ -1,103 +0,0 @@
#pragma once
#include <Parsers/New/AST/fwd_decl.h>
#include <common/demangle.h>
#include <Common/TypePromotion.h>
#include <Parsers/ASTExpressionList.h>
#include <initializer_list>
#include <iostream>
namespace DB::AST
{
class INode : public TypePromotion<INode>
{
public:
virtual ~INode() = default;
virtual ASTPtr convertToOld() const { return ASTPtr(); }
virtual String toString() const { return {}; }
void dump() const { dump(0); }
protected:
INode() = default;
INode(std::initializer_list<Ptr> list) { children = list; }
explicit INode(PtrList list) { children = list; }
explicit INode(size_t size) { children.resize(size); }
void push(const Ptr& child) { children.push_back(child); }
void set(size_t i, const Ptr& child) { children[i] = child; }
bool has(size_t i) const { return i < children.size() && children[i]; }
const Ptr & get(size_t i) const { return children[i]; }
template <class ChildType>
bool has(size_t i) const { return has(i) && children[i]->as<ChildType>(); }
template <class ChildType>
ChildType * get(size_t i) const { return children[i]->template as<ChildType>(); }
auto begin() const { return children.cbegin(); }
auto end() const { return children.cend(); }
auto size() const { return children.size(); }
private:
PtrList children; // any child potentially may point to |nullptr|
void dump(int indentation) const
{
for (auto i = 0; i < indentation; ++i) std::cout << " ";
std::cout << "" << demangle(typeid(*this).name()) << " (" << dumpInfo() << ")" << std::endl;
for (const auto & child : children) if (child) child->dump(indentation + 1);
}
virtual String dumpInfo() const { return ""; }
};
template <class T, char Separator>
class List : public INode {
public:
List() = default;
List(std::initializer_list<PtrTo<T>> list)
{
for (const auto & i : list) push(i);
}
using INode::begin;
using INode::end;
using INode::size;
void push(const PtrTo<T> & node) { INode::push(node); }
ASTPtr convertToOld() const override
{
auto list = std::make_shared<ASTExpressionList>(Separator);
for (const auto & child : *this) list->children.emplace_back(child->convertToOld());
return list;
}
String toString() const override
{
if (!size()) return {};
auto string = (*begin())->toString();
for (auto next = ++begin(); next != end(); ++next)
string += String(1, Separator) + " " + (*next)->toString();
return string;
}
};
template <class T>
class SimpleClause : public INode
{
public:
explicit SimpleClause(PtrTo<T> expr) : INode{expr} {}
ASTPtr convertToOld() const override { return get(0)->convertToOld(); }
};
}

View File

@ -1,174 +0,0 @@
#include <Parsers/New/AST/Identifier.h>
#include <IO/ReadHelpers.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
Identifier::Identifier(const String & name_) : name(name_)
{
if (name.front() == '`' || name.front() == '"')
{
String s;
ReadBufferFromMemory in(name.data(), name.size());
if (name.front() == '`')
readBackQuotedStringWithSQLStyle(s, in);
else
readDoubleQuotedStringWithSQLStyle(s, in);
assert(in.count() == name.size());
name = s;
}
}
Identifier::Identifier(const String & name_, const String & nested_name) : name(name_ + "." + nested_name)
{
}
ASTPtr Identifier::convertToOld() const
{
return std::make_shared<ASTIdentifier>(getQualifiedName());
}
String Identifier::toString() const
{
return getQualifiedName();
}
DatabaseIdentifier::DatabaseIdentifier(PtrTo<Identifier> name) : Identifier(*name)
{
}
TableIdentifier::TableIdentifier(PtrTo<DatabaseIdentifier> database, PtrTo<Identifier> name) : Identifier(*name), db(database)
{
}
void TableIdentifier::makeCompound() const
{
if (db)
{
name = db->getName();
db.reset();
}
}
ASTPtr TableIdentifier::convertToOld() const
{
if (db) return std::make_shared<ASTTableIdentifier>(db->getName(), getName());
else return std::make_shared<ASTTableIdentifier>(getName());
}
ColumnIdentifier::ColumnIdentifier(PtrTo<TableIdentifier> table_, PtrTo<Identifier> name) : Identifier(name->getName()), table(table_)
{
}
void ColumnIdentifier::makeCompound() const
{
if (table)
{
name = table->getName() + "." + getName();
if (table->getDatabase()) table->makeCompound();
else table.reset();
}
}
ASTPtr ColumnIdentifier::convertToOld() const
{
std::vector<String> parts;
if (table)
{
if (table->getDatabase()) parts.push_back(table->getDatabase()->getName());
parts.push_back(table->getName());
}
parts.push_back(getName());
return std::make_shared<ASTIdentifier>(std::move(parts));
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitAlias(ClickHouseParser::AliasContext *ctx)
{
if (ctx->IDENTIFIER()) return std::make_shared<Identifier>(ctx->IDENTIFIER()->getText());
if (ctx->keywordForAlias()) return std::make_shared<Identifier>(ctx->keywordForAlias()->getText());
__builtin_unreachable();
}
antlrcpp::Any ParseTreeVisitor::visitColumnIdentifier(ClickHouseParser::ColumnIdentifierContext *ctx)
{
auto table = ctx->tableIdentifier() ? visit(ctx->tableIdentifier()).as<PtrTo<TableIdentifier>>() : nullptr;
return std::make_shared<ColumnIdentifier>(table, visit(ctx->nestedIdentifier()));
}
antlrcpp::Any ParseTreeVisitor::visitDatabaseIdentifier(ClickHouseParser::DatabaseIdentifierContext *ctx)
{
return std::make_shared<DatabaseIdentifier>(visit(ctx->identifier()).as<PtrTo<Identifier>>());
}
antlrcpp::Any ParseTreeVisitor::visitIdentifier(ClickHouseParser::IdentifierContext *ctx)
{
if (ctx->IDENTIFIER()) return std::make_shared<Identifier>(ctx->IDENTIFIER()->getText());
if (ctx->interval()) return std::make_shared<Identifier>(ctx->interval()->getText());
if (ctx->keyword()) return std::make_shared<Identifier>(ctx->keyword()->getText());
__builtin_unreachable();
}
antlrcpp::Any ParseTreeVisitor::visitIdentifierOrNull(ClickHouseParser::IdentifierOrNullContext *ctx)
{
if (ctx->identifier()) return visit(ctx->identifier());
if (ctx->NULL_SQL())
{
if (ctx->NULL_SQL()->getSymbol()->getText() == "Null") return std::make_shared<Identifier>("Null");
else {
// TODO: raise error
}
}
__builtin_unreachable();
}
antlrcpp::Any ParseTreeVisitor::visitInterval(ClickHouseParser::IntervalContext *)
{
asm (""); // prevent symbol removal
__builtin_unreachable();
}
antlrcpp::Any ParseTreeVisitor::visitKeyword(ClickHouseParser::KeywordContext *)
{
asm (""); // prevent symbol removal
__builtin_unreachable();
}
antlrcpp::Any ParseTreeVisitor::visitKeywordForAlias(ClickHouseParser::KeywordForAliasContext *)
{
asm (""); // prevent symbol removal
__builtin_unreachable();
}
antlrcpp::Any ParseTreeVisitor::visitNestedIdentifier(ClickHouseParser::NestedIdentifierContext *ctx)
{
if (ctx->identifier().size() == 2)
{
auto name1 = visit(ctx->identifier(0)).as<PtrTo<Identifier>>()->getName();
auto name2 = visit(ctx->identifier(1)).as<PtrTo<Identifier>>()->getName();
return std::make_shared<Identifier>(name1, name2);
}
else return visit(ctx->identifier(0));
}
antlrcpp::Any ParseTreeVisitor::visitTableIdentifier(ClickHouseParser::TableIdentifierContext *ctx)
{
auto database = ctx->databaseIdentifier() ? visit(ctx->databaseIdentifier()).as<PtrTo<DatabaseIdentifier>>() : nullptr;
return std::make_shared<TableIdentifier>(database, visit(ctx->identifier()));
}
}

View File

@ -1,66 +0,0 @@
#pragma once
#include <Parsers/New/AST/INode.h>
namespace DB::AST
{
class Identifier : public INode
{
public:
explicit Identifier(const String & name_);
Identifier(const String & name_, const String & nested_name);
const auto & getName() const { return name; }
ASTPtr convertToOld() const override;
String toString() const override;
virtual String getQualifiedName() const { return name; };
protected:
mutable String name; // protected and non-const because identifiers may become `column.nested` from `table.column`
String dumpInfo() const override { return getQualifiedName(); }
};
class DatabaseIdentifier : public Identifier
{
public:
explicit DatabaseIdentifier(PtrTo<Identifier> name);
};
class TableIdentifier : public Identifier
{
public:
TableIdentifier(PtrTo<DatabaseIdentifier> database, PtrTo<Identifier> name);
auto getDatabase() const { return db; }
void makeCompound() const;
String getQualifiedName() const override { return (db ? db->getQualifiedName() + "." : String()) + getName(); }
ASTPtr convertToOld() const override;
private:
mutable PtrTo<DatabaseIdentifier> db;
};
class ColumnIdentifier : public Identifier
{
public:
ColumnIdentifier(PtrTo<TableIdentifier> table, PtrTo<Identifier> name);
auto getTable() const { return table; }
void makeCompound() const;
String getQualifiedName() const override { return (table ? table->getQualifiedName() + "." : String()) + getName(); }
ASTPtr convertToOld() const override;
private:
mutable PtrTo<TableIdentifier> table;
};
}

View File

@ -1,125 +0,0 @@
#include <Parsers/New/AST/InsertQuery.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTInsertQuery.h>
#include <Parsers/New/AST/ColumnExpr.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/SelectUnionQuery.h>
#include <Parsers/New/AST/TableExpr.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
// static
PtrTo<DataClause> DataClause::createFormat(PtrTo<Identifier> identifier, size_t data_offset)
{
PtrTo<DataClause> clause(new DataClause(ClauseType::FORMAT, {identifier}));
clause->offset = data_offset;
return clause;
}
// static
PtrTo<DataClause> DataClause::createSelect(PtrTo<SelectUnionQuery> query)
{
return PtrTo<DataClause>(new DataClause(ClauseType::SELECT, {query}));
}
// static
PtrTo<DataClause> DataClause::createValues(size_t data_offset)
{
PtrTo<DataClause> clause(new DataClause(ClauseType::VALUES, {}));
clause->offset = data_offset;
return clause;
}
DataClause::DataClause(ClauseType type, PtrList exprs) : INode(exprs), clause_type(type)
{
}
ASTPtr DataClause::convertToOld() const
{
if (clause_type != ClauseType::SELECT) return {};
return get(SUBQUERY)->convertToOld();
}
// static
PtrTo<InsertQuery> InsertQuery::createTable(PtrTo<TableIdentifier> identifier, PtrTo<ColumnNameList> list, PtrTo<DataClause> clause)
{
return PtrTo<InsertQuery>(new InsertQuery(QueryType::TABLE, {identifier, list, clause}));
}
// static
PtrTo<InsertQuery> InsertQuery::createFunction(PtrTo<TableFunctionExpr> function, PtrTo<ColumnNameList> list, PtrTo<DataClause> clause)
{
return PtrTo<InsertQuery>(new InsertQuery(QueryType::FUNCTION, {function, list, clause}));
}
InsertQuery::InsertQuery(QueryType type, PtrList exprs) : Query(exprs), query_type(type)
{
}
ASTPtr InsertQuery::convertToOld() const
{
auto query = std::make_shared<ASTInsertQuery>();
switch(query_type)
{
case QueryType::FUNCTION:
query->table_function = get(FUNCTION)->convertToOld();
break;
case QueryType::TABLE:
query->table_id = get(IDENTIFIER)->convertToOld()->as<ASTTableIdentifier>()->getTableId();
break;
}
if (has(COLUMNS)) query->columns = get(COLUMNS)->convertToOld();
if (get<DataClause>(DATA)->getType() == DataClause::ClauseType::SELECT)
{
query->select = get(DATA)->convertToOld();
query->children.push_back(query->select);
}
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitColumnsClause(ClickHouseParser::ColumnsClauseContext *ctx)
{
auto list = std::make_shared<ColumnNameList>();
for (auto * name : ctx->nestedIdentifier()) list->push(visit(name));
return list;
}
antlrcpp::Any ParseTreeVisitor::visitDataClauseFormat(ClickHouseParser::DataClauseFormatContext *ctx)
{
return DataClause::createFormat(visit(ctx->identifier()), ctx->getStop()->getStopIndex() + 1);
}
antlrcpp::Any ParseTreeVisitor::visitDataClauseSelect(ClickHouseParser::DataClauseSelectContext *ctx)
{
return DataClause::createSelect(visit(ctx->selectUnionStmt()));
}
antlrcpp::Any ParseTreeVisitor::visitDataClauseValues(ClickHouseParser::DataClauseValuesContext *ctx)
{
return DataClause::createValues(ctx->getStop()->getStopIndex() + 1);
}
antlrcpp::Any ParseTreeVisitor::visitInsertStmt(ClickHouseParser::InsertStmtContext *ctx)
{
auto columns = ctx->columnsClause() ? visit(ctx->columnsClause()).as<PtrTo<ColumnNameList>>() : nullptr;
if (ctx->FUNCTION()) return InsertQuery::createFunction(visit(ctx->tableFunctionExpr()), columns, visit(ctx->dataClause()));
if (ctx->tableIdentifier()) return InsertQuery::createTable(visit(ctx->tableIdentifier()), columns, visit(ctx->dataClause()));
__builtin_unreachable();
}
}

View File

@ -1,73 +0,0 @@
#pragma once
#include <Parsers/New/AST/Query.h>
namespace DB::AST
{
class DataClause : public INode
{
public:
enum class ClauseType
{
FORMAT,
SELECT,
VALUES,
};
static PtrTo<DataClause> createFormat(PtrTo<Identifier> identifier, size_t data_offset);
static PtrTo<DataClause> createSelect(PtrTo<SelectUnionQuery> query);
static PtrTo<DataClause> createValues(size_t data_offset);
auto getType() const { return clause_type; }
auto getOffset() const { return offset; }
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
FORMAT = 0, // Identifier
SUBQUERY = 0, // SelectUnionQuery
};
ClauseType clause_type;
size_t offset = 0;
DataClause(ClauseType type, PtrList exprs);
};
class InsertQuery : public Query
{
public:
static PtrTo<InsertQuery> createFunction(PtrTo<TableFunctionExpr> function, PtrTo<ColumnNameList> list, PtrTo<DataClause> clause);
static PtrTo<InsertQuery> createTable(PtrTo<TableIdentifier> identifier, PtrTo<ColumnNameList> list, PtrTo<DataClause> clause);
bool hasData() const { return get<DataClause>(DATA)->getType() != DataClause::ClauseType::SELECT; }
size_t getDataOffset() const { return get<DataClause>(DATA)->getOffset(); }
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
IDENTIFIER = 0, // TableIdentifier
FUNCTION = 0, // TableFunctionExpr
COLUMNS = 1, // ColumnNameList
DATA = 2, // DataClause
};
enum class QueryType
{
FUNCTION,
TABLE,
};
QueryType query_type;
InsertQuery(QueryType type, PtrList exprs);
String dumpInfo() const override { return String("has_data=") + (hasData() ? "true" : "false"); }
};
}

View File

@ -1,326 +0,0 @@
#include <Parsers/New/AST/JoinExpr.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTTablesInSelectQuery.h>
#include <Parsers/New/AST/RatioExpr.h>
#include <Parsers/New/AST/TableExpr.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::ErrorCodes
{
extern const int UNEXPECTED_AST_STRUCTURE;
}
namespace DB::AST
{
JoinConstraintClause::JoinConstraintClause(ConstraintType type_, PtrTo<ColumnExprList> list) : SimpleClause{list}, type(type_)
{
}
SampleClause::SampleClause(PtrTo<RatioExpr> ratio, PtrTo<RatioExpr> offset) : INode{ratio, offset}
{
}
ASTPtr SampleClause::convertToOld() const
{
auto list = std::make_shared<ASTExpressionList>();
list->children.push_back(get(RATIO)->convertToOld());
if (has(OFFSET)) list->children.push_back(get(OFFSET)->convertToOld());
return list;
}
// static
PtrTo<JoinExpr> JoinExpr::createTableExpr(PtrTo<TableExpr> expr, PtrTo<SampleClause> clause, bool final)
{
return PtrTo<JoinExpr>(new JoinExpr(JoinExpr::ExprType::TABLE, final, {expr, clause}));
}
// static
PtrTo<JoinExpr> JoinExpr::createJoinOp(
PtrTo<JoinExpr> left_expr, PtrTo<JoinExpr> right_expr, JoinOpType op, JoinOpMode mode, PtrTo<JoinConstraintClause> clause)
{
return PtrTo<JoinExpr>(new JoinExpr(ExprType::JOIN_OP, op, mode, {left_expr, right_expr, clause}));
}
JoinExpr::JoinExpr(JoinExpr::ExprType type, bool final_, PtrList exprs) : INode(exprs), expr_type(type), final(final_)
{
}
JoinExpr::JoinExpr(JoinExpr::ExprType type, JoinExpr::JoinOpType op, JoinExpr::JoinOpMode mode, PtrList exprs)
: INode(exprs), expr_type(type), op_type(op), op_mode(mode)
{
}
ASTPtr JoinExpr::convertToOld() const
{
/** The sole convertible chain of Join's may look like:
*
* FROM table1 JOIN table2 ON SMTH JOIN table3 ON SMTH JOIN
*
* Since Join is a left-associative operation then the tree will look like:
*
* JoinExpr
* / \
* JoinExpr
* / \
* JoinExpr table3
* / \
* table1 table2
*
* To linearize this tree we have to start from the top-most expression.
*/
auto list = std::make_shared<ASTExpressionList>();
if (expr_type == ExprType::TABLE)
{
auto element = std::make_shared<ASTTablesInSelectQueryElement>();
element->children.emplace_back(get(TABLE)->convertToOld());
element->table_expression = element->children.back();
element->table_expression->as<ASTTableExpression>()->final = final;
if (has(SAMPLE))
{
auto old_list = get(SAMPLE)->convertToOld();
element->table_expression->as<ASTTableExpression>()->sample_size = old_list->children[0];
element->table_expression->children.push_back(element->table_expression->as<ASTTableExpression>()->sample_size);
if (old_list->children.size() > 1)
{
element->table_expression->as<ASTTableExpression>()->sample_offset = old_list->children[1];
element->table_expression->children.push_back(element->table_expression->as<ASTTableExpression>()->sample_offset);
}
}
list->children.emplace_back(element);
}
else if (expr_type == ExprType::JOIN_OP)
{
if (get<JoinExpr>(RIGHT_EXPR)->expr_type != ExprType::TABLE)
throw Exception(ErrorCodes::UNEXPECTED_AST_STRUCTURE, "Cannot convert new tree-like JoinExpr to old AST");
auto left = get(LEFT_EXPR)->convertToOld(), right = get(RIGHT_EXPR)->convertToOld(); // ASTExpressionList's
list->children.insert(list->children.end(), left->children.begin(), left->children.end()); // Insert all the previously parsed left subtree
list->children.emplace_back(right->children[0]); // Insert only first (single) ASTTablesInSelectQueryElement which should contain only ASTTableExpression
auto element = std::make_shared<ASTTableJoin>();
switch (op_mode)
{
case JoinOpMode::DEFAULT:
element->locality = ASTTableJoin::Locality::Unspecified;
break;
case JoinOpMode::GLOBAL:
element->locality = ASTTableJoin::Locality::Global;
break;
case JoinOpMode::LOCAL:
element->locality = ASTTableJoin::Locality::Local;
break;
}
switch (op_type)
{
case JoinOpType::CROSS:
element->kind = ASTTableJoin::Kind::Cross;
break;
case JoinOpType::FULL:
element->kind = ASTTableJoin::Kind::Full;
break;
case JoinOpType::FULL_ALL:
element->kind = ASTTableJoin::Kind::Full;
element->strictness = ASTTableJoin::Strictness::All;
break;
case JoinOpType::FULL_ANY:
element->kind = ASTTableJoin::Kind::Full;
element->strictness = ASTTableJoin::Strictness::Any;
break;
case JoinOpType::INNER:
element->kind = ASTTableJoin::Kind::Inner;
break;
case JoinOpType::INNER_ALL:
element->kind = ASTTableJoin::Kind::Inner;
element->strictness = ASTTableJoin::Strictness::All;
break;
case JoinOpType::INNER_ANY:
element->kind = ASTTableJoin::Kind::Inner;
element->strictness = ASTTableJoin::Strictness::Any;
break;
case JoinOpType::INNER_ASOF:
element->kind = ASTTableJoin::Kind::Inner;
element->strictness = ASTTableJoin::Strictness::Asof;
break;
case JoinOpType::LEFT:
element->kind = ASTTableJoin::Kind::Left;
break;
case JoinOpType::LEFT_ALL:
element->kind = ASTTableJoin::Kind::Left;
element->strictness = ASTTableJoin::Strictness::All;
break;
case JoinOpType::LEFT_ANTI:
element->kind = ASTTableJoin::Kind::Left;
element->strictness = ASTTableJoin::Strictness::Anti;
break;
case JoinOpType::LEFT_ANY:
element->kind = ASTTableJoin::Kind::Left;
element->strictness = ASTTableJoin::Strictness::Any;
break;
case JoinOpType::LEFT_ASOF:
element->kind = ASTTableJoin::Kind::Left;
element->strictness = ASTTableJoin::Strictness::Asof;
break;
case JoinOpType::LEFT_SEMI:
element->kind = ASTTableJoin::Kind::Left;
element->strictness = ASTTableJoin::Strictness::Semi;
break;
case JoinOpType::RIGHT:
element->kind = ASTTableJoin::Kind::Right;
break;
case JoinOpType::RIGHT_ANTI:
element->kind = ASTTableJoin::Kind::Right;
element->strictness = ASTTableJoin::Strictness::Anti;
break;
case JoinOpType::RIGHT_ALL:
element->kind = ASTTableJoin::Kind::Right;
element->strictness = ASTTableJoin::Strictness::All;
break;
case JoinOpType::RIGHT_ANY:
element->kind = ASTTableJoin::Kind::Right;
element->strictness = ASTTableJoin::Strictness::Any;
break;
case JoinOpType::RIGHT_ASOF:
element->kind = ASTTableJoin::Kind::Right;
element->strictness = ASTTableJoin::Strictness::Asof;
break;
case JoinOpType::RIGHT_SEMI:
element->kind = ASTTableJoin::Kind::Right;
element->strictness = ASTTableJoin::Strictness::Semi;
break;
}
if (has(CONSTRAINT))
{
const auto * constraint = get<JoinConstraintClause>(CONSTRAINT);
switch(constraint->getType())
{
case JoinConstraintClause::ConstraintType::ON:
element->on_expression = constraint->convertToOld();
if (element->on_expression->children.size() > 1)
throw Exception(ErrorCodes::UNEXPECTED_AST_STRUCTURE, "Cannot convert JoinExpr with more than one ON expression");
element->on_expression = element->on_expression->children[0];
element->children.push_back(element->on_expression);
break;
case JoinConstraintClause::ConstraintType::USING:
element->using_expression_list = constraint->convertToOld();
element->children.push_back(element->using_expression_list);
break;
}
}
list->children.back()->children.emplace_back(element);
list->children.back()->as<ASTTablesInSelectQueryElement>()->table_join = element;
}
return list;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitJoinConstraintClause(ClickHouseParser::JoinConstraintClauseContext *ctx)
{
return std::make_shared<JoinConstraintClause>(
ctx->ON() ? JoinConstraintClause::ConstraintType::ON : JoinConstraintClause::ConstraintType::USING,
visit(ctx->columnExprList()));
}
antlrcpp::Any ParseTreeVisitor::visitJoinExprCrossOp(ClickHouseParser::JoinExprCrossOpContext *ctx)
{
auto [op, mode] = std::pair<JoinExpr::JoinOpType, JoinExpr::JoinOpMode>(visit(ctx->joinOpCross()));
return JoinExpr::createJoinOp(visit(ctx->joinExpr(0)), visit(ctx->joinExpr(1)), op, mode, nullptr);
}
antlrcpp::Any ParseTreeVisitor::visitJoinExprOp(ClickHouseParser::JoinExprOpContext *ctx)
{
auto mode = JoinExpr::JoinOpMode::DEFAULT;
auto op = ctx->joinOp() ? visit(ctx->joinOp()).as<JoinExpr::JoinOpType>() : JoinExpr::JoinOpType::INNER;
if (ctx->GLOBAL()) mode = JoinExpr::JoinOpMode::GLOBAL;
else if (ctx->LOCAL()) mode = JoinExpr::JoinOpMode::LOCAL;
return JoinExpr::createJoinOp(visit(ctx->joinExpr(0)), visit(ctx->joinExpr(1)), op, mode, visit(ctx->joinConstraintClause()));
}
antlrcpp::Any ParseTreeVisitor::visitJoinExprParens(ClickHouseParser::JoinExprParensContext *ctx)
{
return visit(ctx->joinExpr());
}
antlrcpp::Any ParseTreeVisitor::visitJoinExprTable(ClickHouseParser::JoinExprTableContext *ctx)
{
auto sample = ctx->sampleClause() ? visit(ctx->sampleClause()).as<PtrTo<SampleClause>>() : nullptr;
return JoinExpr::createTableExpr(visit(ctx->tableExpr()), sample, !!ctx->FINAL());
}
antlrcpp::Any ParseTreeVisitor::visitJoinOpCross(ClickHouseParser::JoinOpCrossContext *ctx)
{
std::pair<JoinExpr::JoinOpType, JoinExpr::JoinOpMode> op{
JoinExpr::JoinOpType::CROSS, JoinExpr::JoinOpMode::DEFAULT};
if (ctx->GLOBAL()) op.second = JoinExpr::JoinOpMode::GLOBAL;
else if (ctx->LOCAL()) op.second = JoinExpr::JoinOpMode::LOCAL;
return op;
}
antlrcpp::Any ParseTreeVisitor::visitJoinOpFull(ClickHouseParser::JoinOpFullContext *ctx)
{
if (ctx->ALL()) return JoinExpr::JoinOpType::FULL_ALL;
if (ctx->ANY()) return JoinExpr::JoinOpType::FULL_ANY;
return JoinExpr::JoinOpType::FULL;
}
antlrcpp::Any ParseTreeVisitor::visitJoinOpInner(ClickHouseParser::JoinOpInnerContext *ctx)
{
if (ctx->ALL()) return JoinExpr::JoinOpType::INNER_ALL;
if (ctx->ANY()) return JoinExpr::JoinOpType::INNER_ANY;
if (ctx->ASOF()) return JoinExpr::JoinOpType::INNER_ASOF;
return JoinExpr::JoinOpType::INNER;
}
antlrcpp::Any ParseTreeVisitor::visitJoinOpLeftRight(ClickHouseParser::JoinOpLeftRightContext *ctx)
{
if (ctx->LEFT())
{
if (ctx->SEMI()) return JoinExpr::JoinOpType::LEFT_SEMI;
if (ctx->ALL()) return JoinExpr::JoinOpType::LEFT_ALL;
if (ctx->ANTI()) return JoinExpr::JoinOpType::LEFT_ANTI;
if (ctx->ANY()) return JoinExpr::JoinOpType::LEFT_ANY;
if (ctx->ASOF()) return JoinExpr::JoinOpType::LEFT_ASOF;
return JoinExpr::JoinOpType::LEFT;
}
else if (ctx->RIGHT())
{
if (ctx->SEMI()) return JoinExpr::JoinOpType::RIGHT_SEMI;
if (ctx->ALL()) return JoinExpr::JoinOpType::RIGHT_ALL;
if (ctx->ANTI()) return JoinExpr::JoinOpType::RIGHT_ANTI;
if (ctx->ANY()) return JoinExpr::JoinOpType::RIGHT_ANY;
if (ctx->ASOF()) return JoinExpr::JoinOpType::RIGHT_ASOF;
return JoinExpr::JoinOpType::RIGHT;
}
__builtin_unreachable();
}
antlrcpp::Any ParseTreeVisitor::visitSampleClause(ClickHouseParser::SampleClauseContext *ctx)
{
auto offset = ctx->ratioExpr().size() == 2 ? visit(ctx->ratioExpr(1)).as<PtrTo<RatioExpr>>() : nullptr;
return std::make_shared<SampleClause>(visit(ctx->ratioExpr(0)), offset);
}
}

View File

@ -1,103 +0,0 @@
#pragma once
#include <Parsers/New/AST/INode.h>
namespace DB::AST
{
class JoinConstraintClause : public SimpleClause<ColumnExprList>
{
public:
enum class ConstraintType
{
ON,
USING,
};
JoinConstraintClause(ConstraintType type, PtrTo<ColumnExprList> list);
auto getType() const { return type; }
private:
const ConstraintType type;
};
class SampleClause : public INode
{
public:
SampleClause(PtrTo<RatioExpr> ratio_, PtrTo<RatioExpr> offset_);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
RATIO = 0, // RatioExpr
OFFSET = 1, // RatioExpr (optional)
};
};
class JoinExpr : public INode
{
public:
enum class JoinOpType
{
INNER,
INNER_ALL,
INNER_ANY,
INNER_ASOF,
LEFT,
LEFT_SEMI,
LEFT_ALL,
LEFT_ANTI,
LEFT_ANY,
LEFT_ASOF,
RIGHT,
RIGHT_SEMI,
RIGHT_ALL,
RIGHT_ANTI,
RIGHT_ANY,
RIGHT_ASOF,
FULL,
FULL_ALL,
FULL_ANY,
CROSS,
};
enum class JoinOpMode
{
DEFAULT, // actual mode depends on setting's 'distributed_product_mode' value
GLOBAL,
LOCAL,
};
static PtrTo<JoinExpr> createTableExpr(PtrTo<TableExpr> expr, PtrTo<SampleClause> clause, bool final);
static PtrTo<JoinExpr> createJoinOp(PtrTo<JoinExpr> left_expr, PtrTo<JoinExpr> right_expr, JoinOpType op, JoinOpMode mode, PtrTo<JoinConstraintClause> clause);
ASTPtr convertToOld() const override; // returns topologically sorted elements as ASTExpressionList
private:
enum ChildIndex : UInt8
{
TABLE = 0, // TableExpr
SAMPLE = 1, // SampleClause (optional)
LEFT_EXPR = 0, // JoinExpr
RIGHT_EXPR = 1, // JoinExpr
CONSTRAINT = 2, // JoinConstraintClause
};
enum class ExprType
{
TABLE,
JOIN_OP,
};
const ExprType expr_type;
const JoinOpType op_type = JoinOpType::INNER;
const JoinOpMode op_mode = JoinOpMode::DEFAULT;
const bool final = false;
JoinExpr(ExprType type, bool final, PtrList exprs);
JoinExpr(ExprType type, JoinOpType op, JoinOpMode mode, PtrList exprs);
};
}

View File

@ -1,56 +0,0 @@
#include <Parsers/New/AST/KillQuery.h>
#include <Parsers/ASTKillQueryQuery.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
// static
PtrTo<KillQuery> KillQuery::createMutation(PtrTo<ClusterClause> cluster, bool sync, bool test, PtrTo<WhereClause> where)
{
PtrTo<KillQuery> query(new KillQuery(cluster, QueryType::MUTATION, {where}));
query->sync = sync;
query->test = test;
return query;
}
KillQuery::KillQuery(PtrTo<ClusterClause> cluster, QueryType type, PtrList exprs) : DDLQuery(cluster, exprs), query_type(type)
{
}
ASTPtr KillQuery::convertToOld() const
{
auto query = std::make_shared<ASTKillQueryQuery>();
query->cluster = cluster_name;
switch(query_type)
{
case QueryType::MUTATION:
query->type = ASTKillQueryQuery::Type::Mutation;
query->sync = sync;
query->test = test;
query->where_expression = get(WHERE)->convertToOld();
query->children.push_back(query->where_expression);
break;
}
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitKillMutationStmt(ClickHouseParser::KillMutationStmtContext * ctx)
{
auto cluster = ctx->clusterClause() ? visit(ctx->clusterClause()).as<PtrTo<ClusterClause>>() : nullptr;
return KillQuery::createMutation(cluster, !!ctx->SYNC(), !!ctx->TEST(), visit(ctx->whereClause()));
}
}

View File

@ -1,33 +0,0 @@
#pragma once
#include <Parsers/New/AST/DDLQuery.h>
namespace DB::AST
{
class KillQuery : public DDLQuery
{
public:
static PtrTo<KillQuery> createMutation(PtrTo<ClusterClause> cluster, bool sync, bool test, PtrTo<WhereClause> where);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
WHERE = 0, // WhereClause
};
enum class QueryType
{
MUTATION,
};
const QueryType query_type;
bool sync = false, test = false;
KillQuery(PtrTo<ClusterClause> cluster, QueryType type, PtrList exprs);
};
}

View File

@ -1,39 +0,0 @@
#include <Parsers/New/AST/LimitExpr.h>
#include <Parsers/New/AST/ColumnExpr.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
LimitExpr::LimitExpr(PtrTo<ColumnExpr> limit, PtrTo<ColumnExpr> offset) : INode{limit, offset}
{
}
ASTPtr LimitExpr::convertToOld() const
{
auto list = std::make_shared<ASTExpressionList>();
if (has(OFFSET)) list->children.push_back(get(OFFSET)->convertToOld());
list->children.push_back(get(LIMIT)->convertToOld());
return list;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitLimitExpr(ClickHouseParser::LimitExprContext *ctx)
{
if (ctx->columnExpr().size() == 2)
return std::make_shared<LimitExpr>(visit(ctx->columnExpr(0)), visit(ctx->columnExpr(1)));
else
return std::make_shared<LimitExpr>(visit(ctx->columnExpr(0)).as<PtrTo<ColumnExpr>>());
}
}

View File

@ -1,24 +0,0 @@
#pragma once
#include <Parsers/New/AST/INode.h>
namespace DB::AST
{
class LimitExpr : public INode
{
public:
explicit LimitExpr(PtrTo<ColumnExpr> limit, PtrTo<ColumnExpr> offset = nullptr);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
LIMIT = 0, // ColumnExpr
OFFSET = 1, // ColumnExpr (optional)
};
};
}

View File

@ -1,222 +0,0 @@
#include <Parsers/New/AST/Literal.h>
#include <IO/ReadHelpers.h>
#include <IO/WriteBufferFromString.h>
#include <IO/WriteHelpers.h>
#include <Parsers/ASTLiteral.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
// static
PtrTo<Literal> Literal::createNull()
{
return PtrTo<Literal>(new Literal(LiteralType::NULL_LITERAL, String()));
}
// static
PtrTo<NumberLiteral> Literal::createNumber(antlr4::tree::TerminalNode * literal, bool negative)
{
auto number = std::make_shared<NumberLiteral>(literal);
if (negative) number->makeNegative();
return number;
}
// static
PtrTo<NumberLiteral> Literal::createNumber(const String & literal)
{
bool has_minus = literal[0] == '-';
auto number = std::make_shared<NumberLiteral>(has_minus ? literal.substr(1) : literal);
if (has_minus) number->makeNegative();
return number;
}
// static
PtrTo<StringLiteral> Literal::createString(antlr4::tree::TerminalNode * literal)
{
return std::make_shared<StringLiteral>(literal);
}
// static
PtrTo<StringLiteral> Literal::createString(const String & literal)
{
return std::make_shared<StringLiteral>(literal);
}
Literal::Literal(LiteralType type_, const String & token_) : token(token_), type(type_)
{
}
ASTPtr Literal::convertToOld() const
{
auto as_field = [this] () -> Field
{
switch(type)
{
case LiteralType::NULL_LITERAL:
return Field(Null());
case LiteralType::NUMBER:
{
const auto * number = this->as<NumberLiteral>();
if (!number->isNegative())
if (auto value = number->as<UInt64>()) return Field(*value);
if (auto value = number->as<Int64>()) return Field(*value);
if (auto value = number->as<Float64>()) return Field(*value);
return Field();
}
case LiteralType::STRING:
return asString();
}
__builtin_unreachable();
};
return std::make_shared<ASTLiteral>(as_field());
}
String Literal::toString() const
{
WriteBufferFromOwnString wb;
writeEscapedString(token, wb);
return type == LiteralType::STRING ? "'" + wb.str() + "'" : wb.str();
}
NumberLiteral::NumberLiteral(antlr4::tree::TerminalNode * literal) : Literal(LiteralType::NUMBER, literal->getSymbol()->getText())
{
}
NumberLiteral::NumberLiteral(const String & literal) : Literal(LiteralType::NUMBER, literal)
{
}
String NumberLiteral::toString() const
{
return (minus ? String("-") : String()) + Literal::toString();
}
ASTSampleRatio::Rational NumberLiteral::convertToOldRational() const
{
UInt64 num_before = 0;
UInt64 num_after = 0;
Int64 exponent = 0;
const char * pos = token.data(), * end = token.data() + token.size();
const char * pos_after_first_num = tryReadIntText(num_before, pos, end);
bool has_num_before_point [[maybe_unused]] = pos_after_first_num > pos;
pos = pos_after_first_num;
bool has_point = pos < end && *pos == '.';
if (has_point)
++pos;
assert (has_num_before_point || has_point);
size_t number_of_digits_after_point = 0;
if (has_point)
{
const char * pos_after_second_num = tryReadIntText(num_after, pos, end);
number_of_digits_after_point = pos_after_second_num - pos;
pos = pos_after_second_num;
}
bool has_exponent = pos < end && (*pos == 'e' || *pos == 'E');
if (has_exponent)
{
++pos;
const char * pos_after_exponent [[maybe_unused]] = tryReadIntText(exponent, pos, end);
assert (pos_after_exponent != pos);
}
ASTSampleRatio::Rational res;
res.numerator = num_before * intExp10(number_of_digits_after_point) + num_after;
res.denominator = intExp10(number_of_digits_after_point);
if (exponent > 0)
res.numerator *= intExp10(exponent);
if (exponent < 0)
res.denominator *= intExp10(-exponent);
return res;
}
StringLiteral::StringLiteral(antlr4::tree::TerminalNode * literal) : Literal(LiteralType::STRING, literal->getSymbol()->getText())
{
String s;
ReadBufferFromMemory in(token.data(), token.size());
readQuotedStringWithSQLStyle(s, in);
assert(in.count() == token.size());
token = s;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitFloatingLiteral(ClickHouseParser::FloatingLiteralContext * ctx)
{
if (ctx->FLOATING_LITERAL()) return Literal::createNumber(ctx->FLOATING_LITERAL());
const auto * dot = ctx->DOT()->getSymbol();
if (!ctx->DECIMAL_LITERAL().empty())
{
// .1234
if (dot->getTokenIndex() < ctx->DECIMAL_LITERAL(0)->getSymbol()->getTokenIndex())
return Literal::createNumber(dot->getText() + ctx->DECIMAL_LITERAL(0)->getSymbol()->getText());
// 1234.
else if (ctx->DECIMAL_LITERAL().size() == 1 && !ctx->OCTAL_LITERAL())
return Literal::createNumber(ctx->DECIMAL_LITERAL(0)->getSymbol()->getText() + dot->getText());
// 1234.1234
else if (ctx->DECIMAL_LITERAL().size() == 2)
return Literal::createNumber(
ctx->DECIMAL_LITERAL(0)->getSymbol()->getText() + dot->getText() + ctx->DECIMAL_LITERAL(1)->getSymbol()->getText());
// 1234.0123
else
return Literal::createNumber(
ctx->DECIMAL_LITERAL(0)->getSymbol()->getText() + dot->getText() + ctx->OCTAL_LITERAL()->getSymbol()->getText());
}
else
// .0123
return Literal::createNumber(dot->getText() + ctx->OCTAL_LITERAL()->getSymbol()->getText());
__builtin_unreachable();
}
antlrcpp::Any ParseTreeVisitor::visitLiteral(ClickHouseParser::LiteralContext * ctx)
{
if (ctx->NULL_SQL())
return Literal::createNull();
if (ctx->STRING_LITERAL())
return std::static_pointer_cast<Literal>(Literal::createString(ctx->STRING_LITERAL()));
if (ctx->numberLiteral())
return std::static_pointer_cast<Literal>(visit(ctx->numberLiteral()).as<PtrTo<NumberLiteral>>());
__builtin_unreachable();
}
antlrcpp::Any ParseTreeVisitor::visitNumberLiteral(ClickHouseParser::NumberLiteralContext *ctx)
{
if (ctx->floatingLiteral())
{
auto number = visit(ctx->floatingLiteral()).as<PtrTo<NumberLiteral>>();
if (ctx->DASH()) number->makeNegative();
return number;
}
if (ctx->OCTAL_LITERAL()) return Literal::createNumber(ctx->OCTAL_LITERAL(), !!ctx->DASH());
if (ctx->DECIMAL_LITERAL()) return Literal::createNumber(ctx->DECIMAL_LITERAL(), !!ctx->DASH());
if (ctx->HEXADECIMAL_LITERAL()) return Literal::createNumber(ctx->HEXADECIMAL_LITERAL(), !!ctx->DASH());
if (ctx->INF()) return Literal::createNumber(ctx->INF(), !!ctx->DASH());
if (ctx->NAN_SQL()) return Literal::createNumber(ctx->NAN_SQL());
__builtin_unreachable();
}
}

View File

@ -1,96 +0,0 @@
#pragma once
#include <Parsers/New/AST/INode.h>
#include <Core/Field.h>
#include <Parsers/ASTSampleRatio.h>
#include <Token.h>
#include <tree/TerminalNode.h>
#include <sstream>
namespace DB::AST
{
class Literal : public INode
{
public:
enum class LiteralType
{
NULL_LITERAL,
NUMBER,
STRING,
};
static PtrTo<Literal> createNull();
static PtrTo<NumberLiteral> createNumber(antlr4::tree::TerminalNode * literal, bool negative = false);
static PtrTo<NumberLiteral> createNumber(const String& literal); // checks first symbol for '-' character
static PtrTo<StringLiteral> createString(antlr4::tree::TerminalNode * literal);
static PtrTo<StringLiteral> createString(const String& literal); // without quotes
ASTPtr convertToOld() const override;
String toString() const override;
bool is(LiteralType what) const { return type == what; }
protected:
String token; // STRING is stored without quotes and interpolated with escape-sequences.
Literal(LiteralType type, const String & token);
template <typename T>
std::optional<T> asNumber(bool minus) const
{
T number;
std::stringstream ss(String(minus ? "-" : "+") + token);
if (token.size() > 2 && (token[1] == 'x' || token[1] == 'X')) ss >> std::hex >> number;
else if (token.size() > 1 && (token[0] == '0')) ss >> std::oct >> number;
else ss >> number;
if (ss.fail() || !ss.eof())
return {};
return number;
}
auto asString() const { return token; }
private:
LiteralType type;
String dumpInfo() const override { return token; }
};
class NumberLiteral : public Literal
{
public:
explicit NumberLiteral(antlr4::tree::TerminalNode * literal);
explicit NumberLiteral(const String & literal);
String toString() const override;
void makeNegative() { minus = true; }
bool isNegative() const { return minus; }
template <typename T> std::optional<T> as() const { return asNumber<T>(minus); }
ASTSampleRatio::Rational convertToOldRational() const;
private:
bool minus = false;
};
class StringLiteral : public Literal
{
public:
explicit StringLiteral(antlr4::tree::TerminalNode * literal);
explicit StringLiteral(const String & literal) : Literal(LiteralType::STRING, literal) {}
template <typename T>
T as() const
{
return asString();
}
};
}

View File

@ -1,59 +0,0 @@
#include <Parsers/New/AST/OptimizeQuery.h>
#include <Interpreters/StorageID.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTOptimizeQuery.h>
#include <Parsers/New/AST/AlterTableQuery.h>
#include <Parsers/New/AST/ColumnExpr.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
OptimizeQuery::OptimizeQuery(PtrTo<ClusterClause> cluster, PtrTo<TableIdentifier> identifier, PtrTo<PartitionClause> clause, bool final_, bool deduplicate_)
: DDLQuery(cluster, {identifier, clause}), final(final_), deduplicate(deduplicate_)
{
}
ASTPtr OptimizeQuery::convertToOld() const
{
auto query = std::make_shared<ASTOptimizeQuery>();
{
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(TABLE)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->shortName();
query->uuid = table->uuid;
}
if (has(PARTITION))
{
query->partition = get(PARTITION)->convertToOld();
query->children.push_back(query->partition);
}
query->final = final;
query->deduplicate = deduplicate;
query->cluster = cluster_name;
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitOptimizeStmt(ClickHouseParser::OptimizeStmtContext *ctx)
{
auto cluster = ctx->clusterClause() ? visit(ctx->clusterClause()).as<PtrTo<ClusterClause>>() : nullptr;
auto clause = ctx->partitionClause() ? visit(ctx->partitionClause()).as<PtrTo<PartitionClause>>() : nullptr;
return std::make_shared<OptimizeQuery>(cluster, visit(ctx->tableIdentifier()), clause, !!ctx->FINAL(), !!ctx->DEDUPLICATE());
}
}

View File

@ -1,27 +0,0 @@
#pragma once
#include <Parsers/New/AST/DDLQuery.h>
namespace DB::AST
{
class OptimizeQuery : public DDLQuery
{
public:
OptimizeQuery(
PtrTo<ClusterClause> cluster, PtrTo<TableIdentifier> identifier, PtrTo<PartitionClause> clause, bool final, bool deduplicate);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
TABLE = 0, // TableIdentifier
PARTITION, // PartitionClause
};
const bool final, deduplicate;
};
}

View File

@ -1,62 +0,0 @@
#include <Parsers/New/AST/OrderExpr.h>
#include <Parsers/ASTOrderByElement.h>
#include <Parsers/New/AST/ColumnExpr.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
OrderExpr::OrderExpr(PtrTo<ColumnExpr> expr, NullsOrder nulls_, PtrTo<StringLiteral> collate, bool ascending)
: INode{expr, collate}, nulls(nulls_), asc(ascending)
{
}
ASTPtr OrderExpr::convertToOld() const
{
auto expr = std::make_shared<ASTOrderByElement>();
expr->children.push_back(get(EXPR)->convertToOld());
expr->direction = asc ? 1 : -1;
expr->nulls_direction_was_explicitly_specified = (nulls != NATURAL);
if (nulls == NATURAL) expr->nulls_direction = expr->direction;
else expr->nulls_direction = (nulls == NULLS_LAST) ? expr->direction : -expr->direction;
if (has(COLLATE))
{
expr->collation = get(COLLATE)->convertToOld();
expr->children.push_back(expr->collation);
}
// TODO: WITH FILL?
return expr;
}
}
namespace DB
{
antlrcpp::Any ParseTreeVisitor::visitOrderExprList(ClickHouseParser::OrderExprListContext *ctx)
{
auto expr_list = std::make_shared<AST::OrderExprList>();
for (auto* expr : ctx->orderExpr()) expr_list->push(visit(expr));
return expr_list;
}
antlrcpp::Any ParseTreeVisitor::visitOrderExpr(ClickHouseParser::OrderExprContext *ctx)
{
AST::OrderExpr::NullsOrder nulls = AST::OrderExpr::NATURAL;
if (ctx->FIRST()) nulls = AST::OrderExpr::NULLS_FIRST;
else if (ctx->LAST()) nulls = AST::OrderExpr::NULLS_LAST;
AST::PtrTo<AST::StringLiteral> collate;
if (ctx->COLLATE()) collate = AST::Literal::createString(ctx->STRING_LITERAL());
return std::make_shared<AST::OrderExpr>(visit(ctx->columnExpr()), nulls, collate, !ctx->DESCENDING() && !ctx->DESC());
}
}

View File

@ -1,33 +0,0 @@
#pragma once
#include <Parsers/New/AST/INode.h>
namespace DB::AST
{
class OrderExpr : public INode
{
public:
enum NullsOrder {
NATURAL,
NULLS_FIRST,
NULLS_LAST,
};
OrderExpr(PtrTo<ColumnExpr> expr, NullsOrder nulls_, PtrTo<StringLiteral> collate, bool ascending = true);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
EXPR = 0, // ColumnExpr
COLLATE, // StringLiteral (optional)
};
NullsOrder nulls;
bool asc;
};
}

View File

@ -1,34 +0,0 @@
#include <Parsers/New/AST/Query.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/Literal.h>
namespace DB::AST
{
void Query::setOutFile(PtrTo<StringLiteral> literal)
{
out_file = literal;
}
void Query::setFormat(PtrTo<Identifier> id)
{
format = id;
}
void Query::convertToOldPartially(const std::shared_ptr<ASTQueryWithOutput> & query) const
{
if (out_file)
{
query->out_file = out_file->convertToOld();
query->children.push_back(query->out_file);
}
if (format)
{
query->format = format->convertToOld();
query->children.push_back(query->format);
}
}
}

View File

@ -1,29 +0,0 @@
#pragma once
#include <Parsers/New/AST/INode.h>
#include <Parsers/ASTQueryWithOutput.h>
namespace DB::AST
{
class Query : public INode {
public:
void setOutFile(PtrTo<StringLiteral> literal);
void setFormat(PtrTo<Identifier> id);
protected:
Query() = default;
Query(std::initializer_list<Ptr> list) : INode(list) {}
explicit Query(PtrList list) : INode(list) {}
void convertToOldPartially(const std::shared_ptr<ASTQueryWithOutput> & query) const;
private:
// TODO: put them to |children|
PtrTo<StringLiteral> out_file;
PtrTo<Identifier> format;
};
}

View File

@ -1,32 +0,0 @@
What is AST?
===
AST stands for Abstract Syntax Tree, which is opposed to Concrete Syntax Tree (or Parse Tree). Read [this](https://eli.thegreenplace.net/2009/02/16/abstract-vs-concrete-syntax-trees/) post to get a sketchy overview of the difference between two concepts.
AST **must not** repeat the grammar constructions or follow them. It's convenient to have similar structure but nothing more.
The main purpose of AST is to be easily handled by interpreter - the formatting of the original query is not the purpose of AST.
Basic principles in code
===
- The base class for all AST elements is `INode` (INode.h).
- **All** sub-elements must be stored inside `INode::children` vector in a
**predetermined order** and with **predetermined type**: some elements may be `nullptr` to preserve positions of other elements.
- The order may be defined as a position in vector from the start, the last element, and some pattern of variable number of elements
in between. It's convenient to define `enum ChildIndex : Uint8 {…}` with index numbers for each class.
- If there is more than one variable pack of elements or the order can't be deterministic, then wrap elements into the lists and store the
multi-level structure (see `ColumnExpr::ExprType::FUNCTION` for example).
- Don't do multi-level structure just for nothing or to mimic the parse tree: the less is depth the better.
- The whole grammar separates expressions for databases, tables and columns. That way we already assess the semantics on the parser level.
E.g. don't use `identifier` where you know you should use `tableIdentifier`, etc.
Name conventions
===
**Query**. The top-level element that allows to distinguish different types of SQL queries. The base class is `Query` (Query.h).
**Statement**. An essential part of a query that describes its structure and possible alternatives.
**Clause**. A part of the statement designed to differ logical parts for more convenient parsing. I.e. there are many clauses in SELECT statement that are optional and contain `columnExpr` elements. Without clauses it will be hard for visitor to distinguish which `columnExpr` refers to what.
**Expression**. An element that should be somehow calculated or interpreted and result in some value.
**

View File

@ -1,43 +0,0 @@
#include <Parsers/New/AST/RatioExpr.h>
#include <Parsers/ASTSampleRatio.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
RatioExpr::RatioExpr(PtrTo<NumberLiteral> num1, PtrTo<NumberLiteral> num2) : INode{num1, num2}
{
}
ASTPtr RatioExpr::convertToOld() const
{
auto numerator = get<NumberLiteral>(NUMERATOR)->convertToOldRational();
if (has(DENOMINATOR))
{
auto denominator = get<NumberLiteral>(DENOMINATOR)->convertToOldRational();
numerator.numerator = numerator.numerator * denominator.denominator;
numerator.denominator = numerator.denominator * denominator.numerator;
}
return std::make_shared<ASTSampleRatio>(numerator);
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitRatioExpr(ClickHouseParser::RatioExprContext *ctx)
{
auto denominator = ctx->numberLiteral().size() == 2 ? visit(ctx->numberLiteral(1)).as<PtrTo<NumberLiteral>>() : nullptr;
return std::make_shared<RatioExpr>(visit(ctx->numberLiteral(0)), denominator);
}
}

View File

@ -1,24 +0,0 @@
#pragma once
#include <Parsers/New/AST/INode.h>
namespace DB::AST
{
class RatioExpr : public INode
{
public:
RatioExpr(PtrTo<NumberLiteral> num1, PtrTo<NumberLiteral> num2);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NUMERATOR = 0, // NumberLiteral
DENOMINATOR = 1, // NumberLiteral (optional)
};
};
}

View File

@ -1,58 +0,0 @@
#include <Parsers/New/AST/RenameQuery.h>
#include <Interpreters/StorageID.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTRenameQuery.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
RenameQuery::RenameQuery(PtrTo<ClusterClause> cluster, PtrTo<List<TableIdentifier>> list) : DDLQuery(cluster, {list})
{
}
ASTPtr RenameQuery::convertToOld() const
{
auto query = std::make_shared<ASTRenameQuery>();
for (auto table = get<List<TableIdentifier>>(EXPRS)->begin(), end = get<List<TableIdentifier>>(EXPRS)->end(); table != end; ++table)
{
ASTRenameQuery::Element element;
if (auto database = (*table)->as<TableIdentifier>()->getDatabase())
element.from.database = database->getName();
element.from.table = (*table)->as<TableIdentifier>()->getName();
++table;
if (auto database = (*table)->as<TableIdentifier>()->getDatabase())
element.to.database = database->getName();
element.to.table = (*table)->as<TableIdentifier>()->getName();
query->elements.push_back(element);
}
query->cluster = cluster_name;
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitRenameStmt(ClickHouseParser::RenameStmtContext *ctx)
{
auto list = std::make_shared<List<TableIdentifier>>();
auto cluster = ctx->clusterClause() ? visit(ctx->clusterClause()).as<PtrTo<ClusterClause>>() : nullptr;
for (auto * identifier : ctx->tableIdentifier()) list->push(visit(identifier));
return std::make_shared<RenameQuery>(cluster, list);
}
}

View File

@ -1,23 +0,0 @@
#pragma once
#include <Parsers/New/AST/DDLQuery.h>
namespace DB::AST
{
class RenameQuery : public DDLQuery
{
public:
explicit RenameQuery(PtrTo<ClusterClause> cluster, PtrTo<List<TableIdentifier>> list);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
EXPRS = 0, // List<TableIdentifier>
};
};
}

View File

@ -1,444 +0,0 @@
#include <Parsers/New/AST/SelectUnionQuery.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTLiteral.h>
#include <Parsers/ASTProjectionSelectQuery.h>
#include <Parsers/ASTSelectQuery.h>
#include <Parsers/ASTSelectWithUnionQuery.h>
#include <Parsers/ASTSetQuery.h>
#include <Parsers/ASTTablesInSelectQuery.h>
#include <Parsers/New/AST/ColumnExpr.h>
#include <Parsers/New/AST/JoinExpr.h>
#include <Parsers/New/AST/LimitExpr.h>
#include <Parsers/New/AST/SettingExpr.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::ErrorCodes
{
extern const int TOP_AND_LIMIT_TOGETHER;
}
namespace DB::AST
{
// FROM Clause
FromClause::FromClause(PtrTo<JoinExpr> expr) : INode{expr}
{
}
ASTPtr FromClause::convertToOld() const
{
auto old_tables = std::make_shared<ASTTablesInSelectQuery>();
old_tables->children = get(EXPR)->convertToOld()->children;
return old_tables;
}
// ARRAY JOIN Clause
ArrayJoinClause::ArrayJoinClause(PtrTo<ColumnExprList> expr_list, bool left_) : INode{expr_list}, left(left_)
{
}
ASTPtr ArrayJoinClause::convertToOld() const
{
auto element = std::make_shared<ASTTablesInSelectQueryElement>();
auto array_join = std::make_shared<ASTArrayJoin>();
if (left) array_join->kind = ASTArrayJoin::Kind::Left;
else array_join->kind = ASTArrayJoin::Kind::Inner;
array_join->expression_list = get(EXPRS)->convertToOld();
array_join->children.push_back(array_join->expression_list);
element->array_join = array_join;
element->children.push_back(element->array_join);
return element;
}
// LIMIT By Clause
LimitByClause::LimitByClause(PtrTo<LimitExpr> expr, PtrTo<ColumnExprList> expr_list) : INode{expr, expr_list}
{
}
ASTPtr LimitByClause::convertToOld() const
{
auto list = std::make_shared<ASTExpressionList>();
list->children.push_back(get(LIMIT)->convertToOld());
list->children.push_back(get(EXPRS)->convertToOld());
return list;
}
// LIMIT Clause
LimitClause::LimitClause(bool with_ties_, PtrTo<LimitExpr> expr) : INode{expr}, with_ties(with_ties_)
{
}
ASTPtr LimitClause::convertToOld() const
{
return get(EXPR)->convertToOld();
}
// SETTINGS Clause
SettingsClause::SettingsClause(PtrTo<SettingExprList> expr_list) : INode{expr_list}
{
}
ASTPtr SettingsClause::convertToOld() const
{
auto expr = std::make_shared<ASTSetQuery>();
for (const auto & child : get(EXPRS)->as<SettingExprList &>())
{
const auto * setting = child->as<SettingExpr>();
expr->changes.emplace_back(setting->getName()->getName(), setting->getValue()->convertToOld()->as<ASTLiteral>()->value);
}
return expr;
}
// PROJECTION SELECT Caluse
ProjectionSelectStmt::ProjectionSelectStmt(PtrTo<ColumnExprList> expr_list)
: INode(MAX_INDEX)
{
set(COLUMNS, expr_list);
}
void ProjectionSelectStmt::setWithClause(PtrTo<WithClause> clause)
{
set(WITH, clause);
}
void ProjectionSelectStmt::setGroupByClause(PtrTo<GroupByClause> clause)
{
set(GROUP_BY, clause);
}
void ProjectionSelectStmt::setOrderByClause(PtrTo<ProjectionOrderByClause> clause)
{
set(ORDER_BY, clause);
}
ASTPtr ProjectionSelectStmt::convertToOld() const
{
auto old_select = std::make_shared<ASTProjectionSelectQuery>();
old_select->setExpression(ASTProjectionSelectQuery::Expression::SELECT, get(COLUMNS)->convertToOld());
if (has(WITH)) old_select->setExpression(ASTProjectionSelectQuery::Expression::WITH, get(WITH)->convertToOld());
if (has(GROUP_BY)) old_select->setExpression(ASTProjectionSelectQuery::Expression::GROUP_BY, get(GROUP_BY)->convertToOld());
if (has(ORDER_BY))
{
ASTPtr order_expression;
auto expr_list = get(ORDER_BY)->convertToOld();
if (expr_list->children.size() == 1)
{
order_expression = expr_list->children.front();
}
else
{
auto function_node = std::make_shared<ASTFunction>();
function_node->name = "tuple";
function_node->arguments = expr_list;
function_node->children.push_back(expr_list);
order_expression = function_node;
}
old_select->setExpression(ASTProjectionSelectQuery::Expression::ORDER_BY, std::move(order_expression));
}
return old_select;
}
// SELECT Statement
SelectStmt::SelectStmt(bool distinct_, ModifierType type, bool totals, PtrTo<ColumnExprList> expr_list)
: INode(MAX_INDEX), modifier_type(type), distinct(distinct_), with_totals(totals)
{
set(COLUMNS, expr_list);
}
void SelectStmt::setWithClause(PtrTo<WithClause> clause)
{
set(WITH, clause);
}
void SelectStmt::setFromClause(PtrTo<FromClause> clause)
{
set(FROM, clause);
}
void SelectStmt::setArrayJoinClause(PtrTo<ArrayJoinClause> clause)
{
set(ARRAY_JOIN, clause);
}
void SelectStmt::setPrewhereClause(PtrTo<PrewhereClause> clause)
{
set(PREWHERE, clause);
}
void SelectStmt::setWhereClause(PtrTo<WhereClause> clause)
{
set(WHERE, clause);
}
void SelectStmt::setGroupByClause(PtrTo<GroupByClause> clause)
{
set(GROUP_BY, clause);
}
void SelectStmt::setHavingClause(PtrTo<HavingClause> clause)
{
set(HAVING, clause);
}
void SelectStmt::setOrderByClause(PtrTo<OrderByClause> clause)
{
set(ORDER_BY, clause);
}
void SelectStmt::setLimitByClause(PtrTo<LimitByClause> clause)
{
set(LIMIT_BY, clause);
}
void SelectStmt::setLimitClause(PtrTo<LimitClause> clause)
{
set(LIMIT, clause);
}
void SelectStmt::setSettingsClause(PtrTo<SettingsClause> clause)
{
set(SETTINGS, clause);
}
ASTPtr SelectStmt::convertToOld() const
{
auto old_select = std::make_shared<ASTSelectQuery>();
old_select->setExpression(ASTSelectQuery::Expression::SELECT, get(COLUMNS)->convertToOld());
old_select->distinct = distinct;
old_select->group_by_with_totals = with_totals;
switch(modifier_type)
{
case ModifierType::NONE:
break;
case ModifierType::CUBE:
old_select->group_by_with_cube = true;
break;
case ModifierType::ROLLUP:
old_select->group_by_with_rollup = true;
break;
}
if (has(WITH)) old_select->setExpression(ASTSelectQuery::Expression::WITH, get(WITH)->convertToOld());
if (has(FROM)) old_select->setExpression(ASTSelectQuery::Expression::TABLES, get(FROM)->convertToOld());
if (has(ARRAY_JOIN)) old_select->tables()->children.push_back(get(ARRAY_JOIN)->convertToOld());
if (has(PREWHERE)) old_select->setExpression(ASTSelectQuery::Expression::PREWHERE, get(PREWHERE)->convertToOld());
if (has(WHERE)) old_select->setExpression(ASTSelectQuery::Expression::WHERE, get(WHERE)->convertToOld());
if (has(GROUP_BY)) old_select->setExpression(ASTSelectQuery::Expression::GROUP_BY, get(GROUP_BY)->convertToOld());
if (has(HAVING)) old_select->setExpression(ASTSelectQuery::Expression::HAVING, get(HAVING)->convertToOld());
if (has(ORDER_BY)) old_select->setExpression(ASTSelectQuery::Expression::ORDER_BY, get(ORDER_BY)->convertToOld());
if (has(LIMIT_BY))
{
auto old_list = get(LIMIT_BY)->convertToOld();
old_select->setExpression(ASTSelectQuery::Expression::LIMIT_BY, std::move(old_list->children[1]));
old_select->setExpression(ASTSelectQuery::Expression::LIMIT_BY_LENGTH, std::move(old_list->children[0]->children[0]));
if (old_list->children[0]->children.size() > 1)
old_select->setExpression(ASTSelectQuery::Expression::LIMIT_BY_OFFSET, std::move(old_list->children[0]->children[1]));
}
if (has(LIMIT))
{
auto old_list = get(LIMIT)->convertToOld();
old_select->limit_with_ties = get<LimitClause>(LIMIT)->with_ties;
old_select->setExpression(ASTSelectQuery::Expression::LIMIT_LENGTH, std::move(old_list->children[0]));
if (old_list->children.size() > 1)
old_select->setExpression(ASTSelectQuery::Expression::LIMIT_OFFSET, std::move(old_list->children[1]));
}
if (has(SETTINGS)) old_select->setExpression(ASTSelectQuery::Expression::SETTINGS, get(SETTINGS)->convertToOld());
return old_select;
}
SelectUnionQuery::SelectUnionQuery(PtrTo<List<SelectStmt>> stmts) : Query{stmts}
{
}
void SelectUnionQuery::appendSelect(PtrTo<SelectStmt> stmt)
{
if (!has(STMTS)) push(std::make_shared<List<SelectStmt>>());
get<List<SelectStmt>>(STMTS)->push(stmt);
}
void SelectUnionQuery::appendSelect(PtrTo<SelectUnionQuery> query)
{
for (const auto & stmt : query->get(STMTS)->as<List<SelectStmt> &>())
appendSelect(std::static_pointer_cast<SelectStmt>(stmt));
}
ASTPtr SelectUnionQuery::convertToOld() const
{
auto query = std::make_shared<ASTSelectWithUnionQuery>();
query->list_of_selects = std::make_shared<ASTExpressionList>();
query->children.push_back(query->list_of_selects);
for (const auto & select : get(STMTS)->as<List<SelectStmt> &>())
query->list_of_selects->children.push_back(select->convertToOld());
// TODO(ilezhankin): need to parse new UNION DISTINCT
query->list_of_modes
= ASTSelectWithUnionQuery::UnionModes(query->list_of_selects->children.size() - 1, ASTSelectWithUnionQuery::Mode::ALL);
convertToOldPartially(query);
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitWithClause(ClickHouseParser::WithClauseContext *ctx)
{
return std::make_shared<WithClause>(visit(ctx->columnExprList()).as<PtrTo<ColumnExprList>>());
}
antlrcpp::Any ParseTreeVisitor::visitTopClause(ClickHouseParser::TopClauseContext *ctx)
{
auto limit = std::make_shared<LimitExpr>(ColumnExpr::createLiteral(Literal::createNumber(ctx->DECIMAL_LITERAL())));
return std::make_shared<LimitClause>(!!ctx->WITH(), limit);
}
antlrcpp::Any ParseTreeVisitor::visitFromClause(ClickHouseParser::FromClauseContext *ctx)
{
return std::make_shared<FromClause>(visit(ctx->joinExpr()).as<PtrTo<JoinExpr>>());
}
antlrcpp::Any ParseTreeVisitor::visitArrayJoinClause(ClickHouseParser::ArrayJoinClauseContext *ctx)
{
return std::make_shared<ArrayJoinClause>(visit(ctx->columnExprList()), !!ctx->LEFT());
}
antlrcpp::Any ParseTreeVisitor::visitPrewhereClause(ClickHouseParser::PrewhereClauseContext *ctx)
{
return std::make_shared<PrewhereClause>(visit(ctx->columnExpr()).as<PtrTo<ColumnExpr>>());
}
antlrcpp::Any ParseTreeVisitor::visitWhereClause(ClickHouseParser::WhereClauseContext *ctx)
{
return std::make_shared<WhereClause>(visit(ctx->columnExpr()).as<PtrTo<ColumnExpr>>());
}
antlrcpp::Any ParseTreeVisitor::visitGroupByClause(ClickHouseParser::GroupByClauseContext *ctx)
{
return std::make_shared<GroupByClause>(visit(ctx->columnExprList()).as<PtrTo<ColumnExprList>>());
}
antlrcpp::Any ParseTreeVisitor::visitHavingClause(ClickHouseParser::HavingClauseContext *ctx)
{
return std::make_shared<HavingClause>(visit(ctx->columnExpr()).as<PtrTo<ColumnExpr>>());
}
antlrcpp::Any ParseTreeVisitor::visitOrderByClause(ClickHouseParser::OrderByClauseContext *ctx)
{
return std::make_shared<OrderByClause>(visit(ctx->orderExprList()).as<PtrTo<OrderExprList>>());
}
antlrcpp::Any ParseTreeVisitor::visitProjectionOrderByClause(ClickHouseParser::ProjectionOrderByClauseContext *ctx)
{
return std::make_shared<ProjectionOrderByClause>(visit(ctx->columnExprList()).as<PtrTo<ColumnExprList>>());
}
antlrcpp::Any ParseTreeVisitor::visitLimitByClause(ClickHouseParser::LimitByClauseContext *ctx)
{
return std::make_shared<LimitByClause>(visit(ctx->limitExpr()), visit(ctx->columnExprList()));
}
antlrcpp::Any ParseTreeVisitor::visitLimitClause(ClickHouseParser::LimitClauseContext *ctx)
{
return std::make_shared<LimitClause>(!!ctx->WITH(), visit(ctx->limitExpr()).as<PtrTo<LimitExpr>>());
}
antlrcpp::Any ParseTreeVisitor::visitSettingsClause(ClickHouseParser::SettingsClauseContext *ctx)
{
return std::make_shared<SettingsClause>(visit(ctx->settingExprList()).as<PtrTo<SettingExprList>>());
}
antlrcpp::Any ParseTreeVisitor::visitProjectionSelectStmt(ClickHouseParser::ProjectionSelectStmtContext *ctx)
{
PtrTo<ColumnExprList> column_list = visit(ctx->columnExprList());
auto select_stmt = std::make_shared<ProjectionSelectStmt>(column_list);
if (ctx->withClause()) select_stmt->setWithClause(visit(ctx->withClause()));
if (ctx->groupByClause()) select_stmt->setGroupByClause(visit(ctx->groupByClause()));
if (ctx->projectionOrderByClause()) select_stmt->setOrderByClause(visit(ctx->projectionOrderByClause()));
return select_stmt;
}
antlrcpp::Any ParseTreeVisitor::visitSelectStmt(ClickHouseParser::SelectStmtContext *ctx)
{
SelectStmt::ModifierType type = SelectStmt::ModifierType::NONE;
if (ctx->CUBE() || (ctx->groupByClause() && ctx->groupByClause()->CUBE())) type = SelectStmt::ModifierType::CUBE;
else if (ctx->ROLLUP() || (ctx->groupByClause() && ctx->groupByClause()->ROLLUP())) type = SelectStmt::ModifierType::ROLLUP;
auto select_stmt = std::make_shared<SelectStmt>(!!ctx->DISTINCT(), type, !!ctx->TOTALS(), visit(ctx->columnExprList()));
if (ctx->topClause() && ctx->limitClause())
throw Exception("Can not use TOP and LIMIT together", ErrorCodes::TOP_AND_LIMIT_TOGETHER);
if (ctx->withClause()) select_stmt->setWithClause(visit(ctx->withClause()));
if (ctx->topClause()) select_stmt->setLimitClause(visit(ctx->topClause()));
if (ctx->fromClause()) select_stmt->setFromClause(visit(ctx->fromClause()));
if (ctx->arrayJoinClause()) select_stmt->setArrayJoinClause(visit(ctx->arrayJoinClause()));
if (ctx->prewhereClause()) select_stmt->setPrewhereClause(visit(ctx->prewhereClause()));
if (ctx->whereClause()) select_stmt->setWhereClause(visit(ctx->whereClause()));
if (ctx->groupByClause()) select_stmt->setGroupByClause(visit(ctx->groupByClause()));
if (ctx->havingClause()) select_stmt->setHavingClause(visit(ctx->havingClause()));
if (ctx->orderByClause()) select_stmt->setOrderByClause(visit(ctx->orderByClause()));
if (ctx->limitByClause()) select_stmt->setLimitByClause(visit(ctx->limitByClause()));
if (ctx->limitClause()) select_stmt->setLimitClause(visit(ctx->limitClause()));
if (ctx->settingsClause()) select_stmt->setSettingsClause(visit(ctx->settingsClause()));
return select_stmt;
}
antlrcpp::Any ParseTreeVisitor::visitSelectStmtWithParens(ClickHouseParser::SelectStmtWithParensContext *ctx)
{
PtrTo<SelectUnionQuery> query;
if (ctx->selectStmt())
{
query = std::make_shared<SelectUnionQuery>();
query->appendSelect(visit(ctx->selectStmt()).as<PtrTo<SelectStmt>>());
}
else if (ctx->selectUnionStmt())
{
query = visit(ctx->selectUnionStmt());
}
return query;
}
antlrcpp::Any ParseTreeVisitor::visitSelectUnionStmt(ClickHouseParser::SelectUnionStmtContext *ctx)
{
auto select_union_query = std::make_shared<SelectUnionQuery>();
for (auto * stmt : ctx->selectStmtWithParens()) select_union_query->appendSelect(visit(stmt).as<PtrTo<SelectUnionQuery>>());
return select_union_query;
}
}

View File

@ -1,193 +0,0 @@
#pragma once
#include <Parsers/New/AST/Query.h>
#include <Core/Types.h>
#include <list>
namespace DB::AST
{
// Clauses
using WithClause = SimpleClause<ColumnExprList>;
class FromClause : public INode
{
public:
explicit FromClause(PtrTo<JoinExpr> join_expr);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
EXPR = 0, // JoinExpr
};
};
class ArrayJoinClause : public INode
{
public:
ArrayJoinClause(PtrTo<ColumnExprList> expr_list, bool left);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
EXPRS = 0, // ColumnExprList
};
const bool left;
};
using PrewhereClause = SimpleClause<ColumnExpr>;
using GroupByClause = SimpleClause<ColumnExprList>;
using HavingClause = SimpleClause<ColumnExpr>;
class LimitByClause : public INode
{
public:
LimitByClause(PtrTo<LimitExpr> expr, PtrTo<ColumnExprList> expr_list);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
LIMIT = 0, // LimitExpr
EXPRS = 1, // ColumnExprList
};
};
class LimitClause : public INode
{
public:
LimitClause(bool with_ties, PtrTo<LimitExpr> expr);
ASTPtr convertToOld() const override;
const bool with_ties; // FIXME: bad interface, because old AST stores this inside ASTSelectQuery.
private:
enum ChildIndex : UInt8
{
EXPR = 0, // LimitExpr
};
};
class SettingsClause : public INode
{
public:
explicit SettingsClause(PtrTo<SettingExprList> expr_list);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
EXPRS = 0, // SettingExprList
};
};
// Statement
class ProjectionSelectStmt : public INode
{
public:
ProjectionSelectStmt(PtrTo<ColumnExprList> expr_list);
void setWithClause(PtrTo<WithClause> clause);
void setGroupByClause(PtrTo<GroupByClause> clause);
void setOrderByClause(PtrTo<ProjectionOrderByClause> clause);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
COLUMNS = 0, // ColumnExprList
WITH, // WithClause (optional)
GROUP_BY, // GroupByClause (optional)
ORDER_BY, // OrderByClause (optional)
MAX_INDEX,
};
};
class SelectStmt : public INode
{
public:
enum class ModifierType
{
NONE,
CUBE,
ROLLUP,
};
SelectStmt(bool distinct_, ModifierType type, bool totals, PtrTo<ColumnExprList> expr_list);
void setWithClause(PtrTo<WithClause> clause);
void setFromClause(PtrTo<FromClause> clause);
void setArrayJoinClause(PtrTo<ArrayJoinClause> clause);
void setPrewhereClause(PtrTo<PrewhereClause> clause);
void setWhereClause(PtrTo<WhereClause> clause);
void setGroupByClause(PtrTo<GroupByClause> clause);
void setHavingClause(PtrTo<HavingClause> clause);
void setOrderByClause(PtrTo<OrderByClause> clause);
void setLimitByClause(PtrTo<LimitByClause> clause);
void setLimitClause(PtrTo<LimitClause> clause);
void setSettingsClause(PtrTo<SettingsClause> clause);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
COLUMNS = 0, // ColumnExprList
WITH, // WithClause (optional)
FROM, // FromClause (optional)
ARRAY_JOIN, // ArrayJoinClause (optional)
PREWHERE, // PrewhereClause (optional)
WHERE, // WhereClause (optional)
GROUP_BY, // GroupByClause (optional)
HAVING, // HavingClause (optional)
ORDER_BY, // OrderByClause (optional)
LIMIT_BY, // LimitByClause (optional)
LIMIT, // LimitClause (optional)
SETTINGS, // SettingsClause (optional)
MAX_INDEX,
};
const ModifierType modifier_type;
const bool distinct, with_totals;
};
class SelectUnionQuery : public Query
{
public:
SelectUnionQuery() = default;
explicit SelectUnionQuery(PtrTo<List<SelectStmt>> stmts);
void appendSelect(PtrTo<SelectStmt> stmt);
void appendSelect(PtrTo<SelectUnionQuery> query);
void shouldBeScalar() { is_scalar = true; }
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
STMTS = 0, // List<SelectStmt>
};
bool is_scalar = false;
};
}

View File

@ -1,43 +0,0 @@
#include <Parsers/New/AST/SetQuery.h>
#include <Parsers/ASTLiteral.h>
#include <Parsers/ASTSetQuery.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/AST/SettingExpr.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
SetQuery::SetQuery(PtrTo<SettingExprList> list) : Query{list}
{
}
ASTPtr SetQuery::convertToOld() const
{
auto expr = std::make_shared<ASTSetQuery>();
for (const auto & child : get(EXPRS)->as<SettingExprList &>())
{
const auto * setting = child->as<SettingExpr>();
expr->changes.emplace_back(setting->getName()->getName(), setting->getValue()->convertToOld()->as<ASTLiteral>()->value);
}
return expr;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitSetStmt(ClickHouseParser::SetStmtContext *ctx)
{
return std::make_shared<SetQuery>(visit(ctx->settingExprList()).as<PtrTo<SettingExprList>>());
}
}

View File

@ -1,23 +0,0 @@
#pragma once
#include <Parsers/New/AST/Query.h>
namespace DB::AST
{
class SetQuery : public Query
{
public:
explicit SetQuery(PtrTo<SettingExprList> list);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
EXPRS = 0, // SettingExprList
};
};
}

View File

@ -1,33 +0,0 @@
#include <Parsers/New/AST/SettingExpr.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
SettingExpr::SettingExpr(PtrTo<Identifier> name, PtrTo<Literal> value) : INode{name, value}
{
}
}
namespace DB
{
antlrcpp::Any ParseTreeVisitor::visitSettingExprList(ClickHouseParser::SettingExprListContext *ctx)
{
auto expr_list = std::make_shared<AST::SettingExprList>();
for (auto* expr : ctx->settingExpr()) expr_list->push(visit(expr));
return expr_list;
}
antlrcpp::Any ParseTreeVisitor::visitSettingExpr(ClickHouseParser::SettingExprContext *ctx)
{
return std::make_shared<AST::SettingExpr>(visit(ctx->identifier()), visit(ctx->literal()));
}
}

View File

@ -1,25 +0,0 @@
#pragma once
#include <Parsers/New/AST/INode.h>
namespace DB::AST
{
class SettingExpr : public INode
{
public:
SettingExpr(PtrTo<Identifier> name, PtrTo<Literal> value);
auto getName() const { return std::static_pointer_cast<Identifier>(get(NAME)); }
auto getValue() const { return std::static_pointer_cast<Literal>(get(VALUE)); }
private:
enum ChildIndex : UInt8
{
NAME = 0,
VALUE = 1,
};
};
}

View File

@ -1,96 +0,0 @@
#include <Parsers/New/AST/ShowCreateQuery.h>
#include <Interpreters/StorageID.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/ParseTreeVisitor.h>
#include <Parsers/TablePropertiesQueriesASTs.h>
namespace DB::AST
{
// static
PtrTo<ShowCreateQuery> ShowCreateQuery::createDatabase(PtrTo<DatabaseIdentifier> identifier)
{
return PtrTo<ShowCreateQuery>(new ShowCreateQuery(QueryType::DATABASE, {identifier}));
}
// static
PtrTo<ShowCreateQuery> ShowCreateQuery::createDictionary(PtrTo<TableIdentifier> identifier)
{
return PtrTo<ShowCreateQuery>(new ShowCreateQuery(QueryType::DICTIONARY, {identifier}));
}
// static
PtrTo<ShowCreateQuery> ShowCreateQuery::createTable(bool temporary, PtrTo<TableIdentifier> identifier)
{
PtrTo<ShowCreateQuery> query(new ShowCreateQuery(QueryType::TABLE, {identifier}));
query->temporary = temporary;
return query;
}
ShowCreateQuery::ShowCreateQuery(QueryType type, PtrList exprs) : Query(exprs), query_type(type)
{
}
ASTPtr ShowCreateQuery::convertToOld() const
{
switch(query_type)
{
case QueryType::DATABASE:
{
auto query = std::make_shared<ASTShowCreateDatabaseQuery>();
query->database = get<DatabaseIdentifier>(IDENTIFIER)->getName();
return query;
}
case QueryType::DICTIONARY:
{
auto query = std::make_shared<ASTShowCreateDictionaryQuery>();
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(IDENTIFIER)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->shortName();
query->uuid = table->uuid;
return query;
}
case QueryType::TABLE:
{
auto query = std::make_shared<ASTShowCreateTableQuery>();
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(IDENTIFIER)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->shortName();
query->uuid = table->uuid;
query->temporary = temporary;
return query;
}
}
__builtin_unreachable();
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitShowCreateDatabaseStmt(ClickHouseParser::ShowCreateDatabaseStmtContext *ctx)
{
return ShowCreateQuery::createDatabase(visit(ctx->databaseIdentifier()));
}
antlrcpp::Any ParseTreeVisitor::visitShowCreateDictionaryStmt(ClickHouseParser::ShowCreateDictionaryStmtContext * ctx)
{
return ShowCreateQuery::createDictionary(visit(ctx->tableIdentifier()));
}
antlrcpp::Any ParseTreeVisitor::visitShowCreateTableStmt(ClickHouseParser::ShowCreateTableStmtContext *ctx)
{
return ShowCreateQuery::createTable(!!ctx->TEMPORARY(), visit(ctx->tableIdentifier()));
}
}

View File

@ -1,36 +0,0 @@
#pragma once
#include <Parsers/New/AST/Query.h>
namespace DB::AST
{
class ShowCreateQuery : public Query
{
public:
static PtrTo<ShowCreateQuery> createDatabase(PtrTo<DatabaseIdentifier> identifier);
static PtrTo<ShowCreateQuery> createDictionary(PtrTo<TableIdentifier> identifier);
static PtrTo<ShowCreateQuery> createTable(bool temporary, PtrTo<TableIdentifier> identifier);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
IDENTIFIER = 0, // DatabaseIdentifier or TableIdentifier
};
enum class QueryType
{
DATABASE,
DICTIONARY,
TABLE,
};
QueryType query_type;
bool temporary = false;
ShowCreateQuery(QueryType type, PtrList exprs);
};
}

View File

@ -1,49 +0,0 @@
#include <Parsers/New/AST/ShowQuery.h>
#include <Parsers/ASTShowTablesQuery.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
// static
PtrTo<ShowQuery> ShowQuery::createDictionaries(PtrTo<DatabaseIdentifier> from)
{
return PtrTo<ShowQuery>(new ShowQuery(QueryType::DICTIONARIES, {from}));
}
ShowQuery::ShowQuery(QueryType type, PtrList exprs) : Query(exprs), query_type(type)
{
}
ASTPtr ShowQuery::convertToOld() const
{
auto query = std::make_shared<ASTShowTablesQuery>();
switch(query_type)
{
case QueryType::DICTIONARIES:
query->dictionaries = true;
if (has(FROM)) query->from = get<DatabaseIdentifier>(FROM)->getQualifiedName();
break;
}
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitShowDictionariesStmt(ClickHouseParser::ShowDictionariesStmtContext *ctx)
{
auto from = ctx->databaseIdentifier() ? visit(ctx->databaseIdentifier()).as<PtrTo<DatabaseIdentifier>>() : nullptr;
return ShowQuery::createDictionaries(from);
}
}

View File

@ -1,32 +0,0 @@
#pragma once
#include <Parsers/New/AST/Query.h>
namespace DB::AST
{
class ShowQuery : public Query
{
public:
static PtrTo<ShowQuery> createDictionaries(PtrTo<DatabaseIdentifier> from);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
FROM = 0, // DatabaseIdentifier (optional)
};
enum class QueryType
{
DICTIONARIES,
};
const QueryType query_type;
ShowQuery(QueryType type, PtrList exprs);
};
}

View File

@ -1,191 +0,0 @@
#include <Parsers/New/AST/SystemQuery.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTSystemQuery.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/ParseTreeVisitor.h>
#include <Interpreters/StorageID.h>
namespace DB::AST
{
// static
PtrTo<SystemQuery> SystemQuery::createDistributedSends(bool stop, PtrTo<TableIdentifier> identifier)
{
PtrTo<SystemQuery> query(new SystemQuery(QueryType::DISTRIBUTED_SENDS, {identifier}));
query->stop = stop;
return query;
}
// static
PtrTo<SystemQuery> SystemQuery::createFetches(bool stop, PtrTo<TableIdentifier> identifier)
{
PtrTo<SystemQuery> query(new SystemQuery(QueryType::FETCHES, {identifier}));
query->stop = stop;
return query;
}
// static
PtrTo<SystemQuery> SystemQuery::createFlushDistributed(PtrTo<TableIdentifier> identifier)
{
return PtrTo<SystemQuery>(new SystemQuery(QueryType::FLUSH_DISTRIBUTED, {identifier}));
}
// static
PtrTo<SystemQuery> SystemQuery::createFlushLogs()
{
return PtrTo<SystemQuery>(new SystemQuery(QueryType::FLUSH_LOGS, {}));
}
// static
PtrTo<SystemQuery> SystemQuery::createMerges(bool stop, PtrTo<TableIdentifier> identifier)
{
PtrTo<SystemQuery> query(new SystemQuery(QueryType::MERGES, {identifier}));
query->stop = stop;
return query;
}
// static
PtrTo<SystemQuery> SystemQuery::createReloadDictionaries()
{
return PtrTo<SystemQuery>(new SystemQuery(QueryType::RELOAD_DICTIONARIES, {}));
}
// static
PtrTo<SystemQuery> SystemQuery::createReloadDictionary(PtrTo<TableIdentifier> identifier)
{
return PtrTo<SystemQuery>(new SystemQuery(QueryType::RELOAD_DICTIONARY, {identifier}));
}
// static
PtrTo<SystemQuery> SystemQuery::createReplicatedSends(bool stop)
{
PtrTo<SystemQuery> query(new SystemQuery(QueryType::REPLICATED_SENDS, {}));
query->stop = stop;
return query;
}
// static
PtrTo<SystemQuery> SystemQuery::createSyncReplica(PtrTo<TableIdentifier> identifier)
{
return PtrTo<SystemQuery>(new SystemQuery(QueryType::SYNC_REPLICA, {identifier}));
}
// static
PtrTo<SystemQuery> SystemQuery::createTTLMerges(bool stop, PtrTo<TableIdentifier> identifier)
{
PtrTo<SystemQuery> query(new SystemQuery(QueryType::TTL_MERGES, {identifier}));
query->stop = stop;
return query;
}
SystemQuery::SystemQuery(QueryType type, PtrList exprs) : Query(exprs), query_type(type)
{
}
ASTPtr SystemQuery::convertToOld() const
{
auto query = std::make_shared<ASTSystemQuery>();
switch(query_type)
{
case QueryType::DISTRIBUTED_SENDS:
query->type = stop ? ASTSystemQuery::Type::STOP_DISTRIBUTED_SENDS : ASTSystemQuery::Type::START_DISTRIBUTED_SENDS;
{
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(TABLE)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->shortName();
}
break;
case QueryType::FETCHES:
query->type = stop ? ASTSystemQuery::Type::STOP_FETCHES : ASTSystemQuery::Type::START_FETCHES;
{
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(TABLE)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->shortName();
}
break;
case QueryType::FLUSH_DISTRIBUTED:
query->type = ASTSystemQuery::Type::FLUSH_DISTRIBUTED;
{
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(TABLE)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->shortName();
}
break;
case QueryType::FLUSH_LOGS:
query->type = ASTSystemQuery::Type::FLUSH_LOGS;
break;
case QueryType::MERGES:
query->type = stop ? ASTSystemQuery::Type::STOP_MERGES : ASTSystemQuery::Type::START_MERGES;
{
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(TABLE)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->shortName();
}
break;
case QueryType::RELOAD_DICTIONARIES:
query->type = ASTSystemQuery::Type::RELOAD_DICTIONARIES;
break;
case QueryType::RELOAD_DICTIONARY:
query->type = ASTSystemQuery::Type::RELOAD_DICTIONARY;
{
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(TABLE)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->getTableId().table_name;
}
break;
case QueryType::REPLICATED_SENDS:
query->type = stop ? ASTSystemQuery::Type::STOP_REPLICATED_SENDS : ASTSystemQuery::Type::START_REPLICATED_SENDS;
break;
case QueryType::SYNC_REPLICA:
query->type = ASTSystemQuery::Type::SYNC_REPLICA;
{
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(TABLE)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->shortName();
}
break;
case QueryType::TTL_MERGES:
query->type = stop ? ASTSystemQuery::Type::STOP_TTL_MERGES : ASTSystemQuery::Type::START_TTL_MERGES;
{
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(TABLE)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->shortName();
}
break;
}
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitSystemStmt(ClickHouseParser::SystemStmtContext *ctx)
{
if (ctx->FLUSH() && ctx->DISTRIBUTED()) return SystemQuery::createFlushDistributed(visit(ctx->tableIdentifier()));
if (ctx->FLUSH() && ctx->LOGS()) return SystemQuery::createFlushLogs();
if (ctx->DISTRIBUTED() && ctx->SENDS()) return SystemQuery::createDistributedSends(!!ctx->STOP(), visit(ctx->tableIdentifier()));
if (ctx->FETCHES()) return SystemQuery::createFetches(!!ctx->STOP(), visit(ctx->tableIdentifier()));
if (ctx->MERGES())
{
if (ctx->TTL()) return SystemQuery::createTTLMerges(!!ctx->STOP(), visit(ctx->tableIdentifier()));
else return SystemQuery::createMerges(!!ctx->STOP(), visit(ctx->tableIdentifier()));
}
if (ctx->RELOAD())
{
if (ctx->DICTIONARIES()) return SystemQuery::createReloadDictionaries();
if (ctx->DICTIONARY()) return SystemQuery::createReloadDictionary(visit(ctx->tableIdentifier()));
}
if (ctx->REPLICATED() && ctx->SENDS()) return SystemQuery::createReplicatedSends(!!ctx->STOP());
if (ctx->SYNC() && ctx->REPLICA()) return SystemQuery::createSyncReplica(visit(ctx->tableIdentifier()));
__builtin_unreachable();
}
}

View File

@ -1,50 +0,0 @@
#pragma once
#include <Parsers/New/AST/Query.h>
namespace DB::AST
{
class SystemQuery : public Query
{
public:
static PtrTo<SystemQuery> createDistributedSends(bool stop, PtrTo<TableIdentifier> identifier);
static PtrTo<SystemQuery> createFetches(bool stop, PtrTo<TableIdentifier> identifier);
static PtrTo<SystemQuery> createFlushDistributed(PtrTo<TableIdentifier> identifier);
static PtrTo<SystemQuery> createFlushLogs();
static PtrTo<SystemQuery> createMerges(bool stop, PtrTo<TableIdentifier> identifier);
static PtrTo<SystemQuery> createReloadDictionaries();
static PtrTo<SystemQuery> createReloadDictionary(PtrTo<TableIdentifier> identifier);
static PtrTo<SystemQuery> createReplicatedSends(bool stop);
static PtrTo<SystemQuery> createSyncReplica(PtrTo<TableIdentifier> identifier);
static PtrTo<SystemQuery> createTTLMerges(bool stop, PtrTo<TableIdentifier> identifier);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
TABLE = 0,
};
enum class QueryType
{
DISTRIBUTED_SENDS,
FETCHES,
FLUSH_DISTRIBUTED,
FLUSH_LOGS,
MERGES,
RELOAD_DICTIONARIES,
RELOAD_DICTIONARY,
REPLICATED_SENDS,
SYNC_REPLICA,
TTL_MERGES,
};
QueryType query_type;
bool stop = false;
SystemQuery(QueryType type, PtrList exprs);
};
}

View File

@ -1,264 +0,0 @@
#include <Parsers/New/AST/TableElementExpr.h>
#include <Parsers/ASTColumnDeclaration.h>
#include <Parsers/ASTConstraintDeclaration.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTIndexDeclaration.h>
#include <Parsers/ASTProjectionDeclaration.h>
#include <Parsers/New/AST/ColumnExpr.h>
#include <Parsers/New/AST/ColumnTypeExpr.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/AST/SelectUnionQuery.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
CodecArgExpr::CodecArgExpr(PtrTo<Identifier> identifier, PtrTo<ColumnExprList> list) : INode{identifier, list}
{
}
ASTPtr CodecArgExpr::convertToOld() const
{
auto func = std::make_shared<ASTFunction>();
func->name = get<Identifier>(NAME)->getName();
if (has(ARGS))
{
func->arguments = get(ARGS)->convertToOld();
func->children.push_back(func->arguments);
}
return func;
}
CodecExpr::CodecExpr(PtrTo<CodecArgList> list) : INode{list}
{
}
ASTPtr CodecExpr::convertToOld() const
{
auto func = std::make_shared<ASTFunction>();
func->name = "codec";
func->arguments = get(ARGS)->convertToOld();
func->children.push_back(func->arguments);
return func;
}
TableColumnPropertyExpr::TableColumnPropertyExpr(PropertyType type, PtrTo<ColumnExpr> expr) : INode{expr}, property_type(type)
{
}
ASTPtr TableColumnPropertyExpr::convertToOld() const
{
return get(EXPR)->convertToOld();
}
// static
PtrTo<TableElementExpr> TableElementExpr::createColumn(
PtrTo<Identifier> name,
PtrTo<ColumnTypeExpr> type,
PtrTo<TableColumnPropertyExpr> property,
PtrTo<StringLiteral> comment,
PtrTo<CodecExpr> codec,
PtrTo<ColumnExpr> ttl)
{
return PtrTo<TableElementExpr>(new TableElementExpr(ExprType::COLUMN, {name, type, property, comment, codec, ttl}));
}
// static
PtrTo<TableElementExpr> TableElementExpr::createConstraint(PtrTo<Identifier> identifier, PtrTo<ColumnExpr> expr)
{
return PtrTo<TableElementExpr>(new TableElementExpr(ExprType::CONSTRAINT, {identifier, expr}));
}
// static
PtrTo<TableElementExpr>
TableElementExpr::createIndex(PtrTo<Identifier> name, PtrTo<ColumnExpr> expr, PtrTo<ColumnTypeExpr> type, PtrTo<NumberLiteral> granularity)
{
return PtrTo<TableElementExpr>(new TableElementExpr(ExprType::INDEX, {name, expr, type, granularity}));
}
// static
PtrTo<TableElementExpr>
TableElementExpr::createProjection(PtrTo<Identifier> name, PtrTo<ProjectionSelectStmt> query)
{
return PtrTo<TableElementExpr>(new TableElementExpr(ExprType::PROJECTION, {name, query}));
}
TableElementExpr::TableElementExpr(ExprType type, PtrList exprs) : INode(exprs), expr_type(type)
{
}
ASTPtr TableElementExpr::convertToOld() const
{
switch(expr_type)
{
case ExprType::COLUMN:
{
auto expr = std::make_shared<ASTColumnDeclaration>();
expr->name = get<Identifier>(NAME)->getName(); // FIXME: do we have correct nested identifier here already?
if (has(TYPE))
{
expr->type = get(TYPE)->convertToOld();
expr->children.push_back(expr->type);
}
if (has(PROPERTY))
{
switch(get<TableColumnPropertyExpr>(PROPERTY)->getType())
{
case TableColumnPropertyExpr::PropertyType::ALIAS:
expr->default_specifier = "ALIAS";
break;
case TableColumnPropertyExpr::PropertyType::DEFAULT:
expr->default_specifier = "DEFAULT";
break;
case TableColumnPropertyExpr::PropertyType::MATERIALIZED:
expr->default_specifier = "MATERIALIZED";
break;
}
expr->default_expression = get(PROPERTY)->convertToOld();
expr->children.push_back(expr->default_expression);
}
if (has(COMMENT))
{
expr->comment = get(COMMENT)->convertToOld();
expr->children.push_back(expr->comment);
}
if (has(CODEC))
{
expr->codec = get(CODEC)->convertToOld();
expr->children.push_back(expr->codec);
}
if (has(TTL))
{
expr->ttl = get(TTL)->convertToOld();
expr->children.push_back(expr->ttl);
}
return expr;
}
case ExprType::CONSTRAINT:
{
auto expr = std::make_shared<ASTConstraintDeclaration>();
expr->name = get<Identifier>(NAME)->getName();
expr->set(expr->expr, get(EXPR)->convertToOld());
return expr;
}
case ExprType::INDEX:
{
auto expr = std::make_shared<ASTIndexDeclaration>();
expr->name = get<Identifier>(NAME)->getName();
expr->set(expr->expr, get(EXPR)->convertToOld());
expr->set(expr->type, get(INDEX_TYPE)->convertToOld());
expr->granularity = get<NumberLiteral>(GRANULARITY)->as<UInt64>().value_or(0); // FIXME: throw exception instead of default.
return expr;
}
case ExprType::PROJECTION:
{
auto expr = std::make_shared<ASTProjectionDeclaration>();
expr->name = get<Identifier>(NAME)->getName();
expr->set(expr->query, get(QUERY)->convertToOld());
return expr;
}
}
__builtin_unreachable();
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitCodecArgExpr(ClickHouseParser::CodecArgExprContext *ctx)
{
auto list = ctx->columnExprList() ? visit(ctx->columnExprList()).as<PtrTo<ColumnExprList>>() : nullptr;
return std::make_shared<CodecArgExpr>(visit(ctx->identifier()), list);
}
antlrcpp::Any ParseTreeVisitor::visitCodecExpr(ClickHouseParser::CodecExprContext *ctx)
{
auto list = std::make_shared<CodecArgList>();
for (auto * arg : ctx->codecArgExpr()) list->push(visit(arg));
return std::make_shared<CodecExpr>(list);
}
antlrcpp::Any ParseTreeVisitor::visitTableColumnDfnt(ClickHouseParser::TableColumnDfntContext *ctx)
{
PtrTo<TableColumnPropertyExpr> property;
PtrTo<ColumnTypeExpr> type;
PtrTo<StringLiteral> comment;
PtrTo<CodecExpr> codec;
PtrTo<ColumnExpr> ttl;
if (ctx->tableColumnPropertyExpr()) property = visit(ctx->tableColumnPropertyExpr());
if (ctx->columnTypeExpr()) type = visit(ctx->columnTypeExpr());
if (ctx->STRING_LITERAL()) comment = Literal::createString(ctx->STRING_LITERAL());
if (ctx->codecExpr()) codec = visit(ctx->codecExpr());
if (ctx->TTL()) ttl = visit(ctx->columnExpr());
return TableElementExpr::createColumn(visit(ctx->nestedIdentifier()), type, property, comment, codec, ttl);
}
antlrcpp::Any ParseTreeVisitor::visitTableColumnPropertyExpr(ClickHouseParser::TableColumnPropertyExprContext *ctx)
{
TableColumnPropertyExpr::PropertyType type;
if (ctx->DEFAULT()) type = TableColumnPropertyExpr::PropertyType::DEFAULT;
else if (ctx->MATERIALIZED()) type = TableColumnPropertyExpr::PropertyType::MATERIALIZED;
else if (ctx->ALIAS()) type = TableColumnPropertyExpr::PropertyType::ALIAS;
else __builtin_unreachable();
return std::make_shared<TableColumnPropertyExpr>(type, visit(ctx->columnExpr()));
}
antlrcpp::Any ParseTreeVisitor::visitTableElementExprColumn(ClickHouseParser::TableElementExprColumnContext *ctx)
{
return visit(ctx->tableColumnDfnt());
}
antlrcpp::Any ParseTreeVisitor::visitTableElementExprConstraint(ClickHouseParser::TableElementExprConstraintContext *ctx)
{
return TableElementExpr::createConstraint(visit(ctx->identifier()), visit(ctx->columnExpr()));
}
antlrcpp::Any ParseTreeVisitor::visitTableElementExprIndex(ClickHouseParser::TableElementExprIndexContext *ctx)
{
return visit(ctx->tableIndexDfnt());
}
antlrcpp::Any ParseTreeVisitor::visitTableElementExprProjection(ClickHouseParser::TableElementExprProjectionContext *ctx)
{
return visit(ctx->tableProjectionDfnt());
}
antlrcpp::Any ParseTreeVisitor::visitTableIndexDfnt(ClickHouseParser::TableIndexDfntContext *ctx)
{
return TableElementExpr::createIndex(
visit(ctx->nestedIdentifier()),
visit(ctx->columnExpr()),
visit(ctx->columnTypeExpr()),
Literal::createNumber(ctx->DECIMAL_LITERAL()));
}
antlrcpp::Any ParseTreeVisitor::visitTableProjectionDfnt(ClickHouseParser::TableProjectionDfntContext *ctx)
{
return TableElementExpr::createProjection(
visit(ctx->nestedIdentifier()),
visit(ctx->projectionSelectStmt()));
}
}

View File

@ -1,123 +0,0 @@
#pragma once
#include <Parsers/New/AST/INode.h>
namespace DB::AST
{
class CodecArgExpr : public INode
{
public:
CodecArgExpr(PtrTo<Identifier> identifier, PtrTo<ColumnExprList> list);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // Identifier
ARGS = 1, // ColumnExprList (optional)
};
};
class CodecExpr : public INode
{
public:
explicit CodecExpr(PtrTo<CodecArgList> list);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
ARGS = 0, // CodecArgList
};
};
class TableColumnPropertyExpr : public INode
{
public:
enum class PropertyType
{
DEFAULT,
MATERIALIZED,
ALIAS,
};
TableColumnPropertyExpr(PropertyType type, PtrTo<ColumnExpr> expr);
auto getType() const { return property_type; }
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
EXPR = 0, // ColumnExpr
};
PropertyType property_type;
};
class TableElementExpr : public INode
{
public:
enum class ExprType
{
COLUMN,
CONSTRAINT,
INDEX,
PROJECTION,
};
static PtrTo<TableElementExpr> createColumn(
PtrTo<Identifier> name,
PtrTo<ColumnTypeExpr> type,
PtrTo<TableColumnPropertyExpr> property,
PtrTo<StringLiteral> comment,
PtrTo<CodecExpr> codec,
PtrTo<ColumnExpr> ttl);
static PtrTo<TableElementExpr> createConstraint(PtrTo<Identifier> identifier, PtrTo<ColumnExpr> expr);
static PtrTo<TableElementExpr>
createIndex(PtrTo<Identifier> name, PtrTo<ColumnExpr> expr, PtrTo<ColumnTypeExpr> type, PtrTo<NumberLiteral> granularity);
static PtrTo<TableElementExpr>
createProjection(PtrTo<Identifier> name, PtrTo<ProjectionSelectStmt> query);
auto getType() const { return expr_type; }
ASTPtr convertToOld() const override;
private:
enum ChildIndex: UInt8
{
// COLUMN
NAME = 0, // Identifier
TYPE = 1, // ColumnExprType (optional)
PROPERTY = 2, // TableColumnPropertyExpr
COMMENT = 3, // StringLiteral (optional)
CODEC = 4, // CodecExpr (optional)
TTL = 5, // ColumnExpr (optional)
// CONSTRAINT
// NAME = 0,
// EXPR = 1,
// INDEX
EXPR = 1, // ColumnExpr
INDEX_TYPE = 2, // ColumnTypeExpr
GRANULARITY = 3, // NumberLiteral
// PROJECTION
QUERY = 1, // ColumnExpr
};
const ExprType expr_type;
TableElementExpr(ExprType type, PtrList exprs);
};
}

View File

@ -1,190 +0,0 @@
#include <Parsers/New/AST/TableExpr.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/AST/SelectUnionQuery.h>
#include <Parsers/New/ParseTreeVisitor.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTSubquery.h>
#include <Parsers/ASTTablesInSelectQuery.h>
namespace DB::AST
{
TableArgExpr::TableArgExpr(PtrTo<Literal> literal) : INode{literal}
{
}
TableArgExpr::TableArgExpr(PtrTo<TableFunctionExpr> function) : INode{function}
{
}
TableArgExpr::TableArgExpr(PtrTo<Identifier> identifier) : INode{identifier}
{
}
ASTPtr TableArgExpr::convertToOld() const
{
return get(EXPR)->convertToOld();
}
// static
PtrTo<TableExpr> TableExpr::createAlias(PtrTo<TableExpr> expr, PtrTo<Identifier> alias)
{
return PtrTo<TableExpr>(new TableExpr(ExprType::ALIAS, {expr, alias}));
}
// static
PtrTo<TableExpr> TableExpr::createFunction(PtrTo<TableFunctionExpr> function)
{
return PtrTo<TableExpr>(new TableExpr(ExprType::FUNCTION, {function}));
}
// static
PtrTo<TableExpr> TableExpr::createIdentifier(PtrTo<TableIdentifier> identifier)
{
return PtrTo<TableExpr>(new TableExpr(ExprType::IDENTIFIER, {identifier}));
}
// static
PtrTo<TableExpr> TableExpr::createSubquery(PtrTo<SelectUnionQuery> subquery)
{
return PtrTo<TableExpr>(new TableExpr(ExprType::SUBQUERY, {subquery}));
}
ASTPtr TableExpr::convertToOld() const
{
// TODO: SAMPLE and RATIO also goes here somehow
switch (expr_type)
{
case ExprType::ALIAS:
{
auto expr = get(EXPR)->convertToOld();
auto * table_expr = expr->as<ASTTableExpression>();
if (table_expr->database_and_table_name)
table_expr->database_and_table_name->setAlias(get<Identifier>(ALIAS)->getName());
else if (table_expr->table_function)
table_expr->table_function->setAlias(get<Identifier>(ALIAS)->getName());
else if (table_expr->subquery)
table_expr->subquery->setAlias(get<Identifier>(ALIAS)->getName());
return expr;
}
case ExprType::FUNCTION:
{
auto expr = std::make_shared<ASTTableExpression>();
auto func = get(FUNCTION)->convertToOld();
expr->table_function = func;
expr->children.push_back(func);
return expr;
}
case ExprType::IDENTIFIER:
{
auto expr = std::make_shared<ASTTableExpression>();
expr->database_and_table_name = get(IDENTIFIER)->convertToOld();
expr->children.emplace_back(expr->database_and_table_name);
return expr;
}
case ExprType::SUBQUERY:
{
auto expr = std::make_shared<ASTTableExpression>();
expr->subquery = std::make_shared<ASTSubquery>();
expr->subquery->children.push_back(get(SUBQUERY)->convertToOld());
expr->children.push_back(expr->subquery);
return expr;
}
}
__builtin_unreachable();
}
TableExpr::TableExpr(TableExpr::ExprType type, PtrList exprs) : INode(exprs), expr_type(type)
{
}
String TableExpr::dumpInfo() const
{
switch(expr_type)
{
case ExprType::ALIAS: return "ALIAS";
case ExprType::FUNCTION: return "FUNCTION";
case ExprType::IDENTIFIER: return "IDENTIFIER";
case ExprType::SUBQUERY: return "SUBQUERY";
}
__builtin_unreachable();
}
TableFunctionExpr::TableFunctionExpr(PtrTo<Identifier> name, PtrTo<TableArgList> args) : INode{name, args}
{
}
ASTPtr TableFunctionExpr::convertToOld() const
{
auto func = std::make_shared<ASTFunction>();
func->name = get<Identifier>(NAME)->getName();
func->arguments = has(ARGS) ? get(ARGS)->convertToOld() : std::make_shared<TableArgList>()->convertToOld();
func->children.push_back(func->arguments);
return func;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitTableArgExpr(ClickHouseParser::TableArgExprContext *ctx)
{
if (ctx->literal()) return std::make_shared<TableArgExpr>(visit(ctx->literal()).as<PtrTo<Literal>>());
if (ctx->tableFunctionExpr()) return std::make_shared<TableArgExpr>(visit(ctx->tableFunctionExpr()).as<PtrTo<TableFunctionExpr>>());
if (ctx->nestedIdentifier()) return std::make_shared<TableArgExpr>(visit(ctx->nestedIdentifier()).as<PtrTo<Identifier>>());
__builtin_unreachable();
}
antlrcpp::Any ParseTreeVisitor::visitTableArgList(ClickHouseParser::TableArgListContext * ctx)
{
auto list = std::make_shared<TableArgList>();
for (auto * arg : ctx->tableArgExpr()) list->push(visit(arg));
return list;
}
antlrcpp::Any ParseTreeVisitor::visitTableExprAlias(ClickHouseParser::TableExprAliasContext *ctx)
{
if (ctx->AS()) return TableExpr::createAlias(visit(ctx->tableExpr()), visit(ctx->identifier()));
else return TableExpr::createAlias(visit(ctx->tableExpr()), visit(ctx->alias()));
}
antlrcpp::Any ParseTreeVisitor::visitTableExprFunction(ClickHouseParser::TableExprFunctionContext *ctx)
{
return TableExpr::createFunction(visit(ctx->tableFunctionExpr()));
}
antlrcpp::Any ParseTreeVisitor::visitTableExprIdentifier(ClickHouseParser::TableExprIdentifierContext *ctx)
{
return TableExpr::createIdentifier(visit(ctx->tableIdentifier()).as<PtrTo<TableIdentifier>>());
}
antlrcpp::Any ParseTreeVisitor::visitTableExprSubquery(ClickHouseParser::TableExprSubqueryContext *ctx)
{
return TableExpr::createSubquery(visit(ctx->selectUnionStmt()));
}
antlrcpp::Any ParseTreeVisitor::visitTableFunctionExpr(ClickHouseParser::TableFunctionExprContext *ctx)
{
auto list = ctx->tableArgList() ? visit(ctx->tableArgList()).as<PtrTo<TableArgList>>() : nullptr;
return std::make_shared<TableFunctionExpr>(visit(ctx->identifier()), list);
}
}

View File

@ -1,81 +0,0 @@
#pragma once
#include <Parsers/New/AST/INode.h>
namespace DB::AST
{
class TableArgExpr : public INode
{
public:
explicit TableArgExpr(PtrTo<Literal> literal);
explicit TableArgExpr(PtrTo<TableFunctionExpr> function);
explicit TableArgExpr(PtrTo<Identifier> identifier);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
EXPR = 0, // Literal or TableFunctionExpr or Identifier
};
};
class TableExpr : public INode
{
public:
static PtrTo<TableExpr> createAlias(PtrTo<TableExpr> expr, PtrTo<Identifier> alias);
static PtrTo<TableExpr> createFunction(PtrTo<TableFunctionExpr> function);
static PtrTo<TableExpr> createIdentifier(PtrTo<TableIdentifier> identifier);
static PtrTo<TableExpr> createSubquery(PtrTo<SelectUnionQuery> subquery);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
// ALIAS
EXPR = 0, // TableExpr
ALIAS = 1, // Identifier
// FUNCTION
FUNCTION = 0, // TableFunctionExpr
// IDENTIFIER
IDENTIFIER = 0, // TableIdentifier
// SUBQUERY
SUBQUERY = 0, // SelectUnionSubquery
};
enum class ExprType
{
ALIAS,
FUNCTION,
IDENTIFIER,
SUBQUERY,
};
ExprType expr_type;
TableExpr(ExprType type, PtrList exprs);
String dumpInfo() const override;
};
class TableFunctionExpr : public INode
{
public:
TableFunctionExpr(PtrTo<Identifier> name, PtrTo<TableArgList> args);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0,
ARGS = 1,
};
};
}

View File

@ -1,47 +0,0 @@
#include <Parsers/New/AST/TruncateQuery.h>
#include <Parsers/ASTDropQuery.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
TruncateQuery::TruncateQuery(PtrTo<ClusterClause> cluster, bool temporary_, bool if_exists_, PtrTo<TableIdentifier> identifier)
: DDLQuery(cluster, {identifier}), temporary(temporary_), if_exists(if_exists_)
{
}
ASTPtr TruncateQuery::convertToOld() const
{
auto query = std::make_shared<ASTDropQuery>();
query->kind = ASTDropQuery::Truncate;
query->if_exists = if_exists;
query->temporary = temporary;
query->cluster = cluster_name;
query->table = get<TableIdentifier>(NAME)->getName();
if (auto database = get<TableIdentifier>(NAME)->getDatabase())
query->database = database->getName();
convertToOldPartially(query);
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitTruncateStmt(ClickHouseParser::TruncateStmtContext *ctx)
{
auto cluster = ctx->clusterClause() ? visit(ctx->clusterClause()).as<PtrTo<ClusterClause>>() : nullptr;
return std::make_shared<TruncateQuery>(cluster, !!ctx->TEMPORARY(), !!ctx->IF(), visit(ctx->tableIdentifier()));
}
}

View File

@ -1,25 +0,0 @@
#pragma once
#include <Parsers/New/AST/DDLQuery.h>
namespace DB::AST
{
class TruncateQuery : public DDLQuery
{
public:
TruncateQuery(PtrTo<ClusterClause> cluster, bool temporary, bool if_exists, PtrTo<TableIdentifier> identifier);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
NAME = 0, // TableIdentifier
};
const bool temporary, if_exists;
};
}

View File

@ -1,37 +0,0 @@
#include <Parsers/New/AST/UseQuery.h>
#include <Parsers/ASTUseQuery.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
UseQuery::UseQuery(PtrTo<DatabaseIdentifier> identifier)
{
push(identifier);
}
ASTPtr UseQuery::convertToOld() const
{
auto query = std::make_shared<ASTUseQuery>();
query->database = get<DatabaseIdentifier>(DATABASE)->getName();
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitUseStmt(ClickHouseParser::UseStmtContext *ctx)
{
return std::make_shared<UseQuery>(visit(ctx->databaseIdentifier()).as<PtrTo<DatabaseIdentifier>>());
}
}

View File

@ -1,23 +0,0 @@
#pragma once
#include <Parsers/New/AST/Query.h>
namespace DB::AST
{
class UseQuery : public Query
{
public:
explicit UseQuery(PtrTo<DatabaseIdentifier> identifier);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
DATABASE = 0,
};
};
}

View File

@ -1,51 +0,0 @@
#include <Parsers/New/AST/WatchQuery.h>
#include <Interpreters/StorageID.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTWatchQuery.h>
#include <Parsers/New/AST/Identifier.h>
#include <Parsers/New/AST/Literal.h>
#include <Parsers/New/ParseTreeVisitor.h>
namespace DB::AST
{
WatchQuery::WatchQuery(bool events_, PtrTo<TableIdentifier> identifier, PtrTo<NumberLiteral> literal)
: Query{identifier, literal}, events(events_)
{
}
ASTPtr WatchQuery::convertToOld() const
{
auto query = std::make_shared<ASTWatchQuery>();
auto table = std::static_pointer_cast<ASTTableIdentifier>(get(TABLE)->convertToOld());
query->database = table->getDatabaseName();
query->table = table->shortName();
query->uuid = table->uuid;
query->is_watch_events = events;
if (has(LIMIT))
query->limit_length = get(LIMIT)->convertToOld();
convertToOldPartially(query);
return query;
}
}
namespace DB
{
using namespace AST;
antlrcpp::Any ParseTreeVisitor::visitWatchStmt(ClickHouseParser::WatchStmtContext *ctx)
{
auto limit = ctx->DECIMAL_LITERAL() ? Literal::createNumber(ctx->DECIMAL_LITERAL()) : nullptr;
return std::make_shared<WatchQuery>(!!ctx->EVENTS(), visit(ctx->tableIdentifier()), limit);
}
}

View File

@ -1,26 +0,0 @@
#pragma once
#include <Parsers/New/AST/Query.h>
namespace DB::AST
{
class WatchQuery : public Query
{
public:
WatchQuery(bool events, PtrTo<TableIdentifier> identifier, PtrTo<NumberLiteral> literal);
ASTPtr convertToOld() const override;
private:
enum ChildIndex : UInt8
{
TABLE = 0, // TableIdentifier
LIMIT = 1, // NumberLiteral (optional)
};
const bool events;
};
}

View File

@ -1,91 +0,0 @@
#pragma once
#include <memory>
#include <vector>
namespace DB::AST
{
class INode;
template <class T, char Separator = ','>
class List;
template <class T>
class SimpleClause;
template <class T = INode>
using PtrTo = std::shared_ptr<T>;
using Ptr = PtrTo<>;
using PtrList = std::vector<Ptr>;
class AssignmentExpr;
class CodecArgExpr;
class CodecExpr;
class ColumnExpr;
class ColumnFunctionExpr;
class ColumnIdentifier;
class ColumnLambdaExpr;
class ColumnTypeExpr;
class DatabaseIdentifier;
class DictionaryArgExpr;
class DictionaryAttributeExpr;
class EngineClause;
class EngineExpr;
class EnumValue;
class Identifier;
class JoinExpr;
class JsonExpr;
class JsonValue;
class LimitExpr;
class Literal;
class NumberLiteral;
class OrderExpr;
class PartitionClause;
class Query;
class RatioExpr;
class TableSchemaClause;
class ProjectionSelectStmt;
class SelectStmt;
class SelectUnionQuery;
class SettingExpr;
class SettingsClause;
class StringLiteral;
class TableArgExpr;
class TableColumnPropertyExpr;
class TableElementExpr;
class TableExpr;
class TableFunctionExpr;
class TableIdentifier;
class TTLExpr;
using AssignmentExprList = List<AssignmentExpr>;
using CodecArgList = List<CodecArgExpr>;
using ColumnExprList = List<ColumnExpr>;
using ColumnNameList = List<Identifier>;
using ColumnParamList = ColumnExprList;
using ColumnTypeExprList = List<ColumnTypeExpr>;
using DictionaryArgList = List<DictionaryArgExpr, 0>;
using DictionaryAttributeList = List<DictionaryAttributeExpr>;
using EnumValueList = List<EnumValue>;
using JsonExprList = List<JsonExpr>;
using JsonValueList = List<JsonValue>;
using OrderExprList = List<OrderExpr>;
using QueryList = List<Query, ';'>;
using SettingExprList = List<SettingExpr>;
using TableArgList = List<TableArgExpr>;
using TableElementList = List<TableElementExpr>;
using TTLExprList = List<TTLExpr>;
using ClusterClause = SimpleClause<StringLiteral>;
using DestinationClause = SimpleClause<TableIdentifier>;
using OrderByClause = SimpleClause<OrderExprList>;
using ProjectionOrderByClause = SimpleClause<ColumnExprList>;
using PrimaryKeyClause = SimpleClause<ColumnExpr>;
using TTLClause = SimpleClause<TTLExprList>;
using UUIDClause = SimpleClause<StringLiteral>;
using WhereClause = SimpleClause<ColumnExpr>;
}

View File

@ -1,93 +0,0 @@
set (SRCS
AST/AlterTableQuery.cpp
AST/AttachQuery.cpp
AST/CheckQuery.cpp
AST/ColumnExpr.cpp
AST/ColumnTypeExpr.cpp
AST/CreateDatabaseQuery.cpp
AST/CreateDictionaryQuery.cpp
AST/CreateLiveViewQuery.cpp
AST/CreateMaterializedViewQuery.cpp
AST/CreateTableQuery.cpp
AST/CreateViewQuery.cpp
AST/DDLQuery.cpp
AST/DescribeQuery.cpp
AST/DropQuery.cpp
AST/EngineExpr.cpp
AST/ExistsQuery.cpp
AST/ExplainQuery.cpp
AST/Identifier.cpp
AST/InsertQuery.cpp
AST/JoinExpr.cpp
AST/KillQuery.cpp
AST/LimitExpr.cpp
AST/Literal.cpp
AST/OptimizeQuery.cpp
AST/OrderExpr.cpp
AST/Query.cpp
AST/RatioExpr.cpp
AST/RenameQuery.cpp
AST/SelectUnionQuery.cpp
AST/SetQuery.cpp
AST/SettingExpr.cpp
AST/ShowCreateQuery.cpp
AST/ShowQuery.cpp
AST/SystemQuery.cpp
AST/TableElementExpr.cpp
AST/TableExpr.cpp
AST/TruncateQuery.cpp
AST/UseQuery.cpp
AST/WatchQuery.cpp
CharInputStream.cpp
ClickHouseLexer.cpp
ClickHouseParser.cpp
ClickHouseParserVisitor.cpp
LexerErrorListener.cpp
parseQuery.cpp
ParserErrorListener.cpp
ParseTreeVisitor.cpp
)
add_library (clickhouse_parsers_new ${SRCS})
target_compile_options (clickhouse_parsers_new
PRIVATE
-Wno-c++2a-compat
-Wno-deprecated-this-capture
-Wno-documentation-html
-Wno-documentation
-Wno-documentation-deprecated-sync
-Wno-shadow-field
-Wno-unused-parameter
-Wno-extra-semi
-Wno-inconsistent-missing-destructor-override
)
# XXX: hack for old clang-10!
if (HAS_SUGGEST_DESTRUCTOR_OVERRIDE)
target_compile_options (clickhouse_parsers_new
PRIVATE
-Wno-suggest-destructor-override
)
endif ()
# XXX: hack for old gcc-10!
if (HAS_SHADOW)
target_compile_options (clickhouse_parsers_new
PRIVATE
-Wno-shadow
)
endif ()
target_link_libraries (clickhouse_parsers_new PUBLIC antlr4-runtime clickhouse_common_io clickhouse_parsers)
# ANTLR generates u8 string literals, which are incompatible with |std::string| in C++20.
# See https://github.com/antlr/antlr4/issues/2683
set_source_files_properties(
ClickHouseLexer.cpp
ClickHouseParser.cpp
PROPERTIES COMPILE_FLAGS -std=c++17
)
# Disable clang-tidy for whole target.
set_target_properties(clickhouse_parsers_new PROPERTIES CXX_CLANG_TIDY "")

Some files were not shown because too many files have changed in this diff Show More