diff --git a/dbms/src/Functions/FunctionsMiscellaneous.cpp b/dbms/src/Functions/FunctionsMiscellaneous.cpp index 7257754b6ac..914a6861652 100644 --- a/dbms/src/Functions/FunctionsMiscellaneous.cpp +++ b/dbms/src/Functions/FunctionsMiscellaneous.cpp @@ -268,9 +268,9 @@ class FunctionGetSizeOfEnumType : public IFunction void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) const override { - if (auto type = checkAndGetDataType(block.getByPosition(arguments[0]).type.get())) + if (const auto * type = checkAndGetDataType(block.getByPosition(arguments[0]).type.get())) block.getByPosition(result).column = DataTypeUInt8().createColumnConst(block.rows(), UInt64(type->getValues().size())); - else if (auto type = checkAndGetDataType(block.getByPosition(arguments[0]).type.get())) + else if (const auto * type = checkAndGetDataType(block.getByPosition(arguments[0]).type.get())) block.getByPosition(result).column = DataTypeUInt16().createColumnConst(block.rows(), UInt64(type->getValues().size())); else throw Exception("The argument for function " + getName() + " must be Enum", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); @@ -751,7 +751,7 @@ class FunctionIn : public IFunction ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); bool return_nullable = arguments[0].type->isNullable(); ColumnPtr column_set_ptr = arguments[1].column; - auto * column_set = typeid_cast(&*column_set_ptr); + const auto * column_set = typeid_cast(&*column_set_ptr); return_nullable |= column_set->getData()->containsNullValue(); if (return_nullable) @@ -796,6 +796,11 @@ class FunctionIn : public IFunction materialized_tuple = const_tuple->convertToFullColumn(); tuple = typeid_cast(materialized_tuple.get()); } + auto left_column_vector = left_arg.column; + if (left_arg.column->isColumnConst()) + { + left_column_vector = left_column_vector->convertToFullColumnIfConst(); + } if (tuple) { @@ -806,7 +811,16 @@ class FunctionIn : public IFunction block_of_key_columns.insert({tuple_columns[i], tuple_types[i], ""}); } else - block_of_key_columns.insert(left_arg); + { + if (left_arg.column->isColumnConst()) + { + block_of_key_columns.insert({left_column_vector, left_arg.type, ""}); + } + else + { + block_of_key_columns.insert(left_arg); + } + } if constexpr (ignore_null) { @@ -819,14 +833,14 @@ class FunctionIn : public IFunction if (return_nullable) { auto nested_res = column_set->getData()->execute(block_of_key_columns, negative); - if (left_arg.column->isColumnNullable()) + if (left_column_vector->isColumnNullable()) { - ColumnPtr result_null_map_column = dynamic_cast(*left_arg.column).getNullMapColumnPtr(); + ColumnPtr result_null_map_column = dynamic_cast(*left_column_vector).getNullMapColumnPtr(); if (set_contains_null) { MutableColumnPtr mutable_result_null_map_column = (*std::move(result_null_map_column)).mutate(); NullMap & result_null_map = dynamic_cast(*mutable_result_null_map_column).getData(); - auto uint8_column = checkAndGetColumn(nested_res.get()); + const auto * uint8_column = checkAndGetColumn(nested_res.get()); const auto & data = uint8_column->getData(); for (size_t i = 0, size = result_null_map.size(); i < size; i++) { @@ -841,8 +855,8 @@ class FunctionIn : public IFunction { auto col_null_map = ColumnUInt8::create(); ColumnUInt8::Container & vec_null_map = col_null_map->getData(); - vec_null_map.assign(block.rows(), (UInt8)0); - auto uint8_column = checkAndGetColumn(nested_res.get()); + vec_null_map.assign(block.rows(), static_cast(0)); + const auto * uint8_column = checkAndGetColumn(nested_res.get()); const auto & data = uint8_column->getData(); for (size_t i = 0, size = vec_null_map.size(); i < size; i++) { @@ -1051,7 +1065,7 @@ void FunctionReplicate::executeImpl(Block & block, const ColumnNumbers & argumen if (!array_column) { - auto const_array_column = checkAndGetColumnConst(block.getByPosition(arguments[1]).column.get()); + const auto * const_array_column = checkAndGetColumnConst(block.getByPosition(arguments[1]).column.get()); if (!const_array_column) throw Exception("Unexpected column for replicate", ErrorCodes::ILLEGAL_COLUMN); temp_column = const_array_column->convertToFullColumn(); @@ -1235,7 +1249,7 @@ class FunctionNumericPredicate : public IFunction void executeImpl(Block & block, const ColumnNumbers & arguments, const size_t result) const override { - const auto in = block.getByPosition(arguments.front()).column.get(); + const auto * const in = block.getByPosition(arguments.front()).column.get(); if (!execute(block, in, result) && !execute(block, in, result) @@ -1369,7 +1383,7 @@ class FunctionVersion : public IFunction } private: - std::string getVersion() const; + static std::string getVersion(); }; @@ -1877,7 +1891,7 @@ class FunctionThrowIf : public IFunction void executeImpl(Block & block, const ColumnNumbers & arguments, const size_t result) const override { - const auto in = block.getByPosition(arguments.front()).column.get(); + const auto * const in = block.getByPosition(arguments.front()).column.get(); if (!execute(block, in, result) && !execute(block, in, result) @@ -1911,7 +1925,7 @@ class FunctionThrowIf : public IFunction }; -std::string FunctionVersion::getVersion() const +std::string FunctionVersion::getVersion() { std::ostringstream os; os << TiFlashBuildInfo::getVersion(); diff --git a/tests/fullstack-test/expr/in_expression.test b/tests/fullstack-test/expr/in_expression.test index 28ba86792ec..d3c16449031 100644 --- a/tests/fullstack-test/expr/in_expression.test +++ b/tests/fullstack-test/expr/in_expression.test @@ -39,3 +39,144 @@ mysql> select * from test.t where d in (2, 'y'); +------+------+------+------------------------+ mysql> drop table if exists test.t; +mysql> create table test.t(a int primary key, b int not null, c int); +mysql> insert into test.t values(0,0,0),(1,0,1),(2,0,null),(3,1,0),(4,1,1),(5,1,null),(6,0,0),(7,0,1),(8,0,null),(9,1,0),(10,1,1),(11,1,null); +mysql> alter table test.t set tiflash replica 1; +func> wait_table test t + +mysql> set tidb_enforce_mpp=1; select avg(a or 1) in (null,0,0), avg(a or 1) in (null,1,1), avg(b or 1) in (0,0), avg(b or 1) in (1,1), avg(c or 1) in (0,0), avg(c or 1) in (1,1) from test.t group by a,b,c; ++---------------------------+---------------------------+----------------------+----------------------+----------------------+----------------------+ +| avg(a or 1) in (null,0,0) | avg(a or 1) in (null,1,1) | avg(b or 1) in (0,0) | avg(b or 1) in (1,1) | avg(c or 1) in (0,0) | avg(c or 1) in (1,1) | ++---------------------------+---------------------------+----------------------+----------------------+----------------------+----------------------+ +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | ++---------------------------+---------------------------+----------------------+----------------------+----------------------+----------------------+ +mysql> set tidb_enforce_mpp=1; select avg(a or 0) in (null,0,0), avg(a or 0) in (null,1,1), avg(b or 0) in (0,0), avg(b or 0) in (1,1), avg(c or 0) in (0,0), avg(c or 0) in (1,1) from test.t group by a,b,c; ++---------------------------+---------------------------+----------------------+----------------------+----------------------+----------------------+ +| avg(a or 0) in (null,0,0) | avg(a or 0) in (null,1,1) | avg(b or 0) in (0,0) | avg(b or 0) in (1,1) | avg(c or 0) in (0,0) | avg(c or 0) in (1,1) | ++---------------------------+---------------------------+----------------------+----------------------+----------------------+----------------------+ +| 1 | NULL | 1 | 0 | 1 | 0 | +| NULL | 1 | 1 | 0 | 0 | 1 | +| NULL | 1 | 1 | 0 | NULL | NULL | +| NULL | 1 | 0 | 1 | 1 | 0 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | NULL | NULL | +| NULL | 1 | 1 | 0 | 1 | 0 | +| NULL | 1 | 1 | 0 | 0 | 1 | +| NULL | 1 | 1 | 0 | NULL | NULL | +| NULL | 1 | 0 | 1 | 1 | 0 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | NULL | NULL | ++---------------------------+---------------------------+----------------------+----------------------+----------------------+----------------------+ +mysql> set tidb_enforce_mpp=1; select avg(a and 0) in (null,0,0), avg(a and 0) in (null,1,1), avg(b and 0) in (0,0), avg(b and 0) in (1,1), avg(c and 0) in (0,0), avg(c and 0) in (1,1) from test.t group by a,b,c; ++----------------------------+----------------------------+-----------------------+-----------------------+-----------------------+-----------------------+ +| avg(a and 0) in (null,0,0) | avg(a and 0) in (null,1,1) | avg(b and 0) in (0,0) | avg(b and 0) in (1,1) | avg(c and 0) in (0,0) | avg(c and 0) in (1,1) | ++----------------------------+----------------------------+-----------------------+-----------------------+-----------------------+-----------------------+ +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | ++----------------------------+----------------------------+-----------------------+-----------------------+-----------------------+-----------------------+ +mysql> set tidb_enforce_mpp=1; select avg(a and 1) in (null,0,0), avg(a and 1) in (null,1,1), avg(b and 1) in (0,0), avg(b and 1) in (1,1), avg(c and 1) in (0,0), avg(c and 1) in (1,1) from test.t group by a,b,c; ++----------------------------+----------------------------+-----------------------+-----------------------+-----------------------+-----------------------+ +| avg(a and 1) in (null,0,0) | avg(a and 1) in (null,1,1) | avg(b and 1) in (0,0) | avg(b and 1) in (1,1) | avg(c and 1) in (0,0) | avg(c and 1) in (1,1) | ++----------------------------+----------------------------+-----------------------+-----------------------+-----------------------+-----------------------+ +| 1 | NULL | 1 | 0 | 1 | 0 | +| NULL | 1 | 1 | 0 | 0 | 1 | +| NULL | 1 | 1 | 0 | NULL | NULL | +| NULL | 1 | 0 | 1 | 1 | 0 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | NULL | NULL | +| NULL | 1 | 1 | 0 | 1 | 0 | +| NULL | 1 | 1 | 0 | 0 | 1 | +| NULL | 1 | 1 | 0 | NULL | NULL | +| NULL | 1 | 0 | 1 | 1 | 0 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | NULL | NULL | ++----------------------------+----------------------------+-----------------------+-----------------------+-----------------------+-----------------------+ +mysql> set tidb_enforce_mpp=1; select (a or 1) in (null,0,0), (a or 1) in (null,1,1), (b or 1) in (0,0), (b or 1) in (1,1), (c or 1) in (0,0), (c or 1) in (1,1) from test.t; ++------------------------+------------------------+-------------------+-------------------+-------------------+-------------------+ +| (a or 1) in (null,0,0) | (a or 1) in (null,1,1) | (b or 1) in (0,0) | (b or 1) in (1,1) | (c or 1) in (0,0) | (c or 1) in (1,1) | ++------------------------+------------------------+-------------------+-------------------+-------------------+-------------------+ +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | 0 | 1 | ++------------------------+------------------------+-------------------+-------------------+-------------------+-------------------+ +mysql> set tidb_enforce_mpp=1; select (a or 0) in (null,0,0), (a or 0) in (null,1,1), (b or 0) in (0,0), (b or 0) in (1,1), (c or 0) in (0,0), (c or 0) in (1,1) from test.t; ++------------------------+------------------------+-------------------+-------------------+-------------------+-------------------+ +| (a or 0) in (null,0,0) | (a or 0) in (null,1,1) | (b or 0) in (0,0) | (b or 0) in (1,1) | (c or 0) in (0,0) | (c or 0) in (1,1) | ++------------------------+------------------------+-------------------+-------------------+-------------------+-------------------+ +| 1 | NULL | 1 | 0 | 1 | 0 | +| NULL | 1 | 1 | 0 | 0 | 1 | +| NULL | 1 | 1 | 0 | NULL | NULL | +| NULL | 1 | 0 | 1 | 1 | 0 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | NULL | NULL | +| NULL | 1 | 1 | 0 | 1 | 0 | +| NULL | 1 | 1 | 0 | 0 | 1 | +| NULL | 1 | 1 | 0 | NULL | NULL | +| NULL | 1 | 0 | 1 | 1 | 0 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | NULL | NULL | ++------------------------+------------------------+-------------------+-------------------+-------------------+-------------------+ +mysql> set tidb_enforce_mpp=1; select (a and 0) in (null,0,0), (a and 0) in (null,1,1), (b and 0) in (0,0), (b and 0) in (1,1), (c and 0) in (0,0), (c and 0) in (1,1) from test.t; ++-------------------------+-------------------------+--------------------+--------------------+--------------------+--------------------+ +| (a and 0) in (null,0,0) | (a and 0) in (null,1,1) | (b and 0) in (0,0) | (b and 0) in (1,1) | (c and 0) in (0,0) | (c and 0) in (1,1) | ++-------------------------+-------------------------+--------------------+--------------------+--------------------+--------------------+ +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | +| 1 | NULL | 1 | 0 | 1 | 0 | ++-------------------------+-------------------------+--------------------+--------------------+--------------------+--------------------+ +mysql> set tidb_enforce_mpp=1; select (a and 1) in (null,0,0), (a and 1) in (null,1,1), (b and 1) in (0,0), (b and 1) in (1,1), (c and 1) in (0,0), (c and 1) in (1,1) from test.t; ++-------------------------+-------------------------+--------------------+--------------------+--------------------+--------------------+ +| (a and 1) in (null,0,0) | (a and 1) in (null,1,1) | (b and 1) in (0,0) | (b and 1) in (1,1) | (c and 1) in (0,0) | (c and 1) in (1,1) | ++-------------------------+-------------------------+--------------------+--------------------+--------------------+--------------------+ +| 1 | NULL | 1 | 0 | 1 | 0 | +| NULL | 1 | 1 | 0 | 0 | 1 | +| NULL | 1 | 1 | 0 | NULL | NULL | +| NULL | 1 | 0 | 1 | 1 | 0 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | NULL | NULL | +| NULL | 1 | 1 | 0 | 1 | 0 | +| NULL | 1 | 1 | 0 | 0 | 1 | +| NULL | 1 | 1 | 0 | NULL | NULL | +| NULL | 1 | 0 | 1 | 1 | 0 | +| NULL | 1 | 0 | 1 | 0 | 1 | +| NULL | 1 | 0 | 1 | NULL | NULL | ++-------------------------+-------------------------+--------------------+--------------------+--------------------+--------------------+