Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
0ee947c6
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,发现更多精彩内容 >>
提交
0ee947c6
编写于
7月 06, 2014
作者:
A
Alexey Milovidov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
dbms: fixed leak in GLOBAL IN; improvements [#METR-11370].
上级
e7722f50
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
45 addition
and
51 deletion
+45
-51
dbms/include/DB/Common/PODArray.h
dbms/include/DB/Common/PODArray.h
+9
-13
dbms/src/Interpreters/ExpressionAnalyzer.cpp
dbms/src/Interpreters/ExpressionAnalyzer.cpp
+36
-38
未找到文件。
dbms/include/DB/Common/PODArray.h
浏览文件 @
0ee947c6
...
...
@@ -45,7 +45,7 @@ class PODArray : private boost::noncopyable, private std::allocator<char> /// em
{
private:
typedef
std
::
allocator
<
char
>
Allocator
;
static
const
size_t
initial_size
;
static
const
expr
size_t
initial_size
=
4096
;
char
*
c_start
;
char
*
c_end
;
...
...
@@ -56,7 +56,7 @@ private:
T
*
t_start
()
{
return
reinterpret_cast
<
T
*>
(
c_start
);
}
T
*
t_end
()
{
return
reinterpret_cast
<
T
*>
(
c_end
);
}
T
*
t_end_of_storage
()
{
return
reinterpret_cast
<
T
*>
(
c_end_of_storage
);
}
const
T
*
t_start
()
const
{
return
reinterpret_cast
<
const
T
*>
(
c_start
);
}
const
T
*
t_end
()
const
{
return
reinterpret_cast
<
const
T
*>
(
c_end
);
}
const
T
*
t_end_of_storage
()
const
{
return
reinterpret_cast
<
const
T
*>
(
c_end_of_storage
);
}
...
...
@@ -77,9 +77,9 @@ private:
return
n
;
}
static
size_t
to_size
(
size_t
n
)
{
return
byte_size
(
std
::
max
(
initial_size
,
round_up_to_power_of_two
(
n
)));
}
void
alloc
(
size_t
n
)
{
if
(
n
==
0
)
...
...
@@ -87,7 +87,7 @@ private:
c_start
=
c_end
=
c_end_of_storage
=
nullptr
;
return
;
}
size_t
bytes_to_alloc
=
to_size
(
n
);
if
(
current_memory_tracker
)
...
...
@@ -101,7 +101,7 @@ private:
{
if
(
c_start
==
nullptr
)
return
;
if
(
use_libc_realloc
)
::
free
(
c_start
);
else
...
...
@@ -118,7 +118,7 @@ private:
alloc
(
n
);
return
;
}
ptrdiff_t
end_diff
=
c_end
-
c_start
;
size_t
bytes_to_alloc
=
to_size
(
n
);
...
...
@@ -296,11 +296,11 @@ public:
{
if
(
*
this_it
!=
*
that_it
)
return
false
;
++
this_it
;
++
that_it
;
}
return
true
;
}
...
...
@@ -310,9 +310,5 @@ public:
}
};
template
<
typename
T
>
const
size_t
PODArray
<
T
>::
initial_size
=
4096
;
}
dbms/src/Interpreters/ExpressionAnalyzer.cpp
浏览文件 @
0ee947c6
...
...
@@ -287,7 +287,7 @@ void ExpressionAnalyzer::normalizeTreeImpl(ASTPtr & ast, MapOfASTs & finished_as
/// может быть указано IN t, где t - таблица, что равносильно IN (SELECT * FROM t).
if
(
node
->
name
==
"in"
||
node
->
name
==
"notIn"
||
node
->
name
==
"globalIn"
||
node
->
name
==
"globalNotIn"
)
if
(
ASTIdentifier
*
right
=
typeid_cast
<
ASTIdentifier
*>
(
&*
node
->
arguments
->
children
[
1
]
))
if
(
ASTIdentifier
*
right
=
typeid_cast
<
ASTIdentifier
*>
(
&*
node
->
arguments
->
children
.
at
(
1
)
))
right
->
kind
=
ASTIdentifier
::
Table
;
}
else
if
(
ASTIdentifier
*
node
=
typeid_cast
<
ASTIdentifier
*>
(
&*
ast
))
...
...
@@ -333,6 +333,12 @@ void ExpressionAnalyzer::normalizeTreeImpl(ASTPtr & ast, MapOfASTs & finished_as
}
}
}
else
if
(
ASTJoin
*
node
=
typeid_cast
<
ASTJoin
*>
(
&*
ast
))
{
/// может быть указано JOIN t, где t - таблица, что равносильно JOIN (SELECT * FROM t).
if
(
ASTIdentifier
*
right
=
typeid_cast
<
ASTIdentifier
*>
(
&*
node
->
table
))
right
->
kind
=
ASTIdentifier
::
Table
;
}
/// Если заменили корень поддерева вызовемся для нового корня снова - на случай, если алиас заменился на алиас.
if
(
replaced
)
...
...
@@ -385,12 +391,6 @@ void ExpressionAnalyzer::normalizeTreeImpl(ASTPtr & ast, MapOfASTs & finished_as
node
->
kind
=
ASTFunction
::
FUNCTION
;
}
}
else
if
(
ASTJoin
*
node
=
typeid_cast
<
ASTJoin
*>
(
&*
ast
))
{
/// может быть указано JOIN t, где t - таблица, что равносильно JOIN (SELECT * FROM t).
if
(
ASTIdentifier
*
right
=
typeid_cast
<
ASTIdentifier
*>
(
&*
node
->
table
))
right
->
kind
=
ASTIdentifier
::
Table
;
}
current_asts
.
erase
(
initial_ast
);
current_asts
.
erase
(
ast
);
...
...
@@ -413,7 +413,7 @@ void ExpressionAnalyzer::makeSetsForIndexImpl(ASTPtr & node, const Block & sampl
if
(
func
&&
func
->
kind
==
ASTFunction
::
FUNCTION
&&
(
func
->
name
==
"in"
||
func
->
name
==
"notIn"
))
{
IAST
&
args
=
*
func
->
arguments
;
ASTPtr
&
arg
=
args
.
children
[
1
]
;
ASTPtr
&
arg
=
args
.
children
.
at
(
1
)
;
if
(
!
typeid_cast
<
ASTSet
*>
(
&*
arg
)
&&
!
typeid_cast
<
ASTSubquery
*>
(
&*
arg
)
&&
!
typeid_cast
<
ASTIdentifier
*>
(
&*
arg
))
{
...
...
@@ -494,7 +494,8 @@ void ExpressionAnalyzer::addExternalStorage(ASTPtr & subquery_or_table_name)
Block
sample
=
interpreter
.
getSampleBlock
();
NamesAndTypesListPtr
columns
=
new
NamesAndTypesList
(
sample
.
getColumnsList
());
String
external_table_name
=
"_data"
+
toString
(
external_table_id
++
);
String
external_table_name
=
"_data"
+
toString
(
external_table_id
);
++
external_table_id
;
external_storage
=
StorageMemory
::
create
(
external_table_name
,
columns
);
ASTIdentifier
*
ast_ident
=
new
ASTIdentifier
;
...
...
@@ -505,12 +506,11 @@ void ExpressionAnalyzer::addExternalStorage(ASTPtr & subquery_or_table_name)
external_data
[
external_table_name
]
=
interpreter
.
execute
();
/// Добавляем множество, при обработке которого будет заполнена внешняя таблица. // TODO JOIN
ASTSet
*
ast_set
=
new
ASTSet
(
"external_"
+
subquery_or_table_name
->
getColumnName
());
ast_set
->
set
=
new
Set
(
settings
.
limits
);
ast_set
->
set
->
setSource
(
external_data
[
external_table_name
]);
ast_set
->
set
->
setExternalOutput
(
external_tables
[
external_table_name
]);
ast_set
->
set
->
setOnlyExternal
(
true
);
sets_with_subqueries
[
ast_set
->
getColumnName
()]
=
ast_set
->
set
;
SetPtr
set
=
new
Set
(
settings
.
limits
);
set
->
setSource
(
external_data
[
external_table_name
]);
set
->
setExternalOutput
(
external_tables
[
external_table_name
]);
set
->
setOnlyExternal
(
true
);
sets_with_subqueries
[
"external_"
+
subquery_or_table_name
->
getColumnName
()]
=
set
;
}
...
...
@@ -521,7 +521,7 @@ void ExpressionAnalyzer::makeSet(ASTFunction * node, const Block & sample_block)
* Перечисление значений парсится как функция tuple.
*/
IAST
&
args
=
*
node
->
arguments
;
ASTPtr
&
arg
=
args
.
children
[
1
]
;
ASTPtr
&
arg
=
args
.
children
.
at
(
1
)
;
if
(
typeid_cast
<
ASTSet
*>
(
&*
arg
))
return
;
...
...
@@ -578,7 +578,7 @@ void ExpressionAnalyzer::makeSet(ASTFunction * node, const Block & sample_block)
}
}
else
subquery
=
arg
->
children
[
0
]
;
subquery
=
arg
->
children
.
at
(
0
)
;
/// Если чтение из внешней таблицы, то источник данных уже вычислен.
if
(
!
external
)
...
...
@@ -615,10 +615,10 @@ void ExpressionAnalyzer::makeSet(ASTFunction * node, const Block & sample_block)
void
ExpressionAnalyzer
::
makeExplicitSet
(
ASTFunction
*
node
,
const
Block
&
sample_block
,
bool
create_ordered_set
)
{
IAST
&
args
=
*
node
->
arguments
;
ASTPtr
&
arg
=
args
.
children
[
1
]
;
ASTPtr
&
arg
=
args
.
children
.
at
(
1
)
;
DataTypes
set_element_types
;
ASTPtr
&
left_arg
=
args
.
children
[
0
]
;
ASTPtr
&
left_arg
=
args
.
children
.
at
(
0
)
;
ASTFunction
*
left_arg_tuple
=
typeid_cast
<
ASTFunction
*>
(
&*
left_arg
);
...
...
@@ -649,7 +649,7 @@ void ExpressionAnalyzer::makeExplicitSet(ASTFunction * node, const Block & sampl
ErrorCodes
::
ILLEGAL_TYPE_OF_ARGUMENT
);
/// Отличм случай (x, y) in ((1, 2), (3, 4)) от случая (x, y) in (1, 2).
ASTFunction
*
any_element
=
typeid_cast
<
ASTFunction
*>
(
&*
set_func
->
arguments
->
children
[
0
]
);
ASTFunction
*
any_element
=
typeid_cast
<
ASTFunction
*>
(
&*
set_func
->
arguments
->
children
.
at
(
0
)
);
if
(
set_element_types
.
size
()
>=
2
&&
(
!
any_element
||
any_element
->
name
!=
"tuple"
))
single_value
=
true
;
else
...
...
@@ -830,7 +830,7 @@ void ExpressionAnalyzer::getArrayJoinedColumns()
/// чтобы получить правильное количество строк.
if
(
array_join_result_to_source
.
empty
())
{
ASTPtr
expr
=
select_query
->
array_join_expression_list
->
children
[
0
]
;
ASTPtr
expr
=
select_query
->
array_join_expression_list
->
children
.
at
(
0
)
;
String
source_name
=
expr
->
getColumnName
();
String
result_name
=
expr
->
getAliasOrColumnName
();
...
...
@@ -921,7 +921,7 @@ void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool onl
{
if
(
node
->
arguments
->
children
.
size
()
!=
1
)
throw
Exception
(
"arrayJoin requires exactly 1 argument"
,
ErrorCodes
::
TYPE_MISMATCH
);
ASTPtr
arg
=
node
->
arguments
->
children
[
0
]
;
ASTPtr
arg
=
node
->
arguments
->
children
.
at
(
0
)
;
getActionsImpl
(
arg
,
no_subqueries
,
only_consts
,
actions_stack
);
if
(
!
only_consts
)
{
...
...
@@ -942,7 +942,7 @@ void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool onl
if
(
!
no_subqueries
)
{
/// Найдем тип первого аргумента (потом getActionsImpl вызовется для него снова и ни на что не повлияет).
getActionsImpl
(
node
->
arguments
->
children
[
0
]
,
no_subqueries
,
only_consts
,
actions_stack
);
getActionsImpl
(
node
->
arguments
->
children
.
at
(
0
)
,
no_subqueries
,
only_consts
,
actions_stack
);
/// Превратим tuple или подзапрос в множество.
makeSet
(
node
,
actions_stack
.
getSampleBlock
());
...
...
@@ -958,7 +958,7 @@ void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool onl
fake_column
.
type
=
new
DataTypeUInt8
;
fake_column
.
column
=
new
ColumnConstUInt8
(
1
,
0
);
actions_stack
.
addAction
(
ExpressionAction
::
addColumn
(
fake_column
));
getActionsImpl
(
node
->
arguments
->
children
[
0
]
,
no_subqueries
,
only_consts
,
actions_stack
);
getActionsImpl
(
node
->
arguments
->
children
.
at
(
0
)
,
no_subqueries
,
only_consts
,
actions_stack
);
}
return
;
}
...
...
@@ -973,10 +973,8 @@ void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool onl
/// Если у функции есть аргумент-лямбда-выражение, нужно определить его тип до рекурсивного вызова.
bool
has_lambda_arguments
=
false
;
for
(
size_t
i
=
0
;
i
<
node
->
arguments
->
children
.
size
();
++
i
)
for
(
auto
&
child
:
node
->
arguments
->
children
)
{
ASTPtr
child
=
node
->
arguments
->
children
[
i
];
ASTFunction
*
lambda
=
typeid_cast
<
ASTFunction
*>
(
&*
child
);
ASTSet
*
set
=
typeid_cast
<
ASTSet
*>
(
&*
child
);
if
(
lambda
&&
lambda
->
name
==
"lambda"
)
...
...
@@ -985,7 +983,7 @@ void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool onl
if
(
lambda
->
arguments
->
children
.
size
()
!=
2
)
throw
Exception
(
"lambda requires two arguments"
,
ErrorCodes
::
NUMBER_OF_ARGUMENTS_DOESNT_MATCH
);
ASTFunction
*
lambda_args_tuple
=
typeid_cast
<
ASTFunction
*>
(
&*
lambda
->
arguments
->
children
[
0
]
);
ASTFunction
*
lambda_args_tuple
=
typeid_cast
<
ASTFunction
*>
(
&*
lambda
->
arguments
->
children
.
at
(
0
)
);
if
(
!
lambda_args_tuple
||
lambda_args_tuple
->
name
!=
"tuple"
)
throw
Exception
(
"First argument of lambda must be a tuple"
,
ErrorCodes
::
TYPE_MISMATCH
);
...
...
@@ -1059,7 +1057,7 @@ void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool onl
if
(
lambda
&&
lambda
->
name
==
"lambda"
)
{
DataTypeExpression
*
lambda_type
=
typeid_cast
<
DataTypeExpression
*>
(
&*
argument_types
[
i
]);
ASTFunction
*
lambda_args_tuple
=
typeid_cast
<
ASTFunction
*>
(
&*
lambda
->
arguments
->
children
[
0
]
);
ASTFunction
*
lambda_args_tuple
=
typeid_cast
<
ASTFunction
*>
(
&*
lambda
->
arguments
->
children
.
at
(
0
)
);
ASTs
lambda_arg_asts
=
lambda_args_tuple
->
arguments
->
children
;
NamesAndTypesList
lambda_arguments
;
...
...
@@ -1076,10 +1074,10 @@ void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool onl
}
actions_stack
.
pushLevel
(
lambda_arguments
);
getActionsImpl
(
lambda
->
arguments
->
children
[
1
]
,
no_subqueries
,
only_consts
,
actions_stack
);
getActionsImpl
(
lambda
->
arguments
->
children
.
at
(
1
)
,
no_subqueries
,
only_consts
,
actions_stack
);
ExpressionActionsPtr
lambda_actions
=
actions_stack
.
popLevel
();
String
result_name
=
lambda
->
arguments
->
children
[
1
]
->
getColumnName
();
String
result_name
=
lambda
->
arguments
->
children
.
at
(
1
)
->
getColumnName
();
lambda_actions
->
finalize
(
Names
(
1
,
result_name
));
DataTypePtr
result_type
=
lambda_actions
->
getSampleBlock
().
getByName
(
result_name
).
type
;
argument_types
[
i
]
=
new
DataTypeExpression
(
lambda_type
->
getArgumentTypes
(),
result_type
);
...
...
@@ -1293,7 +1291,7 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty
/// TODO: поддержка идентификаторов вместо подзапросов.
InterpreterSelectQuery
interpreter
(
typeid_cast
<
ASTJoin
&>
(
*
select_query
->
join
).
table
->
children
[
0
]
,
subquery_context
,
typeid_cast
<
ASTJoin
&>
(
*
select_query
->
join
).
table
->
children
.
at
(
0
)
,
subquery_context
,
required_joined_columns
,
QueryProcessingStage
::
Complete
,
subquery_depth
+
1
);
...
...
@@ -1418,7 +1416,7 @@ bool ExpressionAnalyzer::appendOrderBy(ExpressionActionsChain & chain, bool only
ASTOrderByElement
*
ast
=
typeid_cast
<
ASTOrderByElement
*>
(
&*
asts
[
i
]);
if
(
!
ast
||
ast
->
children
.
size
()
!=
1
)
throw
Exception
(
"Bad order expression AST"
,
ErrorCodes
::
UNKNOWN_TYPE_OF_AST_NODE
);
ASTPtr
order_expression
=
ast
->
children
[
0
]
;
ASTPtr
order_expression
=
ast
->
children
.
at
(
0
)
;
step
.
required_output
.
push_back
(
order_expression
->
getColumnName
());
}
...
...
@@ -1654,7 +1652,7 @@ void ExpressionAnalyzer::collectJoinedColumns(NameSet & joined_columns, NamesAnd
auto
&
node
=
typeid_cast
<
ASTJoin
&>
(
*
select_query
->
join
);
auto
&
keys
=
typeid_cast
<
ASTExpressionList
&>
(
*
node
.
using_expr_list
);
auto
&
table
=
node
.
table
->
children
[
0
]
;
/// TODO: поддержка идентификаторов.
auto
&
table
=
node
.
table
->
children
.
at
(
0
)
;
/// TODO: поддержка идентификаторов.
size_t
num_join_keys
=
keys
.
children
.
size
();
...
...
@@ -1737,16 +1735,16 @@ void ExpressionAnalyzer::getRequiredColumnsImpl(ASTPtr ast,
if
(
node
->
arguments
->
children
.
size
()
!=
2
)
throw
Exception
(
"lambda requires two arguments"
,
ErrorCodes
::
NUMBER_OF_ARGUMENTS_DOESNT_MATCH
);
ASTFunction
*
lambda_args_tuple
=
typeid_cast
<
ASTFunction
*>
(
&*
node
->
arguments
->
children
[
0
]
);
ASTFunction
*
lambda_args_tuple
=
typeid_cast
<
ASTFunction
*>
(
&*
node
->
arguments
->
children
.
at
(
0
)
);
if
(
!
lambda_args_tuple
||
lambda_args_tuple
->
name
!=
"tuple"
)
throw
Exception
(
"First argument of lambda must be a tuple"
,
ErrorCodes
::
TYPE_MISMATCH
);
/// Не нужно добавлять формальные параметры лямбда-выражения в required_columns.
Names
added_ignored
;
for
(
size_t
i
=
0
;
i
<
lambda_args_tuple
->
arguments
->
children
.
size
();
++
i
)
for
(
auto
&
child
:
lambda_args_tuple
->
arguments
->
children
)
{
ASTIdentifier
*
identifier
=
typeid_cast
<
ASTIdentifier
*>
(
&*
lambda_args_tuple
->
arguments
->
children
[
i
]
);
ASTIdentifier
*
identifier
=
typeid_cast
<
ASTIdentifier
*>
(
&*
child
);
if
(
!
identifier
)
throw
Exception
(
"lambda argument declarations must be identifiers"
,
ErrorCodes
::
TYPE_MISMATCH
);
...
...
@@ -1758,7 +1756,7 @@ void ExpressionAnalyzer::getRequiredColumnsImpl(ASTPtr ast,
}
}
getRequiredColumnsImpl
(
node
->
arguments
->
children
[
1
]
,
getRequiredColumnsImpl
(
node
->
arguments
->
children
.
at
(
1
)
,
required_columns
,
ignored_names
,
available_joined_columns
,
required_joined_columns
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录