2019-09-18 12:46:57 +00:00
|
|
|
#pragma once
|
|
|
|
|
2021-07-21 17:03:33 +00:00
|
|
|
#include <Columns/ColumnsNumber.h>
|
2020-07-10 18:10:06 +00:00
|
|
|
#include <Core/Block.h>
|
2019-09-18 12:46:57 +00:00
|
|
|
#include <Interpreters/IJoin.h>
|
2021-01-31 19:25:47 +00:00
|
|
|
#include <Interpreters/ActionsDAG.h>
|
|
|
|
#include <Interpreters/ExpressionActions.h>
|
2019-09-18 12:46:57 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
|
|
|
struct ColumnWithTypeAndName;
|
2020-07-10 18:10:06 +00:00
|
|
|
class TableJoin;
|
2019-09-18 12:46:57 +00:00
|
|
|
class IColumn;
|
|
|
|
using ColumnRawPtrs = std::vector<const IColumn *>;
|
2021-07-21 17:03:33 +00:00
|
|
|
using UInt8ColumnDataPtr = const ColumnUInt8::Container *;
|
2021-06-25 12:03:10 +00:00
|
|
|
using UInt8ColumnDataPtrVector = std::vector<UInt8ColumnDataPtr>;
|
2019-09-18 12:46:57 +00:00
|
|
|
|
|
|
|
namespace JoinCommon
|
|
|
|
{
|
2021-04-17 19:03:32 +00:00
|
|
|
bool canBecomeNullable(const DataTypePtr & type);
|
|
|
|
DataTypePtr convertTypeToNullable(const DataTypePtr & type);
|
2021-08-06 11:54:04 +00:00
|
|
|
void convertColumnToNullable(ColumnWithTypeAndName & column);
|
2019-09-18 12:46:57 +00:00
|
|
|
void convertColumnsToNullable(Block & block, size_t starting_pos = 0);
|
2021-06-25 12:03:10 +00:00
|
|
|
void convertColumnsToNullable(MutableColumns & mutable_columns, size_t starting_pos = 0);
|
2019-10-29 19:39:42 +00:00
|
|
|
void removeColumnNullability(ColumnWithTypeAndName & column);
|
2020-07-10 18:10:06 +00:00
|
|
|
void changeColumnRepresentation(const ColumnPtr & src_column, ColumnPtr & dst_column);
|
|
|
|
ColumnPtr emptyNotNullableClone(const ColumnPtr & column);
|
2021-07-21 17:03:33 +00:00
|
|
|
ColumnPtr materializeColumn(const Block & block, const String & name);
|
2019-12-17 15:02:42 +00:00
|
|
|
Columns materializeColumns(const Block & block, const Names & names);
|
|
|
|
ColumnRawPtrs materializeColumnsInplace(Block & block, const Names & names);
|
|
|
|
ColumnRawPtrs getRawPointers(const Columns & columns);
|
2019-09-18 12:46:57 +00:00
|
|
|
void removeLowCardinalityInplace(Block & block);
|
2020-09-22 10:16:22 +00:00
|
|
|
void removeLowCardinalityInplace(Block & block, const Names & names, bool change_type = true);
|
2021-08-06 14:15:11 +00:00
|
|
|
void restoreLowCardinalityInplace(Block & block, const Names & lowcard_keys);
|
2019-09-18 12:46:57 +00:00
|
|
|
|
2020-03-13 08:15:43 +00:00
|
|
|
ColumnRawPtrs extractKeysForJoin(const Block & block_keys, const Names & key_names_right);
|
2019-09-18 12:46:57 +00:00
|
|
|
|
2021-07-21 17:03:33 +00:00
|
|
|
/// Throw an exception if join condition column is not UIint8
|
|
|
|
void checkTypesOfMasks(const Block & block_left, const String & condition_name_left,
|
|
|
|
const Block & block_right, const String & condition_name_right);
|
|
|
|
|
|
|
|
/// Throw an exception if blocks have different types of key columns . Compare up to Nullability.
|
|
|
|
void checkTypesOfKeys(const Block & block_left, const Names & key_names_left,
|
|
|
|
const Block & block_right, const Names & key_names_right);
|
|
|
|
|
|
|
|
/// Check both keys and conditions
|
|
|
|
void checkTypesOfKeys(const Block & block_left, const Names & key_names_left, const String & condition_name_left,
|
|
|
|
const Block & block_right, const Names & key_names_right, const String & condition_name_right);
|
2019-09-18 12:46:57 +00:00
|
|
|
|
|
|
|
void createMissedColumns(Block & block);
|
2021-07-14 10:02:23 +00:00
|
|
|
void joinTotals(Block left_totals, Block right_totals, const TableJoin & table_join, Block & out_block);
|
2019-09-18 12:46:57 +00:00
|
|
|
|
2021-01-21 14:18:57 +00:00
|
|
|
void addDefaultValues(IColumn & column, const DataTypePtr & type, size_t count);
|
2021-01-21 13:46:46 +00:00
|
|
|
|
2021-02-09 13:17:42 +00:00
|
|
|
bool typesEqualUpToNullability(DataTypePtr left_type, DataTypePtr right_type);
|
|
|
|
|
2021-07-21 17:03:33 +00:00
|
|
|
/// Return mask array of type ColumnUInt8 for specified column. Source should have type UInt8 or Nullable(UInt8).
|
|
|
|
ColumnPtr getColumnAsMask(const Block & block, const String & column_name);
|
|
|
|
|
|
|
|
/// Split key and other columns by keys name list
|
2021-06-25 12:03:10 +00:00
|
|
|
void splitAdditionalColumns(const NamesVector & key_names, const Block & sample_block, Block & block_keys, Block & block_others);
|
2021-07-21 17:03:33 +00:00
|
|
|
|
2021-05-15 11:39:13 +00:00
|
|
|
void changeLowCardinalityInplace(ColumnWithTypeAndName & column);
|
|
|
|
|
2019-09-18 12:46:57 +00:00
|
|
|
}
|
|
|
|
|
2020-07-10 18:10:06 +00:00
|
|
|
/// Creates result from right table data in RIGHT and FULL JOIN when keys are not present in left table.
|
2021-08-17 13:30:01 +00:00
|
|
|
class NotJoinedBlocks final
|
2020-07-10 18:10:06 +00:00
|
|
|
{
|
|
|
|
public:
|
2021-08-06 14:15:11 +00:00
|
|
|
using LeftToRightKeyRemap = std::unordered_map<String, String>;
|
2020-07-10 18:10:06 +00:00
|
|
|
|
2021-08-09 14:30:37 +00:00
|
|
|
/// Returns non joined columns from right part of join
|
|
|
|
class RightColumnsFiller
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/// Create empty block for right part
|
|
|
|
virtual Block getEmptyBlock() = 0;
|
|
|
|
/// Fill columns from right part of join with not joined rows
|
|
|
|
virtual size_t fillColumns(MutableColumns & columns_right) = 0;
|
|
|
|
|
|
|
|
virtual ~RightColumnsFiller() = default;
|
|
|
|
};
|
|
|
|
|
2021-08-17 13:30:01 +00:00
|
|
|
NotJoinedBlocks(std::unique_ptr<RightColumnsFiller> filler_,
|
2021-08-06 14:15:11 +00:00
|
|
|
const Block & result_sample_block_,
|
|
|
|
size_t left_columns_count,
|
|
|
|
const LeftToRightKeyRemap & left_to_right_key_remap);
|
|
|
|
|
2021-08-17 13:30:01 +00:00
|
|
|
Block read();
|
2021-08-06 14:15:11 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
void extractColumnChanges(size_t right_pos, size_t result_pos);
|
2021-08-06 11:54:04 +00:00
|
|
|
void correctLowcardAndNullability(Block & block);
|
2020-07-10 18:10:06 +00:00
|
|
|
void addLeftColumns(Block & block, size_t rows_added) const;
|
|
|
|
void addRightColumns(Block & block, MutableColumns & columns_right) const;
|
|
|
|
void copySameKeys(Block & block) const;
|
|
|
|
|
2021-08-09 14:30:37 +00:00
|
|
|
std::unique_ptr<RightColumnsFiller> filler;
|
|
|
|
|
2021-08-06 14:15:11 +00:00
|
|
|
/// Right block saved in Join
|
2020-07-10 18:10:06 +00:00
|
|
|
Block saved_block_sample;
|
|
|
|
|
2021-06-25 12:03:10 +00:00
|
|
|
NamesVector key_names_left;
|
|
|
|
NamesVector key_names_right;
|
|
|
|
|
2021-08-06 14:15:11 +00:00
|
|
|
/// Output of join
|
|
|
|
Block result_sample_block;
|
2020-07-10 18:10:06 +00:00
|
|
|
|
|
|
|
/// Indices of columns in result_sample_block that should be generated
|
|
|
|
std::vector<size_t> column_indices_left;
|
|
|
|
/// Indices of columns that come from the right-side table: right_pos -> result_pos
|
|
|
|
std::unordered_map<size_t, size_t> column_indices_right;
|
2021-08-06 14:15:11 +00:00
|
|
|
|
2020-07-10 18:10:06 +00:00
|
|
|
std::unordered_map<size_t, size_t> same_result_keys;
|
2021-08-06 14:15:11 +00:00
|
|
|
|
|
|
|
/// Which right columns (saved in parent) need Nullability/LowCardinality change
|
|
|
|
/// before placing them in result block
|
2021-08-06 11:54:04 +00:00
|
|
|
std::vector<std::pair<size_t, bool>> right_nullability_changes;
|
|
|
|
std::vector<std::pair<size_t, bool>> right_lowcard_changes;
|
2020-07-10 18:10:06 +00:00
|
|
|
|
|
|
|
void setRightIndex(size_t right_pos, size_t result_position);
|
|
|
|
};
|
|
|
|
|
2019-09-18 12:46:57 +00:00
|
|
|
}
|