You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by pa...@apache.org on 2021/10/09 01:58:26 UTC
[shardingsphere] branch master updated: support project subquery,
in subquery and between subquery convert (#12939)
This is an automated email from the ASF dual-hosted git repository.
panjuan 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 5d6ff2b support project subquery, in subquery and between subquery convert (#12939)
5d6ff2b is described below
commit 5d6ff2b9808c09eef61d247703bde0f249ae32cc
Author: Zhengqiang Duan <du...@apache.org>
AuthorDate: Sat Oct 9 09:57:41 2021 +0800
support project subquery, in subquery and between subquery convert (#12939)
* support project subquery, in subquery and between subquery convert
* extract common param
---
.../segment/expression/ExpressionConverter.java | 12 ++++
...verter.java => BetweenExpressionConverter.java} | 21 ++++---
.../impl/ExistsSubqueryExpressionConverter.java | 2 +-
...onConverter.java => InExpressionConverter.java} | 20 ++++---
.../expression/impl/ListExpressionConverter.java | 6 +-
...erter.java => SubqueryExpressionConverter.java} | 14 ++---
.../segment/projection/ProjectionsConverter.java | 8 +++
.../impl/AggregationProjectionConverter.java | 65 ++++++++++++++++++++++
.../impl/SubqueryProjectionConverter.java} | 26 ++++++---
.../statement/SelectStatementConverterTest.java | 28 ++++++++++
10 files changed, 167 insertions(+), 35 deletions(-)
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/ExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/ExpressionConverter.java
index 2ef03dc..6645d6b 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/ExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/ExpressionConverter.java
@@ -19,18 +19,24 @@ package org.apache.shardingsphere.infra.optimize.converter.segment.expression;
import org.apache.calcite.sql.SqlNode;
import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
+import org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl.BetweenExpressionConverter;
import org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl.BinaryOperationExpressionConverter;
import org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl.ColumnConverter;
import org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl.ExistsSubqueryExpressionConverter;
+import org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl.InExpressionConverter;
import org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl.ListExpressionConverter;
import org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl.LiteralExpressionConverter;
+import org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl.SubqueryExpressionConverter;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BetweenExpression;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExistsSubqueryExpression;
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 org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ListExpression;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.CommonExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubqueryExpressionSegment;
import java.util.Optional;
@@ -57,6 +63,12 @@ public final class ExpressionConverter implements SQLSegmentConverter<Expression
return new ColumnConverter().convert((ColumnSegment) segment);
} else if (segment instanceof ExistsSubqueryExpression) {
return new ExistsSubqueryExpressionConverter().convert((ExistsSubqueryExpression) segment);
+ } else if (segment instanceof SubqueryExpressionSegment) {
+ return new SubqueryExpressionConverter().convert((SubqueryExpressionSegment) segment);
+ } else if (segment instanceof InExpression) {
+ return new InExpressionConverter().convert((InExpression) segment);
+ } else if (segment instanceof BetweenExpression) {
+ return new BetweenExpressionConverter().convert((BetweenExpression) segment);
}
throw new UnsupportedOperationException("unsupported TableSegment type: " + segment.getClass());
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BetweenExpressionConverter.java
similarity index 61%
copy from shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java
copy to shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BetweenExpressionConverter.java
index f5d37ff..1afa590 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BetweenExpressionConverter.java
@@ -22,22 +22,29 @@ import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
-import org.apache.shardingsphere.infra.optimize.converter.statement.SelectStatementConverter;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExistsSubqueryExpression;
+import org.apache.shardingsphere.infra.optimize.converter.segment.expression.ExpressionConverter;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BetweenExpression;
+import java.util.Collection;
+import java.util.LinkedList;
import java.util.Optional;
/**
- * Exists subquery expression converter.
+ * Between expression converter.
*/
-public final class ExistsSubqueryExpressionConverter implements SQLSegmentConverter<ExistsSubqueryExpression, SqlNode> {
+public final class BetweenExpressionConverter implements SQLSegmentConverter<BetweenExpression, SqlNode> {
@Override
- public Optional<SqlNode> convert(final ExistsSubqueryExpression expression) {
+ public Optional<SqlNode> convert(final BetweenExpression expression) {
if (null == expression) {
return Optional.empty();
}
- SqlBasicCall sqlNode = new SqlBasicCall(SqlStdOperatorTable.EXISTS, new SqlNode[]{new SelectStatementConverter().convert(expression.getSubquery().getSelect())}, SqlParserPos.ZERO);
- return expression.isNot() ? Optional.of(new SqlBasicCall(SqlStdOperatorTable.NOT, new SqlNode[] {sqlNode}, SqlParserPos.ZERO)) : Optional.of(sqlNode);
+ Collection<SqlNode> sqlNodes = new LinkedList<>();
+ ExpressionConverter expressionConverter = new ExpressionConverter();
+ expressionConverter.convert(expression.getLeft()).ifPresent(sqlNodes::add);
+ expressionConverter.convert(expression.getBetweenExpr()).ifPresent(sqlNodes::add);
+ expressionConverter.convert(expression.getAndExpr()).ifPresent(sqlNodes::add);
+ SqlBasicCall sqlNode = new SqlBasicCall(SqlStdOperatorTable.BETWEEN, sqlNodes.toArray(new SqlNode[]{}), SqlParserPos.ZERO);
+ return expression.isNot() ? Optional.of(new SqlBasicCall(SqlStdOperatorTable.NOT, new SqlNode[]{sqlNode}, SqlParserPos.ZERO)) : Optional.of(sqlNode);
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java
index f5d37ff..5726769 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java
@@ -38,6 +38,6 @@ public final class ExistsSubqueryExpressionConverter implements SQLSegmentConver
return Optional.empty();
}
SqlBasicCall sqlNode = new SqlBasicCall(SqlStdOperatorTable.EXISTS, new SqlNode[]{new SelectStatementConverter().convert(expression.getSubquery().getSelect())}, SqlParserPos.ZERO);
- return expression.isNot() ? Optional.of(new SqlBasicCall(SqlStdOperatorTable.NOT, new SqlNode[] {sqlNode}, SqlParserPos.ZERO)) : Optional.of(sqlNode);
+ return expression.isNot() ? Optional.of(new SqlBasicCall(SqlStdOperatorTable.NOT, new SqlNode[]{sqlNode}, SqlParserPos.ZERO)) : Optional.of(sqlNode);
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/InExpressionConverter.java
similarity index 64%
copy from shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java
copy to shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/InExpressionConverter.java
index f5d37ff..22c3fc1 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/InExpressionConverter.java
@@ -22,22 +22,28 @@ import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
-import org.apache.shardingsphere.infra.optimize.converter.statement.SelectStatementConverter;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExistsSubqueryExpression;
+import org.apache.shardingsphere.infra.optimize.converter.segment.expression.ExpressionConverter;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.InExpression;
+import java.util.Collection;
+import java.util.LinkedList;
import java.util.Optional;
/**
- * Exists subquery expression converter.
+ * In expression converter.
*/
-public final class ExistsSubqueryExpressionConverter implements SQLSegmentConverter<ExistsSubqueryExpression, SqlNode> {
+public final class InExpressionConverter implements SQLSegmentConverter<InExpression, SqlNode> {
@Override
- public Optional<SqlNode> convert(final ExistsSubqueryExpression expression) {
+ public Optional<SqlNode> convert(final InExpression expression) {
if (null == expression) {
return Optional.empty();
}
- SqlBasicCall sqlNode = new SqlBasicCall(SqlStdOperatorTable.EXISTS, new SqlNode[]{new SelectStatementConverter().convert(expression.getSubquery().getSelect())}, SqlParserPos.ZERO);
- return expression.isNot() ? Optional.of(new SqlBasicCall(SqlStdOperatorTable.NOT, new SqlNode[] {sqlNode}, SqlParserPos.ZERO)) : Optional.of(sqlNode);
+ Collection<SqlNode> sqlNodes = new LinkedList<>();
+ ExpressionConverter expressionConverter = new ExpressionConverter();
+ expressionConverter.convert(expression.getLeft()).ifPresent(sqlNodes::add);
+ expressionConverter.convert(expression.getRight()).ifPresent(sqlNodes::add);
+ 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);
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ListExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ListExpressionConverter.java
index 13e5586..5f049b5 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ListExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ListExpressionConverter.java
@@ -36,12 +36,12 @@ public final class ListExpressionConverter implements SQLSegmentConverter<ListEx
@Override
public Optional<SqlNode> convert(final ListExpression segment) {
SqlNode left = null;
- for (ExpressionSegment item : segment.getItems()) {
- Optional<SqlNode> optional = new ExpressionConverter().convert(item);
+ for (ExpressionSegment each : segment.getItems()) {
+ Optional<SqlNode> optional = new ExpressionConverter().convert(each);
if (!optional.isPresent()) {
continue;
}
- if (left == null) {
+ if (null == left) {
left = optional.get();
continue;
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/SubqueryExpressionConverter.java
similarity index 62%
copy from shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java
copy to shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/SubqueryExpressionConverter.java
index f5d37ff..2733756 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/SubqueryExpressionConverter.java
@@ -17,27 +17,23 @@
package org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl;
-import org.apache.calcite.sql.SqlBasicCall;
import org.apache.calcite.sql.SqlNode;
-import org.apache.calcite.sql.fun.SqlStdOperatorTable;
-import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
import org.apache.shardingsphere.infra.optimize.converter.statement.SelectStatementConverter;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExistsSubqueryExpression;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubqueryExpressionSegment;
import java.util.Optional;
/**
- * Exists subquery expression converter.
+ * Subquery expression converter.
*/
-public final class ExistsSubqueryExpressionConverter implements SQLSegmentConverter<ExistsSubqueryExpression, SqlNode> {
+public final class SubqueryExpressionConverter implements SQLSegmentConverter<SubqueryExpressionSegment, SqlNode> {
@Override
- public Optional<SqlNode> convert(final ExistsSubqueryExpression expression) {
+ public Optional<SqlNode> convert(final SubqueryExpressionSegment expression) {
if (null == expression) {
return Optional.empty();
}
- SqlBasicCall sqlNode = new SqlBasicCall(SqlStdOperatorTable.EXISTS, new SqlNode[]{new SelectStatementConverter().convert(expression.getSubquery().getSelect())}, SqlParserPos.ZERO);
- return expression.isNot() ? Optional.of(new SqlBasicCall(SqlStdOperatorTable.NOT, new SqlNode[] {sqlNode}, SqlParserPos.ZERO)) : Optional.of(sqlNode);
+ return Optional.of(new SelectStatementConverter().convert(expression.getSubquery().getSelect()));
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/ProjectionsConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/ProjectionsConverter.java
index d8842f2..a9763c9 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/ProjectionsConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/ProjectionsConverter.java
@@ -21,14 +21,18 @@ import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
+import org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl.AggregationProjectionConverter;
import org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl.ColumnProjectionConverter;
import org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl.ExpressionProjectionConverter;
import org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl.ShorthandProjectionConverter;
+import org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl.SubqueryProjectionConverter;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationProjectionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ExpressionProjectionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionsSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ShorthandProjectionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.SubqueryProjectionSegment;
import java.util.ArrayList;
import java.util.Collection;
@@ -55,6 +59,10 @@ public final class ProjectionsConverter implements SQLSegmentConverter<Projectio
return new ExpressionProjectionConverter().convert((ExpressionProjectionSegment) segment);
} else if (segment instanceof ShorthandProjectionSegment) {
return new ShorthandProjectionConverter().convert((ShorthandProjectionSegment) segment);
+ } else if (segment instanceof SubqueryProjectionSegment) {
+ return new SubqueryProjectionConverter().convert((SubqueryProjectionSegment) segment);
+ } else if (segment instanceof AggregationProjectionSegment) {
+ return new AggregationProjectionConverter().convert((AggregationProjectionSegment) segment);
}
// TODO process other projection
return Optional.empty();
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/AggregationProjectionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/AggregationProjectionConverter.java
new file mode 100644
index 0000000..7ac0bc2
--- /dev/null
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/AggregationProjectionConverter.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl;
+
+import com.google.common.base.Preconditions;
+import org.apache.calcite.sql.SqlAggFunction;
+import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationProjectionSegment;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.TreeMap;
+
+/**
+ * Aggregation projection converter.
+ */
+public final class AggregationProjectionConverter implements SQLSegmentConverter<AggregationProjectionSegment, SqlNode> {
+
+ private static final Map<String, SqlAggFunction> REGISTRY = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+ static {
+ register(SqlStdOperatorTable.MAX);
+ register(SqlStdOperatorTable.MIN);
+ register(SqlStdOperatorTable.SUM);
+ register(SqlStdOperatorTable.COUNT);
+ register(SqlStdOperatorTable.AVG);
+ }
+
+ private static void register(final SqlAggFunction sqlAggFunction) {
+ REGISTRY.put(sqlAggFunction.getName(), sqlAggFunction);
+ }
+
+ @Override
+ public Optional<SqlNode> convert(final AggregationProjectionSegment segment) {
+ if (null == segment) {
+ return Optional.empty();
+ }
+ return Optional.of(new SqlBasicCall(convertOperator(segment.getType().name()), new SqlNode[]{SqlIdentifier.star(SqlParserPos.ZERO)}, SqlParserPos.ZERO));
+ }
+
+ private SqlAggFunction convertOperator(final String operator) {
+ Preconditions.checkState(REGISTRY.containsKey(operator), "Unsupported SQL operator: `%s`", operator);
+ return REGISTRY.get(operator);
+ }
+}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/SubqueryProjectionConverter.java
similarity index 58%
copy from shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java
copy to shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/SubqueryProjectionConverter.java
index f5d37ff..e2bdef7 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/SubqueryProjectionConverter.java
@@ -15,29 +15,39 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl;
+package org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl;
import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
import org.apache.shardingsphere.infra.optimize.converter.statement.SelectStatementConverter;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExistsSubqueryExpression;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.SubqueryProjectionSegment;
+import java.util.Collection;
+import java.util.LinkedList;
import java.util.Optional;
/**
- * Exists subquery expression converter.
+ * Subquery projection converter.
*/
-public final class ExistsSubqueryExpressionConverter implements SQLSegmentConverter<ExistsSubqueryExpression, SqlNode> {
+public final class SubqueryProjectionConverter implements SQLSegmentConverter<SubqueryProjectionSegment, SqlNode> {
@Override
- public Optional<SqlNode> convert(final ExistsSubqueryExpression expression) {
- if (null == expression) {
+ public Optional<SqlNode> convert(final SubqueryProjectionSegment segment) {
+ if (null == segment) {
return Optional.empty();
}
- SqlBasicCall sqlNode = new SqlBasicCall(SqlStdOperatorTable.EXISTS, new SqlNode[]{new SelectStatementConverter().convert(expression.getSubquery().getSelect())}, SqlParserPos.ZERO);
- return expression.isNot() ? Optional.of(new SqlBasicCall(SqlStdOperatorTable.NOT, new SqlNode[] {sqlNode}, SqlParserPos.ZERO)) : Optional.of(sqlNode);
+ SqlNode sqlNode = new SelectStatementConverter().convert(segment.getSubquery().getSelect());
+ return segment.getAlias().isPresent() ? convert(sqlNode, segment.getAlias().get()) : Optional.of(sqlNode);
+ }
+
+ private Optional<SqlNode> convert(final SqlNode sqlNode, final String alias) {
+ Collection<SqlNode> sqlNodes = new LinkedList<>();
+ sqlNodes.add(sqlNode);
+ sqlNodes.add(new SqlIdentifier(alias, SqlParserPos.ZERO));
+ return Optional.of(new SqlBasicCall(SqlStdOperatorTable.AS, sqlNodes.toArray(new SqlNode[]{}), SqlParserPos.ZERO));
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/statement/SelectStatementConverterTest.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/statement/SelectStatementConverterTest.java
index a92e0fe..5a97bb9 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/statement/SelectStatementConverterTest.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/statement/SelectStatementConverterTest.java
@@ -204,6 +204,34 @@ public final class SelectStatementConverterTest {
assertTrue(expected.equalsDeep(actual, Litmus.THROW));
}
+ @Test
+ public void assertConvertProjectionSubquery() {
+ String sql = "SELECT t_order_federate.order_id, t_order_federate.user_id, (SELECT COUNT(*) FROM t_user_info) FROM t_order_federate";
+ SQLStatement sqlStatement = sqlStatementParserEngine.parse(sql, false);
+ SqlNode expected = parse(sql, new MySQLDatabaseType());
+ SqlNode actual = SQLNodeConvertEngine.convert(sqlStatement);
+ assertTrue(expected.equalsDeep(actual, Litmus.THROW));
+ }
+
+ @Test
+ public void assertConvertInSubquery() {
+ String sql = "SELECT t_order_federate.order_id, t_order_federate.user_id FROM t_order_federate WHERE user_id IN (SELECT * FROM t_user_info)";
+ SQLStatement sqlStatement = sqlStatementParserEngine.parse(sql, false);
+ SqlNode expected = parse(sql, new MySQLDatabaseType());
+ SqlNode actual = SQLNodeConvertEngine.convert(sqlStatement);
+ assertTrue(expected.equalsDeep(actual, Litmus.THROW));
+ }
+
+ @Test
+ public void assertConvertBetweenAndSubquery() {
+ String sql = "SELECT t_order_federate.order_id, t_order_federate.user_id FROM t_order_federate "
+ + "WHERE user_id BETWEEN (SELECT user_id FROM t_user_info WHERE information = 'before') AND (SELECT user_id FROM t_user_info WHERE information = 'after')";
+ SQLStatement sqlStatement = sqlStatementParserEngine.parse(sql, false);
+ SqlNode expected = parse(sql, new MySQLDatabaseType());
+ SqlNode actual = SQLNodeConvertEngine.convert(sqlStatement);
+ assertTrue(expected.equalsDeep(actual, Litmus.THROW));
+ }
+
@SneakyThrows(SqlParseException.class)
private SqlNode parse(final String sql, final DatabaseType databaseType) {
return SqlParser.create(sql, Config.DEFAULT.withConformance(getSQLConformance(databaseType)).withLex(getLex(databaseType))).parseQuery();