#27685
{
    for (const auto & column_name : lowcard_keys)
    {
        if (!block.has(column_name))
            continue;
        if (auto & col = block.getByName(column_name); !col.type->lowCardinality())
            JoinCommon::changeLowCardinalityInplace(col);
    }
    for (size_t i = 0; i < block.columns(); ++i)
    {
        auto & col = block.getByPosition(i);
        if (col.type->lowCardinality() && col.column && !col.column->lowCardinality())
            col.column = changeLowCardinality(col.column, col.type->createColumn());
    }
}
ColumnRawPtrs extractKeysForJoin(const Block & block_keys, const Names & key_names)
{
    size_t keys_size = key_names.size();
    ColumnRawPtrs key_columns(keys_size);
    for (size_t i = 0; i < keys_size; ++i)
    {
        const String & column_name = key_names[i];
        key_columns[i] = block_keys.getByName(column_name).column.get();
        
        if (const auto * nullable = checkAndGetColumn<ColumnNullable>(*key_columns[i]))
            key_columns[i] = &nullable->getNestedColumn();
    }
    return key_columns;
}
void checkTypesOfKeys(const Block & block_left, const Names & key_names_left,