Skip to content

Commit

Permalink
[fix](null_equal) fix wrong result and coredump of operator <=> (#27312)
Browse files Browse the repository at this point in the history
* [fix](null_equal) fix wrong result and coredump of operator <=>

* fix
  • Loading branch information
jacktengg authored Nov 21, 2023
1 parent 402095b commit 016dccb
Show file tree
Hide file tree
Showing 3 changed files with 304 additions and 3 deletions.
37 changes: 34 additions & 3 deletions be/src/vec/functions/comparison_equal_for_null.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,37 @@ class FunctionEqForNull : public IFunction {
size_t result, size_t input_rows_count) const override {
ColumnWithTypeAndName& col_left = block.get_by_position(arguments[0]);
ColumnWithTypeAndName& col_right = block.get_by_position(arguments[1]);
bool left_only_null = col_left.column->only_null();
bool right_only_null = col_right.column->only_null();
if (left_only_null && right_only_null) {
auto result_column = ColumnVector<UInt8>::create(input_rows_count, 1);
block.get_by_position(result).column = std::move(result_column);
return Status::OK();
} else if (left_only_null) {
auto right_type_nullable = col_right.type->is_nullable();
if (!right_type_nullable) {
block.get_by_position(result).column =
ColumnVector<UInt8>::create(input_rows_count);
} else {
auto const* nullable_right_col =
assert_cast<const ColumnNullable*>(col_right.column.get());
block.get_by_position(result).column =
nullable_right_col->get_null_map_column().clone_resized(input_rows_count);
}
return Status::OK();
} else if (right_only_null) {
auto left_type_nullable = col_left.type->is_nullable();
if (!left_type_nullable) {
block.get_by_position(result).column =
ColumnVector<UInt8>::create(input_rows_count, (UInt8)0);
} else {
auto const* nullable_left_col =
assert_cast<const ColumnNullable*>(col_left.column.get());
block.get_by_position(result).column =
nullable_left_col->get_null_map_column().clone_resized(input_rows_count);
}
return Status::OK();
}

const auto& [left_col, left_const] = unpack_if_const(col_left.column);
const auto& [right_col, right_const] = unpack_if_const(col_right.column);
Expand Down Expand Up @@ -153,15 +184,15 @@ class FunctionEqForNull : public IFunction {
bool right_const) {
if (left_const) {
for (int i = 0; i < rows; ++i) {
result[i] |= left[0] & (left[0] == right[i]);
result[i] &= (left[0] == right[i]);
}
} else if (right_const) {
for (int i = 0; i < rows; ++i) {
result[i] |= left[i] & (left[i] == right[0]);
result[i] &= (left[i] == right[0]);
}
} else {
for (int i = 0; i < rows; ++i) {
result[i] |= left[i] & (left[i] == right[i]);
result[i] &= (left[i] == right[i]);
}
}
}
Expand Down
196 changes: 196 additions & 0 deletions regression-test/data/correctness_p0/test_null_equal.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
-- This file is automatically generated. You should know what you did if you want to edit this
-- !test_const1 --
true

-- !test_const2 --
false

-- !test_const3 --
false

-- !test1 --

-- !test2 --

-- !test3 --
1 1
2 2
3 3

-- !test4 --
\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

-- !test5 --
\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

-- !test6 --
\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
1 1
2 2
3 3

74 changes: 74 additions & 0 deletions regression-test/suites/correctness_p0/test_null_equal.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

suite("test_null_equal") {
qt_test_const1 "select null <=> null;"
qt_test_const2 "select null <=> 0;"
qt_test_const3 "select 1 <=> null;"

sql "drop table if exists test_eq_for_null_not_nullable;"
sql """
create table test_eq_for_null_not_nullable(
k1 int not null
) distributed by hash(k1) properties("replication_num"="1");
"""
sql """
insert into test_eq_for_null_not_nullable values
(1),(2),(3);
"""
sql "sync"
qt_test1 "select * from test_eq_for_null_not_nullable where k1 <=> null;"
qt_test2 "select * from test_eq_for_null_not_nullable where null <=> k1;"

sql "drop table if exists test_eq_for_null_nullable;"
sql """
create table test_eq_for_null_nullable(
k1 int
) distributed by hash(k1) properties("replication_num"="1");
"""
sql """
insert into test_eq_for_null_nullable values
(1),(2),(3),
(null), (null), (null),(null),(null),(null),(null),(null),
(null), (null), (null),(null),(null),(null),(null),(null),
(null), (null), (null),(null),(null),(null),(null),(null),
(null), (null), (null),(null),(null),(null),(null),(null),
(null), (null), (null),(null),(null),(null),(null),(null),
(null), (null), (null),(null),(null),(null),(null),(null),
(null), (null), (null),(null),(null),(null),(null),(null);
"""
sql "sync"
qt_test3 "select * from test_eq_for_null_not_nullable l, test_eq_for_null_nullable r where l.k1 <=> r.k1 order by 1;"
qt_test4 "select * from test_eq_for_null_nullable where k1 <=> null;"
qt_test5 "select * from test_eq_for_null_nullable where null <=> k1;"

sql "drop table if exists test_eq_for_null_nullable2;"
sql """
create table test_eq_for_null_nullable2(
k1 int
) distributed by hash(k1) properties("replication_num"="1");
"""
sql """
insert into test_eq_for_null_nullable2 values
(null),(0),(1),(2),(3);
"""
sql "sync"

qt_test6 "select * from test_eq_for_null_nullable a, test_eq_for_null_nullable2 b where a.k1 <=> b.k1 order by 1;"


}

0 comments on commit 016dccb

Please sign in to comment.