diff --git a/cpp/src/binaryop/compiled/binary_ops.cu b/cpp/src/binaryop/compiled/binary_ops.cu index d91b534dffb..56528ba8081 100644 --- a/cpp/src/binaryop/compiled/binary_ops.cu +++ b/cpp/src/binaryop/compiled/binary_ops.cu @@ -405,6 +405,7 @@ void apply_sorting_struct_binary_op(mutable_column_view& out, // Struct child column type and structure mismatches are caught within the two_table_comparator switch (op) { case binary_operator::EQUAL: [[fallthrough]]; + case binary_operator::NULL_EQUALS: [[fallthrough]]; case binary_operator::NOT_EQUAL: detail::apply_struct_equality_op( out, diff --git a/cpp/src/binaryop/compiled/struct_binary_ops.cuh b/cpp/src/binaryop/compiled/struct_binary_ops.cuh index 7cf19ef91e8..804b931fa5b 100644 --- a/cpp/src/binaryop/compiled/struct_binary_ops.cuh +++ b/cpp/src/binaryop/compiled/struct_binary_ops.cuh @@ -109,7 +109,8 @@ void apply_struct_equality_op(mutable_column_view& out, PhysicalEqualityComparator comparator = {}, rmm::cuda_stream_view stream = cudf::default_stream_value) { - CUDF_EXPECTS(op == binary_operator::EQUAL || op == binary_operator::NOT_EQUAL, + CUDF_EXPECTS(op == binary_operator::EQUAL || op == binary_operator::NOT_EQUAL || + op == binary_operator::NULL_EQUALS, "Unsupported operator for these types"); auto tlhs = table_view{{lhs}}; diff --git a/java/src/main/native/src/ColumnViewJni.cpp b/java/src/main/native/src/ColumnViewJni.cpp index f8f7c79ddf0..9687d333ea9 100644 --- a/java/src/main/native/src/ColumnViewJni.cpp +++ b/java/src/main/native/src/ColumnViewJni.cpp @@ -1318,8 +1318,15 @@ JNIEXPORT jlong JNICALL Java_ai_rapids_cudf_ColumnView_binaryOpVV(JNIEnv *env, j cudf::binary_operator op = static_cast(int_op); if (lhs->type().id() == cudf::type_id::STRUCT) { - auto [new_mask, null_count] = cudf::bitmask_and(cudf::table_view{{*lhs, *rhs}}); - auto out = make_fixed_width_column(n_data_type, lhs->size(), std::move(new_mask), null_count); + auto out = make_fixed_width_column(n_data_type, lhs->size(), cudf::mask_state::UNALLOCATED); + + if (op == cudf::binary_operator::NULL_EQUALS) { + out->set_null_mask(rmm::device_buffer{}, 0); + } else { + auto [new_mask, null_count] = cudf::bitmask_and(cudf::table_view{{*lhs, *rhs}}); + out->set_null_mask(std::move(new_mask), null_count); + } + auto out_view = out->mutable_view(); cudf::binops::compiled::detail::apply_sorting_struct_binary_op(out_view, *lhs, *rhs, false, false, op); @@ -1357,9 +1364,15 @@ JNIEXPORT jlong JNICALL Java_ai_rapids_cudf_ColumnView_binaryOpVS(JNIEnv *env, j cudf::binary_operator op = static_cast(int_op); if (lhs->type().id() == cudf::type_id::STRUCT) { - auto [new_mask, new_null_count] = cudf::binops::scalar_col_valid_mask_and(*lhs, *rhs); - auto out = - make_fixed_width_column(n_data_type, lhs->size(), std::move(new_mask), new_null_count); + auto out = make_fixed_width_column(n_data_type, lhs->size(), cudf::mask_state::UNALLOCATED); + + if (op == cudf::binary_operator::NULL_EQUALS) { + out->set_null_mask(rmm::device_buffer{}, 0); + } else { + auto [new_mask, new_null_count] = cudf::binops::scalar_col_valid_mask_and(*lhs, *rhs); + out->set_null_mask(std::move(new_mask), new_null_count); + } + auto rhsv = cudf::make_column_from_scalar(*rhs, 1); auto out_view = out->mutable_view(); cudf::binops::compiled::detail::apply_sorting_struct_binary_op(out_view, *lhs, rhsv->view(), diff --git a/java/src/main/native/src/ScalarJni.cpp b/java/src/main/native/src/ScalarJni.cpp index 9af3edd0356..b44d2604882 100644 --- a/java/src/main/native/src/ScalarJni.cpp +++ b/java/src/main/native/src/ScalarJni.cpp @@ -503,9 +503,15 @@ JNIEXPORT jlong JNICALL Java_ai_rapids_cudf_Scalar_binaryOpSV(JNIEnv *env, jclas cudf::binary_operator op = static_cast(int_op); if (lhs->type().id() == cudf::type_id::STRUCT) { - auto [new_mask, new_null_count] = cudf::binops::scalar_col_valid_mask_and(*rhs, *lhs); - auto out = - make_fixed_width_column(n_data_type, rhs->size(), std::move(new_mask), new_null_count); + auto out = make_fixed_width_column(n_data_type, rhs->size(), cudf::mask_state::UNALLOCATED); + + if (op == cudf::binary_operator::NULL_EQUALS) { + out->set_null_mask(rmm::device_buffer{}, 0); + } else { + auto [new_mask, new_null_count] = cudf::binops::scalar_col_valid_mask_and(*rhs, *lhs); + out->set_null_mask(std::move(new_mask), new_null_count); + } + auto lhs_col = cudf::make_column_from_scalar(*lhs, 1); auto out_view = out->mutable_view(); cudf::binops::compiled::detail::apply_sorting_struct_binary_op(out_view, lhs_col->view(), diff --git a/java/src/test/java/ai/rapids/cudf/BinaryOpTest.java b/java/src/test/java/ai/rapids/cudf/BinaryOpTest.java index 35d1cb39324..28fcfb741e6 100644 --- a/java/src/test/java/ai/rapids/cudf/BinaryOpTest.java +++ b/java/src/test/java/ai/rapids/cudf/BinaryOpTest.java @@ -18,13 +18,19 @@ package ai.rapids.cudf; +import ai.rapids.cudf.HostColumnVector.BasicType; import ai.rapids.cudf.HostColumnVector.Builder; +import ai.rapids.cudf.HostColumnVector.DataType; +import ai.rapids.cudf.HostColumnVector.StructData; +import ai.rapids.cudf.HostColumnVector.StructType; + import org.junit.jupiter.api.Test; import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; import java.util.Arrays; +import java.util.List; import java.util.stream.IntStream; import static ai.rapids.cudf.AssertUtils.assertColumnsAreEqual; @@ -57,6 +63,21 @@ public class BinaryOpTest extends CudfTestBase { private static final long[] DECIMAL64_1 = new long[]{10L, 23L, 12L, 24L, 123456789L}; private static final long[] DECIMAL64_2 = new long[]{33041L, 97290L, 36438L, 25379L, 48473L}; + private static final StructData INT_SD_1 = new StructData(1); + private static final StructData INT_SD_2 = new StructData(2); + private static final StructData INT_SD_3 = new StructData(3); + private static final StructData INT_SD_4 = new StructData(4); + private static final StructData INT_SD_5 = new StructData(5); + private static final StructData INT_SD_NULL = new StructData((List) null); + private static final StructData INT_SD_100 = new StructData(100); + + private static final StructData[] int_struct_data_1 = + new StructData[]{null, INT_SD_1, null, INT_SD_3, INT_SD_4, INT_SD_5, INT_SD_NULL, INT_SD_100}; + private static final StructData[] int_struct_data_2 = + new StructData[]{null, null, INT_SD_2, INT_SD_3, INT_SD_100, INT_SD_5, INT_SD_NULL, INT_SD_4}; + private static final DataType structType = + new StructType(true, new BasicType(true, DType.INT32)); + private static final BigInteger[] DECIMAL128_1 = new BigInteger[]{new BigInteger("1234567891234567"), new BigInteger("1234567891234567"), new BigInteger("1234567891234567"), new BigInteger("1234567891234567"), new BigInteger("1234567891234567")}; private static final BigInteger[] DECIMAL128_2 = new BigInteger[]{new BigInteger("234567891234567"), new BigInteger("234567891234567"), @@ -791,7 +812,11 @@ public void testPow() { @Test public void testEqual() { try (ColumnVector icv = ColumnVector.fromBoxedInts(INTS_1); + ColumnVector intscalar = ColumnVector.fromInts(4); + Scalar sscv = Scalar.structFromColumnViews(intscalar); ColumnVector dcv = ColumnVector.fromBoxedDoubles(DOUBLES_1); + ColumnVector structcv1 = ColumnVector.fromStructs(structType, int_struct_data_1); + ColumnVector structcv2 = ColumnVector.fromStructs(structType, int_struct_data_2); ColumnVector dec32cv_1 = ColumnVector.decimalFromInts(-dec32Scale_1, DECIMAL32_1); ColumnVector dec32cv_2 = ColumnVector.decimalFromInts(-dec32Scale_2, DECIMAL32_2)) { try (ColumnVector answer = icv.equalTo(dcv); @@ -837,6 +862,28 @@ public void testEqual() { (b, l, r, i) -> b.append(Short.toUnsignedInt(l.getShort(i)) == r.getInt(i)))) { assertColumnsAreEqual(expected, answer, "uint16 == uint32"); } + + try (ColumnVector answersv = sscv.equalTo(structcv1); + ColumnVector expectedsv = forEachS(DType.BOOL8, 4, structcv1, + (b, l, r, i) -> b.append(r.isNull(i) ? false : + l == r.getStruct(i).dataRecord.get(0)))) { + assertColumnsAreEqual(expectedsv, answersv, "scalar struct int32 == struct int32"); + } + + try (ColumnVector answervs = structcv1.equalTo(sscv); + ColumnVector expectedvs = forEachS(DType.BOOL8, structcv1, 4, + (b, l, r, i) -> b.append(l.isNull(i) ? false : + r == l.getStruct(i).dataRecord.get(0)))) { + assertColumnsAreEqual(expectedvs, answervs, "struct int32 == scalar struct int32"); + } + + try (ColumnVector answervv = structcv1.equalTo(structcv2); + ColumnVector expectedvv = forEach(DType.BOOL8, structcv1, structcv2, + (b, l, r, i) -> b.append(l.isNull(i) || r.isNull(i) || + l.getStruct(i).dataRecord.get(0) == null || r.getStruct(i).dataRecord.get(0) == null ? + false : l.getStruct(i).dataRecord.get(0) == r.getStruct(i).dataRecord.get(0)))) { + assertColumnsAreEqual(expectedvv, answervv, "struct int32 == struct int32"); + } } } @@ -884,16 +931,16 @@ public void testStringEqualScalarNotPresent() { @Test public void testNotEqual() { - try (ColumnVector icv1 = ColumnVector.fromBoxedInts(INTS_1); - ColumnVector icv2 = ColumnVector.fromBoxedInts(INTS_2); - ColumnVector structcv1 = ColumnVector.makeStruct(icv1); - ColumnVector structcv2 = ColumnVector.makeStruct(icv2); + try (ColumnVector icv = ColumnVector.fromBoxedInts(INTS_1); ColumnVector intscalar = ColumnVector.fromInts(4); + Scalar sscv = Scalar.structFromColumnViews(intscalar); ColumnVector dcv = ColumnVector.fromBoxedDoubles(DOUBLES_1); + ColumnVector structcv1 = ColumnVector.fromStructs(structType, int_struct_data_1); + ColumnVector structcv2 = ColumnVector.fromStructs(structType, int_struct_data_2); ColumnVector dec32cv_1 = ColumnVector.decimalFromInts(-dec32Scale_1, DECIMAL32_1); ColumnVector dec32cv_2 = ColumnVector.decimalFromInts(-dec32Scale_2, DECIMAL32_2)) { - try (ColumnVector answer = icv1.notEqualTo(dcv); - ColumnVector expected = forEach(DType.BOOL8, icv1, dcv, + try (ColumnVector answer = icv.notEqualTo(dcv); + ColumnVector expected = forEach(DType.BOOL8, icv, dcv, (b, l, r, i) -> b.append(l.getInt(i) != r.getDouble(i)))) { assertColumnsAreEqual(expected, answer, "int32 != double"); } @@ -913,36 +960,35 @@ public void testNotEqual() { } try (Scalar s = Scalar.fromFloat(1.0f); - ColumnVector answer = icv1.notEqualTo(s); - ColumnVector expected = forEachS(DType.BOOL8, icv1, 1.0f, + ColumnVector answer = icv.notEqualTo(s); + ColumnVector expected = forEachS(DType.BOOL8, icv, 1.0f, (b, l, r, i) -> b.append(l.getInt(i) != r))) { assertColumnsAreEqual(expected, answer, "int64 != scalar float"); } try (Scalar s = Scalar.fromShort((short) 100); - ColumnVector answer = s.notEqualTo(icv1); - ColumnVector expected = forEachS(DType.BOOL8, (short) 100, icv1, + ColumnVector answer = s.notEqualTo(icv); + ColumnVector expected = forEachS(DType.BOOL8, (short) 100, icv, (b, l, r, i) -> b.append(l != r.getInt(i)))) { assertColumnsAreEqual(expected, answer, "scalar short != int32"); } - try (Scalar s = Scalar.structFromColumnViews(intscalar); - ColumnVector answersv = s.notEqualTo(structcv1); - ColumnVector expectedsv = forEachS(DType.BOOL8, 4, icv1, - (b, l, r, i) -> b.append(r.isNull(i) ? true : l != r.getInt(i)), true)) { + try (ColumnVector answersv = sscv.notEqualTo(structcv1); + ColumnVector expectedsv = forEachS(DType.BOOL8, 4, structcv1, + (b, l, r, i) -> b.append(r.isNull(i) ? true : l != r.getStruct(i).dataRecord.get(0)))) { assertColumnsAreEqual(expectedsv, answersv, "scalar struct int32 != struct int32"); } - try (Scalar s = Scalar.structFromColumnViews(intscalar); - ColumnVector answervs = structcv1.notEqualTo(s); - ColumnVector expectedvs = forEachS(DType.BOOL8, icv1, 4, - (b, l, r, i) -> b.append(l.isNull(i) ? true : l.getInt(i) != r), true)) { + try (ColumnVector answervs = structcv1.notEqualTo(sscv); + ColumnVector expectedvs = forEachS(DType.BOOL8, structcv1, 4, + (b, l, r, i) -> b.append(l.isNull(i) ? true : l.getStruct(i).dataRecord.get(0) != r))) { assertColumnsAreEqual(expectedvs, answervs, "struct int32 != scalar struct int32"); } try (ColumnVector answervv = structcv1.notEqualTo(structcv2); - ColumnVector expectedvv = forEach(DType.BOOL8, icv1, icv2, - (b, l, r, i) -> b.append(l.isNull(i) ? !r.isNull(i) : r.isNull(i) || l.getInt(i) != r.getInt(i)), true)) { + ColumnVector expectedvv = forEach(DType.BOOL8, structcv1, structcv2, + (b, l, r, i) -> b.append(l.isNull(i) ? !r.isNull(i) : + r.isNull(i) || l.getStruct(i).dataRecord.get(0) != r.getStruct(i).dataRecord.get(0)))) { assertColumnsAreEqual(expectedvv, answervv, "struct int32 != struct int32"); } } @@ -993,7 +1039,11 @@ public void testStringNotEqualScalarNotPresent() { @Test public void testLessThan() { try (ColumnVector icv = ColumnVector.fromBoxedInts(INTS_1); + ColumnVector intscalar = ColumnVector.fromInts(4); + Scalar sscv = Scalar.structFromColumnViews(intscalar); ColumnVector dcv = ColumnVector.fromBoxedDoubles(DOUBLES_1); + ColumnVector structcv1 = ColumnVector.fromStructs(structType, int_struct_data_1); + ColumnVector structcv2 = ColumnVector.fromStructs(structType, int_struct_data_2); ColumnVector dec32cv_1 = ColumnVector.decimalFromInts(-dec32Scale_1, DECIMAL32_1); ColumnVector dec32cv_2 = ColumnVector.decimalFromInts(-dec32Scale_2, DECIMAL32_2)) { try (ColumnVector answer = icv.lessThan(dcv); @@ -1021,6 +1071,27 @@ public void testLessThan() { (b, l, r, i) -> b.append(l < r.getInt(i)))) { assertColumnsAreEqual(expected, answer, "scalar short < int32"); } + + try (ColumnVector answersv = sscv.lessThan(structcv1); + ColumnVector expectedsv = forEachS(DType.BOOL8, 4, structcv1, + (b, l, r, i) -> b.append(r.isNull(i) ? false : + l < (Integer) r.getStruct(i).dataRecord.get(0)))) { + assertColumnsAreEqual(expectedsv, answersv, "scalar struct int32 < struct int32"); + } + + try (ColumnVector answervs = structcv1.lessThan(sscv); + ColumnVector expectedvs = forEachS(DType.BOOL8, structcv1, 4, + (b, l, r, i) -> b.append(l.isNull(i) ? true : + (Integer) l.getStruct(i).dataRecord.get(0) < r))) { + assertColumnsAreEqual(expectedvs, answervs, "struct int32 < scalar struct int32"); + } + + try (ColumnVector answervv = structcv1.lessThan(structcv2); + ColumnVector expectedvv = forEach(DType.BOOL8, structcv1, structcv2, + (b, l, r, i) -> b.append(l.isNull(i) ? true : r.isNull(i) || + (Integer)l.getStruct(i).dataRecord.get(0) < (Integer)r.getStruct(i).dataRecord.get(0)))) { + assertColumnsAreEqual(expectedvv, answervv, "struct int32 < struct int32"); + } } } @@ -1075,16 +1146,16 @@ public void testStringLessThanScalarNotPresent() { @Test public void testGreaterThan() { - try (ColumnVector icv1 = ColumnVector.fromBoxedInts(INTS_1); - ColumnVector icv2 = ColumnVector.fromBoxedInts(INTS_2); - ColumnVector structcv1 = ColumnVector.makeStruct(icv1); - ColumnVector structcv2 = ColumnVector.makeStruct(icv2); + try (ColumnVector icv = ColumnVector.fromBoxedInts(INTS_1); ColumnVector intscalar = ColumnVector.fromInts(4); + Scalar sscv = Scalar.structFromColumnViews(intscalar); ColumnVector dcv = ColumnVector.fromBoxedDoubles(DOUBLES_1); + ColumnVector structcv1 = ColumnVector.fromStructs(structType, int_struct_data_1); + ColumnVector structcv2 = ColumnVector.fromStructs(structType, int_struct_data_2); ColumnVector dec32cv1 = ColumnVector.fromDecimals(BIGDECIMAL32_1); ColumnVector dec32cv2 = ColumnVector.fromDecimals(BIGDECIMAL32_2)) { - try (ColumnVector answer = icv1.greaterThan(dcv); - ColumnVector expected = forEach(DType.BOOL8, icv1, dcv, + try (ColumnVector answer = icv.greaterThan(dcv); + ColumnVector expected = forEach(DType.BOOL8, icv, dcv, (b, l, r, i) -> b.append(l.getInt(i) > r.getDouble(i)))) { assertColumnsAreEqual(expected, answer, "int32 > double"); } @@ -1096,36 +1167,37 @@ public void testGreaterThan() { } try (Scalar s = Scalar.fromFloat(1.0f); - ColumnVector answer = icv1.greaterThan(s); - ColumnVector expected = forEachS(DType.BOOL8, icv1, 1.0f, + ColumnVector answer = icv.greaterThan(s); + ColumnVector expected = forEachS(DType.BOOL8, icv, 1.0f, (b, l, r, i) -> b.append(l.getInt(i) > r))) { assertColumnsAreEqual(expected, answer, "int64 > scalar float"); } try (Scalar s = Scalar.fromShort((short) 100); - ColumnVector answer = s.greaterThan(icv1); - ColumnVector expected = forEachS(DType.BOOL8, (short) 100, icv1, + ColumnVector answer = s.greaterThan(icv); + ColumnVector expected = forEachS(DType.BOOL8, (short) 100, icv, (b, l, r, i) -> b.append(l > r.getInt(i)))) { assertColumnsAreEqual(expected, answer, "scalar short > int32"); } - try (Scalar s = Scalar.structFromColumnViews(intscalar); - ColumnVector answersv = s.greaterThan(structcv1); - ColumnVector expectedsv = forEachS(DType.BOOL8, 4, icv1, - (b, l, r, i) -> b.append(r.isNull(i) ? true : l > r.getInt(i)), true)) { + try (ColumnVector answersv = sscv.greaterThan(structcv1); + ColumnVector expectedsv = forEachS(DType.BOOL8, 4, structcv1, + (b, l, r, i) -> b.append(r.isNull(i) ? true : + l > (Integer) r.getStruct(i).dataRecord.get(0)))) { assertColumnsAreEqual(expectedsv, answersv, "scalar struct int32 > struct int32"); } - try (Scalar s = Scalar.structFromColumnViews(intscalar); - ColumnVector answervs = structcv1.greaterThan(s); - ColumnVector expectedvs = forEachS(DType.BOOL8, icv1, 4, - (b, l, r, i) -> b.append(l.isNull(i) ? false : l.getInt(i) > r), true)) { + try (ColumnVector answervs = structcv1.greaterThan(sscv); + ColumnVector expectedvs = forEachS(DType.BOOL8, structcv1, 4, + (b, l, r, i) -> b.append(l.isNull(i) ? false : + (Integer) l.getStruct(i).dataRecord.get(0) > r))) { assertColumnsAreEqual(expectedvs, answervs, "struct int32 > scalar struct int32"); } try (ColumnVector answervv = structcv1.greaterThan(structcv2); - ColumnVector expectedvv = forEach(DType.BOOL8, icv1, icv2, - (b, l, r, i) -> b.append(l.isNull(i) ? false : r.isNull(i) || l.getInt(i) > r.getInt(i)), true)) { + ColumnVector expectedvv = forEach(DType.BOOL8, structcv1, structcv2, + (b, l, r, i) -> b.append(l.isNull(i) ? false : r.isNull(i) || + (Integer)l.getStruct(i).dataRecord.get(0) > (Integer)r.getStruct(i).dataRecord.get(0)))) { assertColumnsAreEqual(expectedvv, answervv, "struct int32 > struct int32"); } } @@ -1181,29 +1253,29 @@ public void testStringGreaterThanScalarNotPresent() { @Test public void testLessOrEqualTo() { - try (ColumnVector icv1 = ColumnVector.fromBoxedInts(INTS_1); - ColumnVector icv2 = ColumnVector.fromBoxedInts(INTS_2); - ColumnVector structcv1 = ColumnVector.makeStruct(icv1); - ColumnVector structcv2 = ColumnVector.makeStruct(icv2); + try (ColumnVector icv = ColumnVector.fromBoxedInts(INTS_1); ColumnVector intscalar = ColumnVector.fromInts(4); + Scalar sscv = Scalar.structFromColumnViews(intscalar); ColumnVector dcv = ColumnVector.fromBoxedDoubles(DOUBLES_1); + ColumnVector structcv1 = ColumnVector.fromStructs(structType, int_struct_data_1); + ColumnVector structcv2 = ColumnVector.fromStructs(structType, int_struct_data_2); ColumnVector dec32cv = ColumnVector.decimalFromInts(-dec32Scale_2, DECIMAL32_2)) { - try (ColumnVector answer = icv1.lessOrEqualTo(dcv); - ColumnVector expected = forEach(DType.BOOL8, icv1, dcv, + try (ColumnVector answer = icv.lessOrEqualTo(dcv); + ColumnVector expected = forEach(DType.BOOL8, icv, dcv, (b, l, r, i) -> b.append(l.getInt(i) <= r.getDouble(i)))) { assertColumnsAreEqual(expected, answer, "int32 <= double"); } try (Scalar s = Scalar.fromFloat(1.0f); - ColumnVector answer = icv1.lessOrEqualTo(s); - ColumnVector expected = forEachS(DType.BOOL8, icv1, 1.0f, + ColumnVector answer = icv.lessOrEqualTo(s); + ColumnVector expected = forEachS(DType.BOOL8, icv, 1.0f, (b, l, r, i) -> b.append(l.getInt(i) <= r))) { assertColumnsAreEqual(expected, answer, "int64 <= scalar float"); } try (Scalar s = Scalar.fromShort((short) 100); - ColumnVector answer = s.lessOrEqualTo(icv1); - ColumnVector expected = forEachS(DType.BOOL8, (short) 100, icv1, + ColumnVector answer = s.lessOrEqualTo(icv); + ColumnVector expected = forEachS(DType.BOOL8, (short) 100, icv, (b, l, r, i) -> b.append(l <= r.getInt(i)))) { assertColumnsAreEqual(expected, answer, "scalar short <= int32"); } @@ -1216,23 +1288,24 @@ public void testLessOrEqualTo() { } } - try (Scalar s = Scalar.structFromColumnViews(intscalar); - ColumnVector answersv = s.lessOrEqualTo(structcv1); - ColumnVector expectedsv = forEachS(DType.BOOL8, 4, icv1, - (b, l, r, i) -> b.append(r.isNull(i) ? false : l <= r.getInt(i)), true)) { + try (ColumnVector answersv = sscv.lessOrEqualTo(structcv1); + ColumnVector expectedsv = forEachS(DType.BOOL8, 4, structcv1, + (b, l, r, i) -> b.append(r.isNull(i) ? false : + l <= (Integer) r.getStruct(i).dataRecord.get(0)))) { assertColumnsAreEqual(expectedsv, answersv, "scalar struct int32 <= struct int32"); } - try (Scalar s = Scalar.structFromColumnViews(intscalar); - ColumnVector answervs = structcv1.lessOrEqualTo(s); - ColumnVector expectedvs = forEachS(DType.BOOL8, icv1, 4, - (b, l, r, i) -> b.append(l.isNull(i) ? true : l.getInt(i) <= r), true)) { + try (ColumnVector answervs = structcv1.lessOrEqualTo(sscv); + ColumnVector expectedvs = forEachS(DType.BOOL8, structcv1, 4, + (b, l, r, i) -> b.append(l.isNull(i) ? true : + (Integer) l.getStruct(i).dataRecord.get(0) <= r))) { assertColumnsAreEqual(expectedvs, answervs, "struct int32 <= scalar struct int32"); } try (ColumnVector answervv = structcv1.lessOrEqualTo(structcv2); - ColumnVector expectedvv = forEach(DType.BOOL8, icv1, icv2, - (b, l, r, i) -> b.append(l.isNull(i) ? true : !r.isNull(i) && l.getInt(i) <= r.getInt(i)), true)) { + ColumnVector expectedvv = forEach(DType.BOOL8, structcv1, structcv2, + (b, l, r, i) -> b.append(l.isNull(i) ? true : !r.isNull(i) && + (Integer)l.getStruct(i).dataRecord.get(0) <= (Integer)r.getStruct(i).dataRecord.get(0)))) { assertColumnsAreEqual(expectedvv, answervv, "struct int32 <= struct int32"); } } @@ -1289,7 +1362,11 @@ public void testStringLessOrEqualToScalarNotPresent() { @Test public void testGreaterOrEqualTo() { try (ColumnVector icv = ColumnVector.fromBoxedInts(INTS_1); + ColumnVector intscalar = ColumnVector.fromInts(4); + Scalar sscv = Scalar.structFromColumnViews(intscalar); ColumnVector dcv = ColumnVector.fromBoxedDoubles(DOUBLES_1); + ColumnVector structcv1 = ColumnVector.fromStructs(structType, int_struct_data_1); + ColumnVector structcv2 = ColumnVector.fromStructs(structType, int_struct_data_2); ColumnVector dec32cv = ColumnVector.decimalFromInts(-dec32Scale_2, DECIMAL32_2)) { try (ColumnVector answer = icv.greaterOrEqualTo(dcv); ColumnVector expected = forEach(DType.BOOL8, icv, dcv, @@ -1318,6 +1395,25 @@ public void testGreaterOrEqualTo() { assertColumnsAreEqual(expected, answer, "dec32 >= scalar dec32"); } } + + try (ColumnVector answersv = sscv.greaterOrEqualTo(structcv1); + ColumnVector expectedsv = forEachS(DType.BOOL8, 4, structcv1, + (b, l, r, i) -> b.append(r.isNull(i) ? true : l >= (Integer) r.getStruct(i).dataRecord.get(0)))) { + assertColumnsAreEqual(expectedsv, answersv, "scalar struct int32 >= struct int32"); + } + + try (ColumnVector answervs = structcv1.greaterOrEqualTo(sscv); + ColumnVector expectedvs = forEachS(DType.BOOL8, structcv1, 4, + (b, l, r, i) -> b.append(l.isNull(i) ? false : (Integer) l.getStruct(i).dataRecord.get(0) >= r))) { + assertColumnsAreEqual(expectedvs, answervs, "struct int32 >= scalar struct int32"); + } + + try (ColumnVector answervv = structcv1.greaterOrEqualTo(structcv2); + ColumnVector expectedvv = forEach(DType.BOOL8, structcv1, structcv2, + (b, l, r, i) -> b.append(l.isNull(i) ? false : !r.isNull(i) && + (Integer)l.getStruct(i).dataRecord.get(0) >= (Integer)r.getStruct(i).dataRecord.get(0)))) { + assertColumnsAreEqual(expectedvv, answervv, "struct int32 >= struct int32"); + } } } @@ -1694,7 +1790,11 @@ public void testArctan2() { @Test public void testEqualNullAware() { try (ColumnVector icv = ColumnVector.fromBoxedInts(INTS_1); - ColumnVector dcv = ColumnVector.fromBoxedDoubles(DOUBLES_1)) { + ColumnVector intscalar = ColumnVector.fromInts(4); + Scalar sscv = Scalar.structFromColumnViews(intscalar); + ColumnVector dcv = ColumnVector.fromBoxedDoubles(DOUBLES_1); + ColumnVector structcv1 = ColumnVector.fromStructs(structType, int_struct_data_1); + ColumnVector structcv2 = ColumnVector.fromStructs(structType, int_struct_data_2)) { try (ColumnVector answer = icv.equalToNullAware(dcv); ColumnVector expected = ColumnVector.fromBoxedBooleans(true, false, false, false, false, false, false)) { @@ -1714,6 +1814,27 @@ public void testEqualNullAware() { false, true)) { assertColumnsAreEqual(expected, answer, "scalar short <=> int32"); } + + try (ColumnVector answersv = sscv.equalToNullAware(structcv1); + ColumnVector expectedsv = forEachS(DType.BOOL8, 4, structcv1, + (b, l, r, i) -> b.append(r.isNull(i) ? false : + l == r.getStruct(i).dataRecord.get(0)), true)) { + assertColumnsAreEqual(expectedsv, answersv, "scalar struct int32 <=> struct int32"); + } + + try (ColumnVector answervs = structcv1.equalToNullAware(sscv); + ColumnVector expectedvs = forEachS(DType.BOOL8, structcv1, 4, + (b, l, r, i) -> b.append(l.isNull(i) ? false : + l.getStruct(i).dataRecord.get(0) == r), true)) { + assertColumnsAreEqual(expectedvs, answervs, "struct int32 <=> scalar struct int32"); + } + + try (ColumnVector answervv = structcv1.equalToNullAware(structcv2); + ColumnVector expectedvv = forEach(DType.BOOL8, structcv1, structcv2, + (b, l, r, i) -> b.append(l.isNull(i) || r.isNull(i) ? l.isNull(i) && r.isNull(i) : + l.getStruct(i).dataRecord.get(0) == r.getStruct(i).dataRecord.get(0)), true)) { + assertColumnsAreEqual(expectedvv, answervv, "struct int32 <=> struct int32"); + } } }