Skip to content

Commit abf60b7

Browse files
committed
not distinct from
1 parent 68f805a commit abf60b7

File tree

7 files changed

+185
-0
lines changed

7 files changed

+185
-0
lines changed

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/expressions/Comparisons.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,22 @@ private static Boolean compareEquals(Object value, Object comparand) {
261261
}
262262
}
263263

264+
@Nullable
265+
@SpotBugsSuppressWarnings("NP_BOOLEAN_RETURN_NULL")
266+
private static Boolean compareNotDistinctFrom(Object value, Object comparand) {
267+
if (value == null && comparand == null) {
268+
return true;
269+
} else if (value == null || comparand == null) {
270+
return false;
271+
} else {
272+
if (value instanceof Message) {
273+
return MessageHelpers.compareMessageEquals(value, comparand);
274+
} else {
275+
return toClassWithRealEquals(value).equals(toClassWithRealEquals(comparand));
276+
}
277+
}
278+
}
279+
264280
@Nullable
265281
@SpotBugsSuppressWarnings("NP_BOOLEAN_RETURN_NULL")
266282
private static Boolean compareStartsWith(@Nullable Object value, @Nullable Object comparand) {
@@ -623,6 +639,7 @@ public enum Type {
623639
STARTS_WITH,
624640
NOT_NULL(false, true),
625641
IS_NULL(true, true),
642+
NOT_DISTINCT_FROM(false),
626643
IN,
627644
TEXT_CONTAINS_ALL(true),
628645
TEXT_CONTAINS_ALL_WITHIN(true),
@@ -722,6 +739,8 @@ public static Boolean evalComparison(@Nonnull Type type, @Nullable Object value,
722739
return null;
723740
}
724741
return !compareEquals(value, comparand);
742+
case NOT_DISTINCT_FROM:
743+
return compareNotDistinctFrom(value, comparand);
725744
case LESS_THAN:
726745
return compare(value, comparand) < 0;
727746
case LESS_THAN_OR_EQUALS:

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/predicates/RangeConstraints.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,7 @@ private boolean canBeUsedInScanPrefix(@Nonnull final Comparisons.Comparison comp
729729
case STARTS_WITH:
730730
case NOT_NULL:
731731
case IS_NULL:
732+
case NOT_DISTINCT_FROM:
732733
return true;
733734
case TEXT_CONTAINS_ALL:
734735
case TEXT_CONTAINS_ALL_WITHIN:

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/values/RelOpValue.java

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ private static Optional<QueryPredicate> promoteOperandsAndCreatePredicate(@Nulla
184184
@Nonnull Value leftChild,
185185
@Nonnull Value rightChild,
186186
@Nonnull final Comparisons.Type comparisonType) {
187+
if (leftChild.getResultType().getTypeCode() == Type.TypeCode.NULL && rightChild.getResultType().getTypeCode() == Type.TypeCode.NULL && comparisonType == Comparisons.Type.NOT_DISTINCT_FROM) {
188+
return Optional.of(ConstantPredicate.TRUE);
189+
}
187190
// maximumType may return null, but only for non-primitive types which is not possible here
188191
final var maxtype = Verify.verifyNotNull(Type.maximumType(leftChild.getResultType(), rightChild.getResultType()));
189192

@@ -255,6 +258,7 @@ private static Comparisons.Type swapBinaryComparisonOperator(@Nonnull Comparison
255258
switch (type) {
256259
case EQUALS:
257260
case NOT_EQUALS:
261+
case NOT_DISTINCT_FROM:
258262
return type;
259263
case LESS_THAN:
260264
return Comparisons.Type.GREATER_THAN;
@@ -290,6 +294,13 @@ private static Value encapsulate(@Nonnull final String functionName,
290294
} else {
291295
final Typed arg1 = arguments.get(1);
292296
final Type res1 = arg1.getResultType();
297+
if (functionName.equals("notDistinctFrom")) {
298+
if (res0.getTypeCode() == Type.TypeCode.NULL && res1.getTypeCode() != Type.TypeCode.NULL) {
299+
return encapsulate("isNull", Comparisons.Type.IS_NULL, List.of(arg1));
300+
} else if (res1.getTypeCode() == Type.TypeCode.NULL && res0.getTypeCode() != Type.TypeCode.NULL) {
301+
return encapsulate("isNull", Comparisons.Type.IS_NULL, List.of(arg0));
302+
}
303+
}
293304
SemanticException.check(res1.isPrimitive() || res1.isEnum() || res1.isUuid(), SemanticException.ErrorCode.COMPARAND_TO_COMPARISON_IS_OF_COMPLEX_TYPE);
294305

295306
final BinaryPhysicalOperator physicalOperator =
@@ -451,6 +462,21 @@ private static Value encapsulate(@Nonnull BuiltInFunction<Value> builtInFunction
451462
}
452463
}
453464

465+
/**
466+
* The {@code notDistinctFrom} function.
467+
*/
468+
@AutoService(BuiltInFunction.class)
469+
public static class NotDistinctFromFn extends BuiltInFunction<Value> {
470+
public NotDistinctFromFn() {
471+
super("notDistinctFrom",
472+
List.of(new Type.Any(), new Type.Any()), NotDistinctFromFn::encapsulate);
473+
}
474+
475+
private static Value encapsulate(@Nonnull BuiltInFunction<Value> builtInFunction, @Nonnull final List<? extends Typed> arguments) {
476+
return RelOpValue.encapsulate(builtInFunction.getFunctionName(), Comparisons.Type.NOT_DISTINCT_FROM, arguments);
477+
}
478+
}
479+
454480
private enum BinaryPhysicalOperator {
455481
// TODO think about equality epsilon for floating-point types.
456482
EQ_BU(Comparisons.Type.EQUALS, Type.TypeCode.BOOLEAN, Type.TypeCode.UNKNOWN, (l, r) -> null),
@@ -763,6 +789,66 @@ private enum BinaryPhysicalOperator {
763789
GTE_SID(Comparisons.Type.GREATER_THAN_OR_EQUALS, Type.TypeCode.STRING, Type.TypeCode.UUID, (l, r) -> Comparisons.evalComparison(Comparisons.Type.GREATER_THAN_OR_EQUALS, PromoteValue.PhysicalOperator.stringToUuidValue((String) l), r)),
764790
GTE_UID(Comparisons.Type.GREATER_THAN_OR_EQUALS, Type.TypeCode.UNKNOWN, Type.TypeCode.UUID, (l, r) -> null),
765791
GTE_IDU(Comparisons.Type.GREATER_THAN_OR_EQUALS, Type.TypeCode.UUID, Type.TypeCode.UNKNOWN, (l, r) -> null),
792+
793+
NOT_DISTINCT_FROM_BU(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.BOOLEAN, Type.TypeCode.UNKNOWN, (l, r) -> null),
794+
NOT_DISTINCT_FROM_BB(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.BOOLEAN, Type.TypeCode.BOOLEAN, (l, r) -> (boolean)l == (boolean)r),
795+
NOT_DISTINCT_FROM_IU(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.INT, Type.TypeCode.UNKNOWN, (l, r) -> null),
796+
NOT_DISTINCT_FROM_II(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.INT, Type.TypeCode.INT, (l, r) -> (int)l == (int)r),
797+
NOT_DISTINCT_FROM_IL(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.INT, Type.TypeCode.LONG, (l, r) -> (int)l == (long)r),
798+
NOT_DISTINCT_FROM_IF(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.INT, Type.TypeCode.FLOAT, (l, r) -> (int)l == (float)r),
799+
NOT_DISTINCT_FROM_ID(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.INT, Type.TypeCode.DOUBLE, (l, r) -> (int)l == (double)r),
800+
NOT_DISTINCT_FROM_LU(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.LONG, Type.TypeCode.UNKNOWN, (l, r) -> null),
801+
NOT_DISTINCT_FROM_LI(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.LONG, Type.TypeCode.INT, (l, r) -> (long)l == (int)r),
802+
NOT_DISTINCT_FROM_LL(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.LONG, Type.TypeCode.LONG, (l, r) -> (long)l == (long)r),
803+
NOT_DISTINCT_FROM_LF(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.LONG, Type.TypeCode.FLOAT, (l, r) -> (long)l == (float)r),
804+
NOT_DISTINCT_FROM_LD(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.LONG, Type.TypeCode.DOUBLE, (l, r) -> (long)l == (double)r),
805+
NOT_DISTINCT_FROM_FU(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.FLOAT, Type.TypeCode.UNKNOWN, (l, r) -> null),
806+
NOT_DISTINCT_FROM_FI(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.FLOAT, Type.TypeCode.INT, (l, r) -> (float)l == (int)r),
807+
NOT_DISTINCT_FROM_FL(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.FLOAT, Type.TypeCode.LONG, (l, r) -> (float)l == (long)r),
808+
NOT_DISTINCT_FROM_FF(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.FLOAT, Type.TypeCode.FLOAT, (l, r) -> (float)l == (float)r),
809+
NOT_DISTINCT_FROM_FD(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.FLOAT, Type.TypeCode.DOUBLE, (l, r) -> (float)l == (double)r),
810+
NOT_DISTINCT_FROM_DU(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.DOUBLE, Type.TypeCode.UNKNOWN, (l, r) -> null),
811+
NOT_DISTINCT_FROM_DI(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.DOUBLE, Type.TypeCode.INT, (l, r) -> (double)l == (int)r),
812+
NOT_DISTINCT_FROM_DL(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.DOUBLE, Type.TypeCode.LONG, (l, r) -> (double)l == (long)r),
813+
NOT_DISTINCT_FROM_DF(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.DOUBLE, Type.TypeCode.FLOAT, (l, r) -> (double)l == (float)r),
814+
NOT_DISTINCT_FROM_DD(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.DOUBLE, Type.TypeCode.DOUBLE, (l, r) -> (double)l == (double)r),
815+
NOT_DISTINCT_FROM_SU(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.STRING, Type.TypeCode.UNKNOWN, (l, r) -> null),
816+
NOT_DISTINCT_FROM_SS(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.STRING, Type.TypeCode.STRING, Object::equals), // TODO: locale-aware comparison
817+
NOT_DISTINCT_FROM_UU(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.UNKNOWN, Type.TypeCode.UNKNOWN, (l, r) -> null),
818+
NOT_DISTINCT_FROM_UB(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.UNKNOWN, Type.TypeCode.BOOLEAN, (l, r) -> null),
819+
NOT_DISTINCT_FROM_UI(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.UNKNOWN, Type.TypeCode.INT, (l, r) -> null),
820+
NOT_DISTINCT_FROM_UL(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.UNKNOWN, Type.TypeCode.LONG, (l, r) -> null),
821+
NOT_DISTINCT_FROM_UF(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.UNKNOWN, Type.TypeCode.FLOAT, (l, r) -> null),
822+
NOT_DISTINCT_FROM_UD(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.UNKNOWN, Type.TypeCode.DOUBLE, (l, r) -> null),
823+
NOT_DISTINCT_FROM_US(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.UNKNOWN, Type.TypeCode.STRING, (l, r) -> null),
824+
NOT_DISTINCT_FROM_UV(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.UNKNOWN, Type.TypeCode.VERSION, (l, r) -> null),
825+
NOT_DISTINCT_FROM_VU(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.VERSION, Type.TypeCode.UNKNOWN, (l, r) -> null),
826+
NOT_DISTINCT_FROM_VV(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.VERSION, Type.TypeCode.VERSION, Object::equals),
827+
828+
NOT_DISTINCT_FROM_BYU(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.BYTES, Type.TypeCode.UNKNOWN, (l, r) -> null),
829+
NOT_DISTINCT_FROM_BYBY(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.BYTES, Type.TypeCode.BYTES, (l, r) -> Comparisons.evalComparison(Comparisons.Type.NOT_DISTINCT_FROM, l, r)),
830+
NOT_DISTINCT_FROM_UBY(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.UNKNOWN, Type.TypeCode.BYTES, (l, r) -> null),
831+
832+
NOT_DISTINCT_FROM_EE(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.ENUM, Type.TypeCode.ENUM, (l, r) -> Comparisons.evalComparison(Comparisons.Type.NOT_DISTINCT_FROM, l, r)),
833+
NOT_DISTINCT_FROM_ES(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.ENUM, Type.TypeCode.STRING, (l, r) -> {
834+
final var otherValue = PromoteValue.PhysicalOperator.stringToEnumValue(((Descriptors.EnumValueDescriptor) l).getType(), (String) r);
835+
return Comparisons.evalComparison(Comparisons.Type.NOT_DISTINCT_FROM, l, otherValue);
836+
}),
837+
NOT_DISTINCT_FROM_SE(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.STRING, Type.TypeCode.ENUM, (l, r) -> {
838+
final var otherValue = PromoteValue.PhysicalOperator.stringToEnumValue(((Descriptors.EnumValueDescriptor) r).getType(), (String) l);
839+
return Comparisons.evalComparison(Comparisons.Type.NOT_DISTINCT_FROM, otherValue, r);
840+
}),
841+
NOT_DISTINCT_FROM_EU(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.ENUM, Type.TypeCode.UNKNOWN, (l, r) -> null),
842+
NOT_DISTINCT_FROM_UE(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.UNKNOWN, Type.TypeCode.ENUM, (l, r) -> null),
843+
844+
NOT_DISTINCT_FROM_IDID(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.UUID, Type.TypeCode.UUID, (l, r) -> Comparisons.evalComparison(Comparisons.Type.NOT_DISTINCT_FROM, l, r)),
845+
NOT_DISTINCT_FROM_IDS(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.UUID, Type.TypeCode.STRING, (l, r) -> Comparisons.evalComparison(Comparisons.Type.NOT_DISTINCT_FROM, l, PromoteValue.PhysicalOperator.stringToUuidValue((String) r))),
846+
NOT_DISTINCT_FROM_SID(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.STRING, Type.TypeCode.UUID, (l, r) -> Comparisons.evalComparison(Comparisons.Type.NOT_DISTINCT_FROM, PromoteValue.PhysicalOperator.stringToUuidValue((String) l), r)),
847+
NOT_DISTINCT_FROM_UID(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.UNKNOWN, Type.TypeCode.UUID, (l, r) -> null),
848+
NOT_DISTINCT_FROM_IDU(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.UUID, Type.TypeCode.UNKNOWN, (l, r) -> null),
849+
850+
NOT_DISTINCT_FROM_NN(Comparisons.Type.NOT_DISTINCT_FROM, Type.TypeCode.NULL, Type.TypeCode.NULL, (l, r) -> true),
851+
766852
;
767853
// We can pass down UUID or String till here.
768854

fdb-relational-core/src/main/antlr/RelationalLexer.g4

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ INSERT: 'INSERT';
127127
INTERVAL: 'INTERVAL';
128128
INTO: 'INTO';
129129
IS: 'IS';
130+
IS_DISTINCT_FROM: 'IS DISTINCT FROM';
131+
IS_NOT_DISTINCT_FROM: 'IS NOT DISTINCT FROM';
130132
ITERATE: 'ITERATE';
131133
JOIN: 'JOIN';
132134
KEY: 'KEY';

fdb-relational-core/src/main/antlr/RelationalParser.g4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,7 @@ unaryOperator
11631163
comparisonOperator
11641164
: '=' | '>' | '<' | '<' '=' | '>' '='
11651165
| '<' '>' | '!' '=' // | '<' '=' '>' // no support for null-safe equality
1166+
| IS_DISTINCT_FROM | IS_NOT_DISTINCT_FROM
11661167
;
11671168

11681169
logicalOperator

fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/query/functions/SqlFunctionCatalogImpl.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ public CatalogedFunction lookupFunction(@Nonnull final String name, @Nonnull fin
7777
private Optional<? extends CatalogedFunction> lookupBuiltInFunction(@Nonnull final String name,
7878
@Nonnull final Expressions expressions) {
7979
final var functionValidator = builtInSynonyms.get(name.toLowerCase(Locale.ROOT));
80+
System.out.println("builtInSynonyms:" + builtInSynonyms.keySet());
81+
System.out.println("name lowercase:" + name.toLowerCase(Locale.ROOT) + "name in builtInSynonyms keyset:" + builtInSynonyms.keySet().contains(name.toLowerCase(Locale.ROOT)));
8082
if (functionValidator == null) {
8183
return Optional.empty();
8284
}
@@ -145,6 +147,7 @@ private static ImmutableMap<String, Function<Integer, Optional<BuiltInFunction<?
145147
.put("coalesce", argumentsCount -> BuiltInFunctionCatalog.resolve("coalesce", argumentsCount))
146148
.put("is null", argumentsCount -> BuiltInFunctionCatalog.resolve("isNull", argumentsCount))
147149
.put("is not null", argumentsCount -> BuiltInFunctionCatalog.resolve("notNull", argumentsCount))
150+
.put("is not distinct from", argumentsCount -> BuiltInFunctionCatalog.resolve("notDistinctFrom", argumentsCount))
148151
.put("range", argumentsCount -> BuiltInFunctionCatalog.resolve("range", argumentsCount))
149152
.put("__pattern_for_like", argumentsCount -> BuiltInFunctionCatalog.resolve("patternForLike", argumentsCount))
150153
.put("__internal_array", argumentsCount -> BuiltInFunctionCatalog.resolve("array", argumentsCount))

fdb-relational-core/src/test/java/com/apple/foundationdb/relational/recordlayer/query/StandardQueryTests.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,79 @@ void aliasingTableToResolveAmbiguityWorks() throws Exception {
881881
}
882882
}
883883

884+
@Test
885+
void testNotDistinctFrom() throws Exception {
886+
final String schema = "CREATE TYPE AS STRUCT contact_detail(phone_number string, address string) " +
887+
"CREATE TABLE student(id bigint, name string, contact contact_detail, score bigint, primary key(id))";
888+
try (var ddl = Ddl.builder().database(URI.create("/TEST/QT")).relationalExtension(relationalExtension).schemaTemplate(schema).build()) {
889+
try (var statement = ddl.setSchemaAndGetConnection().createStatement()) {
890+
final var row1 = EmbeddedRelationalStruct.newBuilder()
891+
.addLong("ID", 1L)
892+
.addString("NAME", "Alice")
893+
.addLong("SCORE", 100)
894+
.build();
895+
final var row2 = EmbeddedRelationalStruct.newBuilder()
896+
.addLong("ID", 2L)
897+
.addString("NAME", "Bob")
898+
.build();
899+
Assertions.assertEquals(1, statement.executeInsert("STUDENT", row1), "Incorrect insertion count");
900+
Assertions.assertEquals(1, statement.executeInsert("STUDENT", row2), "Incorrect insertion count");
901+
902+
Assertions.assertTrue(statement.execute("SELECT * from STUDENT f WHERE score is not distinct from null"), "Did not return a result set from a select statement!");
903+
try (final RelationalResultSet resultSet = statement.getResultSet()) {
904+
ResultSetAssert.assertThat(resultSet)
905+
.hasNextRow()
906+
.hasColumn("NAME", "Bob")
907+
.hasNoNextRow();
908+
}
909+
910+
Assertions.assertTrue(statement.execute("SELECT * from STUDENT f WHERE score is not distinct from 100"), "Did not return a result set from a select statement!");
911+
try (final RelationalResultSet resultSet = statement.getResultSet()) {
912+
ResultSetAssert.assertThat(resultSet)
913+
.hasNextRow()
914+
.hasColumn("NAME", "Alice")
915+
.hasNoNextRow();
916+
}
917+
918+
Assertions.assertTrue(statement.execute("SELECT * from STUDENT f WHERE null is not distinct from score"), "Did not return a result set from a select statement!");
919+
try (final RelationalResultSet resultSet = statement.getResultSet()) {
920+
ResultSetAssert.assertThat(resultSet)
921+
.hasNextRow()
922+
.hasColumn("NAME", "Bob")
923+
.hasNoNextRow();
924+
}
925+
926+
Assertions.assertTrue(statement.execute("SELECT * from STUDENT f WHERE 100 is not distinct from score"), "Did not return a result set from a select statement!");
927+
try (final RelationalResultSet resultSet = statement.getResultSet()) {
928+
ResultSetAssert.assertThat(resultSet)
929+
.hasNextRow()
930+
.hasColumn("NAME", "Alice")
931+
.hasNoNextRow();
932+
}
933+
934+
Assertions.assertTrue(statement.execute("SELECT * from STUDENT f WHERE 100 is not distinct from 100"), "Did not return a result set from a select statement!");
935+
try (final RelationalResultSet resultSet = statement.getResultSet()) {
936+
ResultSetAssert.assertThat(resultSet)
937+
.hasNextRow()
938+
.hasColumn("NAME", "Alice")
939+
.hasNextRow()
940+
.hasColumn("NAME", "Bob")
941+
.hasNoNextRow();
942+
}
943+
944+
Assertions.assertTrue(statement.execute("SELECT * from STUDENT f WHERE null is not distinct from null"), "Did not return a result set from a select statement!");
945+
try (final RelationalResultSet resultSet = statement.getResultSet()) {
946+
ResultSetAssert.assertThat(resultSet)
947+
.hasNextRow()
948+
.hasColumn("NAME", "Alice")
949+
.hasNextRow()
950+
.hasColumn("NAME", "Bob")
951+
.hasNoNextRow();
952+
}
953+
}
954+
}
955+
}
956+
884957
@Test
885958
void testBitmap() throws Exception {
886959
final String query = "SELECT BITMAP_CONSTRUCT_AGG(BITMAP_BIT_POSITION(uid)) as bitmap, category, BITMAP_BUCKET_OFFSET(uid) as offset FROM T1\n" +

0 commit comments

Comments
 (0)