mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-15 19:02:04 +00:00
parent
db4735a105
commit
adb46fa174
@ -510,7 +510,7 @@ ColumnPtr FunctionArrayIntersect::execute(const UnpackedArrays & arrays, Mutable
|
|||||||
map.clear();
|
map.clear();
|
||||||
|
|
||||||
bool all_has_nullable = all_nullable;
|
bool all_has_nullable = all_nullable;
|
||||||
bool current_has_nullable;
|
bool current_has_nullable = false;
|
||||||
|
|
||||||
for (size_t arg_num = 0; arg_num < args; ++arg_num)
|
for (size_t arg_num = 0; arg_num < args; ++arg_num)
|
||||||
{
|
{
|
||||||
@ -549,8 +549,7 @@ ColumnPtr FunctionArrayIntersect::execute(const UnpackedArrays & arrays, Mutable
|
|||||||
++(*value);
|
++(*value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We update offsets for all the arrays except the first one. Offsets for the first array would be updated later.
|
|
||||||
// It is needed to iterate the first array again so that the elements in the result would have fixed order.
|
|
||||||
if (arg_num)
|
if (arg_num)
|
||||||
{
|
{
|
||||||
prev_off[arg_num] = off;
|
prev_off[arg_num] = off;
|
||||||
@ -571,21 +570,15 @@ ColumnPtr FunctionArrayIntersect::execute(const UnpackedArrays & arrays, Mutable
|
|||||||
else
|
else
|
||||||
off = (*arg.offsets)[row];
|
off = (*arg.offsets)[row];
|
||||||
|
|
||||||
bool is_map_serialized = false;
|
|
||||||
for (auto i : collections::range(prev_off[0], off))
|
for (auto i : collections::range(prev_off[0], off))
|
||||||
{
|
{
|
||||||
|
all_has_nullable = all_nullable;
|
||||||
|
current_has_nullable = false;
|
||||||
typename Map::LookupResult pair = nullptr;
|
typename Map::LookupResult pair = nullptr;
|
||||||
|
|
||||||
if (arg.null_map && (*arg.null_map)[i])
|
if (arg.null_map && (*arg.null_map)[i])
|
||||||
{
|
{
|
||||||
current_has_nullable = true;
|
current_has_nullable = true;
|
||||||
if (all_has_nullable && !null_added)
|
|
||||||
{
|
|
||||||
++result_offset;
|
|
||||||
result_data.insertDefault();
|
|
||||||
null_map.push_back(1);
|
|
||||||
null_added = true;
|
|
||||||
}
|
|
||||||
if (null_added)
|
if (null_added)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -598,37 +591,51 @@ ColumnPtr FunctionArrayIntersect::execute(const UnpackedArrays & arrays, Mutable
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char * data = nullptr;
|
const char * data = nullptr;
|
||||||
if (!is_map_serialized)
|
|
||||||
{
|
|
||||||
pair = map.find(columns[0]->serializeValueIntoArena(i, arena, data));
|
pair = map.find(columns[0]->serializeValueIntoArena(i, arena, data));
|
||||||
is_map_serialized = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
prev_off[0] = off;
|
prev_off[0] = off;
|
||||||
if (arg.is_const)
|
if (arg.is_const)
|
||||||
prev_off[0] = 0;
|
prev_off[0] = 0;
|
||||||
|
|
||||||
|
if (!current_has_nullable)
|
||||||
|
all_has_nullable = false;
|
||||||
|
|
||||||
if (pair && pair->getMapped() == args)
|
if (pair && pair->getMapped() == args)
|
||||||
{
|
{
|
||||||
// We increase pair->getMapped() here to not skip duplicate values from the first array.
|
|
||||||
++pair->getMapped();
|
++pair->getMapped();
|
||||||
++result_offset;
|
++result_offset;
|
||||||
if constexpr (is_numeric_column)
|
if constexpr (is_numeric_column)
|
||||||
|
{
|
||||||
|
if (pair->getKey() == columns[0]->getElement(i))
|
||||||
{
|
{
|
||||||
result_data.insertValue(pair->getKey());
|
result_data.insertValue(pair->getKey());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if constexpr (std::is_same_v<ColumnType, ColumnString> || std::is_same_v<ColumnType, ColumnFixedString>)
|
else if constexpr (std::is_same_v<ColumnType, ColumnString> || std::is_same_v<ColumnType, ColumnFixedString>)
|
||||||
|
{
|
||||||
|
if (pair->getKey() == columns[0]->getDataAt(i))
|
||||||
{
|
{
|
||||||
result_data.insertData(pair->getKey().data, pair->getKey().size);
|
result_data.insertData(pair->getKey().data, pair->getKey().size);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char * data = nullptr;
|
const char * data = nullptr;
|
||||||
|
if (pair->getKey() == columns[0]->serializeValueIntoArena(i, arena, data))
|
||||||
|
{
|
||||||
result_data.deserializeAndInsertFromArena(pair->getKey().data);
|
result_data.deserializeAndInsertFromArena(pair->getKey().data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (all_nullable)
|
if (all_nullable)
|
||||||
null_map.push_back(0);
|
null_map.push_back(0);
|
||||||
}
|
}
|
||||||
|
if (all_has_nullable && !null_added)
|
||||||
|
{
|
||||||
|
++result_offset;
|
||||||
|
result_data.insertDefault();
|
||||||
|
null_map.push_back(1);
|
||||||
|
null_added = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result_offsets.getElement(row) = result_offset;
|
result_offsets.getElement(row) = result_offset;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user