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

zhonghongsheng 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 f42425ab11c Support null sharding condition pass to sharding algorithm 
to allow user control null value route (#25214)
f42425ab11c is described below

commit f42425ab11ce3b71736cb9b3e91486c133991f7e
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Tue Apr 18 20:14:09 2023 +0800

    Support null sharding condition pass to sharding algorithm to allow user 
control null value route (#25214)
    
    * Support null sharding condition pass to sharding algorithm to allow user 
control null value route
    
    * Move null sharding value check logic to sharding algorithm
    
    * fix unit test
---
 .../user-manual/error-code/sql-error-code.cn.md    |  2 +-
 .../user-manual/error-code/sql-error-code.en.md    |  2 +-
 .../complex/ComplexInlineShardingAlgorithm.java    |  2 +
 .../datetime/AutoIntervalShardingAlgorithm.java    |  2 +
 .../datetime/IntervalShardingAlgorithm.java        |  2 +
 .../sharding/hint/HintInlineShardingAlgorithm.java |  2 +
 .../sharding/inline/InlineShardingAlgorithm.java   |  5 ++-
 .../sharding/mod/HashModShardingAlgorithm.java     |  2 +
 .../sharding/mod/ModShardingAlgorithm.java         |  2 +
 .../range/AbstractRangeShardingAlgorithm.java      |  3 ++
 .../exception/data/NullShardingValueException.java |  2 +-
 .../engine/condition/ExpressionConditionUtils.java | 10 -----
 .../InsertClauseShardingConditionEngine.java       | 32 ++++++++++++---
 .../InsertClauseShardingConditionEngineTest.java   | 45 +++++++++++++++++-----
 .../ral/queryable/ExportMetaDataExecutorTest.java  |  2 +-
 15 files changed, 85 insertions(+), 30 deletions(-)

diff --git a/docs/document/content/user-manual/error-code/sql-error-code.cn.md 
b/docs/document/content/user-manual/error-code/sql-error-code.cn.md
index 0d9623d6214..9e13db3df32 100644
--- a/docs/document/content/user-manual/error-code/sql-error-code.cn.md
+++ b/docs/document/content/user-manual/error-code/sql-error-code.cn.md
@@ -180,7 +180,7 @@ SQL 错误码以标准的 SQL State,Vendor Code 和详细错误信息提供,
 | 44000     | 20012       | Invalid binding table configuration in 
ShardingRuleConfiguration.                                                      
          |
 | 44000     | 20013       | Can not find sharding rule.                        
                                                                              |
 | 44000     | 20014       | Only allowed 0 or 1 sharding strategy 
configuration.                                                                  
           |
-| 44000     | 20020       | Sharding value can't be null in insert statement.  
                                                                              |
+| 44000     | 20020       | Sharding value can't be null in sql statement.     
                                                                              |
 | HY004     | 20021       | Found different types for sharding value \`%s\`.   
                                                                              |
 | HY004     | 20022       | Invalid %s, datetime pattern should be \`%s\`, 
value is \`%s\`.                                                                
  |
 | 44000     | 20023       | Sharding value %s subtract stop offset %d can not 
be less than start offset %d.                                                  |
diff --git a/docs/document/content/user-manual/error-code/sql-error-code.en.md 
b/docs/document/content/user-manual/error-code/sql-error-code.en.md
index 62c465f7b56..adf42c849a6 100644
--- a/docs/document/content/user-manual/error-code/sql-error-code.en.md
+++ b/docs/document/content/user-manual/error-code/sql-error-code.en.md
@@ -180,7 +180,7 @@ SQL error codes provide by standard `SQL State`, `Vendor 
Code` and `Reason`, whi
 | 44000     | 20012       | Invalid binding table configuration in 
ShardingRuleConfiguration.                                                      
          |
 | 44000     | 20013       | Can not find sharding rule.                        
                                                                              |
 | 44000     | 20014       | Only allowed 0 or 1 sharding strategy 
configuration.                                                                  
           |
-| 44000     | 20020       | Sharding value can't be null in insert statement.  
                                                                              |
+| 44000     | 20020       | Sharding value can't be null in sql statement.     
                                                                              |
 | HY004     | 20021       | Found different types for sharding value \`%s\`.   
                                                                              |
 | HY004     | 20022       | Invalid %s, datetime pattern should be \`%s\`, 
value is \`%s\`.                                                                
  |
 | 44000     | 20023       | Sharding value %s subtract stop offset %d can not 
be less than start offset %d.                                                  |
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/complex/ComplexInlineShardingAlgorithm.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/complex/ComplexInlineShardingAlgorithm.java
index d1344dc752c..31daec4a48c 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/complex/ComplexInlineShardingAlgorithm.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/complex/ComplexInlineShardingAlgorithm.java
@@ -26,6 +26,7 @@ import 
org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardi
 import 
org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingValue;
 import 
org.apache.shardingsphere.sharding.exception.algorithm.sharding.MismatchedComplexInlineShardingAlgorithmColumnAndValueSizeException;
 import 
org.apache.shardingsphere.sharding.exception.algorithm.sharding.ShardingAlgorithmInitializationException;
+import 
org.apache.shardingsphere.sharding.exception.data.NullShardingValueException;
 
 import java.util.Arrays;
 import java.util.Collection;
@@ -93,6 +94,7 @@ public final class ComplexInlineShardingAlgorithm implements 
ComplexKeysSharding
     private String doSharding(final Map<String, Comparable<?>> shardingValues) 
{
         Closure<?> closure = createClosure();
         for (Entry<String, Comparable<?>> entry : shardingValues.entrySet()) {
+            ShardingSpherePreconditions.checkNotNull(entry.getValue(), 
NullShardingValueException::new);
             closure.setProperty(entry.getKey(), entry.getValue());
         }
         return closure.call().toString();
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/datetime/AutoIntervalShardingAlgorithm.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/datetime/AutoIntervalShardingAlgorithm.java
index ceacd299584..cf0d5307325 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/datetime/AutoIntervalShardingAlgorithm.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/datetime/AutoIntervalShardingAlgorithm.java
@@ -27,6 +27,7 @@ import 
org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingVal
 import 
org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
 import 
org.apache.shardingsphere.sharding.exception.algorithm.sharding.ShardingAlgorithmInitializationException;
 import 
org.apache.shardingsphere.sharding.exception.data.InvalidDatetimeFormatException;
+import 
org.apache.shardingsphere.sharding.exception.data.NullShardingValueException;
 
 import java.text.DecimalFormat;
 import java.text.ParsePosition;
@@ -83,6 +84,7 @@ public final class AutoIntervalShardingAlgorithm implements 
StandardShardingAlgo
     
     @Override
     public String doSharding(final Collection<String> availableTargetNames, 
final PreciseShardingValue<Comparable<?>> shardingValue) {
+        ShardingSpherePreconditions.checkNotNull(shardingValue.getValue(), 
NullShardingValueException::new);
         String tableNameSuffix = 
String.valueOf(doSharding(parseDate(shardingValue.getValue())));
         return 
ShardingAutoTableAlgorithmUtils.findMatchedTargetName(availableTargetNames, 
tableNameSuffix, shardingValue.getDataNodeInfo()).orElse(null);
     }
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/datetime/IntervalShardingAlgorithm.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/datetime/IntervalShardingAlgorithm.java
index 3437744917b..c1196e4fcdc 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/datetime/IntervalShardingAlgorithm.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/datetime/IntervalShardingAlgorithm.java
@@ -26,6 +26,7 @@ import 
org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingVal
 import 
org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
 import 
org.apache.shardingsphere.sharding.exception.algorithm.sharding.ShardingAlgorithmInitializationException;
 import 
org.apache.shardingsphere.sharding.exception.data.InvalidDatetimeFormatException;
+import 
org.apache.shardingsphere.sharding.exception.data.NullShardingValueException;
 
 import java.time.Instant;
 import java.time.LocalDate;
@@ -132,6 +133,7 @@ public final class IntervalShardingAlgorithm implements 
StandardShardingAlgorith
     
     @Override
     public String doSharding(final Collection<String> availableTargetNames, 
final PreciseShardingValue<Comparable<?>> shardingValue) {
+        ShardingSpherePreconditions.checkNotNull(shardingValue.getValue(), 
NullShardingValueException::new);
         return doSharding(availableTargetNames, 
Range.singleton(shardingValue.getValue())).stream().findFirst().orElse(null);
     }
     
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/hint/HintInlineShardingAlgorithm.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/hint/HintInlineShardingAlgorithm.java
index 1d25a4f56b5..0943cd340b6 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/hint/HintInlineShardingAlgorithm.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/hint/HintInlineShardingAlgorithm.java
@@ -24,6 +24,7 @@ import 
org.apache.shardingsphere.infra.util.expr.InlineExpressionParser;
 import 
org.apache.shardingsphere.sharding.api.sharding.hint.HintShardingAlgorithm;
 import org.apache.shardingsphere.sharding.api.sharding.hint.HintShardingValue;
 import 
org.apache.shardingsphere.sharding.exception.algorithm.sharding.ShardingAlgorithmInitializationException;
+import 
org.apache.shardingsphere.sharding.exception.data.NullShardingValueException;
 
 import java.util.Collection;
 import java.util.Properties;
@@ -59,6 +60,7 @@ public final class HintInlineShardingAlgorithm implements 
HintShardingAlgorithm<
     }
     
     private String doSharding(final Comparable<?> shardingValue) {
+        ShardingSpherePreconditions.checkNotNull(shardingValue, 
NullShardingValueException::new);
         Closure<?> closure = createClosure();
         closure.setProperty(HINT_INLINE_VALUE_PROPERTY_NAME, shardingValue);
         return closure.call().toString();
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/inline/InlineShardingAlgorithm.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/inline/InlineShardingAlgorithm.java
index 3e7516ed341..58e96d64554 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/inline/InlineShardingAlgorithm.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/inline/InlineShardingAlgorithm.java
@@ -28,6 +28,7 @@ import 
org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingVal
 import 
org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
 import 
org.apache.shardingsphere.sharding.exception.algorithm.sharding.MismatchedInlineShardingAlgorithmExpressionAndColumnException;
 import 
org.apache.shardingsphere.sharding.exception.algorithm.sharding.ShardingAlgorithmInitializationException;
+import 
org.apache.shardingsphere.sharding.exception.data.NullShardingValueException;
 
 import java.util.Collection;
 import java.util.Optional;
@@ -65,9 +66,9 @@ public final class InlineShardingAlgorithm implements 
StandardShardingAlgorithm<
     
     @Override
     public String doSharding(final Collection<String> availableTargetNames, 
final PreciseShardingValue<Comparable<?>> shardingValue) {
+        ShardingSpherePreconditions.checkNotNull(shardingValue.getValue(), 
NullShardingValueException::new);
         Closure<?> closure = createClosure();
-        Comparable<?> value = shardingValue.getValue();
-        closure.setProperty(shardingValue.getColumnName(), value);
+        closure.setProperty(shardingValue.getColumnName(), 
shardingValue.getValue());
         return getTargetShardingNode(closure, shardingValue.getColumnName());
     }
     
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/mod/HashModShardingAlgorithm.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/mod/HashModShardingAlgorithm.java
index deaa7aca410..71c251f4c47 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/mod/HashModShardingAlgorithm.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/mod/HashModShardingAlgorithm.java
@@ -24,6 +24,7 @@ import 
org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingV
 import 
org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
 import 
org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
 import 
org.apache.shardingsphere.sharding.exception.algorithm.sharding.ShardingAlgorithmInitializationException;
+import 
org.apache.shardingsphere.sharding.exception.data.NullShardingValueException;
 
 import java.util.Collection;
 import java.util.Properties;
@@ -51,6 +52,7 @@ public final class HashModShardingAlgorithm implements 
StandardShardingAlgorithm
     
     @Override
     public String doSharding(final Collection<String> availableTargetNames, 
final PreciseShardingValue<Comparable<?>> shardingValue) {
+        ShardingSpherePreconditions.checkNotNull(shardingValue.getValue(), 
NullShardingValueException::new);
         String suffix = 
String.valueOf(hashShardingValue(shardingValue.getValue()) % shardingCount);
         return 
ShardingAutoTableAlgorithmUtils.findMatchedTargetName(availableTargetNames, 
suffix, shardingValue.getDataNodeInfo()).orElse(null);
     }
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/mod/ModShardingAlgorithm.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/mod/ModShardingAlgorithm.java
index a35dd9dbdaf..c04a9bbe51d 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/mod/ModShardingAlgorithm.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/mod/ModShardingAlgorithm.java
@@ -24,6 +24,7 @@ import 
org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingV
 import 
org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
 import 
org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
 import 
org.apache.shardingsphere.sharding.exception.algorithm.sharding.ShardingAlgorithmInitializationException;
+import 
org.apache.shardingsphere.sharding.exception.data.NullShardingValueException;
 import 
org.apache.shardingsphere.sharding.exception.data.ShardingValueOffsetException;
 
 import java.math.BigInteger;
@@ -98,6 +99,7 @@ public final class ModShardingAlgorithm implements 
StandardShardingAlgorithm<Com
     
     @Override
     public String doSharding(final Collection<String> availableTargetNames, 
final PreciseShardingValue<Comparable<?>> shardingValue) {
+        ShardingSpherePreconditions.checkNotNull(shardingValue.getValue(), 
NullShardingValueException::new);
         String shardingResultSuffix = 
getShardingResultSuffix(cutShardingValue(shardingValue.getValue()).mod(new 
BigInteger(String.valueOf(shardingCount))).toString());
         return 
ShardingAutoTableAlgorithmUtils.findMatchedTargetName(availableTargetNames, 
shardingResultSuffix, shardingValue.getDataNodeInfo()).orElse(null);
     }
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/AbstractRangeShardingAlgorithm.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/AbstractRangeShardingAlgorithm.java
index 55f96717234..b70d01ff31f 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/AbstractRangeShardingAlgorithm.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/AbstractRangeShardingAlgorithm.java
@@ -18,12 +18,14 @@
 package org.apache.shardingsphere.sharding.algorithm.sharding.range;
 
 import com.google.common.collect.Range;
+import 
org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
 import 
org.apache.shardingsphere.infra.util.exception.external.sql.type.generic.UnsupportedSQLOperationException;
 import 
org.apache.shardingsphere.sharding.algorithm.sharding.ShardingAutoTableAlgorithmUtils;
 import 
org.apache.shardingsphere.sharding.api.sharding.ShardingAutoTableAlgorithm;
 import 
org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
 import 
org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
 import 
org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
+import 
org.apache.shardingsphere.sharding.exception.data.NullShardingValueException;
 
 import java.util.Collection;
 import java.util.LinkedHashSet;
@@ -47,6 +49,7 @@ public abstract class AbstractRangeShardingAlgorithm 
implements StandardSharding
     
     @Override
     public final String doSharding(final Collection<String> 
availableTargetNames, final PreciseShardingValue<Comparable<?>> shardingValue) {
+        ShardingSpherePreconditions.checkNotNull(shardingValue.getValue(), 
NullShardingValueException::new);
         String suffix = String.valueOf(getPartition(shardingValue.getValue()));
         return 
ShardingAutoTableAlgorithmUtils.findMatchedTargetName(availableTargetNames, 
suffix, shardingValue.getDataNodeInfo()).orElse(null);
     }
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/exception/data/NullShardingValueException.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/exception/data/NullShardingValueException.java
index 6297572eb7f..cdc83c2cfed 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/exception/data/NullShardingValueException.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/exception/data/NullShardingValueException.java
@@ -28,6 +28,6 @@ public final class NullShardingValueException extends 
ShardingSQLException {
     private static final long serialVersionUID = -6223086772479822057L;
     
     public NullShardingValueException() {
-        super(XOpenSQLState.CHECK_OPTION_VIOLATION, 20, "Sharding value can't 
be null in insert statement.");
+        super(XOpenSQLState.CHECK_OPTION_VIOLATION, 20, "Sharding value can't 
be null in sql statement.");
     }
 }
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/ExpressionConditionUtils.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/ExpressionConditionUtils.java
index d349a0381ad..781cad0526b 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/ExpressionConditionUtils.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/ExpressionConditionUtils.java
@@ -20,7 +20,6 @@ package 
org.apache.shardingsphere.sharding.route.engine.condition;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
-import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.CommonExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.ComplexExpressionSegment;
 
 /**
@@ -37,13 +36,4 @@ public final class ExpressionConditionUtils {
     public static boolean isNowExpression(final ExpressionSegment segment) {
         return segment instanceof ComplexExpressionSegment && 
"now()".equalsIgnoreCase(((ComplexExpressionSegment) segment).getText());
     }
-    
-    /**
-     * Judge null expression.
-     * @param segment ExpressionSegment
-     * @return true or false
-     */
-    public static boolean isNullExpression(final ExpressionSegment segment) {
-        return segment instanceof CommonExpressionSegment && 
"null".equalsIgnoreCase(((CommonExpressionSegment) segment).getText());
-    }
 }
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngine.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngine.java
index ff40f233113..fb552cc2a18 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngine.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngine.java
@@ -23,8 +23,9 @@ import 
org.apache.shardingsphere.infra.binder.segment.insert.keygen.GeneratedKey
 import 
org.apache.shardingsphere.infra.binder.segment.insert.values.InsertValueContext;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
+import org.apache.shardingsphere.infra.database.type.DatabaseTypeEngine;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
-import 
org.apache.shardingsphere.sharding.exception.data.NullShardingValueException;
+import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
 import 
org.apache.shardingsphere.sharding.route.engine.condition.ExpressionConditionUtils;
 import 
org.apache.shardingsphere.sharding.route.engine.condition.ShardingCondition;
 import 
org.apache.shardingsphere.sharding.route.engine.condition.value.ListShardingConditionValue;
@@ -40,6 +41,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
@@ -82,17 +84,39 @@ public final class InsertClauseShardingConditionEngine {
         for (InsertValueContext each : insertValueContexts) {
             result.add(createShardingCondition(tableName, 
columnNames.iterator(), each, params, ++rowNumber));
         }
+        appendMissingShardingConditions(sqlStatementContext, columnNames, 
result);
         return result;
     }
     
+    private void appendMissingShardingConditions(final InsertStatementContext 
sqlStatementContext, final Collection<String> columnNames, final 
List<ShardingCondition> shardingConditions) {
+        String defaultSchemaName = 
DatabaseTypeEngine.getDefaultSchemaName(sqlStatementContext.getDatabaseType(), 
database.getName());
+        ShardingSphereSchema schema = 
sqlStatementContext.getTablesContext().getSchemaName().map(database::getSchema).orElseGet(()
 -> database.getSchema(defaultSchemaName));
+        String tableName = 
sqlStatementContext.getSqlStatement().getTable().getTableName().getIdentifier().getValue();
+        Collection<String> allColumnNames = 
schema.getTable(tableName).getColumnNames();
+        if (columnNames.size() == allColumnNames.size()) {
+            return;
+        }
+        for (String each : allColumnNames) {
+            if (!columnNames.contains(each) && 
!shardingRule.isGenerateKeyColumn(each, tableName) && 
shardingRule.findShardingColumn(each, tableName).isPresent()) {
+                appendMissingShardingConditions(shardingConditions, each, 
tableName);
+            }
+        }
+    }
+    
+    private static void appendMissingShardingConditions(final 
List<ShardingCondition> shardingConditions, final String columnName, final 
String tableName) {
+        for (ShardingCondition each : shardingConditions) {
+            each.getValues().add(new ListShardingConditionValue<>(columnName, 
tableName, Collections.singletonList(null)));
+        }
+    }
+    
     private Collection<String> getColumnNames(final InsertStatementContext 
insertStatementContext) {
         Optional<GeneratedKeyContext> generatedKey = 
insertStatementContext.getGeneratedKeyContext();
         if (generatedKey.isPresent() && generatedKey.get().isGenerated()) {
-            Collection<String> result = new 
LinkedList<>(insertStatementContext.getColumnNames());
+            Collection<String> result = new 
LinkedHashSet<>(insertStatementContext.getColumnNames());
             result.remove(generatedKey.get().getColumnName());
             return result;
         }
-        return insertStatementContext.getColumnNames();
+        return new LinkedHashSet<>(insertStatementContext.getColumnNames());
     }
     
     private ShardingCondition createShardingCondition(final String tableName, 
final Iterator<String> columnNames,
@@ -116,8 +140,6 @@ public final class InsertClauseShardingConditionEngine {
                 generateShardingCondition((CommonExpressionSegment) each, 
result, shardingColumn.get(), tableName);
             } else if (ExpressionConditionUtils.isNowExpression(each)) {
                 result.getValues().add(new 
ListShardingConditionValue<>(shardingColumn.get(), tableName, 
Collections.singletonList(timeServiceRule.getDatetime())));
-            } else if (ExpressionConditionUtils.isNullExpression(each)) {
-                throw new NullShardingValueException();
             }
         }
         return result;
diff --git 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngineTest.java
 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngineTest.java
index 0d80fa61091..a4dd1b0049f 100644
--- 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngineTest.java
+++ 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngineTest.java
@@ -22,7 +22,10 @@ import 
org.apache.shardingsphere.infra.binder.segment.insert.keygen.GeneratedKey
 import 
org.apache.shardingsphere.infra.binder.segment.insert.values.InsertSelectContext;
 import 
org.apache.shardingsphere.infra.binder.segment.insert.values.InsertValueContext;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext;
+import org.apache.shardingsphere.infra.database.DefaultDatabase;
+import org.apache.shardingsphere.infra.database.type.dialect.MySQLDatabaseType;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
 import 
org.apache.shardingsphere.sharding.route.engine.condition.ShardingCondition;
 import org.apache.shardingsphere.sharding.rule.ShardingRule;
 import org.apache.shardingsphere.sharding.rule.TableRule;
@@ -38,6 +41,7 @@ import 
org.apache.shardingsphere.timeservice.core.rule.TimeServiceRule;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.mockito.junit.jupiter.MockitoSettings;
@@ -56,6 +60,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -68,17 +73,29 @@ class InsertClauseShardingConditionEngineTest {
     @Mock
     private ShardingRule shardingRule;
     
-    @Mock
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private InsertStatementContext insertStatementContext;
     
     @BeforeEach
     void setUp() {
-        ShardingSphereDatabase database = mock(ShardingSphereDatabase.class);
+        ShardingSphereDatabase database = mockDatabase();
         InsertStatement insertStatement = mockInsertStatement();
         shardingConditionEngine = new 
InsertClauseShardingConditionEngine(database, shardingRule, new 
TimeServiceRule(new TimeServiceRuleConfiguration("System", new Properties())));
         
when(insertStatementContext.getSqlStatement()).thenReturn(insertStatement);
-        
when(insertStatementContext.getColumnNames()).thenReturn(Collections.singletonList("foo_col"));
+        
when(insertStatementContext.getColumnNames()).thenReturn(Collections.singletonList("foo_col_1"));
         
when(insertStatementContext.getInsertValueContexts()).thenReturn(Collections.singletonList(createInsertValueContext()));
+        when(insertStatementContext.getInsertSelectContext()).thenReturn(null);
+        when(insertStatementContext.getDatabaseType()).thenReturn(new 
MySQLDatabaseType());
+        
when(insertStatementContext.getTablesContext().getSchemaName()).thenReturn(Optional.empty());
+    }
+    
+    private static ShardingSphereDatabase mockDatabase() {
+        ShardingSphereDatabase result = mock(ShardingSphereDatabase.class);
+        when(result.getName()).thenReturn(DefaultDatabase.LOGIC_NAME);
+        ShardingSphereSchema schema = mock(ShardingSphereSchema.class, 
RETURNS_DEEP_STUBS);
+        
when(schema.getTable("foo_table").getColumnNames()).thenReturn(Arrays.asList("foo_col_1",
 "foo_col_2"));
+        when(result.getSchema(DefaultDatabase.LOGIC_NAME)).thenReturn(schema);
+        return result;
     }
     
     private InsertStatement mockInsertStatement() {
@@ -111,7 +128,7 @@ class InsertClauseShardingConditionEngineTest {
     void 
assertCreateShardingConditionsInsertStatementWithGeneratedKeyContextUsingCommonExpressionSegmentEmpty()
 {
         
when(insertStatementContext.getInsertValueContexts()).thenReturn(Collections.singletonList(createInsertValueContextAsCommonExpressionSegmentEmptyText()));
         
when(insertStatementContext.getGeneratedKeyContext()).thenReturn(Optional.of(mock(GeneratedKeyContext.class)));
-        when(shardingRule.findShardingColumn(any(), 
any())).thenReturn(Optional.of("foo_sharding_col"));
+        when(shardingRule.findShardingColumn("foo_col_1", 
"foo_table")).thenReturn(Optional.of("foo_col_1"));
         List<ShardingCondition> shardingConditions = 
shardingConditionEngine.createShardingConditions(insertStatementContext, 
Collections.emptyList());
         assertThat(shardingConditions.get(0).getStartIndex(), is(0));
         assertThat(shardingConditions.get(0).getValues().size(), is(1));
@@ -121,8 +138,8 @@ class InsertClauseShardingConditionEngineTest {
     void assertCreateShardingConditionsInsertStatementWithMismatchColumns() {
         InsertValueContext insertValueContext = new 
InsertValueContext(Arrays.asList(new LiteralExpressionSegment(0, 10, "1"), new 
LiteralExpressionSegment(0, 10, "1")), Collections.emptyList(), 0);
         
when(insertStatementContext.getInsertValueContexts()).thenReturn(Collections.singletonList(insertValueContext));
-        when(shardingRule.findShardingColumn(any(), 
any())).thenReturn(Optional.of("foo_sharding_col"));
-        
when(insertStatementContext.getColumnNames()).thenReturn(Collections.singletonList("foo_col1"));
+        when(shardingRule.findShardingColumn("foo_col_1", 
"foo_table")).thenReturn(Optional.of("foo_col_1"));
+        
when(insertStatementContext.getColumnNames()).thenReturn(Collections.singletonList("foo_col_1"));
         assertThrows(InsertColumnsAndValuesMismatchedException.class, () -> 
shardingConditionEngine.createShardingConditions(insertStatementContext, 
Collections.emptyList()));
     }
     
@@ -130,7 +147,7 @@ class InsertClauseShardingConditionEngineTest {
     void 
assertCreateShardingConditionsInsertStatementWithGeneratedKeyContextUsingCommonExpressionSegmentNow()
 {
         
when(insertStatementContext.getInsertValueContexts()).thenReturn(Collections.singletonList(createInsertValueContextAsCommonExpressionSegmentWithNow()));
         
when(insertStatementContext.getGeneratedKeyContext()).thenReturn(Optional.of(mock(GeneratedKeyContext.class)));
-        when(shardingRule.findShardingColumn(any(), 
any())).thenReturn(Optional.of("foo_sharding_col"));
+        when(shardingRule.findShardingColumn("foo_col_1", 
"foo_table")).thenReturn(Optional.of("foo_col_1"));
         List<ShardingCondition> shardingConditions = 
shardingConditionEngine.createShardingConditions(insertStatementContext, 
Collections.emptyList());
         assertThat(shardingConditions.get(0).getStartIndex(), is(0));
         assertFalse(shardingConditions.get(0).getValues().isEmpty());
@@ -150,7 +167,7 @@ class InsertClauseShardingConditionEngineTest {
         
when(insertStatementContext.getGeneratedKeyContext()).thenReturn(Optional.of(generatedKeyContext));
         when(generatedKeyContext.isGenerated()).thenReturn(true);
         
when(generatedKeyContext.getGeneratedValues()).thenReturn(Collections.singletonList("foo_col1"));
-        
when(shardingRule.findTableRule(eq("foo_table"))).thenReturn(Optional.of(new 
TableRule(Collections.singletonList("foo_col"), "test")));
+        
when(shardingRule.findTableRule(eq("foo_table"))).thenReturn(Optional.of(new 
TableRule(Collections.singletonList("foo_col_1"), "test")));
         when(shardingRule.findShardingColumn(any(), 
any())).thenReturn(Optional.of("foo_sharding_col"));
         List<ShardingCondition> shardingConditions = 
shardingConditionEngine.createShardingConditions(insertStatementContext, 
Collections.emptyList());
         assertThat(shardingConditions.get(0).getStartIndex(), is(0));
@@ -161,7 +178,7 @@ class InsertClauseShardingConditionEngineTest {
     void assertCreateShardingConditionsWithParameterMarkers() {
         InsertValueContext insertValueContext = new 
InsertValueContext(Collections.singletonList(new 
ParameterMarkerExpressionSegment(0, 0, 0)), Collections.singletonList(1), 0);
         
when(insertStatementContext.getInsertValueContexts()).thenReturn(Collections.singletonList(insertValueContext));
-        when(shardingRule.findShardingColumn(any(), 
any())).thenReturn(Optional.of("foo_sharding_col"));
+        when(shardingRule.findShardingColumn("foo_col_1", 
"foo_table")).thenReturn(Optional.of("foo_col_1"));
         List<ShardingCondition> shardingConditions = 
shardingConditionEngine.createShardingConditions(insertStatementContext, 
Collections.singletonList(1));
         assertThat(shardingConditions.size(), is(1));
         assertThat(shardingConditions.get(0).getValues().size(), is(1));
@@ -181,4 +198,14 @@ class InsertClauseShardingConditionEngineTest {
         
when(insertStatementContext.getInsertSelectContext()).thenReturn(mock(InsertSelectContext.class));
         
assertTrue(shardingConditionEngine.createShardingConditions(insertStatementContext,
 Collections.emptyList()).isEmpty());
     }
+    
+    @Test
+    void assertCreateShardingConditionsWithoutShardingColumn() {
+        when(shardingRule.findShardingColumn("foo_col_2", 
"foo_table")).thenReturn(Optional.of("foo_col_2"));
+        List<ShardingCondition> actual = 
shardingConditionEngine.createShardingConditions(insertStatementContext, 
Collections.emptyList());
+        assertThat(actual.size(), is(1));
+        assertThat(actual.get(0).getValues().size(), is(1));
+        assertThat(actual.get(0).getValues().get(0).getColumnName(), 
is("foo_col_2"));
+        assertThat(actual.get(0).getValues().get(0).getTableName(), 
is("foo_table"));
+    }
 }
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/queryable/ExportMetaDataExecutorTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/queryable/ExportMetaDataExecutorTest.java
index ed814bcd308..c31ab193c6d 100644
--- 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/queryable/ExportMetaDataExecutorTest.java
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/queryable/ExportMetaDataExecutorTest.java
@@ -98,7 +98,7 @@ class ExportMetaDataExecutorTest {
         Collection<LocalDataQueryResultRow> actual = new 
ExportMetaDataExecutor().getRows(contextManager.getMetaDataContexts().getMetaData(),
 sqlStatement);
         assertThat(actual.size(), is(1));
         LocalDataQueryResultRow row = actual.iterator().next();
-        assertThat(row.getCell(3), 
+        assertThat(row.getCell(3),
                 
is("{\"meta_data\":{\"databases\":{\"empty_metadata\":\"databaseName: 
null\\ndataSources:\\nrules:\\n\"},"
                         + "\"props\":\"\",\"rules\":\"rules:\\n- 
!GLOBAL_CLOCK\\n  enabled: false\\n  provider: local\\n  type: TSO\\n\"}}"));
     }


Reply via email to