Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
615dcc7f
C
ClickHouse
项目概览
2dot5
/
ClickHouse
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
ClickHouse
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
615dcc7f
编写于
1月 17, 2017
作者:
A
Alexey Milovidov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Analyzers: lambdas: preparation [#CLICKHOUSE-11].
上级
01c2caef
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
50 addition
and
17 deletion
+50
-17
dbms/include/DB/Analyzers/TypeAndConstantInference.h
dbms/include/DB/Analyzers/TypeAndConstantInference.h
+1
-1
dbms/src/Analyzers/TypeAndConstantInference.cpp
dbms/src/Analyzers/TypeAndConstantInference.cpp
+49
-16
未找到文件。
dbms/include/DB/Analyzers/TypeAndConstantInference.h
浏览文件 @
615dcc7f
...
...
@@ -43,7 +43,7 @@ struct TypeAndConstantInference
ASTPtr
node
;
DataTypePtr
data_type
;
bool
is_constant_expression
=
false
;
Field
value
;
///
Has meaning if is_constant_expression == true.
ColumnPtr
value
;
/// Constant column.
Has meaning if is_constant_expression == true.
std
::
shared_ptr
<
IFunction
>
function
;
std
::
shared_ptr
<
IAggregateFunction
>
aggregate_function
;
};
...
...
dbms/src/Analyzers/TypeAndConstantInference.cpp
浏览文件 @
615dcc7f
...
...
@@ -22,6 +22,7 @@
#include <DB/AggregateFunctions/AggregateFunctionFactory.h>
#include <DB/Functions/FunctionFactory.h>
#include <DB/Functions/IFunction.h>
#include <DB/Columns/ColumnExpression.h>
namespace
DB
...
...
@@ -49,11 +50,6 @@ Field getValueFromConstantColumn(const ColumnPtr & column)
}
/// Description of single parameter of lambda expression: name -> type.
/// Note, that after AnalyzeLambda step, names of lambda parameters are unique in single select query.
using
LambdaParameters
=
std
::
unordered_map
<
String
,
DataTypePtr
>
;
void
processImpl
(
ASTPtr
&
ast
,
Context
&
context
,
CollectAliases
&
aliases
,
const
AnalyzeColumns
&
columns
,
...
...
@@ -64,12 +60,13 @@ void processImpl(
void
processLiteral
(
const
String
&
column_name
,
const
ASTPtr
&
ast
,
TypeAndConstantInference
::
Info
&
info
)
{
const
ASTLiteral
*
literal
=
static_cast
<
const
ASTLiteral
*>
(
ast
.
get
());
Field
value
=
literal
->
value
;
TypeAndConstantInference
::
ExpressionInfo
expression_info
;
expression_info
.
node
=
ast
;
expression_info
.
is_constant_expression
=
true
;
expression_info
.
value
=
literal
->
value
;
expression_info
.
data_type
=
applyVisitor
(
FieldToDataType
(),
expression_info
.
value
);
expression_info
.
data_type
=
applyVisitor
(
FieldToDataType
(),
value
)
;
expression_info
.
value
=
expression_info
.
data_type
->
createConstColumn
(
1
,
value
);
info
.
emplace
(
column_name
,
std
::
move
(
expression_info
));
}
...
...
@@ -94,7 +91,7 @@ void processIdentifier(const String & column_name, const ASTPtr & ast, TypeAndCo
if
(
column_from_subquery
.
column
)
{
expression_info
.
is_constant_expression
=
true
;
expression_info
.
value
=
getValueFromConstantColumn
(
column_from_subquery
.
column
)
;
expression_info
.
value
=
column_from_subquery
.
column
;
}
}
...
...
@@ -121,6 +118,8 @@ void processIdentifier(const String & column_name, const ASTPtr & ast, TypeAndCo
void
processFunction
(
const
String
&
column_name
,
ASTPtr
&
ast
,
TypeAndConstantInference
::
Info
&
info
,
const
Context
&
context
)
{
std
::
cerr
<<
"processFunction: "
<<
ast
->
getColumnName
()
<<
"
\n
"
;
ASTFunction
*
function
=
static_cast
<
ASTFunction
*>
(
ast
.
get
());
/// Special case for lambda functions. Lambda function has special return type "Expression".
...
...
@@ -215,8 +214,9 @@ void processFunction(const String & column_name, ASTPtr & ast, TypeAndConstantIn
{
String
child_name
=
child
->
getColumnName
();
const
TypeAndConstantInference
::
ExpressionInfo
&
child_info
=
info
.
at
(
child_name
);
columns_for_analysis
.
emplace_back
(
child_info
.
is_constant_expression
?
child_info
.
data_type
->
createConstColumn
(
1
,
child_info
.
value
)
:
nullptr
,
child_info
.
value
,
child_info
.
data_type
,
child_name
);
...
...
@@ -248,7 +248,7 @@ void processFunction(const String & column_name, ASTPtr & ast, TypeAndConstantIn
if
(
result_column
->
isConst
())
{
expression_info
.
is_constant_expression
=
true
;
expression_info
.
value
=
(
*
result_column
)[
0
]
;
expression_info
.
value
=
result_column
;
}
}
...
...
@@ -278,7 +278,7 @@ void processScalarSubquery(const String & column_name, ASTPtr & ast, TypeAndCons
if
(
elem
.
column
)
{
expression_info
.
is_constant_expression
=
true
;
expression_info
.
value
=
getValueFromConstantColumn
(
elem
.
column
)
;
expression_info
.
value
=
elem
.
column
;
}
}
else
...
...
@@ -306,7 +306,7 @@ void processScalarSubquery(const String & column_name, ASTPtr & ast, TypeAndCons
value
[
i
]
=
getValueFromConstantColumn
(
analyzer
.
result
.
getByPosition
(
i
).
column
);
expression_info
.
is_constant_expression
=
true
;
expression_info
.
value
=
Tuple
(
std
::
move
(
value
));
expression_info
.
value
=
expression_info
.
data_type
->
createConstColumn
(
1
,
Tuple
(
std
::
move
(
value
)
));
}
}
...
...
@@ -320,6 +320,8 @@ void processHigherOrderFunction(const String & column_name,
TypeAndConstantInference
::
Info
&
info
,
const
AnalyzeLambdas
&
lambdas
)
{
std
::
cerr
<<
"processHigherOrderFunction
\n
"
;
ASTFunction
*
function
=
static_cast
<
ASTFunction
*>
(
ast
.
get
());
const
FunctionPtr
&
function_ptr
=
FunctionFactory
::
instance
().
get
(
function
->
name
,
context
);
...
...
@@ -334,10 +336,17 @@ void processHigherOrderFunction(const String & column_name,
String
child_name
=
child
->
getColumnName
();
const
TypeAndConstantInference
::
ExpressionInfo
&
child_info
=
info
.
at
(
child_name
);
types
.
emplace_back
(
child_info
.
data_type
);
std
::
cerr
<<
child_info
.
data_type
->
getName
()
<<
"
\n
"
;
}
function_ptr
->
getLambdaArgumentTypes
(
types
);
std
::
cerr
<<
"
\n
"
;
for
(
const
auto
&
type
:
types
)
std
::
cerr
<<
type
->
getName
()
<<
"
\n
"
;
std
::
cerr
<<
"
\n
"
;
/// For every lambda expression, dive into it.
if
(
types
.
size
()
!=
function
->
arguments
->
children
.
size
())
...
...
@@ -368,6 +377,7 @@ void processHigherOrderFunction(const String & column_name,
throw
Exception
(
"DataTypeExpression for lambda function has different number of argument types than number of lambda parameters"
,
ErrorCodes
::
LOGICAL_ERROR
);
NamesAndTypesList
lambda_names_and_types
;
for
(
size_t
param_idx
=
0
,
num_params
=
parameters
.
size
();
param_idx
<
num_params
;
++
param_idx
)
{
TypeAndConstantInference
::
ExpressionInfo
expression_info
;
...
...
@@ -378,11 +388,27 @@ void processHigherOrderFunction(const String & column_name,
expression_info
.
data_type
=
lambda_argument_types
[
param_idx
];
info
.
emplace
(
parameters
[
param_idx
],
std
::
move
(
expression_info
));
lambda_names_and_types
.
emplace_back
(
parameters
[
param_idx
],
lambda_argument_types
[
param_idx
]);
}
/// Now dive into.
processImpl
(
lambda
->
arguments
->
children
[
1
],
context
,
aliases
,
columns
,
info
,
lambdas
);
/// Update information about lambda.
TypeAndConstantInference
::
ExpressionInfo
&
lambda_info
=
info
[
lambda
->
getColumnName
()];
lambda_info
.
node
=
child
;
lambda_info
.
data_type
=
types
[
i
];
lambda_info
.
is_constant_expression
=
true
;
TypeAndConstantInference
::
ExpressionInfo
&
lambda_return_info
=
info
[
lambda
->
arguments
->
children
[
1
]
->
getColumnName
()];
/// TODO Rewrite ColumnExpression and ExpressionActions
ExpressionActionsPtr
actions
=
std
::
make_shared
<
ExpressionActions
>
(
lambda_names_and_types
,
Settings
());
lambda_info
.
value
=
std
::
make_shared
<
ColumnExpression
>
(
1
,
actions
,
lambda_names_and_types
,
lambda_return_info
.
data_type
,
lambda_return_info
.
node
->
getColumnName
());
}
}
}
...
...
@@ -394,7 +420,7 @@ void processImpl(
TypeAndConstantInference
::
Info
&
info
,
const
AnalyzeLambdas
&
lambdas
)
{
const
ASTFunction
*
function
=
typeid_cast
<
const
ASTFunction
*>
(
ast
.
get
())
;
std
::
cerr
<<
"processImpl: "
<<
ast
->
getTreeID
()
<<
"
\n
"
;
/// Bottom-up.
...
...
@@ -410,6 +436,8 @@ void processImpl(
||
typeid_cast
<
const
ASTTableExpression
*>
(
child
.
get
()))
continue
;
const
ASTFunction
*
child_function
=
typeid_cast
<
const
ASTFunction
*>
(
child
.
get
());
/** Postpone diving into lambda expressions.
* We must first infer types of other arguments of higher-order function,
* and then process lambda expression.
...
...
@@ -419,18 +447,23 @@ void processImpl(
* Then, ask function arrayMap, what types will have 'x' and 'y'.
* And then, infer type of 'x + y'.
*/
if
(
function
&&
function
->
name
==
"lambda"
)
if
(
child_function
&&
child_function
->
name
==
"lambda"
)
{
processFunction
(
child
->
getColumnName
(),
child
,
info
,
context
);
continue
;
}
processImpl
(
child
,
context
,
aliases
,
columns
,
info
,
lambdas
);
}
}
const
ASTFunction
*
function
=
nullptr
;
const
ASTLiteral
*
literal
=
nullptr
;
const
ASTIdentifier
*
identifier
=
nullptr
;
const
ASTSubquery
*
subquery
=
nullptr
;
function
false
||
(
function
=
typeid_cast
<
const
ASTFunction
*>
(
ast
.
get
()))
||
(
literal
=
typeid_cast
<
const
ASTLiteral
*>
(
ast
.
get
()))
||
(
identifier
=
typeid_cast
<
const
ASTIdentifier
*>
(
ast
.
get
()))
||
(
subquery
=
typeid_cast
<
const
ASTSubquery
*>
(
ast
.
get
()));
...
...
@@ -488,7 +521,7 @@ void TypeAndConstantInference::dump(WriteBuffer & out) const
if
(
it
->
second
.
is_constant_expression
)
{
writeCString
(
" = "
,
out
);
String
value
=
applyVisitor
(
FieldVisitorToString
(),
it
->
second
.
value
);
String
value
=
applyVisitor
(
FieldVisitorToString
(),
(
*
it
->
second
.
value
)[
0
]
);
writeString
(
value
,
out
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录