Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
e4e313f5
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,发现更多精彩内容 >>
提交
e4e313f5
编写于
1月 28, 2015
作者:
A
Alexey Milovidov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
dbms: StorageJoin: development [#METR-2944].
上级
2b0b4d05
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
92 addition
and
24 deletion
+92
-24
dbms/include/DB/Core/ErrorCodes.h
dbms/include/DB/Core/ErrorCodes.h
+1
-0
dbms/include/DB/DataStreams/CreatingSetsBlockInputStream.h
dbms/include/DB/DataStreams/CreatingSetsBlockInputStream.h
+2
-1
dbms/include/DB/Storages/StorageJoin.h
dbms/include/DB/Storages/StorageJoin.h
+3
-0
dbms/src/DataStreams/CreatingSetsBlockInputStream.cpp
dbms/src/DataStreams/CreatingSetsBlockInputStream.cpp
+6
-4
dbms/src/Interpreters/Context.cpp
dbms/src/Interpreters/Context.cpp
+12
-13
dbms/src/Interpreters/ExpressionAnalyzer.cpp
dbms/src/Interpreters/ExpressionAnalyzer.cpp
+24
-5
dbms/src/Storages/StorageFactory.cpp
dbms/src/Storages/StorageFactory.cpp
+1
-1
dbms/src/Storages/StorageJoin.cpp
dbms/src/Storages/StorageJoin.cpp
+8
-0
dbms/tests/queries/0_stateless/00118_storage_join.reference
dbms/tests/queries/0_stateless/00118_storage_join.reference
+20
-0
dbms/tests/queries/0_stateless/00118_storage_join.sql
dbms/tests/queries/0_stateless/00118_storage_join.sql
+15
-0
未找到文件。
dbms/include/DB/Core/ErrorCodes.h
浏览文件 @
e4e313f5
...
...
@@ -271,6 +271,7 @@ namespace ErrorCodes
UNKNOWN_BLOCK_INFO_FIELD
,
BAD_COLLATION
,
CANNOT_COMPILE_CODE
,
INCOMPATIBLE_TYPE_OF_JOIN
,
POCO_EXCEPTION
=
1000
,
STD_EXCEPTION
,
...
...
dbms/include/DB/DataStreams/CreatingSetsBlockInputStream.h
浏览文件 @
e4e313f5
...
...
@@ -24,7 +24,8 @@ public:
transfer_overflow_mode
(
limits
.
transfer_overflow_mode
)
{
for
(
auto
&
elem
:
subqueries_for_sets
)
children
.
push_back
(
elem
.
second
.
source
);
if
(
elem
.
second
.
source
)
children
.
push_back
(
elem
.
second
.
source
);
children
.
push_back
(
input
);
}
...
...
dbms/include/DB/Storages/StorageJoin.h
浏览文件 @
e4e313f5
...
...
@@ -39,6 +39,9 @@ public:
/// Получить доступ к внутренностям.
JoinPtr
&
getJoin
()
{
return
join
;
}
/// Убедиться, что структура данных подходит для осуществления JOIN такого типа.
void
assertCompatible
(
ASTJoin
::
Kind
kind_
,
ASTJoin
::
Strictness
strictness_
)
const
;
private:
const
Names
&
key_names
;
ASTJoin
::
Kind
kind
;
/// LEFT | INNER
...
...
dbms/src/DataStreams/CreatingSetsBlockInputStream.cpp
浏览文件 @
e4e313f5
...
...
@@ -10,12 +10,14 @@ Block CreatingSetsBlockInputStream::readImpl()
if
(
!
created
)
{
/// Заполнение временных таблиц идёт первым - потому что эти таблицы могут затем использоваться для создания Set/Join.
for
(
auto
&
elem
:
subqueries_for_sets
)
{
create
(
elem
.
second
);
if
(
isCancelled
())
return
res
;
if
(
elem
.
second
.
source
)
/// Бывают заранее подготовленные Set/Join - для них не указывается source.
{
create
(
elem
.
second
);
if
(
isCancelled
())
return
res
;
}
}
created
=
true
;
...
...
dbms/src/Interpreters/Context.cpp
浏览文件 @
e4e313f5
...
...
@@ -132,8 +132,8 @@ void Context::assertTableExists(const String & database_name, const String & tab
String
db
=
database_name
.
empty
()
?
current_database
:
database_name
;
Databases
::
const_iterator
it
;
if
(
shared
->
databases
.
end
()
==
(
it
=
shared
->
databases
.
find
(
db
))
)
Databases
::
const_iterator
it
=
shared
->
databases
.
find
(
db
)
;
if
(
shared
->
databases
.
end
()
==
it
)
throw
Exception
(
"Database "
+
db
+
" doesn't exist"
,
ErrorCodes
::
UNKNOWN_DATABASE
);
if
(
it
->
second
.
end
()
==
it
->
second
.
find
(
table_name
))
...
...
@@ -199,8 +199,8 @@ StoragePtr Context::tryGetExternalTable(const String & table_name) const
{
Poco
::
ScopedLock
<
Poco
::
Mutex
>
lock
(
shared
->
mutex
);
Tables
::
const_iterator
jt
;
if
(
external_tables
.
end
()
==
(
jt
=
external_tables
.
find
(
table_name
))
)
Tables
::
const_iterator
jt
=
external_tables
.
find
(
table_name
)
;
if
(
external_tables
.
end
()
==
jt
)
return
StoragePtr
();
return
jt
->
second
;
...
...
@@ -211,9 +211,6 @@ StoragePtr Context::getTable(const String & database_name, const String & table_
{
Poco
::
ScopedLock
<
Poco
::
Mutex
>
lock
(
shared
->
mutex
);
Databases
::
const_iterator
it
;
Tables
::
const_iterator
jt
;
if
(
database_name
.
empty
())
{
StoragePtr
res
;
...
...
@@ -226,10 +223,12 @@ StoragePtr Context::getTable(const String & database_name, const String & table_
}
String
db
=
database_name
.
empty
()
?
current_database
:
database_name
;
if
(
shared
->
databases
.
end
()
==
(
it
=
shared
->
databases
.
find
(
db
)))
Databases
::
const_iterator
it
=
shared
->
databases
.
find
(
db
);
if
(
shared
->
databases
.
end
()
==
it
)
throw
Exception
(
"Database "
+
db
+
" doesn't exist"
,
ErrorCodes
::
UNKNOWN_DATABASE
);
if
(
it
->
second
.
end
()
==
(
jt
=
it
->
second
.
find
(
table_name
)))
Tables
::
const_iterator
jt
=
it
->
second
.
find
(
table_name
);
if
(
it
->
second
.
end
()
==
jt
)
throw
Exception
(
"Table "
+
db
+
"."
+
table_name
+
" doesn't exist."
,
ErrorCodes
::
UNKNOWN_TABLE
);
return
jt
->
second
;
...
...
@@ -252,12 +251,12 @@ StoragePtr Context::tryGetTable(const String & database_name, const String & tab
}
String
db
=
database_name
.
empty
()
?
current_database
:
database_name
;
Databases
::
const_iterator
it
;
if
(
shared
->
databases
.
end
()
==
(
it
=
shared
->
databases
.
find
(
db
))
)
Databases
::
const_iterator
it
=
shared
->
databases
.
find
(
db
)
;
if
(
shared
->
databases
.
end
()
==
it
)
return
StoragePtr
();
Tables
::
const_iterator
jt
;
if
(
it
->
second
.
end
()
==
(
jt
=
it
->
second
.
find
(
table_name
))
)
Tables
::
const_iterator
jt
=
it
->
second
.
find
(
table_name
)
;
if
(
it
->
second
.
end
()
==
jt
)
return
StoragePtr
();
return
jt
->
second
;
...
...
dbms/src/Interpreters/ExpressionAnalyzer.cpp
浏览文件 @
e4e313f5
...
...
@@ -22,11 +22,10 @@
#include <DB/Interpreters/InterpreterSelectQuery.h>
#include <DB/Interpreters/ExpressionAnalyzer.h>
#include <DB/Storages/StorageMergeTree.h>
#include <DB/Storages/StorageDistributed.h>
#include <DB/Storages/StorageMemory.h>
#include <DB/Storages/StorageReplicatedMergeTree.h>
#include <DB/Storages/StorageSet.h>
#include <DB/Storages/StorageJoin.h>
#include <DB/DataStreams/LazyBlockInputStream.h>
#include <DB/DataStreams/copyData.h>
...
...
@@ -1431,15 +1430,35 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty
String
join_id
=
ast_join
.
table
->
getColumnName
();
SubqueryForSet
&
subquery_for_set
=
subqueries_for_sets
[
join_id
];
/// Особый случай - если справа JOIN указано имя таблицы, при чём, таблица имеет тип Join (заранее подготовленное отображение).
/// TODO В этом синтаксисе не поддерживается указание имени БД.
ASTIdentifier
*
identifier
=
typeid_cast
<
ASTIdentifier
*>
(
&*
ast_join
.
table
);
if
(
identifier
)
{
StoragePtr
table
=
context
.
tryGetTable
(
""
,
identifier
->
name
);
if
(
table
)
{
StorageJoin
*
storage_join
=
typeid_cast
<
StorageJoin
*>
(
table
.
get
());
if
(
storage_join
)
{
storage_join
->
assertCompatible
(
ast_join
.
kind
,
ast_join
.
strictness
);
/// TODO Проверять набор ключей.
JoinPtr
&
join
=
storage_join
->
getJoin
();
subquery_for_set
.
join
=
join
;
}
}
}
if
(
!
subquery_for_set
.
join
)
{
Names
join_key_names_left
(
join_key_names_left_set
.
begin
(),
join_key_names_left_set
.
end
());
Names
join_key_names_right
(
join_key_names_right_set
.
begin
(),
join_key_names_right_set
.
end
());
JoinPtr
join
=
new
Join
(
join_key_names_left
,
join_key_names_right
,
settings
.
limits
,
ast_join
.
kind
,
ast_join
.
strictness
);
/* for (const auto & name_type : columns_added_by_join)
std::cerr << "! Column added by JOIN: " << name_type.name << std::endl;*/
Names
required_joined_columns
(
join_key_names_right
.
begin
(),
join_key_names_right
.
end
());
for
(
const
auto
&
name_type
:
columns_added_by_join
)
required_joined_columns
.
push_back
(
name_type
.
name
);
...
...
dbms/src/Storages/StorageFactory.cpp
浏览文件 @
e4e313f5
...
...
@@ -216,7 +216,7 @@ StoragePtr StorageFactory::get(
if
(
!
kind_id
)
throw
Exception
(
"Second parameter of storage Join must be LEFT or INNER (without quotes)."
,
ErrorCodes
::
BAD_ARGUMENTS
);
const
String
kind_str
=
Poco
::
toLower
(
strictness
_id
->
name
);
const
String
kind_str
=
Poco
::
toLower
(
kind
_id
->
name
);
ASTJoin
::
Kind
kind
;
if
(
kind_str
==
"left"
)
kind
=
ASTJoin
::
Kind
::
Left
;
...
...
dbms/src/Storages/StorageJoin.cpp
浏览文件 @
e4e313f5
...
...
@@ -37,4 +37,12 @@ StorageJoin::StorageJoin(
}
void
StorageJoin
::
assertCompatible
(
ASTJoin
::
Kind
kind_
,
ASTJoin
::
Strictness
strictness_
)
const
{
/// NOTE Можно немного ослабить.
if
(
!
(
kind
==
kind_
&&
strictness
==
strictness_
))
throw
Exception
(
"Table "
+
name
+
" has incompatible type of JOIN."
,
ErrorCodes
::
INCOMPATIBLE_TYPE_OF_JOIN
);
}
}
dbms/tests/queries/0_stateless/00118_storage_join.reference
0 → 100644
浏览文件 @
e4e313f5
0
1 abc
2 def
3
4
5
6
7
8
9
0
1 abc
2 def
3
4
5
6 ghi
7
8
9
dbms/tests/queries/0_stateless/00118_storage_join.sql
0 → 100644
浏览文件 @
e4e313f5
DROP
TABLE
IF
EXISTS
test
.
join
;
CREATE
TABLE
test
.
join
(
k
UInt8
,
s
String
)
ENGINE
=
Join
(
ANY
,
LEFT
,
k
);
USE
test
;
INSERT
INTO
test
.
join
VALUES
(
1
,
'abc'
),
(
2
,
'def'
);
SELECT
k
,
s
FROM
(
SELECT
number
AS
k
FROM
system
.
numbers
LIMIT
10
)
ANY
LEFT
JOIN
join
USING
k
;
INSERT
INTO
test
.
join
VALUES
(
6
,
'ghi'
);
SELECT
k
,
s
FROM
(
SELECT
number
AS
k
FROM
system
.
numbers
LIMIT
10
)
ANY
LEFT
JOIN
join
USING
k
;
USE
default
;
DROP
TABLE
test
.
join
;
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录