Merge pull request #5238 from janplus/if-nullable-bug

Fix if, multiIf's nullable bug.
This commit is contained in:
alexey-milovidov 2019-05-12 11:47:37 +03:00 committed by GitHub
commit 9ce2dd8803
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 211 additions and 189 deletions

View File

@ -656,7 +656,7 @@ private:
block.getByPosition(result).column = std::move(result_column);
}
bool executeForNullableCondition(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count)
bool executeForNullableCondition(Block & block, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/)
{
const ColumnWithTypeAndName & arg_cond = block.getByPosition(arguments[0]);
bool cond_is_null = arg_cond.column->onlyNull();
@ -664,7 +664,7 @@ private:
if (cond_is_null)
{
block.getByPosition(result).column = block.getByPosition(result).type->createColumnConstWithDefaultValue(input_rows_count);
block.getByPosition(result).column = std::move(block.getByPosition(arguments[2]).column);
return true;
}
@ -680,25 +680,8 @@ private:
executeImpl(temporary_block, {0, 1, 2}, 3, temporary_block.rows());
const ColumnPtr & result_column = temporary_block.getByPosition(3).column;
if (result_column->isColumnNullable())
{
MutableColumnPtr mutable_result_column = (*std::move(result_column)).mutate();
static_cast<ColumnNullable &>(*mutable_result_column).applyNullMap(static_cast<const ColumnNullable &>(*arg_cond.column));
block.getByPosition(result).column = std::move(mutable_result_column);
return true;
}
else if (result_column->onlyNull())
{
block.getByPosition(result).column = block.getByPosition(result).type->createColumnConstWithDefaultValue(input_rows_count);
return true;
}
else
{
block.getByPosition(result).column = ColumnNullable::create(
materializeColumnIfConst(result_column), static_cast<const ColumnNullable &>(*arg_cond.column).getNullMapColumnPtr());
return true;
}
block.getByPosition(result).column = std::move(temporary_block.getByPosition(3).column);
return true;
}
return false;
@ -917,11 +900,11 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (arguments[0]->onlyNull())
return arguments[0];
return arguments[2];
if (arguments[0]->isNullable())
return makeNullable(getReturnTypeImpl({
removeNullable(arguments[0]), arguments[1], arguments[2]}));
return getReturnTypeImpl({
removeNullable(arguments[0]), arguments[1], arguments[2]});
if (!WhichDataType(arguments[0]).isUInt8())
throw Exception("Illegal type " + arguments[0]->getName() + " of first argument (condition) of function if. Must be UInt8.",

View File

@ -63,16 +63,12 @@ public:
throw Exception{"Invalid number of arguments for function " + getName(),
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH};
/// Conditions must be UInt8, Nullable(UInt8) or Null. If one of conditions is Nullable, the result is also Nullable.
bool have_nullable_condition = false;
for_conditions([&](const DataTypePtr & arg)
{
const IDataType * nested_type;
if (arg->isNullable())
{
have_nullable_condition = true;
if (arg->onlyNull())
return;
@ -98,11 +94,7 @@ public:
types_of_branches.emplace_back(arg);
});
DataTypePtr common_type_of_branches = getLeastSupertype(types_of_branches);
return have_nullable_condition
? makeNullable(common_type_of_branches)
: common_type_of_branches;
return getLeastSupertype(types_of_branches);
}
void executeImpl(Block & block, const ColumnNumbers & args, size_t result, size_t input_rows_count) override

View File

@ -66,7 +66,7 @@
\N \N \N
2 7 2
5 1 5
9 \N \N
9 \N 9
42 42 \N
\N 6 \N
\N \N \N
@ -100,6 +100,28 @@
42
\N
\N
----- if -----
a 1 UInt8
b 1 UInt8
c 0 UInt8
\N 0 UInt8
a \N Nullable(UInt8)
b \N Nullable(UInt8)
c 0 Nullable(UInt8)
\N 0 Nullable(UInt8)
----- case when -----
a 1 UInt8
b 1 UInt8
c 0 UInt8
\N 0 UInt8
a \N Nullable(UInt8)
b \N Nullable(UInt8)
c 0 Nullable(UInt8)
\N 0 Nullable(UInt8)
a 1 Nullable(UInt8)
b 1 Nullable(UInt8)
c \N Nullable(UInt8)
\N \N Nullable(UInt8)
----- multiIf -----
\N
2

View File

@ -146,6 +146,21 @@ SELECT '----- IS NULL, IS NOT NULL -----';
SELECT col1 FROM test1 WHERE col1 IS NOT NULL ORDER BY col1 ASC;
SELECT col1 FROM test1 WHERE col1 IS NULL;
SELECT '----- if -----';
DROP TABLE IF EXISTS test.test1;
CREATE TABLE test.test1 (col1 Nullable(String)) ENGINE=TinyLog;
INSERT INTO test.test1 VALUES ('a'), ('b'), ('c'), (NULL);
SELECT col1, if(col1 IN ('a' ,'b'), 1, 0) AS t, toTypeName(t) FROM test.test1;
SELECT col1, if(col1 IN ('a' ,'b'), NULL, 0) AS t, toTypeName(t) FROM test.test1;
SELECT '----- case when -----';
SELECT col1, CASE WHEN col1 IN ('a' ,'b') THEN 1 ELSE 0 END AS t, toTypeName(t) FROM test.test1;
SELECT col1, CASE WHEN col1 IN ('a' ,'b') THEN NULL ELSE 0 END AS t, toTypeName(t) FROM test.test1;
SELECT col1, CASE WHEN col1 IN ('a' ,'b') THEN 1 END AS t, toTypeName(t) FROM test.test1;
SELECT '----- multiIf -----';
SELECT multiIf(1, NULL, 1, 3, 4);

View File

@ -1,3 +1,4 @@
---------- constant_true ----------
Hello
Hello
Hello
@ -158,6 +159,7 @@ Hello
7
8
9
---------- constant_false ----------
World
World
World
@ -318,6 +320,17 @@ World
-7
-8
-9
---------- constant_null ----------
World
World
World
World
World
World
World
World
World
World
\N
\N
\N
@ -328,7 +341,36 @@ World
\N
\N
\N
0
-1
-2
-3
-4
-5
-6
-7
-8
-9
0
-1
-2
-3
-4
\N
-6
-7
-8
-9
World
World
World
World
World
World
World
World
World
World
\N
\N
\N
@ -339,7 +381,36 @@ World
\N
\N
\N
0
-1
-2
-3
-4
-5
-6
-7
-8
-9
0
-1
-2
-3
-4
\N
-6
-7
-8
-9
World
World
World
World
World
World
World
World
World
World
\N
\N
\N
@ -350,7 +421,36 @@ World
\N
\N
\N
0
-1
-2
-3
-4
-5
-6
-7
-8
-9
0
-1
-2
-3
-4
\N
-6
-7
-8
-9
World
World
World
World
World
World
World
World
World
World
\N
\N
\N
@ -361,123 +461,27 @@ World
\N
\N
\N
0
-1
-2
-3
-4
-5
-6
-7
-8
-9
0
-1
-2
-3
-4
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
-6
-7
-8
-9
---------- cond_non_constant ----------
World
Hello
World
@ -638,15 +642,16 @@ World
7
-8
-9
---------- cond_non_constant_nullable ----------
World
Hello
\N
World
World
Hello
\N
World
World
Hello
\N
World
World
\N
Hello
@ -660,33 +665,33 @@ Hello
\N
0
Hello
\N
-2
-3
Hello
-5
-6
Hello
-8
-9
0
Hello
-2
-3
Hello
\N
-6
Hello
\N
-9
0
Hello
\N
-3
Hello
\N
-6
Hello
\N
-8
-9
World
\N
\N
World
World
\N
\N
World
World
\N
\N
World
World
\N
\N
@ -700,33 +705,33 @@ World
\N
0
\N
\N
-2
-3
\N
\N
-5
-6
\N
\N
-8
-9
0
\N
\N
-2
-3
\N
\N
-6
\N
\N
-8
-9
World
1
\N
World
World
4
\N
World
World
7
\N
World
World
\N
1
@ -740,33 +745,33 @@ World
\N
0
1
\N
-2
-3
4
\N
-5
-6
7
\N
-8
-9
0
1
\N
-2
-3
4
\N
-6
7
\N
-8
-9
World
1
\N
World
World
4
\N
World
World
7
\N
World
World
\N
1
@ -780,21 +785,21 @@ World
\N
0
1
\N
-2
-3
4
\N
-5
-6
7
\N
-8
-9
0
1
\N
-2
-3
4
\N
-6
7
\N
-8
-9

View File

@ -31,6 +31,7 @@ AS SELECT
nullIf(toString(-number), '-5') AS else_non_constant_nullable
FROM system.numbers LIMIT 10;
SELECT '---------- constant_true ----------';
SELECT constant_true ? then_constant : else_constant AS res FROM nullable_00431;
SELECT constant_true ? then_constant : constant_null AS res FROM nullable_00431;
@ -52,6 +53,7 @@ SELECT constant_true ? then_non_constant_nullable : constant_null AS res FROM nu
SELECT constant_true ? then_non_constant_nullable : else_non_constant AS res FROM nullable_00431;
SELECT constant_true ? then_non_constant_nullable : else_non_constant_nullable AS res FROM nullable_00431;
SELECT '---------- constant_false ----------';
SELECT constant_false ? then_constant : else_constant AS res FROM nullable_00431;
SELECT constant_false ? then_constant : constant_null AS res FROM nullable_00431;
@ -73,6 +75,7 @@ SELECT constant_false ? then_non_constant_nullable : constant_null AS res FROM n
SELECT constant_false ? then_non_constant_nullable : else_non_constant AS res FROM nullable_00431;
SELECT constant_false ? then_non_constant_nullable : else_non_constant_nullable AS res FROM nullable_00431;
SELECT '---------- constant_null ----------';
SELECT constant_null ? then_constant : else_constant AS res FROM nullable_00431;
SELECT constant_null ? then_constant : constant_null AS res FROM nullable_00431;
@ -94,6 +97,7 @@ SELECT constant_null ? then_non_constant_nullable : constant_null AS res FROM nu
SELECT constant_null ? then_non_constant_nullable : else_non_constant AS res FROM nullable_00431;
SELECT constant_null ? then_non_constant_nullable : else_non_constant_nullable AS res FROM nullable_00431;
SELECT '---------- cond_non_constant ----------';
SELECT cond_non_constant ? then_constant : else_constant AS res FROM nullable_00431;
SELECT cond_non_constant ? then_constant : constant_null AS res FROM nullable_00431;
@ -115,6 +119,7 @@ SELECT cond_non_constant ? then_non_constant_nullable : constant_null AS res FRO
SELECT cond_non_constant ? then_non_constant_nullable : else_non_constant AS res FROM nullable_00431;
SELECT cond_non_constant ? then_non_constant_nullable : else_non_constant_nullable AS res FROM nullable_00431;
SELECT '---------- cond_non_constant_nullable ----------';
SELECT cond_non_constant_nullable ? then_constant : else_constant AS res FROM nullable_00431;
SELECT cond_non_constant_nullable ? then_constant : constant_null AS res FROM nullable_00431;