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\"}}"));
}