19
19
#include < DataTypes/DataTypeArray.h>
20
20
#include < DataTypes/DataTypeDate.h>
21
21
#include < DataTypes/DataTypeDateTime.h>
22
+ #include < DataTypes/DataTypeSet.h>
22
23
#include < DataTypes/DataTypeString.h>
23
24
#include < DataTypes/DataTypeTuple.h>
25
+ #include < DataTypes/DataTypeNullable.h>
24
26
#include < DataTypes/DataTypesNumber.h>
25
27
#include < DataTypes/DataTypeEnum.h>
26
28
#include < DataTypes/NumberTraits.h>
@@ -681,34 +683,44 @@ class FunctionMaterialize : public IFunction
681
683
}
682
684
};
683
685
684
- template <bool negative, bool global>
686
+ template <bool negative, bool global, bool ignore_null >
685
687
struct FunctionInName ;
686
688
template <>
687
- struct FunctionInName <false , false >
689
+ struct FunctionInName <false , false , true >
688
690
{
689
691
static constexpr auto name = " in" ;
690
692
};
691
693
template <>
692
- struct FunctionInName <false , true >
694
+ struct FunctionInName <false , false , false >
695
+ {
696
+ static constexpr auto name = " tidbIn" ;
697
+ };
698
+ template <>
699
+ struct FunctionInName <false , true , true >
693
700
{
694
701
static constexpr auto name = " globalIn" ;
695
702
};
696
703
template <>
697
- struct FunctionInName <true , false >
704
+ struct FunctionInName <true , false , true >
698
705
{
699
706
static constexpr auto name = " notIn" ;
700
707
};
701
708
template <>
702
- struct FunctionInName <true , true >
709
+ struct FunctionInName <true , false , false >
710
+ {
711
+ static constexpr auto name = " tidbNotIn" ;
712
+ };
713
+ template <>
714
+ struct FunctionInName <true , true , true >
703
715
{
704
716
static constexpr auto name = " globalNotIn" ;
705
717
};
706
718
707
- template <bool negative, bool global>
719
+ template <bool negative, bool global, bool ignore_null >
708
720
class FunctionIn : public IFunction
709
721
{
710
722
public:
711
- static constexpr auto name = FunctionInName<negative, global>::name;
723
+ static constexpr auto name = FunctionInName<negative, global, ignore_null >::name;
712
724
static FunctionPtr create (const Context &)
713
725
{
714
726
return std::make_shared<FunctionIn>();
@@ -724,9 +736,27 @@ class FunctionIn : public IFunction
724
736
return 2 ;
725
737
}
726
738
727
- DataTypePtr getReturnTypeImpl (const DataTypes & /* arguments*/ ) const override
739
+ DataTypePtr getReturnTypeImpl (const ColumnsWithTypeAndName & arguments) const override
728
740
{
729
- return std::make_shared<DataTypeUInt8>();
741
+ if constexpr (ignore_null)
742
+ return std::make_shared<DataTypeUInt8>();
743
+
744
+ auto type = removeNullable (arguments[0 ].type );
745
+ if (typeid_cast<const DataTypeTuple *>(type.get ()))
746
+ throw Exception (" Illegal type (" + arguments[0 ].type ->getName () + " ) of 1 argument of function " + getName (),
747
+ ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
748
+ if (!typeid_cast<const DataTypeSet *>(arguments[1 ].type .get ()))
749
+ throw Exception (" Illegal type (" + arguments[1 ].type ->getName () + " ) of 2 argument of function " + getName (),
750
+ ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
751
+ bool return_nullable = arguments[0 ].type ->isNullable ();
752
+ ColumnPtr column_set_ptr = arguments[1 ].column ;
753
+ auto * column_set = typeid_cast<const ColumnSet *>(&*column_set_ptr);
754
+ return_nullable |= column_set->getData ()->containsNullValue ();
755
+
756
+ if (return_nullable)
757
+ return makeNullable (std::make_shared<DataTypeUInt8>());
758
+ else
759
+ return std::make_shared<DataTypeUInt8>();
730
760
}
731
761
732
762
bool useDefaultImplementationForNulls () const override
@@ -736,6 +766,16 @@ class FunctionIn : public IFunction
736
766
737
767
void executeImpl (Block & block, const ColumnNumbers & arguments, size_t result) override
738
768
{
769
+ const ColumnWithTypeAndName & left_arg = block.getByPosition (arguments[0 ]);
770
+ if constexpr (!ignore_null)
771
+ {
772
+ if (left_arg.type ->onlyNull ())
773
+ {
774
+ block.getByPosition (result).column =
775
+ block.getByPosition (result).type ->createColumnConst (block.rows (),Null ());
776
+ return ;
777
+ }
778
+ }
739
779
// / Second argument must be ColumnSet.
740
780
ColumnPtr column_set_ptr = block.getByPosition (arguments[1 ]).column ;
741
781
const ColumnSet * column_set = typeid_cast<const ColumnSet *>(&*column_set_ptr);
@@ -746,7 +786,6 @@ class FunctionIn : public IFunction
746
786
Block block_of_key_columns;
747
787
748
788
// / First argument may be tuple or single column.
749
- const ColumnWithTypeAndName & left_arg = block.getByPosition (arguments[0 ]);
750
789
const ColumnTuple * tuple = typeid_cast<const ColumnTuple *>(left_arg.column .get ());
751
790
const ColumnConst * const_tuple = checkAndGetColumnConst<ColumnTuple>(left_arg.column .get ());
752
791
const DataTypeTuple * type_tuple = typeid_cast<const DataTypeTuple *>(left_arg.type .get ());
@@ -769,7 +808,55 @@ class FunctionIn : public IFunction
769
808
else
770
809
block_of_key_columns.insert (left_arg);
771
810
772
- block.getByPosition (result).column = column_set->getData ()->execute (block_of_key_columns, negative);
811
+ if constexpr (ignore_null)
812
+ {
813
+ block.getByPosition (result).column = column_set->getData ()->execute (block_of_key_columns, negative);
814
+ }
815
+ else
816
+ {
817
+ bool set_contains_null = column_set->getData ()->containsNullValue ();
818
+ bool return_nullable = left_arg.type ->isNullable () || set_contains_null;
819
+ if (return_nullable)
820
+ {
821
+ auto nested_res = column_set->getData ()->execute (block_of_key_columns, negative);
822
+ if (left_arg.column ->isColumnNullable ())
823
+ {
824
+ ColumnPtr result_null_map_column = dynamic_cast <const ColumnNullable &>(*left_arg.column ).getNullMapColumnPtr ();
825
+ if (set_contains_null)
826
+ {
827
+ MutableColumnPtr mutable_result_null_map_column = (*std::move (result_null_map_column)).mutate ();
828
+ NullMap & result_null_map = dynamic_cast <ColumnUInt8 &>(*mutable_result_null_map_column).getData ();
829
+ auto uint8_column = checkAndGetColumn<ColumnUInt8>(nested_res.get ());
830
+ const auto & data = uint8_column->getData ();
831
+ for (size_t i = 0 , size = result_null_map.size (); i < size; i++)
832
+ {
833
+ if (data[i] == negative)
834
+ result_null_map[i] = 1 ;
835
+ }
836
+ result_null_map_column = std::move (mutable_result_null_map_column);
837
+ }
838
+ block.getByPosition (result).column = ColumnNullable::create (nested_res, result_null_map_column);
839
+ }
840
+ else
841
+ {
842
+ auto col_null_map = ColumnUInt8::create ();
843
+ ColumnUInt8::Container & vec_null_map = col_null_map->getData ();
844
+ vec_null_map.assign (block.rows (), (UInt8 ) 0 );
845
+ auto uint8_column = checkAndGetColumn<ColumnUInt8>(nested_res.get ());
846
+ const auto & data = uint8_column->getData ();
847
+ for (size_t i = 0 , size = vec_null_map.size (); i < size; i++)
848
+ {
849
+ if (data[i] == negative)
850
+ vec_null_map[i] = 1 ;
851
+ }
852
+ block.getByPosition (result).column = ColumnNullable::create (nested_res, std::move (col_null_map));
853
+ }
854
+ }
855
+ else
856
+ {
857
+ block.getByPosition (result).column = column_set->getData ()->execute (block_of_key_columns, negative);
858
+ }
859
+ }
773
860
}
774
861
};
775
862
@@ -1865,10 +1952,12 @@ void registerFunctionsMiscellaneous(FunctionFactory & factory)
1865
1952
factory.registerFunction <FunctionBar>();
1866
1953
factory.registerFunction <FunctionHasColumnInTable>();
1867
1954
1868
- factory.registerFunction <FunctionIn<false , false >>();
1869
- factory.registerFunction <FunctionIn<false , true >>();
1870
- factory.registerFunction <FunctionIn<true , false >>();
1871
- factory.registerFunction <FunctionIn<true , true >>();
1955
+ factory.registerFunction <FunctionIn<false , false , true >>();
1956
+ factory.registerFunction <FunctionIn<false , true , true >>();
1957
+ factory.registerFunction <FunctionIn<true , false , true >>();
1958
+ factory.registerFunction <FunctionIn<true , true , true >>();
1959
+ factory.registerFunction <FunctionIn<true , false , false >>();
1960
+ factory.registerFunction <FunctionIn<false , false , false >>();
1872
1961
1873
1962
factory.registerFunction <FunctionIsFinite>();
1874
1963
factory.registerFunction <FunctionIsInfinite>();
0 commit comments