You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2022/01/04 02:17:57 UTC
[shardingsphere] branch master updated: support concat method, improve in expression convert (#14492)
This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new d2b2eac support concat method, improve in expression convert (#14492)
d2b2eac is described below
commit d2b2eacfc5d6a7724e7344cc94475a251a3b0bfc
Author: liguoping <xd...@163.com>
AuthorDate: Tue Jan 4 10:17:08 2022 +0800
support concat method, improve in expression convert (#14492)
* commit
* concat 暂存
* subquery specially
* code style
---
.../segment/expression/ExpressionConverter.java | 11 ++++++++---
.../segment/expression/impl/FunctionConverter.java | 20 +++++++++++++++++++-
.../expression/impl/InExpressionConverter.java | 15 +++++++++++++--
.../expression/impl/ListExpressionConverter.java | 11 +++++++++++
.../impl/AggregationProjectionConverter.java | 19 +++++++++++++++----
.../SQLNodeConvertEngineParameterizedTest.java | 1 +
6 files changed, 67 insertions(+), 10 deletions(-)
diff --git a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/ExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/ExpressionConverter.java
index ee594af..395c7c1 100644
--- a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/ExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/ExpressionConverter.java
@@ -23,8 +23,10 @@ import org.apache.calcite.sql.SqlDynamicParam;
import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.SqlLiteral;
import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.SqlOperator;
import org.apache.calcite.sql.SqlSelect;
+import org.apache.calcite.sql.SqlUnresolvedFunction;
import org.apache.calcite.sql.fun.SqlBetweenOperator;
import org.apache.calcite.sql.fun.SqlCastFunction;
import org.apache.calcite.sql.fun.SqlInOperator;
@@ -73,7 +75,7 @@ public final class ExpressionConverter implements SQLSegmentConverter<Expression
// TODO
throw new UnsupportedOperationException("unsupported CommonExpressionSegment");
} else if (segment instanceof ListExpression) {
- return new ListExpressionConverter().convertToSQLNode((ListExpression) segment);
+ return new ListExpressionConverter().convertToSQLNode((ListExpression) segment).map(optional -> optional);
} else if (segment instanceof BinaryOperationExpression) {
return new BinaryOperationExpressionConverter().convertToSQLNode((BinaryOperationExpression) segment).map(optional -> optional);
} else if (segment instanceof ColumnSegment) {
@@ -97,7 +99,7 @@ public final class ExpressionConverter implements SQLSegmentConverter<Expression
@Override
public Optional<ExpressionSegment> convertToSQLSegment(final SqlNode sqlNode) {
if (null == sqlNode) {
- return Optional.empty();
+ return Optional.empty();
}
if (sqlNode instanceof SqlIdentifier) {
return new ColumnConverter().convertToSQLSegment((SqlIdentifier) sqlNode).map(optional -> optional);
@@ -114,6 +116,9 @@ public final class ExpressionConverter implements SQLSegmentConverter<Expression
if (sqlNode instanceof SqlDynamicParam) {
return new ParameterMarkerExpressionConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
}
+ if (sqlNode instanceof SqlNodeList) {
+ return new ListExpressionConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
+ }
return Optional.empty();
}
@@ -137,7 +142,7 @@ public final class ExpressionConverter implements SQLSegmentConverter<Expression
if (operator instanceof SqlBinaryOperator || operator instanceof SqlLikeOperator) {
return new BinaryOperationExpressionConverter().convertToSQLSegment(sqlBasicCall).map(optional -> optional);
}
- if (operator instanceof SqlPositionFunction || operator instanceof SqlCastFunction) {
+ if (operator instanceof SqlPositionFunction || operator instanceof SqlCastFunction || operator instanceof SqlUnresolvedFunction) {
return new FunctionConverter().convertToSQLSegment(sqlBasicCall).map(optional -> optional);
}
return Optional.empty();
diff --git a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/impl/FunctionConverter.java b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/impl/FunctionConverter.java
index f1c79bf..abbda47 100644
--- a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/impl/FunctionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/impl/FunctionConverter.java
@@ -20,16 +20,23 @@ package org.apache.shardingsphere.infra.federation.optimizer.converter.segment.e
import org.apache.calcite.sql.SqlBasicCall;
import org.apache.calcite.sql.SqlCharStringLiteral;
import org.apache.calcite.sql.SqlDataTypeSpec;
+import org.apache.calcite.sql.SqlDynamicParam;
+import org.apache.calcite.sql.SqlFunctionCategory;
+import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.SqlLiteral;
import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.SqlUnresolvedFunction;
import org.apache.calcite.sql.SqlUserDefinedTypeNameSpec;
import org.apache.calcite.sql.fun.SqlCastFunction;
import org.apache.calcite.sql.fun.SqlPositionFunction;
import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.shardingsphere.infra.federation.optimizer.converter.context.ConverterContextHolder;
import org.apache.shardingsphere.infra.federation.optimizer.converter.segment.SQLSegmentConverter;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.DataTypeSegment;
import java.util.ArrayList;
@@ -50,6 +57,10 @@ public final class FunctionConverter implements SQLSegmentConverter<FunctionSegm
if ("CAST".equalsIgnoreCase(segment.getFunctionName())) {
return Optional.of(new SqlBasicCall(new SqlCastFunction(), getSqlNodes(segment.getParameters()), SqlParserPos.ZERO));
}
+ if ("CONCAT".equalsIgnoreCase(segment.getFunctionName())) {
+ return Optional.of(new SqlBasicCall(new SqlUnresolvedFunction(new SqlIdentifier("CONCAT", SqlParserPos.ZERO),
+ null, null, null, null, SqlFunctionCategory.USER_DEFINED_FUNCTION), getSqlNodes(segment.getParameters()), SqlParserPos.ZERO));
+ }
return Optional.empty();
}
@@ -64,7 +75,8 @@ public final class FunctionConverter implements SQLSegmentConverter<FunctionSegm
}
private String getFunctionText(final SqlBasicCall sqlBasicCall) {
- if (null != sqlBasicCall.getOperator() && sqlBasicCall.getOperator() instanceof SqlCastFunction) {
+ SqlOperator operator;
+ if (null != (operator = sqlBasicCall.getOperator()) && (operator instanceof SqlCastFunction || operator instanceof SqlUnresolvedFunction)) {
return sqlBasicCall.toString().replace("`", "");
}
return sqlBasicCall.toString();
@@ -81,6 +93,9 @@ public final class FunctionConverter implements SQLSegmentConverter<FunctionSegm
result.add(dataTypeSegment);
} else if (operand instanceof SqlCharStringLiteral) {
result.add(new LiteralExpressionSegment(getStartIndex(operand), getStopIndex(operand), operand.toString().replace("'", "")));
+ } else if (operand instanceof SqlDynamicParam) {
+ ConverterContextHolder.get().getParameterCount().getAndIncrement();
+ result.add(new ParameterMarkerExpressionSegment(getStartIndex(operand), getStopIndex(operand), ((SqlDynamicParam) operand).getIndex()));
}
});
return result;
@@ -95,6 +110,9 @@ public final class FunctionConverter implements SQLSegmentConverter<FunctionSegm
if (sqlSegment instanceof DataTypeSegment) {
sqlNodes.add(new SqlDataTypeSpec(new SqlUserDefinedTypeNameSpec(((DataTypeSegment) sqlSegment).getDataTypeName(), SqlParserPos.ZERO), SqlParserPos.ZERO));
}
+ if (sqlSegment instanceof ParameterMarkerExpressionSegment) {
+ sqlNodes.add(new SqlDynamicParam(((ParameterMarkerExpressionSegment) sqlSegment).getParameterMarkerIndex(), SqlParserPos.ZERO));
+ }
});
return sqlNodes.toArray(new SqlNode[0]);
}
diff --git a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/impl/InExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/impl/InExpressionConverter.java
index 04d7a7c..7b57ef0 100644
--- a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/impl/InExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/impl/InExpressionConverter.java
@@ -20,6 +20,8 @@ package org.apache.shardingsphere.infra.federation.optimizer.converter.segment.e
import lombok.RequiredArgsConstructor;
import org.apache.calcite.sql.SqlBasicCall;
import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlSelect;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.shardingsphere.infra.federation.optimizer.converter.segment.SQLSegmentConverter;
@@ -27,6 +29,7 @@ import org.apache.shardingsphere.infra.federation.optimizer.converter.segment.ex
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.InExpression;
+import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Optional;
@@ -51,7 +54,14 @@ public final class InExpressionConverter implements SQLSegmentConverter<InExpres
Collection<SqlNode> sqlNodes = new LinkedList<>();
ExpressionConverter expressionConverter = new ExpressionConverter();
expressionConverter.convertToSQLNode(expression.getLeft()).ifPresent(sqlNodes::add);
- expressionConverter.convertToSQLNode(expression.getRight()).ifPresent(sqlNodes::add);
+ expressionConverter.convertToSQLNode(expression.getRight()).ifPresent(sqlNode -> {
+ if (sqlNode instanceof SqlBasicCall) {
+ SqlNodeList sqlNodeList = new SqlNodeList(Arrays.asList(((SqlBasicCall) sqlNode).getOperands().clone()), SqlParserPos.ZERO);
+ sqlNodes.add(sqlNodeList);
+ } else {
+ sqlNodes.add(sqlNode);
+ }
+ });
SqlBasicCall sqlNode = new SqlBasicCall(SqlStdOperatorTable.IN, sqlNodes.toArray(new SqlNode[]{}), SqlParserPos.ZERO);
return expression.isNot() ? Optional.of(new SqlBasicCall(SqlStdOperatorTable.NOT, new SqlNode[]{sqlNode}, SqlParserPos.ZERO)) : Optional.of(sqlNode);
}
@@ -64,6 +74,7 @@ public final class InExpressionConverter implements SQLSegmentConverter<InExpres
ExpressionConverter expressionConverter = new ExpressionConverter();
ExpressionSegment left = expressionConverter.convertToSQLSegment(sqlBasicCall.getOperandList().get(0)).orElseThrow(IllegalStateException::new);
ExpressionSegment right = expressionConverter.convertToSQLSegment(sqlBasicCall.getOperandList().get(1)).orElseThrow(IllegalStateException::new);
- return Optional.of(new InExpression(getStartIndex(sqlBasicCall), getStopIndex(sqlBasicCall) + 1, left, right, not));
+ return Optional.of(new InExpression(getStartIndex(sqlBasicCall),
+ sqlBasicCall.getOperandList().get(1) instanceof SqlSelect ? getStopIndex(sqlBasicCall) + 1 : getStopIndex(sqlBasicCall), left, right, not));
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/impl/ListExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/impl/ListExpressionConverter.java
index cd28447..ab9968c 100644
--- a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/impl/ListExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/expression/impl/ListExpressionConverter.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.infra.federation.optimizer.converter.segment.e
import org.apache.calcite.sql.SqlBasicCall;
import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.shardingsphere.infra.federation.optimizer.converter.segment.SQLSegmentConverter;
@@ -26,6 +27,7 @@ import org.apache.shardingsphere.infra.federation.optimizer.converter.segment.ex
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ListExpression;
+import java.util.List;
import java.util.Optional;
/**
@@ -52,6 +54,15 @@ public final class ListExpressionConverter implements SQLSegmentConverter<ListEx
@Override
public Optional<ListExpression> convertToSQLSegment(final SqlNode sqlNode) {
+ if (null == sqlNode) {
+ return Optional.empty();
+ }
+ if (sqlNode instanceof SqlNodeList) {
+ List<SqlNode> items = ((SqlNodeList) sqlNode).getList();
+ ListExpression result = new ListExpression(getStartIndex(sqlNode), getStopIndex(sqlNode));
+ items.forEach(item -> new ExpressionConverter().convertToSQLSegment(item).ifPresent(result.getItems()::add));
+ return Optional.of(result);
+ }
return Optional.empty();
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/projection/impl/AggregationProjectionConverter.java b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/projection/impl/AggregationProjectionConverter.java
index 8fadfc2..e9a0bf8 100644
--- a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/projection/impl/AggregationProjectionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/converter/segment/projection/impl/AggregationProjectionConverter.java
@@ -77,11 +77,11 @@ public final class AggregationProjectionConverter implements SQLSegmentConverter
}
if (segment.getAlias().isPresent()) {
return Optional.of(new SqlBasicCall(SqlStdOperatorTable.AS, new SqlNode[]{new SqlBasicCall(convertOperator(segment.getType().name()),
- new SqlNode[]{SqlIdentifier.star(parameters, SqlParserPos.ZERO, Collections.singletonList(SqlParserPos.ZERO))}, SqlParserPos.ZERO, false, functionQuantifier),
+ new SqlNode[]{createParametersSqlNode(parameters)}, SqlParserPos.ZERO, false, functionQuantifier),
SqlIdentifier.star(Collections.singletonList(segment.getAlias().get()), SqlParserPos.ZERO, Collections.singletonList(SqlParserPos.ZERO))}, SqlParserPos.ZERO));
}
- return Optional.of(new SqlBasicCall(convertOperator(segment.getType().name()),
- new SqlNode[]{SqlIdentifier.star(parameters, SqlParserPos.ZERO, Collections.singletonList(SqlParserPos.ZERO))}, SqlParserPos.ZERO, false, functionQuantifier));
+ return Optional.of(new SqlBasicCall(convertOperator(segment.getType().name()),
+ new SqlNode[]{createParametersSqlNode(parameters)}, SqlParserPos.ZERO, false, functionQuantifier));
}
@Override
@@ -91,7 +91,7 @@ public final class AggregationProjectionConverter implements SQLSegmentConverter
}
if (isAsOperatorAggregationType(sqlBasicCall)) {
SqlBasicCall subSqlBasicCall = (SqlBasicCall) sqlBasicCall.getOperandList().get(0);
- AggregationType aggregationType = AggregationType.valueOf(subSqlBasicCall.getOperator().getName());
+ AggregationType aggregationType = AggregationType.valueOf(subSqlBasicCall.getOperator().getName().toUpperCase());
String innerExpression = getInnerExpression(subSqlBasicCall);
AliasSegment aliasSegment = new AliasSegment(getStartIndex(sqlBasicCall.getOperandList().get(1)), getStopIndex(sqlBasicCall.getOperandList().get(1)),
new IdentifierValue(((SqlIdentifier) sqlBasicCall.getOperandList().get(1)).names.get(0)));
@@ -148,4 +148,15 @@ public final class AggregationProjectionConverter implements SQLSegmentConverter
&& sqlBasicCall.getOperandList().get(0) instanceof SqlBasicCall
&& AggregationType.isAggregationType(((SqlBasicCall) sqlBasicCall.getOperandList().get(0)).getOperator().getName());
}
+
+ private SqlNode createParametersSqlNode(final List<String> parameters) {
+ if (1 == parameters.size()) {
+ try {
+ Long.parseLong(parameters.get(0));
+ return SqlLiteral.createExactNumeric(parameters.get(0), SqlParserPos.ZERO);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ return SqlIdentifier.star(parameters, SqlParserPos.ZERO, Collections.singletonList(SqlParserPos.ZERO));
+ }
}
diff --git a/shardingsphere-test/shardingsphere-optimize-test/src/test/java/org/apache/shardingsphere/infra/federation/converter/parameterized/engine/SQLNodeConvertEngineParameterizedTest.java b/shardingsphere-test/shardingsphere-optimize-test/src/test/java/org/apache/shardingsphere/infra/federation/converter/parameterized/engine/SQLNodeConvertEngineParameterizedTest.java
index 8a03dcf..98e77ef 100644
--- a/shardingsphere-test/shardingsphere-optimize-test/src/test/java/org/apache/shardingsphere/infra/federation/converter/parameterized/engine/SQLNodeConvertEngineParameterizedTest.java
+++ b/shardingsphere-test/shardingsphere-optimize-test/src/test/java/org/apache/shardingsphere/infra/federation/converter/parameterized/engine/SQLNodeConvertEngineParameterizedTest.java
@@ -95,6 +95,7 @@ public final class SQLNodeConvertEngineParameterizedTest {
SUPPORTED_SQL_CASE_IDS.add("select_with_union");
SUPPORTED_SQL_CASE_IDS.add("select_cast_function");
SUPPORTED_SQL_CASE_IDS.add("select_with_same_table_name_and_alias");
+ SUPPORTED_SQL_CASE_IDS.add("select_count_like_concat");
}
private final String sqlCaseId;