|
76 | 76 | import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT; |
77 | 77 | import static org.elasticsearch.xpack.esql.core.type.DataType.TSID_DATA_TYPE; |
78 | 78 | import static org.elasticsearch.xpack.esql.core.type.DataType.UNDER_CONSTRUCTION; |
| 79 | +import static org.hamcrest.Matchers.anyOf; |
79 | 80 | import static org.hamcrest.Matchers.containsString; |
80 | 81 | import static org.hamcrest.Matchers.equalTo; |
81 | 82 | import static org.hamcrest.Matchers.is; |
@@ -226,7 +227,7 @@ public LookupJoinTypesIT(BinaryComparisonOperation operation) { |
226 | 227 |
|
227 | 228 | // Tests for all unsupported types |
228 | 229 | DataType[] unsupported = Join.UNSUPPORTED_TYPES; |
229 | | - boolean isNonEqualityComparison = operation == BinaryComparisonOperation.GT |
| 230 | + boolean isLessOrGreater = operation == BinaryComparisonOperation.GT |
230 | 231 | || operation == BinaryComparisonOperation.GTE |
231 | 232 | || operation == BinaryComparisonOperation.LT |
232 | 233 | || operation == BinaryComparisonOperation.LTE; |
@@ -256,7 +257,7 @@ public LookupJoinTypesIT(BinaryComparisonOperation operation) { |
256 | 257 | continue; |
257 | 258 | } |
258 | 259 | if (operation != null && type == DENSE_VECTOR |
259 | | - || isNonEqualityComparison |
| 260 | + || isLessOrGreater |
260 | 261 | && (type == GEO_POINT || type == GEO_SHAPE || type == CARTESIAN_POINT || type == CARTESIAN_SHAPE)) { |
261 | 262 | configs.addUnsupportedComparisonFails(type, type, operation); |
262 | 263 | } else { |
@@ -290,7 +291,7 @@ public LookupJoinTypesIT(BinaryComparisonOperation operation) { |
290 | 291 | assertThat("Claiming supported for unsupported type: " + type, List.of(unsupported).contains(type), is(false)); |
291 | 292 | if (existingIndex(existing, type, type, operation) == false) { |
292 | 293 | // Only add the configuration if it doesn't already exist |
293 | | - if (type == BOOLEAN && isNonEqualityComparison) { |
| 294 | + if (type == BOOLEAN && isLessOrGreater) { |
294 | 295 | // Boolean does not support inequality operations |
295 | 296 | configs.addUnsupportedComparisonFails(type, type, operation); |
296 | 297 | } else { |
@@ -327,8 +328,14 @@ public LookupJoinTypesIT(BinaryComparisonOperation operation) { |
327 | 328 | for (DataType mainType : supported) { |
328 | 329 | for (DataType lookupType : supported) { |
329 | 330 | if (existingIndex(existing, mainType, lookupType, operation) == false) { |
330 | | - // Only add the configuration if it doesn't already exist |
331 | | - configs.addFails(mainType, lookupType); |
| 331 | + if (operation == null) { |
| 332 | + // Only add the configuration if it doesn't already exist |
| 333 | + configs.addFails(mainType, lookupType); |
| 334 | + } else if (isLessOrGreater) { |
| 335 | + configs.addIncompatibleDifferentTypesLessGreater(mainType, lookupType, operation); |
| 336 | + } else { |
| 337 | + configs.addMismatchedComparisonFailsEqualNotEqual(mainType, lookupType, operation); |
| 338 | + } |
332 | 339 | } |
333 | 340 | } |
334 | 341 | } |
@@ -662,6 +669,46 @@ private void addFails(DataType mainType, DataType lookupType) { |
662 | 669 | ); |
663 | 670 | } |
664 | 671 |
|
| 672 | + private void addMismatchedComparisonFailsEqualNotEqual( |
| 673 | + DataType mainType, |
| 674 | + DataType lookupType, |
| 675 | + BinaryComparisonOperation operation |
| 676 | + ) { |
| 677 | + String fieldNameLeft = LOOKUP_INDEX_PREFIX + lookupType.esType() + suffixLeftFieldName(operation); |
| 678 | + String fieldNameRight = LOOKUP_INDEX_PREFIX + lookupType.esType(); |
| 679 | + final Consumer<VerificationException> assertion = e -> { |
| 680 | + String errorMessage1 = String.format( |
| 681 | + Locale.ROOT, |
| 682 | + "first argument of [%s %s %s] is [", |
| 683 | + fieldNameLeft, |
| 684 | + operation.symbol(), |
| 685 | + fieldNameRight |
| 686 | + ); |
| 687 | + String errorMessage3 = String.format(Locale.ROOT, " but was [%s]", lookupType.widenSmallNumeric().typeName()); |
| 688 | + assertThat(e.getMessage(), containsString(errorMessage1)); |
| 689 | + assertThat(e.getMessage(), containsString("] so second argument must also be [")); |
| 690 | + assertThat(e.getMessage(), containsString(errorMessage3)); |
| 691 | + }; |
| 692 | + |
| 693 | + add(new TestConfigFails<>(mainType, lookupType, VerificationException.class, assertion, operation)); |
| 694 | + } |
| 695 | + |
| 696 | + private void addIncompatibleDifferentTypesLessGreater(DataType mainType, DataType lookupType, BinaryComparisonOperation operation) { |
| 697 | + String fieldNameLeft = LOOKUP_INDEX_PREFIX + lookupType.esType() + suffixLeftFieldName(operation); |
| 698 | + String fieldNameRight = LOOKUP_INDEX_PREFIX + lookupType.esType(); |
| 699 | + |
| 700 | + String errorMessage1 = String.format(Locale.ROOT, "argument of [%s %s %s]", fieldNameLeft, operation.symbol(), fieldNameRight); |
| 701 | + |
| 702 | + add(new TestConfigFails<>(mainType, lookupType, VerificationException.class, e -> { |
| 703 | + assertThat(e.getMessage().toLowerCase(Locale.ROOT), containsString(errorMessage1)); |
| 704 | + assertThat( |
| 705 | + e.getMessage().toLowerCase(Locale.ROOT), |
| 706 | + anyOf(List.of(containsString(mainType.widenSmallNumeric().typeName()), containsString("numeric"))) |
| 707 | + ); |
| 708 | + assertThat(e.getMessage().toLowerCase(Locale.ROOT), containsString(lookupType.typeName())); |
| 709 | + }, operation)); |
| 710 | + } |
| 711 | + |
665 | 712 | private void addUnsupportedComparisonFails(DataType mainType, DataType lookupType, BinaryComparisonOperation operation) { |
666 | 713 | String fieldNameLeft = LOOKUP_INDEX_PREFIX + lookupType.esType() + suffixLeftFieldName(operation); |
667 | 714 | String fieldNameRight = LOOKUP_INDEX_PREFIX + lookupType.esType(); |
|
0 commit comments