This is an automated email from the ASF dual-hosted git repository.

duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 4d7cbafdca4 Support null condition value routing (#29680)
4d7cbafdca4 is described below

commit 4d7cbafdca4ca4feefd39bd33b2ebaf914e93a87
Author: ZhangCheng <[email protected]>
AuthorDate: Tue Jan 9 09:22:00 2024 +0800

    Support null condition value routing (#29680)
---
 .../engine/condition/generator/ConditionValue.java    |  3 ++-
 .../impl/ConditionValueCompareOperatorGenerator.java  | 11 +++++++----
 .../condition/generator/ConditionValueTest.java       | 19 +++++++++++++++++++
 .../ConditionValueCompareOperatorGeneratorTest.java   | 17 +++++++++++++++++
 4 files changed, 45 insertions(+), 5 deletions(-)

diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/ConditionValue.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/ConditionValue.java
index 439c9caccd3..b211602e4e2 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/ConditionValue.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/ConditionValue.java
@@ -58,7 +58,8 @@ public final class ConditionValue {
         int parameterMarkerIndex = expressionSegment.getParameterMarkerIndex();
         if (parameterMarkerIndex < params.size()) {
             Object result = params.get(parameterMarkerIndex);
-            ShardingSpherePreconditions.checkState(result instanceof 
Comparable, () -> new NotImplementComparableValueException("Sharding", result));
+            isNull = null == result;
+            ShardingSpherePreconditions.checkState(null == result || result 
instanceof Comparable, () -> new 
NotImplementComparableValueException("Sharding", result));
             return (Comparable<?>) result;
         }
         return null;
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/impl/ConditionValueCompareOperatorGenerator.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/impl/ConditionValueCompareOperatorGenerator.java
index a30566e077d..0a0bdc01730 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/impl/ConditionValueCompareOperatorGenerator.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/impl/ConditionValueCompareOperatorGenerator.java
@@ -66,6 +66,9 @@ public final class ConditionValueCompareOperatorGenerator 
implements ConditionVa
         ExpressionSegment valueExpression = predicate.getLeft() instanceof 
ColumnSegment ? predicate.getRight() : predicate.getLeft();
         ConditionValue conditionValue = new ConditionValue(valueExpression, 
params);
         Optional<Comparable<?>> value = conditionValue.getValue();
+        if (conditionValue.isNull()) {
+            return generate(null, column, operator, 
conditionValue.getParameterMarkerIndex().orElse(-1));
+        }
         if (value.isPresent()) {
             return generate(value.get(), column, operator, 
conditionValue.getParameterMarkerIndex().orElse(-1));
         }
@@ -83,13 +86,13 @@ public final class ConditionValueCompareOperatorGenerator 
implements ConditionVa
             case EQUAL:
                 return Optional.of(new 
ListShardingConditionValue<>(columnName, tableName, new 
ArrayList<>(Collections.singleton(comparable)), parameterMarkerIndexes));
             case GREATER_THAN:
-                return Optional.of(new 
RangeShardingConditionValue<>(columnName, tableName, 
Range.greaterThan(comparable), parameterMarkerIndexes));
+                return null == comparable ? Optional.empty() : Optional.of(new 
RangeShardingConditionValue<>(columnName, tableName, 
Range.greaterThan(comparable), parameterMarkerIndexes));
             case LESS_THAN:
-                return Optional.of(new 
RangeShardingConditionValue<>(columnName, tableName, 
Range.lessThan(comparable), parameterMarkerIndexes));
+                return null == comparable ? Optional.empty() : Optional.of(new 
RangeShardingConditionValue<>(columnName, tableName, 
Range.lessThan(comparable), parameterMarkerIndexes));
             case AT_MOST:
-                return Optional.of(new 
RangeShardingConditionValue<>(columnName, tableName, Range.atMost(comparable), 
parameterMarkerIndexes));
+                return null == comparable ? Optional.empty() : Optional.of(new 
RangeShardingConditionValue<>(columnName, tableName, Range.atMost(comparable), 
parameterMarkerIndexes));
             case AT_LEAST:
-                return Optional.of(new 
RangeShardingConditionValue<>(columnName, tableName, Range.atLeast(comparable), 
parameterMarkerIndexes));
+                return null == comparable ? Optional.empty() : Optional.of(new 
RangeShardingConditionValue<>(columnName, tableName, Range.atLeast(comparable), 
parameterMarkerIndexes));
             case IS:
                 return "null".equalsIgnoreCase(String.valueOf(comparable))
                         ? Optional.of(new 
ListShardingConditionValue<>(columnName, tableName, new 
ArrayList<>(Collections.singleton(null)), parameterMarkerIndexes))
diff --git 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/ConditionValueTest.java
 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/ConditionValueTest.java
index ceca5e9e29a..0b6dcb0922f 100644
--- 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/ConditionValueTest.java
+++ 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/ConditionValueTest.java
@@ -41,6 +41,15 @@ class ConditionValueTest {
         assertFalse(conditionValue.getParameterMarkerIndex().isPresent());
     }
     
+    @Test
+    void assertGetValueFromLiteralExpressionSegmentOfNullValue() {
+        ExpressionSegment expressionSegment = new LiteralExpressionSegment(0, 
0, null);
+        ConditionValue conditionValue = new ConditionValue(expressionSegment, 
new LinkedList<>());
+        assertFalse(conditionValue.getValue().isPresent());
+        assertTrue(conditionValue.isNull());
+        assertFalse(conditionValue.getParameterMarkerIndex().isPresent());
+    }
+    
     @Test
     void assertGetValueFromParameterMarkerSegment() {
         ExpressionSegment expressionSegment = new 
ParameterMarkerExpressionSegment(0, 0, 0);
@@ -50,4 +59,14 @@ class ConditionValueTest {
         assertTrue(conditionValue.getParameterMarkerIndex().isPresent());
         assertThat(conditionValue.getParameterMarkerIndex().get(), is(0));
     }
+    
+    @Test
+    void assertGetValueFromParameterMarkerSegmentOfNullValue() {
+        ExpressionSegment expressionSegment = new 
ParameterMarkerExpressionSegment(0, 0, 0);
+        ConditionValue conditionValue = new ConditionValue(expressionSegment, 
Collections.singletonList(null));
+        assertFalse(conditionValue.getValue().isPresent());
+        assertTrue(conditionValue.isNull());
+        assertTrue(conditionValue.getParameterMarkerIndex().isPresent());
+        assertThat(conditionValue.getParameterMarkerIndex().get(), is(0));
+    }
 }
diff --git 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/impl/ConditionValueCompareOperatorGeneratorTest.java
 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/impl/ConditionValueCompareOperatorGeneratorTest.java
index 14b1574c138..fd225af6a22 100644
--- 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/impl/ConditionValueCompareOperatorGeneratorTest.java
+++ 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/generator/impl/ConditionValueCompareOperatorGeneratorTest.java
@@ -59,6 +59,16 @@ class ConditionValueCompareOperatorGeneratorTest {
         
assertTrue(shardingConditionValue.get().getParameterMarkerIndexes().isEmpty());
     }
     
+    @SuppressWarnings("unchecked")
+    @Test
+    void assertGenerateNullConditionValue() {
+        BinaryOperationExpression rightValue = new 
BinaryOperationExpression(0, 0, mock(ColumnSegment.class), new 
LiteralExpressionSegment(0, 0, null), "=", null);
+        Optional<ShardingConditionValue> shardingConditionValue = 
generator.generate(rightValue, column, new LinkedList<>(), 
mock(TimestampServiceRule.class));
+        assertTrue(shardingConditionValue.isPresent());
+        assertTrue(((ListShardingConditionValue<Integer>) 
shardingConditionValue.get()).getValues().contains(null));
+        
assertTrue(shardingConditionValue.get().getParameterMarkerIndexes().isEmpty());
+    }
+    
     @SuppressWarnings("unchecked")
     @Test
     void assertGenerateConditionValueWithLessThanOperator() {
@@ -69,6 +79,13 @@ class ConditionValueCompareOperatorGeneratorTest {
         
assertTrue(shardingConditionValue.get().getParameterMarkerIndexes().isEmpty());
     }
     
+    @Test
+    void assertGenerateNullConditionValueWithLessThanOperator() {
+        BinaryOperationExpression rightValue = new 
BinaryOperationExpression(0, 0, mock(ColumnSegment.class), new 
LiteralExpressionSegment(0, 0, null), "<", null);
+        Optional<ShardingConditionValue> shardingConditionValue = 
generator.generate(rightValue, column, new LinkedList<>(), 
mock(TimestampServiceRule.class));
+        assertFalse(shardingConditionValue.isPresent());
+    }
+    
     @SuppressWarnings("unchecked")
     @Test
     void assertGenerateConditionValueWithGreaterThanOperator() {

Reply via email to