mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
fix transform_null_in with sets of tuples
This commit is contained in:
parent
045b274880
commit
8d42305184
@ -5,7 +5,7 @@
|
|||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
ColumnPtr extractNestedColumnsAndNullMap(ColumnRawPtrs & key_columns, ConstNullMapPtr & null_map, bool exact_null)
|
ColumnPtr extractNestedColumnsAndNullMap(ColumnRawPtrs & key_columns, ConstNullMapPtr & null_map)
|
||||||
{
|
{
|
||||||
ColumnPtr null_map_holder;
|
ColumnPtr null_map_holder;
|
||||||
|
|
||||||
@ -38,12 +38,7 @@ ColumnPtr extractNestedColumnsAndNullMap(ColumnRawPtrs & key_columns, ConstNullM
|
|||||||
PaddedPODArray<UInt8> & mutable_null_map = assert_cast<ColumnUInt8 &>(*mutable_null_map_holder).getData();
|
PaddedPODArray<UInt8> & mutable_null_map = assert_cast<ColumnUInt8 &>(*mutable_null_map_holder).getData();
|
||||||
const PaddedPODArray<UInt8> & other_null_map = column_nullable->getNullMapData();
|
const PaddedPODArray<UInt8> & other_null_map = column_nullable->getNullMapData();
|
||||||
for (size_t i = 0, size = mutable_null_map.size(); i < size; ++i)
|
for (size_t i = 0, size = mutable_null_map.size(); i < size; ++i)
|
||||||
{
|
|
||||||
if (exact_null)
|
|
||||||
mutable_null_map[i] &= other_null_map[i];
|
|
||||||
else
|
|
||||||
mutable_null_map[i] |= other_null_map[i];
|
mutable_null_map[i] |= other_null_map[i];
|
||||||
}
|
|
||||||
|
|
||||||
null_map_holder = std::move(mutable_null_map_holder);
|
null_map_holder = std::move(mutable_null_map_holder);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,6 @@ namespace DB
|
|||||||
* In 'null_map' return a map of positions where at least one column was NULL.
|
* In 'null_map' return a map of positions where at least one column was NULL.
|
||||||
* @returns ownership column of null_map.
|
* @returns ownership column of null_map.
|
||||||
*/
|
*/
|
||||||
ColumnPtr extractNestedColumnsAndNullMap(ColumnRawPtrs & key_columns, ConstNullMapPtr & null_map, bool exact_null = false);
|
ColumnPtr extractNestedColumnsAndNullMap(ColumnRawPtrs & key_columns, ConstNullMapPtr & null_map);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -87,8 +87,6 @@ void NO_INLINE Set::insertFromBlockImplCase(
|
|||||||
{
|
{
|
||||||
if ((*null_map)[i])
|
if ((*null_map)[i])
|
||||||
{
|
{
|
||||||
has_null = true;
|
|
||||||
|
|
||||||
if constexpr (build_filter)
|
if constexpr (build_filter)
|
||||||
{
|
{
|
||||||
(*out_filter)[i] = false;
|
(*out_filter)[i] = false;
|
||||||
@ -140,7 +138,9 @@ void Set::setHeader(const Block & header)
|
|||||||
|
|
||||||
/// We will insert to the Set only keys, where all components are not NULL.
|
/// We will insert to the Set only keys, where all components are not NULL.
|
||||||
ConstNullMapPtr null_map{};
|
ConstNullMapPtr null_map{};
|
||||||
ColumnPtr null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map, transform_null_in);
|
ColumnPtr null_map_holder;
|
||||||
|
if (!transform_null_in)
|
||||||
|
extractNestedColumnsAndNullMap(key_columns, null_map);
|
||||||
|
|
||||||
if (fill_set_elements)
|
if (fill_set_elements)
|
||||||
{
|
{
|
||||||
@ -180,7 +180,9 @@ bool Set::insertFromBlock(const Block & block)
|
|||||||
|
|
||||||
/// We will insert to the Set only keys, where all components are not NULL.
|
/// We will insert to the Set only keys, where all components are not NULL.
|
||||||
ConstNullMapPtr null_map{};
|
ConstNullMapPtr null_map{};
|
||||||
ColumnPtr null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map, transform_null_in);
|
ColumnPtr null_map_holder;
|
||||||
|
if (!transform_null_in)
|
||||||
|
null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map);
|
||||||
|
|
||||||
/// Filter to extract distinct values from the block.
|
/// Filter to extract distinct values from the block.
|
||||||
ColumnUInt8::MutablePtr filter;
|
ColumnUInt8::MutablePtr filter;
|
||||||
@ -259,8 +261,9 @@ ColumnPtr Set::execute(const Block & block, bool negative) const
|
|||||||
|
|
||||||
/// We will check existence in Set only for keys, where all components are not NULL.
|
/// We will check existence in Set only for keys, where all components are not NULL.
|
||||||
ConstNullMapPtr null_map{};
|
ConstNullMapPtr null_map{};
|
||||||
|
ColumnPtr null_map_holder;
|
||||||
ColumnPtr null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map, transform_null_in);
|
if (!transform_null_in)
|
||||||
|
null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map);
|
||||||
|
|
||||||
executeOrdinary(key_columns, vec_res, negative, null_map);
|
executeOrdinary(key_columns, vec_res, negative, null_map);
|
||||||
|
|
||||||
@ -303,9 +306,6 @@ void NO_INLINE Set::executeImplCase(
|
|||||||
{
|
{
|
||||||
if (has_null_map && (*null_map)[i])
|
if (has_null_map && (*null_map)[i])
|
||||||
{
|
{
|
||||||
if (transform_null_in && has_null)
|
|
||||||
vec_res[i] = !negative;
|
|
||||||
else
|
|
||||||
vec_res[i] = negative;
|
vec_res[i] = negative;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -108,10 +108,9 @@ private:
|
|||||||
/// Do we need to additionally store all elements of the set in explicit form for subsequent use for index.
|
/// Do we need to additionally store all elements of the set in explicit form for subsequent use for index.
|
||||||
bool fill_set_elements;
|
bool fill_set_elements;
|
||||||
|
|
||||||
|
/// If true, insert NULL values to set.
|
||||||
bool transform_null_in;
|
bool transform_null_in;
|
||||||
|
|
||||||
bool has_null = false;
|
|
||||||
|
|
||||||
/// Check if set contains all the data.
|
/// Check if set contains all the data.
|
||||||
bool is_created = false;
|
bool is_created = false;
|
||||||
|
|
||||||
|
17
tests/queries/0_stateless/01558_transform_null_in.reference
Normal file
17
tests/queries/0_stateless/01558_transform_null_in.reference
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
4
|
||||||
|
2
|
||||||
|
2
|
||||||
|
1
|
||||||
|
0
|
||||||
|
3
|
||||||
|
==============
|
||||||
|
1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
0
|
31
tests/queries/0_stateless/01558_transform_null_in.sql
Normal file
31
tests/queries/0_stateless/01558_transform_null_in.sql
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
SET transform_null_in = 1;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS null_in_1;
|
||||||
|
CREATE TABLE null_in_1 (u UInt32, n Nullable(UInt32)) ENGINE = Memory;
|
||||||
|
INSERT INTO null_in_1 VALUES (1, NULL), (2, 2), (3, NULL), (4, 4), (5, NULL);
|
||||||
|
|
||||||
|
SELECT count() FROM null_in_1 WHERE n IN (1, 2, NULL);
|
||||||
|
SELECT count() FROM null_in_1 WHERE u IN (1, 2, NULL);
|
||||||
|
SELECT count() FROM null_in_1 WHERE (u, n) IN ((1, 2), (1, NULL), (2, 2));
|
||||||
|
SELECT count() FROM null_in_1 WHERE (u, n) IN ((NULL, NULL), (2, 2), (NULL, 2));
|
||||||
|
SELECT count() FROM null_in_1 WHERE (u, n) IN (42, NULL);
|
||||||
|
SELECT count() FROM null_in_1 WHERE (u, n) NOT IN ((3, NULL), (5, NULL));
|
||||||
|
|
||||||
|
SELECT '==============';
|
||||||
|
DROP TABLE IF EXISTS null_in_1;
|
||||||
|
|
||||||
|
CREATE TABLE null_in_1 (a Nullable(UInt32), b Nullable(UInt32)) ENGINE = Memory;
|
||||||
|
INSERT INTO null_in_1 VALUES (1, NULL) (0, NULL) (NULL, NULL) (NULL, 1) (NULL, 0) (0, 0) (1, 1);
|
||||||
|
|
||||||
|
SELECT count() FROM null_in_1 WHERE (a, b) IN (1, NULL);
|
||||||
|
SELECT count() FROM null_in_1 WHERE (a, b) IN (0, NULL);
|
||||||
|
SELECT count() FROM null_in_1 WHERE (a, b) IN (42, NULL);
|
||||||
|
SELECT count() FROM null_in_1 WHERE (a, b) IN (NULL, 0);
|
||||||
|
SELECT count() FROM null_in_1 WHERE (a, b) IN (NULL, 1);
|
||||||
|
SELECT count() FROM null_in_1 WHERE (a, b) IN (NULL, 42);
|
||||||
|
SELECT count() FROM null_in_1 WHERE (a, b) IN (NULL, NULL);
|
||||||
|
SELECT count() FROM null_in_1 WHERE (a, b) IN (0, 0);
|
||||||
|
SELECT count() FROM null_in_1 WHERE (a, b) IN (1, 1);
|
||||||
|
SELECT count() FROM null_in_1 WHERE (a, b) IN (1, 42);
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS null_in_1;
|
Loading…
Reference in New Issue
Block a user