fix transform_null_in with sets of tuples

This commit is contained in:
Anton Popov 2020-11-05 21:07:44 +03:00
parent 045b274880
commit 8d42305184
6 changed files with 62 additions and 20 deletions

View File

@ -5,7 +5,7 @@
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;
@ -38,12 +38,7 @@ ColumnPtr extractNestedColumnsAndNullMap(ColumnRawPtrs & key_columns, ConstNullM
PaddedPODArray<UInt8> & mutable_null_map = assert_cast<ColumnUInt8 &>(*mutable_null_map_holder).getData();
const PaddedPODArray<UInt8> & other_null_map = column_nullable->getNullMapData();
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);
}

View File

@ -9,6 +9,6 @@ namespace DB
* In 'null_map' return a map of positions where at least one column was NULL.
* @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);
}

View File

@ -87,8 +87,6 @@ void NO_INLINE Set::insertFromBlockImplCase(
{
if ((*null_map)[i])
{
has_null = true;
if constexpr (build_filter)
{
(*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.
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)
{
@ -180,7 +180,9 @@ bool Set::insertFromBlock(const Block & block)
/// We will insert to the Set only keys, where all components are not NULL.
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.
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.
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);
executeOrdinary(key_columns, vec_res, negative, null_map);
@ -303,10 +306,7 @@ void NO_INLINE Set::executeImplCase(
{
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
{

View File

@ -108,10 +108,9 @@ private:
/// Do we need to additionally store all elements of the set in explicit form for subsequent use for index.
bool fill_set_elements;
/// If true, insert NULL values to set.
bool transform_null_in;
bool has_null = false;
/// Check if set contains all the data.
bool is_created = false;

View File

@ -0,0 +1,17 @@
4
2
2
1
0
3
==============
1
1
0
1
1
0
1
1
1
0

View 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;