mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 01:51:59 +00:00
Support ColumnConst(ColumnLowCardinality) in JoinCommon::convertColumnToNullable
This commit is contained in:
parent
dfccc85a33
commit
ae3726643d
@ -106,15 +106,42 @@ DataTypePtr convertTypeToNullable(const DataTypePtr & type)
|
||||
return type;
|
||||
}
|
||||
|
||||
static bool canBecomeNullable(const ColumnPtr & col)
|
||||
/// Convert column to nullable. If column LowCardinality or Const, convert nested column.
|
||||
/// Returns nullptr if conversion cannot be performed.
|
||||
static ColumnPtr tryConvertColumnToNullable(const ColumnPtr & col)
|
||||
{
|
||||
if (const ColumnConst * col_const = checkAndGetColumn<ColumnConst>(*col))
|
||||
return col_const->getDataColumnPtr()->isNullable() || col_const->getDataColumnPtr()->canBeInsideNullable();
|
||||
if (isColumnNullable(*col) || col->canBeInsideNullable())
|
||||
return makeNullable(col);
|
||||
|
||||
if (const ColumnLowCardinality * col_lc = checkAndGetColumn<ColumnLowCardinality>(*col))
|
||||
return col_lc->nestedIsNullable() || col_lc->nestedCanBeInsideNullable();
|
||||
|
||||
return isColumnNullable(*col) || col->canBeInsideNullable();
|
||||
if (col->lowCardinality())
|
||||
{
|
||||
auto mut_col = IColumn::mutate(std::move(col));
|
||||
ColumnLowCardinality * col_lc = assert_cast<ColumnLowCardinality *>(mut_col.get());
|
||||
if (col_lc->nestedIsNullable())
|
||||
{
|
||||
return mut_col;
|
||||
}
|
||||
else if (col_lc->nestedCanBeInsideNullable())
|
||||
{
|
||||
col_lc->nestedToNullable();
|
||||
return mut_col;
|
||||
}
|
||||
}
|
||||
else if (const ColumnConst * col_const = checkAndGetColumn<ColumnConst>(*col))
|
||||
{
|
||||
const auto & nested = col_const->getDataColumnPtr();
|
||||
if (nested->isNullable() || nested->canBeInsideNullable())
|
||||
{
|
||||
return makeNullable(col);
|
||||
}
|
||||
else if (nested->lowCardinality())
|
||||
{
|
||||
ColumnPtr nested_nullable = tryConvertColumnToNullable(nested);
|
||||
if (nested_nullable)
|
||||
return ColumnConst::create(nested_nullable, col_const->size());
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void convertColumnToNullable(ColumnWithTypeAndName & column)
|
||||
@ -125,23 +152,11 @@ void convertColumnToNullable(ColumnWithTypeAndName & column)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!canBecomeNullable(column.column))
|
||||
return;
|
||||
|
||||
column.type = convertTypeToNullable(column.type);
|
||||
|
||||
if (column.column->lowCardinality())
|
||||
ColumnPtr nullable_column = tryConvertColumnToNullable(column.column);
|
||||
if (nullable_column)
|
||||
{
|
||||
/// Convert nested to nullable, not LowCardinality itself
|
||||
auto mut_col = IColumn::mutate(std::move(column.column));
|
||||
ColumnLowCardinality * col_as_lc = assert_cast<ColumnLowCardinality *>(mut_col.get());
|
||||
if (!col_as_lc->nestedIsNullable())
|
||||
col_as_lc->nestedToNullable();
|
||||
column.column = std::move(mut_col);
|
||||
}
|
||||
else
|
||||
{
|
||||
column.column = makeNullable(column.column);
|
||||
column.type = convertTypeToNullable(column.type);
|
||||
column.column = std::move(nullable_column);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1 +1,8 @@
|
||||
1 2 3 1 3
|
||||
1 UInt8 2 UInt8 3 Nullable(UInt8)
|
||||
1 LowCardinality(UInt8) 2 LowCardinality(UInt8) 3 LowCardinality(Nullable(UInt8))
|
||||
1 LowCardinality(UInt8) 2 LowCardinality(UInt8) 1 LowCardinality(Nullable(UInt8))
|
||||
1 UInt8 2 UInt8 3 Nullable(UInt8)
|
||||
1 UInt8 2 UInt8 1 Nullable(UInt8) 3 Nullable(UInt8)
|
||||
1 LowCardinality(UInt8) 2 LowCardinality(UInt8) 3 LowCardinality(Nullable(UInt8))
|
||||
1 LowCardinality(UInt8) 2 LowCardinality(UInt8) 1 LowCardinality(Nullable(UInt8)) 3 LowCardinality(Nullable(UInt8))
|
||||
|
@ -1 +1,11 @@
|
||||
SELECT *, d.* FROM ( SELECT 1 AS id, 2 AS value ) a SEMI LEFT JOIN ( SELECT 1 AS id, 3 AS values ) AS d USING id SETTINGS join_use_nulls=1;
|
||||
SET join_use_nulls = 1;
|
||||
|
||||
SELECT *, d.* FROM ( SELECT 1 AS id, 2 AS value ) a SEMI LEFT JOIN ( SELECT 1 AS id, 3 AS values ) AS d USING id;
|
||||
|
||||
SELECT id, toTypeName(id), value, toTypeName(value), d.values, toTypeName(d.values) FROM ( SELECT 1 AS id, 2 AS value ) a SEMI LEFT JOIN ( SELECT 1 AS id, 3 AS values ) AS d USING id;
|
||||
SELECT id, toTypeName(id), value, toTypeName(value), d.values, toTypeName(d.values) FROM ( SELECT toLowCardinality(1) AS id, toLowCardinality(2) AS value ) a SEMI LEFT JOIN ( SELECT toLowCardinality(1) AS id, toLowCardinality(3) AS values ) AS d USING id;
|
||||
SELECT id, toTypeName(id), value, toTypeName(value), d.id, toTypeName(d.id) FROM ( SELECT toLowCardinality(1) AS id, toLowCardinality(2) AS value ) a SEMI LEFT JOIN ( SELECT toLowCardinality(1) AS id, toLowCardinality(3) AS values ) AS d USING id;
|
||||
SELECT id, toTypeName(id), value, toTypeName(value), d.values, toTypeName(d.values) FROM ( SELECT 1 AS id, 2 AS value ) a SEMI LEFT JOIN ( SELECT 1 AS id, 3 AS values ) AS d USING id;
|
||||
SELECT id, toTypeName(id), value, toTypeName(value), d.id, toTypeName(d.id) , d.values, toTypeName(d.values) FROM ( SELECT 1 AS id, 2 AS value ) a SEMI LEFT JOIN ( SELECT 1 AS id, 3 AS values ) AS d USING id;
|
||||
SELECT id, toTypeName(id), value, toTypeName(value), d.values, toTypeName(d.values) FROM ( SELECT toLowCardinality(1) AS id, toLowCardinality(2) AS value ) a SEMI LEFT JOIN ( SELECT toLowCardinality(1) AS id, toLowCardinality(3) AS values ) AS d USING id;
|
||||
SELECT id, toTypeName(id), value, toTypeName(value), d.id, toTypeName(d.id) , d.values, toTypeName(d.values) FROM ( SELECT toLowCardinality(1) AS id, toLowCardinality(2) AS value ) a SEMI LEFT JOIN ( SELECT toLowCardinality(1) AS id, toLowCardinality(3) AS values ) AS d USING id;
|
||||
|
Loading…
Reference in New Issue
Block a user