mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 09:32:06 +00:00
Merge branch 'master' into inconsisteny
This commit is contained in:
commit
705e839390
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -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
|
||||
|
1
contrib/CMakeLists.txt
vendored
1
contrib/CMakeLists.txt
vendored
@ -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
contrib/antlr4-runtime
vendored
1
contrib/antlr4-runtime
vendored
@ -1 +0,0 @@
|
||||
Subproject commit 672643e9a427ef803abf13bc8cb4989606553d64
|
@ -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})
|
@ -160,7 +160,6 @@ function clone_submodules
|
||||
|
||||
SUBMODULES_TO_UPDATE=(
|
||||
contrib/abseil-cpp
|
||||
contrib/antlr4-runtime
|
||||
contrib/boost
|
||||
contrib/zlib-ng
|
||||
contrib/libxml2
|
||||
|
@ -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
|
||||
|
@ -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”的聚合函数语法和常规函数是一样的。
|
||||
|
||||
@ -121,7 +124,7 @@ CH只支持用单引号包含的字母。特殊字符可通过反斜杠进行转
|
||||
## 数据类型及数据库/表引擎 {#data_types-and-database-table-engines}
|
||||
|
||||
`CREATE` 语句中的数据类型和表引擎写法与变量或函数类似。
|
||||
换句话说,它们可以用括号包含参数列表。更多信息,参见“数据类型,” “数据表引擎” 和 “CREATE语句”等章节
|
||||
换句话说,它们可以包含或不包含用括号包含的参数列表。更多信息,参见“数据类型,” “数据表引擎” 和 “CREATE语句”等章节
|
||||
|
||||
## 表达式别名 {#syntax-expression_aliases}
|
||||
|
||||
@ -134,14 +137,14 @@ expr AS 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支持的表达式.
|
||||
|
||||
例如, `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"`.
|
||||
|
||||
@ -149,11 +152,12 @@ expr AS alias
|
||||
|
||||
别名在当前查询或子查询中是全局可见的,你可以在查询语句的任何位置对表达式定义别名
|
||||
|
||||
别名在当前查询的子查询及不同子查询中是不可见的。例如,执行如下查询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}
|
||||
|
||||
表达式是函数、标识符、字符、运算符的应用程序、括号中的表达式、子查询或星号。它也可以包含别名。
|
||||
表达式是函数、标识符、字符、使用运算符的语句、括号中的表达式、子查询或星号。它也可以包含别名。
|
||||
表达式列表是用逗号分隔的一个或多个表达式。
|
||||
反过来,函数和运算符可以将表达式作为参数。
|
||||
|
||||
|
@ -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) \
|
||||
|
@ -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)
|
||||
|
@ -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) \
|
||||
\
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()))
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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));
|
||||
|
||||
@ -385,25 +379,11 @@ static std::tuple<ASTPtr, BlockIO> executeQueryImpl(
|
||||
String query_database;
|
||||
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.
|
||||
|
@ -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 : "");
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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>
|
||||
};
|
||||
};
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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)
|
||||
};
|
||||
};
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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>>());
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#include <Parsers/New/AST/DDLQuery.h>
|
||||
|
||||
|
||||
namespace DB::AST
|
||||
{
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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>>());
|
||||
}
|
||||
|
||||
}
|
@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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>>());
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
@ -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(); }
|
||||
};
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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"); }
|
||||
};
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
@ -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>>());
|
||||
}
|
||||
|
||||
}
|
@ -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)
|
||||
};
|
||||
};
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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.
|
||||
**
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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)
|
||||
};
|
||||
};
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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>
|
||||
};
|
||||
};
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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>>());
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
};
|
||||
};
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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>>());
|
||||
}
|
||||
|
||||
}
|
@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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>;
|
||||
|
||||
}
|
@ -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
Loading…
Reference in New Issue
Block a user