Fix join using nullable in old analyzer

This commit is contained in:
vdimir 2024-01-08 11:55:47 +00:00
parent b4bfd01322
commit 06652f9714
No known key found for this signature in database
GPG Key ID: 6EE4CE2BEDC51862
4 changed files with 59 additions and 7 deletions

View File

@ -375,8 +375,9 @@ void TableJoin::addJoinedColumnsAndCorrectTypesImpl(TColumns & left_columns, boo
* So we need to know changed types in result tables before further analysis (e.g. analyzeAggregation)
* For `JOIN ON expr1 == expr2` we will infer common type later in makeTableJoin,
* when part of plan built and types of expression will be known.
* Also for using we set `require_strict_keys_match = true` because we want to have Nullable(T) in result table in case of any table has NULLs.
*/
inferJoinKeyCommonType(left_columns, columns_from_joined_table, !isSpecialStorage());
inferJoinKeyCommonType(left_columns, columns_from_joined_table, !isSpecialStorage(), /* require_strict_keys_match = */ true);
if (auto it = left_type_map.find(col.name); it != left_type_map.end())
{
@ -560,7 +561,9 @@ TableJoin::createConvertingActions(
NameToNameMap left_column_rename;
NameToNameMap right_column_rename;
inferJoinKeyCommonType(left_sample_columns, right_sample_columns, !isSpecialStorage());
/// FullSortingMerge join algorithm doesn't support joining keys with different types (e.g. String and Nullable(String))
bool require_strict_keys_match = isEnabledAlgorithm(JoinAlgorithm::FULL_SORTING_MERGE);
inferJoinKeyCommonType(left_sample_columns, right_sample_columns, !isSpecialStorage(), require_strict_keys_match);
if (!left_type_map.empty() || !right_type_map.empty())
{
left_dag = applyKeyConvertToTable(left_sample_columns, left_type_map, JoinTableSide::Left, left_column_rename);
@ -614,11 +617,8 @@ TableJoin::createConvertingActions(
}
template <typename LeftNamesAndTypes, typename RightNamesAndTypes>
void TableJoin::inferJoinKeyCommonType(const LeftNamesAndTypes & left, const RightNamesAndTypes & right, bool allow_right)
void TableJoin::inferJoinKeyCommonType(const LeftNamesAndTypes & left, const RightNamesAndTypes & right, bool allow_right, bool require_strict_keys_match)
{
/// FullSortingMerge and PartialMerge join algorithms don't support joining keys with different types
/// (e.g. String and LowCardinality(String))
bool require_strict_keys_match = isEnabledAlgorithm(JoinAlgorithm::FULL_SORTING_MERGE);
if (!left_type_map.empty() || !right_type_map.empty())
return;

View File

@ -218,7 +218,7 @@ private:
/// Calculates common supertypes for corresponding join key columns.
template <typename LeftNamesAndTypes, typename RightNamesAndTypes>
void inferJoinKeyCommonType(const LeftNamesAndTypes & left, const RightNamesAndTypes & right, bool allow_right);
void inferJoinKeyCommonType(const LeftNamesAndTypes & left, const RightNamesAndTypes & right, bool allow_right, bool require_strict_keys_match);
void deduplicateAndQualifyColumnNames(const NameSet & left_table_columns, const String & right_table_prefix);

View File

@ -0,0 +1,33 @@
0
1
2
3
4
5
6
7
8
9
\N
0
1
2
3
4
5
6
7
8
9
\N
0
1
2
3
4
5
6
7
8
9
\N

View File

@ -0,0 +1,19 @@
DROP TABLE IF EXISTS t;
DROP TABLE IF EXISTS r;
SET allow_suspicious_low_cardinality_types = 1;
CREATE TABLE t (`x` UInt32, `s` LowCardinality(String)) ENGINE = Memory;
INSERT INTO t SELECT number, toString(number) FROM numbers(5);
CREATE TABLE r (`x` LowCardinality(Nullable(UInt32)), `s` Nullable(String)) ENGINE = Memory;
INSERT INTO r SELECT number, toString(number) FROM numbers(2, 8);
INSERT INTO r VALUES (NULL, NULL);
SELECT x FROM t FULL JOIN r USING (x) ORDER BY ALL
;
SELECT x FROM t FULL JOIN r USING (x) ORDER BY ALL
SETTINGS join_algorithm = 'full_sorting_merge';
SELECT x FROM t FULL JOIN r USING (x) ORDER BY ALL
SETTINGS join_algorithm = 'partial_merge';