You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2023/04/18 12:14:19 UTC
[shardingsphere] branch master updated: Support null sharding condition pass to sharding algorithm to allow user control null value route (#25214)
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 <du...@apache.org>
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\"}}"));
}