Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
45adacf0
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,发现更多精彩内容 >>
提交
45adacf0
编写于
6月 18, 2020
作者:
N
Nikolai Kochetov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Use QueryPlan in InterpreterSelectQuery [part 2].
上级
e0841360
变更
15
展开全部
隐藏空白更改
内联
并排
Showing
15 changed file
with
341 addition
and
172 deletion
+341
-172
src/Interpreters/InterpreterSelectQuery.cpp
src/Interpreters/InterpreterSelectQuery.cpp
+124
-127
src/Interpreters/InterpreterSelectQuery.h
src/Interpreters/InterpreterSelectQuery.h
+3
-0
src/Interpreters/InterpreterSelectWithUnionQuery.cpp
src/Interpreters/InterpreterSelectWithUnionQuery.cpp
+24
-37
src/Interpreters/InterpreterSelectWithUnionQuery.h
src/Interpreters/InterpreterSelectWithUnionQuery.h
+4
-3
src/Processors/QueryPipeline.cpp
src/Processors/QueryPipeline.cpp
+3
-2
src/Processors/QueryPipeline.h
src/Processors/QueryPipeline.h
+1
-1
src/Processors/QueryPlan/ConvertingStep.cpp
src/Processors/QueryPlan/ConvertingStep.cpp
+48
-0
src/Processors/QueryPlan/ConvertingStep.h
src/Processors/QueryPlan/ConvertingStep.h
+20
-0
src/Processors/QueryPlan/MergeSortingStep.cpp
src/Processors/QueryPlan/MergeSortingStep.cpp
+1
-1
src/Processors/QueryPlan/QueryPlan.cpp
src/Processors/QueryPlan/QueryPlan.cpp
+43
-0
src/Processors/QueryPlan/QueryPlan.h
src/Processors/QueryPlan/QueryPlan.h
+7
-0
src/Processors/QueryPlan/TotalsHavingStep.h
src/Processors/QueryPlan/TotalsHavingStep.h
+0
-1
src/Processors/QueryPlan/UnionStep.cpp
src/Processors/QueryPlan/UnionStep.cpp
+39
-0
src/Processors/QueryPlan/UnionStep.h
src/Processors/QueryPlan/UnionStep.h
+22
-0
src/Processors/ya.make
src/Processors/ya.make
+2
-0
未找到文件。
src/Interpreters/InterpreterSelectQuery.cpp
浏览文件 @
45adacf0
此差异已折叠。
点击以展开。
src/Interpreters/InterpreterSelectQuery.h
浏览文件 @
45adacf0
...
@@ -77,6 +77,9 @@ public:
...
@@ -77,6 +77,9 @@ public:
/// Execute a query. Get the stream of blocks to read.
/// Execute a query. Get the stream of blocks to read.
BlockIO
execute
()
override
;
BlockIO
execute
()
override
;
/// Builds QueryPlan for current query.
void
buildQueryPlan
(
QueryPlan
&
query_plan
);
bool
ignoreLimits
()
const
override
{
return
options
.
ignore_limits
;
}
bool
ignoreLimits
()
const
override
{
return
options
.
ignore_limits
;
}
bool
ignoreQuota
()
const
override
{
return
options
.
ignore_quota
;
}
bool
ignoreQuota
()
const
override
{
return
options
.
ignore_quota
;
}
...
...
src/Interpreters/InterpreterSelectWithUnionQuery.cpp
浏览文件 @
45adacf0
...
@@ -6,10 +6,9 @@
...
@@ -6,10 +6,9 @@
#include <Columns/getLeastSuperColumn.h>
#include <Columns/getLeastSuperColumn.h>
#include <Common/typeid_cast.h>
#include <Common/typeid_cast.h>
#include <Parsers/queryToString.h>
#include <Parsers/queryToString.h>
#include <Processors/QueryPlan/IQueryPlanStep.h>
#include <Processors/Sources/NullSource.h>
#include <Processors/QueryPlan/QueryPlan.h>
#include <Processors/QueryPipeline.h>
#include <Processors/QueryPlan/UnionStep.h>
#include <Processors/Pipe.h>
namespace
DB
namespace
DB
...
@@ -173,47 +172,35 @@ Block InterpreterSelectWithUnionQuery::getSampleBlock(
...
@@ -173,47 +172,35 @@ Block InterpreterSelectWithUnionQuery::getSampleBlock(
return
cache
[
key
]
=
InterpreterSelectWithUnionQuery
(
query_ptr
,
context
,
SelectQueryOptions
().
analyze
()).
getSampleBlock
();
return
cache
[
key
]
=
InterpreterSelectWithUnionQuery
(
query_ptr
,
context
,
SelectQueryOptions
().
analyze
()).
getSampleBlock
();
}
}
void
InterpreterSelectWithUnionQuery
::
buildQueryPlan
(
QueryPlan
&
query_plan
)
BlockIO
InterpreterSelectWithUnionQuery
::
execute
()
{
{
BlockIO
res
;
size_t
num_plans
=
nested_interpreters
.
size
();
QueryPipeline
&
main_pipeline
=
res
.
pipeline
;
std
::
vector
<
QueryPlan
>
plans
(
num_plans
);
std
::
vector
<
QueryPipeline
>
pipelines
;
DataStreams
data_streams
(
num_plans
);
bool
has_main_pipeline
=
false
;
Blocks
headers
;
headers
.
reserve
(
nested_interpreters
.
size
());
for
(
auto
&
interpreter
:
nested_interpreters
)
for
(
size_t
i
=
0
;
i
<
num_plans
;
++
i
)
{
{
if
(
!
has_main_pipeline
)
nested_interpreters
[
i
]
->
buildQueryPlan
(
plans
[
i
]);
{
data_streams
[
i
]
=
plans
[
i
].
getCurrentDataStream
();
has_main_pipeline
=
true
;
main_pipeline
=
interpreter
->
execute
().
pipeline
;
headers
.
emplace_back
(
main_pipeline
.
getHeader
());
}
else
{
pipelines
.
emplace_back
(
interpreter
->
execute
().
pipeline
);
headers
.
emplace_back
(
pipelines
.
back
().
getHeader
());
}
}
}
if
(
!
has_main_pipeline
)
auto
max_threads
=
context
->
getSettingsRef
().
max_threads
;
main_pipeline
.
init
(
Pipe
(
std
::
make_shared
<
NullSource
>
(
getSampleBlock
()))
);
auto
union_step
=
std
::
make_unique
<
UnionStep
>
(
std
::
move
(
data_streams
),
result_header
,
max_threads
);
if
(
!
pipelines
.
empty
())
query_plan
.
unitePlans
(
std
::
move
(
union_step
),
std
::
move
(
plans
));
{
}
auto
common_header
=
getCommonHeaderForUnion
(
headers
);
main_pipeline
.
unitePipelines
(
std
::
move
(
pipelines
),
common_header
);
// nested queries can force 1 thread (due to simplicity)
BlockIO
InterpreterSelectWithUnionQuery
::
execute
()
// but in case of union this cannot be done.
{
UInt64
max_threads
=
context
->
getSettingsRef
().
max_threads
;
BlockIO
res
;
main_pipeline
.
setMaxThreads
(
std
::
min
<
UInt64
>
(
nested_interpreters
.
size
(),
max_threads
));
}
QueryPlan
query_plan
;
buildQueryPlan
(
query_plan
);
auto
pipeline
=
query_plan
.
buildQueryPipeline
();
main_pipeline
.
addInterpreterContext
(
context
);
res
.
pipeline
=
std
::
move
(
*
pipeline
);
res
.
pipeline
.
addInterpreterContext
(
context
);
return
res
;
return
res
;
}
}
...
...
src/Interpreters/InterpreterSelectWithUnionQuery.h
浏览文件 @
45adacf0
...
@@ -5,14 +5,12 @@
...
@@ -5,14 +5,12 @@
#include <Interpreters/SelectQueryOptions.h>
#include <Interpreters/SelectQueryOptions.h>
#include <Parsers/IAST_fwd.h>
#include <Parsers/IAST_fwd.h>
#include <Processors/QueryPipeline.h>
namespace
DB
namespace
DB
{
{
class
Context
;
class
Context
;
class
InterpreterSelectQuery
;
class
InterpreterSelectQuery
;
class
QueryPlan
;
/** Interprets one or multiple SELECT queries inside UNION ALL chain.
/** Interprets one or multiple SELECT queries inside UNION ALL chain.
*/
*/
...
@@ -27,6 +25,9 @@ public:
...
@@ -27,6 +25,9 @@ public:
~
InterpreterSelectWithUnionQuery
()
override
;
~
InterpreterSelectWithUnionQuery
()
override
;
/// Builds QueryPlan for current query.
void
buildQueryPlan
(
QueryPlan
&
query_plan
);
BlockIO
execute
()
override
;
BlockIO
execute
()
override
;
bool
ignoreLimits
()
const
override
{
return
options
.
ignore_limits
;
}
bool
ignoreLimits
()
const
override
{
return
options
.
ignore_limits
;
}
...
...
src/Processors/QueryPipeline.cpp
浏览文件 @
45adacf0
...
@@ -563,7 +563,7 @@ void QueryPipeline::setOutputFormat(ProcessorPtr output)
...
@@ -563,7 +563,7 @@ void QueryPipeline::setOutputFormat(ProcessorPtr output)
}
}
void
QueryPipeline
::
unitePipelines
(
void
QueryPipeline
::
unitePipelines
(
std
::
vector
<
QueryPipeline
>
&&
pipelines
,
const
Block
&
common_header
)
std
::
vector
<
std
::
unique_ptr
<
QueryPipeline
>>
pipelines
,
const
Block
&
common_header
)
{
{
if
(
initialized
())
if
(
initialized
())
{
{
...
@@ -583,8 +583,9 @@ void QueryPipeline::unitePipelines(
...
@@ -583,8 +583,9 @@ void QueryPipeline::unitePipelines(
if
(
totals_having_port
)
if
(
totals_having_port
)
totals
.
push_back
(
totals_having_port
);
totals
.
push_back
(
totals_having_port
);
for
(
auto
&
pipeline
:
pipelines
)
for
(
auto
&
pipeline
_ptr
:
pipelines
)
{
{
auto
&
pipeline
=
*
pipeline_ptr
;
pipeline
.
checkInitialized
();
pipeline
.
checkInitialized
();
if
(
!
pipeline
.
isCompleted
())
if
(
!
pipeline
.
isCompleted
())
...
...
src/Processors/QueryPipeline.h
浏览文件 @
45adacf0
...
@@ -135,7 +135,7 @@ public:
...
@@ -135,7 +135,7 @@ public:
void
enableQuotaForCurrentStreams
();
void
enableQuotaForCurrentStreams
();
void
unitePipelines
(
std
::
vector
<
QueryPipeline
>
&&
pipelines
,
const
Block
&
common_header
);
void
unitePipelines
(
std
::
vector
<
std
::
unique_ptr
<
QueryPipeline
>>
pipelines
,
const
Block
&
common_header
);
PipelineExecutorPtr
execute
();
PipelineExecutorPtr
execute
();
...
...
src/Processors/QueryPlan/ConvertingStep.cpp
0 → 100644
浏览文件 @
45adacf0
#include <Processors/QueryPlan/ConvertingStep.h>
#include <Processors/QueryPipeline.h>
#include <Processors/Transforms/ConvertingTransform.h>
namespace
DB
{
static
ITransformingStep
::
DataStreamTraits
getTraits
()
{
return
ITransformingStep
::
DataStreamTraits
{
.
preserves_distinct_columns
=
true
};
}
static
void
filterDistinctColumns
(
const
Block
&
res_header
,
NameSet
&
distinct_columns
)
{
if
(
distinct_columns
.
empty
())
return
;
NameSet
new_distinct_columns
;
for
(
const
auto
&
column
:
res_header
)
if
(
distinct_columns
.
count
(
column
.
name
))
new_distinct_columns
.
insert
(
column
.
name
);
distinct_columns
.
swap
(
new_distinct_columns
);
}
ConvertingStep
::
ConvertingStep
(
const
DataStream
&
input_stream_
,
Block
result_header_
)
:
ITransformingStep
(
input_stream_
,
result_header_
,
getTraits
())
,
result_header
(
std
::
move
(
result_header_
))
{
/// Some columns may be removed
filterDistinctColumns
(
output_stream
->
header
,
output_stream
->
distinct_columns
);
filterDistinctColumns
(
output_stream
->
header
,
output_stream
->
local_distinct_columns
);
}
void
ConvertingStep
::
transformPipeline
(
QueryPipeline
&
pipeline
)
{
pipeline
.
addSimpleTransform
([
&
](
const
Block
&
header
)
{
return
std
::
make_shared
<
ConvertingTransform
>
(
header
,
result_header
,
ConvertingTransform
::
MatchColumnsMode
::
Name
);
});
}
}
src/Processors/QueryPlan/ConvertingStep.h
0 → 100644
浏览文件 @
45adacf0
#pragma once
#include <Processors/QueryPlan/ITransformingStep.h>
namespace
DB
{
class
ConvertingStep
:
public
ITransformingStep
{
public:
ConvertingStep
(
const
DataStream
&
input_stream_
,
Block
result_header_
);
String
getName
()
const
override
{
return
"Converting"
;
}
void
transformPipeline
(
QueryPipeline
&
pipeline
)
override
;
private:
Block
result_header
;
};
}
src/Processors/QueryPlan/MergeSortingStep.cpp
浏览文件 @
45adacf0
...
@@ -40,7 +40,7 @@ void MergeSortingStep::transformPipeline(QueryPipeline & pipeline)
...
@@ -40,7 +40,7 @@ void MergeSortingStep::transformPipeline(QueryPipeline & pipeline)
return
std
::
make_shared
<
MergeSortingTransform
>
(
return
std
::
make_shared
<
MergeSortingTransform
>
(
header
,
description
,
max_merged_block_size
,
limit
,
header
,
description
,
max_merged_block_size
,
limit
,
max_bytes_before_remerge
,
max_bytes_before_remerge
/
pipeline
.
getNumStreams
()
,
max_bytes_before_external_sort
,
max_bytes_before_external_sort
,
tmp_volume
,
tmp_volume
,
min_free_disk_space
);
min_free_disk_space
);
...
...
src/Processors/QueryPlan/QueryPlan.cpp
浏览文件 @
45adacf0
...
@@ -35,6 +35,43 @@ const DataStream & QueryPlan::getCurrentDataStream() const
...
@@ -35,6 +35,43 @@ const DataStream & QueryPlan::getCurrentDataStream() const
return
root
->
step
->
getOutputStream
();
return
root
->
step
->
getOutputStream
();
}
}
void
QueryPlan
::
unitePlans
(
QueryPlanStepPtr
step
,
std
::
vector
<
QueryPlan
>
plans
)
{
if
(
isInitialized
())
throw
Exception
(
"Cannot unite plans because current QueryPlan is already initialized"
,
ErrorCodes
::
LOGICAL_ERROR
);
const
auto
&
inputs
=
step
->
getInputStreams
();
size_t
num_inputs
=
step
->
getInputStreams
().
size
();
if
(
num_inputs
!=
plans
.
size
())
{
throw
Exception
(
"Cannot unite QueryPlans using "
+
step
->
getName
()
+
" because step has different number of inputs. "
"Has "
+
std
::
to_string
(
plans
.
size
())
+
" plans "
"and "
+
std
::
to_string
(
num_inputs
)
+
" inputs"
,
ErrorCodes
::
LOGICAL_ERROR
);
}
for
(
size_t
i
=
0
;
i
<
num_inputs
;
++
i
)
{
const
auto
&
step_header
=
inputs
[
i
].
header
;
const
auto
&
plan_header
=
plans
[
i
].
getCurrentDataStream
().
header
;
if
(
!
blocksHaveEqualStructure
(
step_header
,
plan_header
))
throw
Exception
(
"Cannot unite QueryPlans using "
+
step
->
getName
()
+
" because "
"it has incompatible header with plan "
+
root
->
step
->
getName
()
+
" "
"plan header: "
+
plan_header
.
dumpStructure
()
+
"step header: "
+
step_header
.
dumpStructure
(),
ErrorCodes
::
LOGICAL_ERROR
);
}
for
(
auto
&
plan
:
plans
)
nodes
.
insert
(
nodes
.
end
(),
plan
.
nodes
.
begin
(),
plan
.
nodes
.
end
());
nodes
.
emplace_back
(
Node
{.
step
=
std
::
move
(
step
)});
root
=
&
nodes
.
back
();
for
(
auto
&
plan
:
plans
)
root
->
children
.
emplace_back
(
plan
.
root
);
}
void
QueryPlan
::
addStep
(
QueryPlanStepPtr
step
)
void
QueryPlan
::
addStep
(
QueryPlanStepPtr
step
)
{
{
checkNotCompleted
();
checkNotCompleted
();
...
@@ -48,6 +85,7 @@ void QueryPlan::addStep(QueryPlanStepPtr step)
...
@@ -48,6 +85,7 @@ void QueryPlan::addStep(QueryPlanStepPtr step)
"step has no inputs, but QueryPlan is already initialised"
,
ErrorCodes
::
LOGICAL_ERROR
);
"step has no inputs, but QueryPlan is already initialised"
,
ErrorCodes
::
LOGICAL_ERROR
);
nodes
.
emplace_back
(
Node
{.
step
=
std
::
move
(
step
)});
nodes
.
emplace_back
(
Node
{.
step
=
std
::
move
(
step
)});
root
=
&
nodes
.
back
();
return
;
return
;
}
}
...
@@ -100,7 +138,12 @@ QueryPipelinePtr QueryPlan::buildQueryPipeline()
...
@@ -100,7 +138,12 @@ QueryPipelinePtr QueryPlan::buildQueryPipeline()
size_t
next_child
=
frame
.
pipelines
.
size
();
size_t
next_child
=
frame
.
pipelines
.
size
();
if
(
next_child
==
frame
.
node
->
children
.
size
())
if
(
next_child
==
frame
.
node
->
children
.
size
())
{
{
bool
limit_max_threads
=
frame
.
pipelines
.
empty
();
last_pipeline
=
frame
.
node
->
step
->
updatePipeline
(
std
::
move
(
frame
.
pipelines
));
last_pipeline
=
frame
.
node
->
step
->
updatePipeline
(
std
::
move
(
frame
.
pipelines
));
if
(
limit_max_threads
)
last_pipeline
->
setMaxThreads
(
max_threads
);
stack
.
pop
();
stack
.
pop
();
}
}
else
else
...
...
src/Processors/QueryPlan/QueryPlan.h
浏览文件 @
45adacf0
...
@@ -18,6 +18,7 @@ using QueryPipelinePtr = std::unique_ptr<QueryPipeline>;
...
@@ -18,6 +18,7 @@ using QueryPipelinePtr = std::unique_ptr<QueryPipeline>;
class
QueryPlan
class
QueryPlan
{
{
public:
public:
void
unitePlans
(
QueryPlanStepPtr
step
,
std
::
vector
<
QueryPlan
>
plans
);
void
addStep
(
QueryPlanStepPtr
step
);
void
addStep
(
QueryPlanStepPtr
step
);
bool
isInitialized
()
const
{
return
root
!=
nullptr
;
}
/// Tree is not empty
bool
isInitialized
()
const
{
return
root
!=
nullptr
;
}
/// Tree is not empty
...
@@ -26,6 +27,10 @@ public:
...
@@ -26,6 +27,10 @@ public:
QueryPipelinePtr
buildQueryPipeline
();
QueryPipelinePtr
buildQueryPipeline
();
/// Set upper limit for the recommend number of threads. Will be applied to the newly-created pipelines.
/// TODO: make it in a better way.
void
setMaxThreads
(
size_t
max_threads_
)
{
max_threads
=
max_threads_
;
}
private:
private:
struct
Node
struct
Node
{
{
...
@@ -40,6 +45,8 @@ private:
...
@@ -40,6 +45,8 @@ private:
void
checkInitialized
()
const
;
void
checkInitialized
()
const
;
void
checkNotCompleted
()
const
;
void
checkNotCompleted
()
const
;
size_t
max_threads
=
0
;
};
};
}
}
src/Processors/QueryPlan/TotalsHavingStep.h
浏览文件 @
45adacf0
#pragma once
#pragma once
#include <Processors/QueryPlan/ITransformingStep.h>
#include <Processors/QueryPlan/ITransformingStep.h>
#include <DataStreams/SizeLimits.h>
namespace
DB
namespace
DB
{
{
...
...
src/Processors/QueryPlan/UnionStep.cpp
0 → 100644
浏览文件 @
45adacf0
#include <Processors/QueryPlan/UnionStep.h>
#include <Processors/QueryPipeline.h>
#include <Processors/Sources/NullSource.h>
#include <Interpreters/Context.h>
namespace
DB
{
UnionStep
::
UnionStep
(
DataStreams
input_streams_
,
Block
result_header
,
size_t
max_threads_
)
:
header
(
std
::
move
(
result_header
))
,
max_threads
(
max_threads_
)
{
input_streams
=
std
::
move
(
input_streams_
);
/// TODO: update traits
output_stream
=
DataStream
{.
header
=
header
};
}
QueryPipelinePtr
UnionStep
::
updatePipeline
(
QueryPipelines
pipelines
)
{
auto
pipeline
=
std
::
make_unique
<
QueryPipeline
>
();
if
(
pipelines
.
empty
())
{
pipeline
->
init
(
Pipe
(
std
::
make_shared
<
NullSource
>
(
output_stream
->
header
)));
return
pipeline
;
}
size_t
num_pipelines
=
pipelines
.
size
();
pipeline
->
unitePipelines
(
std
::
move
(
pipelines
),
output_stream
->
header
);
if
(
num_pipelines
>
1
)
{
// nested queries can force 1 thread (due to simplicity)
// but in case of union this cannot be done.
pipeline
->
setMaxThreads
(
std
::
min
<
UInt64
>
(
num_pipelines
,
max_threads
));
}
}
}
src/Processors/QueryPlan/UnionStep.h
0 → 100644
浏览文件 @
45adacf0
#pragma once
#include <Processors/QueryPlan/IQueryPlanStep.h>
namespace
DB
{
class
UnionStep
:
public
IQueryPlanStep
{
public:
/// max_threads is used to limit the number of threads for result pipeline.
UnionStep
(
DataStreams
input_streams_
,
Block
result_header
,
size_t
max_threads_
);
String
getName
()
const
override
{
return
"Union"
;
}
QueryPipelinePtr
updatePipeline
(
QueryPipelines
pipelines
)
override
;
private:
Block
header
;
size_t
max_threads
;
};
}
src/Processors/ya.make
浏览文件 @
45adacf0
...
@@ -139,6 +139,7 @@ SRCS(
...
@@ -139,6 +139,7 @@ SRCS(
Transforms/AggregatingInOrderTransform.cpp
Transforms/AggregatingInOrderTransform.cpp
QueryPlan/AddingDelayedStreamStep.cpp
QueryPlan/AddingDelayedStreamStep.cpp
QueryPlan/AggregatingStep.cpp
QueryPlan/AggregatingStep.cpp
QueryPlan/ConvertingStep.cpp
QueryPlan/CreatingSetsStep.cpp
QueryPlan/CreatingSetsStep.cpp
QueryPlan/CubeStep.cpp
QueryPlan/CubeStep.cpp
QueryPlan/DistinctStep.cpp
QueryPlan/DistinctStep.cpp
...
@@ -157,6 +158,7 @@ SRCS(
...
@@ -157,6 +158,7 @@ SRCS(
QueryPlan/MergingSortedStep.cpp
QueryPlan/MergingSortedStep.cpp
QueryPlan/OffsetsStep.cpp
QueryPlan/OffsetsStep.cpp
QueryPlan/PartialSortingStep.cpp
QueryPlan/PartialSortingStep.cpp
QueryPlan/UnionStep.cpp
QueryPlan/ReadFromPreparedSource.cpp
QueryPlan/ReadFromPreparedSource.cpp
QueryPlan/ReadFromStorageStep.cpp
QueryPlan/ReadFromStorageStep.cpp
QueryPlan/ReadNothingStep.cpp
QueryPlan/ReadNothingStep.cpp
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录