ClickHouse/dbms/src/Storages/StorageJoin.cpp
Amos Bird dc6847d5c6
Fixes StorageJoin's sample block order.
Here is a reproducible test case.
```
create table e (s UInt64, t UInt64) Engine = Memory;
create table v (s UInt64, w Float64, c UInt64) Engine = Join(Any, Inner, s);
insert into e values (1, 2), (1, 3), (1, 4), (2, 1), (2, 4), (3, 1), (4, 2), (4, 3);
insert into v values (1, 0.5, 3), (2, 0.5, 2), (3, 1, 1), (4, 0.5, 2);
select *, w, c from e any inner join v using (s);
```

# before this patch
```
┌─s─┬─t─┬─────w─┬──────────c─┐
│ 1 │ 2 │ 4e-45 │ 1051372192 │
│ 1 │ 3 │ 4e-45 │ 1051372192 │
│ 1 │ 4 │ 4e-45 │ 1051372192 │
│ 2 │ 1 │ 3e-45 │ 1056964608 │
│ 2 │ 4 │ 3e-45 │ 1056964608 │
│ 3 │ 1 │ 1e-45 │ 1065353216 │
│ 4 │ 2 │ 3e-45 │ 1056964608 │
│ 4 │ 3 │ 3e-45 │ 1056964608 │
└───┴───┴───────┴────────────┘
```
# after this patch
```
┌─s─┬─t─┬───w─┬─c─┐
│ 1 │ 2 │ 0.5 │ 3 │
│ 1 │ 3 │ 0.5 │ 3 │
│ 1 │ 4 │ 0.5 │ 3 │
│ 2 │ 1 │ 0.5 │ 2 │
│ 2 │ 4 │ 0.5 │ 2 │
│ 3 │ 1 │   1 │ 1 │
│ 4 │ 2 │ 0.5 │ 2 │
│ 4 │ 3 │ 0.5 │ 2 │
└───┴───┴─────┴───┘
```
2017-11-20 19:46:24 +08:00

63 lines
2.0 KiB
C++

#include <Storages/StorageJoin.h>
#include <Interpreters/Join.h>
#include <Interpreters/Limits.h>
namespace DB
{
namespace ErrorCodes
{
extern const int NO_SUCH_COLUMN_IN_TABLE;
extern const int INCOMPATIBLE_TYPE_OF_JOIN;
}
StorageJoin::StorageJoin(
const String & path_,
const String & name_,
const Names & key_names_,
ASTTableJoin::Kind kind_, ASTTableJoin::Strictness strictness_,
NamesAndTypesListPtr columns_,
const NamesAndTypesList & materialized_columns_,
const NamesAndTypesList & alias_columns_,
const ColumnDefaults & column_defaults_)
: StorageSetOrJoinBase{path_, name_, columns_, materialized_columns_, alias_columns_, column_defaults_},
key_names(key_names_), kind(kind_), strictness(strictness_)
{
/// Check that key exists in table definition.
const auto check_key_exists = [] (const NamesAndTypesList & columns, const String & key)
{
for (const auto & column : columns)
if (column.name == key)
return true;
return false;
};
for (const auto & key : key_names)
if (!check_key_exists(*columns, key) && !check_key_exists(materialized_columns, key))
throw Exception{
"Key column (" + key + ") does not exist in table declaration.",
ErrorCodes::NO_SUCH_COLUMN_IN_TABLE};
/// NOTE StorageJoin doesn't use join_use_nulls setting.
join = std::make_shared<Join>(key_names, key_names, false /* use_nulls */, Limits(), kind, strictness);
join->setSampleBlock(getSampleBlock().sortColumns());
restore();
}
void StorageJoin::assertCompatible(ASTTableJoin::Kind kind_, ASTTableJoin::Strictness strictness_) const
{
/// NOTE Could be more loose.
if (!(kind == kind_ && strictness == strictness_))
throw Exception("Table " + name + " has incompatible type of JOIN.", ErrorCodes::INCOMPATIBLE_TYPE_OF_JOIN);
}
void StorageJoin::insertBlock(const Block & block) { join->insertFromBlock(block); }
size_t StorageJoin::getSize() const { return join->getTotalRowCount(); };
}