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/22 05:18:18 UTC
[shardingsphere] branch master updated: support subquery sql node
convert to sql statement (#13214)
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 32202c0 support subquery sql node convert to sql statement (#13214)
32202c0 is described below
commit 32202c001aa4b667cf129aa3f3a944d58c960e75
Author: Zhengqiang Duan <du...@apache.org>
AuthorDate: Fri Oct 22 13:17:27 2021 +0800
support subquery sql node convert to sql statement (#13214)
* add some case for sql node convert to sql statement
* support case one sql node convert to sql statement
* support more case sql node convert to sql statement
* revert config file
* support subquery convert to sql statement
* adjust unit test
* rename method name
* rename method name
* optimize code
* fix checkstyle
* delete useless file
---
.../converter/segment/SQLSegmentConverter.java | 20 ++++++++
.../segment/expression/ExpressionConverter.java | 57 ++++++++++++++++++++--
.../impl/BetweenExpressionConverter.java | 24 +++++++--
.../impl/BinaryOperationExpressionConverter.java | 23 +++++----
.../segment/expression/impl/ColumnConverter.java | 21 ++++++--
.../impl/ExistsSubqueryExpressionConverter.java | 26 ++++++++--
.../expression/impl/InExpressionConverter.java | 23 +++++++--
.../impl/LiteralExpressionConverter.java | 5 ++
.../impl/SubqueryExpressionConverter.java | 11 ++++-
.../converter/segment/from/TableConverter.java | 17 ++++---
.../segment/from/impl/JoinTableConverter.java | 6 +--
.../segment/from/impl/SimpleTableConverter.java | 13 +++++
.../segment/from/impl/SubqueryTableConverter.java | 19 ++++++--
.../segment/groupby/GroupByConverter.java | 3 +-
.../segment/orderby/OrderByConverter.java | 12 +++--
.../orderby/item/ColumnOrderByItemConverter.java | 12 ++++-
.../orderby/item/OrderByItemConverterUtil.java | 26 ++++++++--
.../segment/projection/ProjectionsConverter.java | 33 +++++++++----
.../impl/AggregationProjectionConverter.java | 14 ++++--
.../projection/impl/ColumnProjectionConverter.java | 8 +--
.../impl/ExpressionProjectionConverter.java | 5 +-
.../impl/ShorthandProjectionConverter.java | 19 ++++++--
.../impl/SubqueryProjectionConverter.java | 14 ++++++
.../converter/segment/where/WhereConverter.java | 9 +++-
24 files changed, 334 insertions(+), 86 deletions(-)
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/SQLSegmentConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/SQLSegmentConverter.java
index 6c201b7..1ca48a0 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/SQLSegmentConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/SQLSegmentConverter.java
@@ -45,4 +45,24 @@ public interface SQLSegmentConverter<S extends SQLSegment, T extends SqlNode> {
* @return converted SQL segment
*/
Optional<S> convertToSQLSegment(T sqlNode);
+
+ /**
+ * Get start index.
+ *
+ * @param sqlNode SQL node
+ * @return start index
+ */
+ default int getStartIndex(SqlNode sqlNode) {
+ return sqlNode.getParserPosition().getColumnNum() - 1;
+ }
+
+ /**
+ * Get stop index.
+ *
+ * @param sqlNode SQL node
+ * @return stop index
+ */
+ default int getStopIndex(SqlNode sqlNode) {
+ return sqlNode.getParserPosition().getEndColumnNum() - 1;
+ }
}
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 6149f81..92b6fb0 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
@@ -17,7 +17,16 @@
package org.apache.shardingsphere.infra.optimize.converter.segment.expression;
+import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlBinaryOperator;
+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.SqlSelect;
+import org.apache.calcite.sql.fun.SqlBetweenOperator;
+import org.apache.calcite.sql.fun.SqlInOperator;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
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;
@@ -58,23 +67,61 @@ public final class ExpressionConverter implements SQLSegmentConverter<Expression
} else if (segment instanceof ListExpression) {
return new ListExpressionConverter().convertToSQLNode((ListExpression) segment);
} else if (segment instanceof BinaryOperationExpression) {
- return new BinaryOperationExpressionConverter().convertToSQLNode((BinaryOperationExpression) segment);
+ return new BinaryOperationExpressionConverter().convertToSQLNode((BinaryOperationExpression) segment).map(optional -> optional);
} else if (segment instanceof ColumnSegment) {
- return new ColumnConverter().convertToSQLNode((ColumnSegment) segment);
+ return new ColumnConverter().convertToSQLNode((ColumnSegment) segment).map(optional -> optional);
} else if (segment instanceof ExistsSubqueryExpression) {
- return new ExistsSubqueryExpressionConverter().convertToSQLNode((ExistsSubqueryExpression) segment);
+ return new ExistsSubqueryExpressionConverter().convertToSQLNode((ExistsSubqueryExpression) segment).map(optional -> optional);
} else if (segment instanceof SubqueryExpressionSegment) {
return new SubqueryExpressionConverter().convertToSQLNode((SubqueryExpressionSegment) segment);
} else if (segment instanceof InExpression) {
- return new InExpressionConverter().convertToSQLNode((InExpression) segment);
+ return new InExpressionConverter().convertToSQLNode((InExpression) segment).map(optional -> optional);
} else if (segment instanceof BetweenExpression) {
- return new BetweenExpressionConverter().convertToSQLNode((BetweenExpression) segment);
+ return new BetweenExpressionConverter().convertToSQLNode((BetweenExpression) segment).map(optional -> optional);
}
throw new UnsupportedOperationException("unsupported TableSegment type: " + segment.getClass());
}
@Override
public Optional<ExpressionSegment> convertToSQLSegment(final SqlNode sqlNode) {
+ if (null == sqlNode) {
+ return Optional.empty();
+ }
+ if (sqlNode instanceof SqlIdentifier) {
+ return new ColumnConverter().convertToSQLSegment((SqlIdentifier) sqlNode).map(optional -> optional);
+ }
+ if (sqlNode instanceof SqlBasicCall) {
+ return convertToSQLSegment((SqlBasicCall) sqlNode, false);
+ }
+ if (sqlNode instanceof SqlSelect) {
+ return new SubqueryExpressionConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
+ }
+ if (sqlNode instanceof SqlLiteral) {
+ return new LiteralExpressionConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
+ }
+ return Optional.empty();
+ }
+
+ private Optional<ExpressionSegment> convertToSQLSegment(final SqlBasicCall sqlBasicCall, final boolean not) {
+ if (null == sqlBasicCall) {
+ return Optional.empty();
+ }
+ SqlOperator operator = sqlBasicCall.getOperator();
+ if (operator.getName().equals(SqlStdOperatorTable.NOT.getName()) && sqlBasicCall.getOperandList().get(0) instanceof SqlBasicCall) {
+ return convertToSQLSegment((SqlBasicCall) sqlBasicCall.getOperandList().get(0), true);
+ }
+ if (operator instanceof SqlInOperator) {
+ return new InExpressionConverter(not).convertToSQLSegment(sqlBasicCall).map(optional -> optional);
+ }
+ if (operator instanceof SqlBetweenOperator) {
+ return new BetweenExpressionConverter(not).convertToSQLSegment(sqlBasicCall).map(optional -> optional);
+ }
+ if (operator.getName().equals(SqlStdOperatorTable.EXISTS.getName())) {
+ return new ExistsSubqueryExpressionConverter(not).convertToSQLSegment(sqlBasicCall).map(optional -> optional);
+ }
+ if (operator instanceof SqlBinaryOperator) {
+ return new BinaryOperationExpressionConverter().convertToSQLSegment(sqlBasicCall).map(optional -> optional);
+ }
return Optional.empty();
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BetweenExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BetweenExpressionConverter.java
index 62817a36..ec2622c 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BetweenExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BetweenExpressionConverter.java
@@ -17,6 +17,7 @@
package org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl;
+import lombok.RequiredArgsConstructor;
import org.apache.calcite.sql.SqlBasicCall;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
@@ -24,6 +25,7 @@ import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
import org.apache.shardingsphere.infra.optimize.converter.segment.expression.ExpressionConverter;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BetweenExpression;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
import java.util.Collection;
import java.util.LinkedList;
@@ -32,10 +34,17 @@ import java.util.Optional;
/**
* Between expression converter.
*/
-public final class BetweenExpressionConverter implements SQLSegmentConverter<BetweenExpression, SqlNode> {
+@RequiredArgsConstructor
+public final class BetweenExpressionConverter implements SQLSegmentConverter<BetweenExpression, SqlBasicCall> {
+
+ private final boolean not;
+
+ public BetweenExpressionConverter() {
+ not = false;
+ }
@Override
- public Optional<SqlNode> convertToSQLNode(final BetweenExpression expression) {
+ public Optional<SqlBasicCall> convertToSQLNode(final BetweenExpression expression) {
if (null == expression) {
return Optional.empty();
}
@@ -49,7 +58,14 @@ public final class BetweenExpressionConverter implements SQLSegmentConverter<Bet
}
@Override
- public Optional<BetweenExpression> convertToSQLSegment(final SqlNode sqlNode) {
- return Optional.empty();
+ public Optional<BetweenExpression> convertToSQLSegment(final SqlBasicCall sqlBasicCall) {
+ if (null == sqlBasicCall) {
+ return Optional.empty();
+ }
+ ExpressionConverter expressionConverter = new ExpressionConverter();
+ ExpressionSegment between = expressionConverter.convertToSQLSegment(sqlBasicCall.getOperandList().get(1)).orElseThrow(IllegalStateException::new);
+ ExpressionSegment and = expressionConverter.convertToSQLSegment(sqlBasicCall.getOperandList().get(2)).orElseThrow(IllegalStateException::new);
+ ExpressionSegment left = expressionConverter.convertToSQLSegment(sqlBasicCall.getOperandList().get(0)).orElseThrow(IllegalStateException::new);
+ return Optional.of(new BetweenExpression(left.getStartIndex(), and.getStopIndex(), left, between, and, not));
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BinaryOperationExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BinaryOperationExpressionConverter.java
index bd42865..459c967 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BinaryOperationExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BinaryOperationExpressionConverter.java
@@ -35,7 +35,7 @@ import java.util.TreeMap;
/**
* Binary operation expression converter.
*/
-public final class BinaryOperationExpressionConverter implements SQLSegmentConverter<BinaryOperationExpression, SqlNode> {
+public final class BinaryOperationExpressionConverter implements SQLSegmentConverter<BinaryOperationExpression, SqlBasicCall> {
private static final Map<String, SqlBinaryOperator> REGISTRY = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
@@ -59,26 +59,25 @@ public final class BinaryOperationExpressionConverter implements SQLSegmentConve
}
@Override
- public Optional<SqlNode> convertToSQLNode(final BinaryOperationExpression segment) {
+ public Optional<SqlBasicCall> convertToSQLNode(final BinaryOperationExpression segment) {
SqlBinaryOperator operator = convertOperator(segment.getOperator());
- SqlNode left = convertExpression(segment.getLeft());
- SqlNode right = convertExpression(segment.getRight());
+ SqlNode left = new ExpressionConverter().convertToSQLNode(segment.getLeft()).orElseThrow(IllegalStateException::new);
+ SqlNode right = new ExpressionConverter().convertToSQLNode(segment.getRight()).orElseThrow(IllegalStateException::new);
return Optional.of(new SqlBasicCall(operator, new SqlNode[] {left, right}, SqlParserPos.ZERO));
}
@Override
- public Optional<BinaryOperationExpression> convertToSQLSegment(final SqlNode sqlNode) {
- return Optional.empty();
+ public Optional<BinaryOperationExpression> convertToSQLSegment(final SqlBasicCall sqlBasicCall) {
+ 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);
+ String operator = sqlBasicCall.getOperator().getName();
+ String text = sqlBasicCall.toString();
+ return Optional.of(new BinaryOperationExpression(getStartIndex(sqlBasicCall), getStopIndex(sqlBasicCall), left, right, operator, text));
}
private SqlBinaryOperator convertOperator(final String operator) {
Preconditions.checkState(REGISTRY.containsKey(operator), "Unsupported SQL operator: `%s`", operator);
return REGISTRY.get(operator);
}
-
- private SqlNode convertExpression(final ExpressionSegment segment) {
- Optional<SqlNode> result = new ExpressionConverter().convertToSQLNode(segment);
- Preconditions.checkState(result.isPresent());
- return result.get();
- }
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ColumnConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ColumnConverter.java
index fc43323..14e8934 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ColumnConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ColumnConverter.java
@@ -17,12 +17,13 @@
package org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl;
+import com.google.common.collect.ImmutableList;
import org.apache.calcite.sql.SqlIdentifier;
-import org.apache.calcite.sql.SqlNode;
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.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
import java.util.Arrays;
import java.util.Optional;
@@ -30,10 +31,10 @@ import java.util.Optional;
/**
* Column converter.
*/
-public final class ColumnConverter implements SQLSegmentConverter<ColumnSegment, SqlNode> {
+public final class ColumnConverter implements SQLSegmentConverter<ColumnSegment, SqlIdentifier> {
@Override
- public Optional<SqlNode> convertToSQLNode(final ColumnSegment segment) {
+ public Optional<SqlIdentifier> convertToSQLNode(final ColumnSegment segment) {
Optional<OwnerSegment> owner = segment.getOwner();
String columnName = segment.getIdentifier().getValue();
SqlIdentifier sqlIdentifier = owner.map(optional
@@ -42,7 +43,17 @@ public final class ColumnConverter implements SQLSegmentConverter<ColumnSegment,
}
@Override
- public Optional<ColumnSegment> convertToSQLSegment(final SqlNode sqlNode) {
- return Optional.empty();
+ public Optional<ColumnSegment> convertToSQLSegment(final SqlIdentifier sqlIdentifier) {
+ if (null == sqlIdentifier) {
+ return Optional.empty();
+ }
+ ImmutableList<String> names = sqlIdentifier.names;
+ if (1 == names.size()) {
+ return Optional.of(new ColumnSegment(getStartIndex(sqlIdentifier), getStopIndex(sqlIdentifier), new IdentifierValue(names.get(0))));
+ }
+ ColumnSegment result = new ColumnSegment(getStartIndex(sqlIdentifier), getStopIndex(sqlIdentifier), new IdentifierValue(names.get(1)));
+ SqlIdentifier owner = sqlIdentifier.getComponent(0);
+ result.setOwner(new OwnerSegment(getStartIndex(owner), getStopIndex(owner), new IdentifierValue(names.get(0))));
+ return Optional.of(result);
}
}
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 49bdab5..db108d9 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
@@ -17,6 +17,7 @@
package org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl;
+import lombok.RequiredArgsConstructor;
import org.apache.calcite.sql.SqlBasicCall;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
@@ -24,16 +25,25 @@ 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.SubquerySegment;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
import java.util.Optional;
/**
* Exists subquery expression converter.
*/
-public final class ExistsSubqueryExpressionConverter implements SQLSegmentConverter<ExistsSubqueryExpression, SqlNode> {
+@RequiredArgsConstructor
+public final class ExistsSubqueryExpressionConverter implements SQLSegmentConverter<ExistsSubqueryExpression, SqlBasicCall> {
+
+ private final boolean not;
+
+ public ExistsSubqueryExpressionConverter() {
+ not = false;
+ }
@Override
- public Optional<SqlNode> convertToSQLNode(final ExistsSubqueryExpression expression) {
+ public Optional<SqlBasicCall> convertToSQLNode(final ExistsSubqueryExpression expression) {
if (null == expression) {
return Optional.empty();
}
@@ -42,7 +52,15 @@ public final class ExistsSubqueryExpressionConverter implements SQLSegmentConver
}
@Override
- public Optional<ExistsSubqueryExpression> convertToSQLSegment(final SqlNode sqlNode) {
- return Optional.empty();
+ public Optional<ExistsSubqueryExpression> convertToSQLSegment(final SqlBasicCall sqlBasicCall) {
+ if (null == sqlBasicCall) {
+ return Optional.empty();
+ }
+ SqlNode subquerySqlNode = sqlBasicCall.getOperandList().get(0);
+ SelectStatement selectStatement = new SelectStatementConverter().convertToSQLStatement(subquerySqlNode);
+ SubquerySegment subquery = new SubquerySegment(getStartIndex(subquerySqlNode) - 1, getStopIndex(subquerySqlNode) + 1, selectStatement);
+ ExistsSubqueryExpression result = new ExistsSubqueryExpression(getStartIndex(sqlBasicCall), subquery.getStopIndex(), subquery);
+ result.setNot(not);
+ return Optional.of(result);
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/InExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/InExpressionConverter.java
index 4285531..b5e0a2a 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/InExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/InExpressionConverter.java
@@ -17,12 +17,14 @@
package org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl;
+import lombok.RequiredArgsConstructor;
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.segment.expression.ExpressionConverter;
+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.Collection;
@@ -32,10 +34,17 @@ import java.util.Optional;
/**
* In expression converter.
*/
-public final class InExpressionConverter implements SQLSegmentConverter<InExpression, SqlNode> {
+@RequiredArgsConstructor
+public final class InExpressionConverter implements SQLSegmentConverter<InExpression, SqlBasicCall> {
+
+ private final boolean not;
+
+ public InExpressionConverter() {
+ not = false;
+ }
@Override
- public Optional<SqlNode> convertToSQLNode(final InExpression expression) {
+ public Optional<SqlBasicCall> convertToSQLNode(final InExpression expression) {
if (null == expression) {
return Optional.empty();
}
@@ -48,7 +57,13 @@ public final class InExpressionConverter implements SQLSegmentConverter<InExpres
}
@Override
- public Optional<InExpression> convertToSQLSegment(final SqlNode sqlNode) {
- return Optional.empty();
+ public Optional<InExpression> convertToSQLSegment(final SqlBasicCall sqlBasicCall) {
+ if (null == sqlBasicCall) {
+ return Optional.empty();
+ }
+ 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));
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/LiteralExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/LiteralExpressionConverter.java
index c418181..9612494 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/LiteralExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/LiteralExpressionConverter.java
@@ -22,6 +22,7 @@ import org.apache.calcite.sql.SqlNode;
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.expr.simple.LiteralExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.util.SQLUtil;
import java.util.Optional;
@@ -43,6 +44,10 @@ public final class LiteralExpressionConverter implements SQLSegmentConverter<Lit
@Override
public Optional<LiteralExpressionSegment> convertToSQLSegment(final SqlNode sqlNode) {
+ if (sqlNode instanceof SqlLiteral) {
+ SqlLiteral sqlLiteral = (SqlLiteral) sqlNode;
+ return Optional.of(new LiteralExpressionSegment(getStartIndex(sqlLiteral), getStopIndex(sqlLiteral), SQLUtil.getExactlyValue(sqlLiteral.toValue())));
+ }
return Optional.empty();
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/SubqueryExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/SubqueryExpressionConverter.java
index dc6ad1b..2fbafd8 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/SubqueryExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/SubqueryExpressionConverter.java
@@ -21,6 +21,8 @@ import org.apache.calcite.sql.SqlNode;
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.subquery.SubqueryExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
import java.util.Optional;
@@ -39,6 +41,13 @@ public final class SubqueryExpressionConverter implements SQLSegmentConverter<Su
@Override
public Optional<SubqueryExpressionSegment> convertToSQLSegment(final SqlNode sqlNode) {
- return Optional.empty();
+ if (null == sqlNode) {
+ return Optional.empty();
+ }
+ SelectStatement selectStatement = new SelectStatementConverter().convertToSQLStatement(sqlNode);
+ // FIXME subquery projection position returned by the CalCite parser does not contain two brackets
+ int startIndex = getStartIndex(sqlNode) - 1;
+ int stopIndex = getStopIndex(sqlNode) + 1;
+ return Optional.of(new SubqueryExpressionSegment(new SubquerySegment(startIndex, stopIndex, selectStatement)));
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/TableConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/TableConverter.java
index 954e6d8..8ef0033 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/TableConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/TableConverter.java
@@ -42,21 +42,22 @@ public final class TableConverter implements SQLSegmentConverter<TableSegment, S
if (segment instanceof SimpleTableSegment) {
return new SimpleTableConverter().convertToSQLNode((SimpleTableSegment) segment);
} else if (segment instanceof JoinTableSegment) {
- return new JoinTableConverter().convertToSQLNode((JoinTableSegment) segment);
+ return new JoinTableConverter().convertToSQLNode((JoinTableSegment) segment).map(optional -> optional);
} else if (segment instanceof SubqueryTableSegment) {
- return new SubqueryTableConverter().convertToSQLNode((SubqueryTableSegment) segment);
+ return new SubqueryTableConverter().convertToSQLNode((SubqueryTableSegment) segment).map(optional -> optional);
}
- throw new UnsupportedOperationException("Unsupported segment segment type: " + segment.getClass());
+ throw new UnsupportedOperationException("Unsupported segment type: " + segment.getClass());
}
@Override
public Optional<TableSegment> convertToSQLSegment(final SqlNode sqlNode) {
- if (sqlNode instanceof SqlBasicCall || sqlNode instanceof SqlIdentifier) {
+ if (sqlNode instanceof SqlIdentifier) {
return new SimpleTableConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
+ } else if (sqlNode instanceof SqlJoin) {
+ return new JoinTableConverter().convertToSQLSegment((SqlJoin) sqlNode).map(optional -> optional);
+ } else if (sqlNode instanceof SqlBasicCall) {
+ return new SubqueryTableConverter().convertToSQLSegment((SqlBasicCall) sqlNode).map(optional -> optional);
}
- if (sqlNode instanceof SqlJoin) {
- return new JoinTableConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
- }
- return Optional.empty();
+ throw new UnsupportedOperationException("Unsupported sql node type: " + sqlNode.getClass());
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/JoinTableConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/JoinTableConverter.java
index 4160080..ac6b7b7 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/JoinTableConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/JoinTableConverter.java
@@ -33,7 +33,7 @@ import java.util.Optional;
/**
* Join converter.
*/
-public final class JoinTableConverter implements SQLSegmentConverter<JoinTableSegment, SqlNode> {
+public final class JoinTableConverter implements SQLSegmentConverter<JoinTableSegment, SqlJoin> {
private static final String JOIN_TYPE_INNER = "INNER";
@@ -44,7 +44,7 @@ public final class JoinTableConverter implements SQLSegmentConverter<JoinTableSe
private static final String JOIN_TYPE_FULL = "FULL";
@Override
- public Optional<SqlNode> convertToSQLNode(final JoinTableSegment segment) {
+ public Optional<SqlJoin> convertToSQLNode(final JoinTableSegment segment) {
SqlNode left = new TableConverter().convertToSQLNode(segment.getLeft()).orElseThrow(IllegalStateException::new);
SqlNode right = new TableConverter().convertToSQLNode(segment.getRight()).orElseThrow(IllegalStateException::new);
Optional<SqlNode> condition = new ExpressionConverter().convertToSQLNode(segment.getCondition());
@@ -54,7 +54,7 @@ public final class JoinTableConverter implements SQLSegmentConverter<JoinTableSe
}
@Override
- public Optional<JoinTableSegment> convertToSQLSegment(final SqlNode sqlNode) {
+ public Optional<JoinTableSegment> convertToSQLSegment(final SqlJoin sqlJoin) {
return Optional.empty();
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SimpleTableConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SimpleTableConverter.java
index 83f17c9..300baed 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SimpleTableConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SimpleTableConverter.java
@@ -17,6 +17,7 @@
package org.apache.shardingsphere.infra.optimize.converter.segment.from.impl;
+import com.google.common.collect.ImmutableList;
import org.apache.calcite.sql.SqlBasicCall;
import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.SqlNode;
@@ -25,6 +26,7 @@ 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.generic.table.SimpleTableSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
import java.util.Optional;
@@ -46,6 +48,17 @@ public final class SimpleTableConverter implements SQLSegmentConverter<SimpleTab
@Override
public Optional<SimpleTableSegment> convertToSQLSegment(final SqlNode sqlNode) {
+ if (sqlNode instanceof SqlBasicCall) {
+ SqlBasicCall sqlBasicCall = (SqlBasicCall) sqlNode;
+ if (sqlBasicCall.getOperator().equals(SqlStdOperatorTable.AS)) {
+ ImmutableList<String> names = ((SqlIdentifier) sqlBasicCall.getOperandList().get(0)).names;
+ SimpleTableSegment tableSegment = new SimpleTableSegment(new TableNameSegment(getStartIndex(sqlNode), getStopIndex(sqlNode), new IdentifierValue(names.get(0))));
+ return Optional.of(tableSegment);
+ }
+ }
+ if (sqlNode instanceof SqlIdentifier) {
+ return Optional.of(new SimpleTableSegment(new TableNameSegment(getStartIndex(sqlNode), getStopIndex(sqlNode), new IdentifierValue(((SqlIdentifier) sqlNode).names.get(0)))));
+ }
return Optional.empty();
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SubqueryTableConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SubqueryTableConverter.java
index ab2611f..fad90b0 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SubqueryTableConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SubqueryTableConverter.java
@@ -24,7 +24,11 @@ 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.subquery.SubquerySegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.AliasSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
import java.util.Collection;
import java.util.LinkedList;
@@ -33,10 +37,10 @@ import java.util.Optional;
/**
* Subquery table converter.
*/
-public final class SubqueryTableConverter implements SQLSegmentConverter<SubqueryTableSegment, SqlNode> {
+public final class SubqueryTableConverter implements SQLSegmentConverter<SubqueryTableSegment, SqlBasicCall> {
@Override
- public Optional<SqlNode> convertToSQLNode(final SubqueryTableSegment segment) {
+ public Optional<SqlBasicCall> convertToSQLNode(final SubqueryTableSegment segment) {
if (null == segment) {
return Optional.empty();
}
@@ -47,7 +51,14 @@ public final class SubqueryTableConverter implements SQLSegmentConverter<Subquer
}
@Override
- public Optional<SubqueryTableSegment> convertToSQLSegment(final SqlNode sqlNode) {
- return Optional.empty();
+ public Optional<SubqueryTableSegment> convertToSQLSegment(final SqlBasicCall sqlBasicCall) {
+ SqlNode select = sqlBasicCall.getOperandList().get(0);
+ SelectStatement selectStatement = new SelectStatementConverter().convertToSQLStatement(select);
+ SubqueryTableSegment result = new SubqueryTableSegment(new SubquerySegment(getStartIndex(sqlBasicCall), getStopIndex(sqlBasicCall), selectStatement));
+ if (sqlBasicCall.getOperator().equals(SqlStdOperatorTable.AS)) {
+ SqlNode alias = sqlBasicCall.getOperandList().get(1);
+ result.setAlias(new AliasSegment(getStartIndex(alias), getStopIndex(alias), new IdentifierValue(alias.toString())));
+ }
+ return Optional.of(result);
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/groupby/GroupByConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/groupby/GroupByConverter.java
index 6e94a3e..8603830 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/groupby/GroupByConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/groupby/GroupByConverter.java
@@ -32,7 +32,8 @@ public final class GroupByConverter implements SQLSegmentConverter<GroupBySegmen
@Override
public Optional<SqlNodeList> convertToSQLNode(final GroupBySegment segment) {
- return null == segment || segment.getGroupByItems().isEmpty() ? Optional.empty() : Optional.of(new SqlNodeList(OrderByItemConverterUtil.convert(segment.getGroupByItems()), SqlParserPos.ZERO));
+ return null == segment || segment.getGroupByItems().isEmpty()
+ ? Optional.empty() : Optional.of(new SqlNodeList(OrderByItemConverterUtil.convertToSQLNode(segment.getGroupByItems()), SqlParserPos.ZERO));
}
@Override
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/OrderByConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/OrderByConverter.java
index 9b3326b..56196c6 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/OrderByConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/OrderByConverter.java
@@ -22,7 +22,9 @@ import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
import org.apache.shardingsphere.infra.optimize.converter.segment.orderby.item.OrderByItemConverterUtil;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.OrderBySegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.OrderByItemSegment;
+import java.util.Collection;
import java.util.Optional;
/**
@@ -32,11 +34,15 @@ public final class OrderByConverter implements SQLSegmentConverter<OrderBySegmen
@Override
public Optional<SqlNodeList> convertToSQLNode(final OrderBySegment segment) {
- return null == segment ? Optional.empty() : Optional.of(new SqlNodeList(OrderByItemConverterUtil.convert(segment.getOrderByItems()), SqlParserPos.ZERO));
+ return null == segment ? Optional.empty() : Optional.of(new SqlNodeList(OrderByItemConverterUtil.convertToSQLNode(segment.getOrderByItems()), SqlParserPos.ZERO));
}
@Override
- public Optional<OrderBySegment> convertToSQLSegment(final SqlNodeList sqlNode) {
- return Optional.empty();
+ public Optional<OrderBySegment> convertToSQLSegment(final SqlNodeList sqlNodeList) {
+ if (null == sqlNodeList) {
+ return Optional.empty();
+ }
+ Collection<OrderByItemSegment> orderByItems = OrderByItemConverterUtil.convertToSQLSegment(sqlNodeList);
+ return Optional.of(new OrderBySegment(getStartIndex(sqlNodeList), getStopIndex(sqlNodeList), orderByItems));
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/ColumnOrderByItemConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/ColumnOrderByItemConverter.java
index 2bde223..dd9c97b 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/ColumnOrderByItemConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/ColumnOrderByItemConverter.java
@@ -18,13 +18,16 @@
package org.apache.shardingsphere.infra.optimize.converter.segment.orderby.item;
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.segment.expression.impl.ColumnConverter;
import org.apache.shardingsphere.sql.parser.sql.common.constant.OrderDirection;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.ColumnOrderByItemSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
import java.util.Objects;
import java.util.Optional;
@@ -36,7 +39,7 @@ public final class ColumnOrderByItemConverter implements SQLSegmentConverter<Col
@Override
public Optional<SqlNode> convertToSQLNode(final ColumnOrderByItemSegment segment) {
- Optional<SqlNode> result = new ColumnConverter().convertToSQLNode(segment.getColumn());
+ Optional<SqlNode> result = new ColumnConverter().convertToSQLNode(segment.getColumn()).map(optional -> optional);
if (result.isPresent() && Objects.equals(OrderDirection.DESC, segment.getOrderDirection())) {
result = Optional.of(new SqlBasicCall(SqlStdOperatorTable.DESC, new SqlNode[] {result.get()}, SqlParserPos.ZERO));
}
@@ -45,6 +48,11 @@ public final class ColumnOrderByItemConverter implements SQLSegmentConverter<Col
@Override
public Optional<ColumnOrderByItemSegment> convertToSQLSegment(final SqlNode sqlNode) {
- return Optional.empty();
+ if (!(sqlNode instanceof SqlIdentifier)) {
+ return Optional.empty();
+ }
+ SqlIdentifier sqlIdentifier = (SqlIdentifier) sqlNode;
+ ColumnSegment column = new ColumnSegment(getStartIndex(sqlIdentifier), getStopIndex(sqlIdentifier), new IdentifierValue(sqlIdentifier.names.get(0)));
+ return Optional.of(new ColumnOrderByItemSegment(column, OrderDirection.ASC));
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/OrderByItemConverterUtil.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/OrderByItemConverterUtil.java
index 11083d1..16f986e 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/OrderByItemConverterUtil.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/OrderByItemConverterUtil.java
@@ -19,15 +19,17 @@ package org.apache.shardingsphere.infra.optimize.converter.segment.orderby.item;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
+import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.ColumnOrderByItemSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.ExpressionOrderByItemSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.IndexOrderByItemSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.OrderByItemSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.TextOrderByItemSegment;
-import java.util.ArrayList;
import java.util.Collection;
+import java.util.LinkedList;
/**
* Order by item converter utility.
@@ -36,13 +38,13 @@ import java.util.Collection;
public final class OrderByItemConverterUtil {
/**
- * Convert order by items.
+ * Convert order by items to sql node.
*
* @param orderByItems order by item list
* @return SQL nodes converted by order by item
*/
- public static Collection<SqlNode> convert(final Collection<OrderByItemSegment> orderByItems) {
- Collection<SqlNode> result = new ArrayList<>(orderByItems.size());
+ public static Collection<SqlNode> convertToSQLNode(final Collection<OrderByItemSegment> orderByItems) {
+ Collection<SqlNode> result = new LinkedList<>();
for (OrderByItemSegment each : orderByItems) {
if (each instanceof ColumnOrderByItemSegment) {
new ColumnOrderByItemConverter().convertToSQLNode((ColumnOrderByItemSegment) each).ifPresent(result::add);
@@ -56,4 +58,20 @@ public final class OrderByItemConverterUtil {
}
return result;
}
+
+ /**
+ * Convert sql node list to order by items.
+ *
+ * @param sqlNodeList sql node list
+ * @return order by items converted by sql node list
+ */
+ public static Collection<OrderByItemSegment> convertToSQLSegment(final SqlNodeList sqlNodeList) {
+ Collection<OrderByItemSegment> result = new LinkedList<>();
+ for (SqlNode each : sqlNodeList) {
+ if (each instanceof SqlIdentifier) {
+ new ColumnOrderByItemConverter().convertToSQLSegment(each).ifPresent(result::add);
+ }
+ }
+ return result;
+ }
}
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 7c28332..c35f705 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,6 +21,8 @@ import org.apache.calcite.sql.SqlBasicCall;
import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlOrderBy;
+import org.apache.calcite.sql.SqlSelect;
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;
@@ -28,6 +30,7 @@ import org.apache.shardingsphere.infra.optimize.converter.segment.projection.imp
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.constant.AggregationType;
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;
@@ -38,7 +41,7 @@ import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.Subquery
import java.util.ArrayList;
import java.util.Collection;
-import java.util.LinkedList;
+import java.util.List;
import java.util.Optional;
/**
@@ -57,28 +60,28 @@ public final class ProjectionsConverter implements SQLSegmentConverter<Projectio
private Optional<SqlNode> getProjectionSQLNode(final ProjectionSegment segment) {
if (segment instanceof ColumnProjectionSegment) {
- return new ColumnProjectionConverter().convertToSQLNode((ColumnProjectionSegment) segment);
+ return new ColumnProjectionConverter().convertToSQLNode((ColumnProjectionSegment) segment).map(optional -> optional);
} else if (segment instanceof ExpressionProjectionSegment) {
return new ExpressionProjectionConverter().convertToSQLNode((ExpressionProjectionSegment) segment);
} else if (segment instanceof ShorthandProjectionSegment) {
- return new ShorthandProjectionConverter().convertToSQLNode((ShorthandProjectionSegment) segment);
+ return new ShorthandProjectionConverter().convertToSQLNode((ShorthandProjectionSegment) segment).map(optional -> optional);
} else if (segment instanceof SubqueryProjectionSegment) {
return new SubqueryProjectionConverter().convertToSQLNode((SubqueryProjectionSegment) segment);
} else if (segment instanceof AggregationProjectionSegment) {
- return new AggregationProjectionConverter().convertToSQLNode((AggregationProjectionSegment) segment);
+ return new AggregationProjectionConverter().convertToSQLNode((AggregationProjectionSegment) segment).map(optional -> optional);
}
// TODO process other projection
return Optional.empty();
}
@Override
- public Optional<ProjectionsSegment> convertToSQLSegment(final SqlNodeList sqlNode) {
- Collection<ProjectionSegment> projections = new LinkedList<>();
- for (SqlNode each : sqlNode) {
+ public Optional<ProjectionsSegment> convertToSQLSegment(final SqlNodeList sqlNodeList) {
+ List<ProjectionSegment> projections = new ArrayList<>();
+ for (SqlNode each : sqlNodeList) {
getProjectionSegment(each).ifPresent(projections::add);
}
- int startIndex = sqlNode.get(0).getParserPosition().getColumnNum() - 1;
- int stopIndex = sqlNode.get(sqlNode.size() - 1).getParserPosition().getEndColumnNum() - 1;
+ int startIndex = projections.get(0).getStartIndex();
+ int stopIndex = projections.get(projections.size() - 1).getStopIndex();
ProjectionsSegment result = new ProjectionsSegment(startIndex, stopIndex);
result.getProjections().addAll(projections);
return Optional.of(result);
@@ -86,9 +89,19 @@ public final class ProjectionsConverter implements SQLSegmentConverter<Projectio
private Optional<ProjectionSegment> getProjectionSegment(final SqlNode sqlNode) {
if (sqlNode instanceof SqlIdentifier) {
- return new ColumnProjectionConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
+ SqlIdentifier sqlIdentifier = (SqlIdentifier) sqlNode;
+ if (SqlIdentifier.STAR.names.equals(sqlIdentifier.names)) {
+ return new ShorthandProjectionConverter().convertToSQLSegment(sqlIdentifier).map(optional -> optional);
+ }
+ return new ColumnProjectionConverter().convertToSQLSegment(sqlIdentifier).map(optional -> optional);
} else if (sqlNode instanceof SqlBasicCall) {
+ SqlBasicCall sqlBasicCall = (SqlBasicCall) sqlNode;
+ if (AggregationType.isAggregationType(sqlBasicCall.getOperator().getName())) {
+ return new AggregationProjectionConverter().convertToSQLSegment(sqlBasicCall).map(optional -> optional);
+ }
return new ExpressionProjectionConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
+ } else if (sqlNode instanceof SqlSelect || sqlNode instanceof SqlOrderBy) {
+ return new SubqueryProjectionConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
}
// 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
index be7bc8f..368d5cb 100644
--- 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
@@ -25,6 +25,7 @@ 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.constant.AggregationType;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationProjectionSegment;
import java.util.Map;
@@ -34,7 +35,7 @@ import java.util.TreeMap;
/**
* Aggregation projection converter.
*/
-public final class AggregationProjectionConverter implements SQLSegmentConverter<AggregationProjectionSegment, SqlNode> {
+public final class AggregationProjectionConverter implements SQLSegmentConverter<AggregationProjectionSegment, SqlBasicCall> {
private static final Map<String, SqlAggFunction> REGISTRY = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
@@ -51,7 +52,7 @@ public final class AggregationProjectionConverter implements SQLSegmentConverter
}
@Override
- public Optional<SqlNode> convertToSQLNode(final AggregationProjectionSegment segment) {
+ public Optional<SqlBasicCall> convertToSQLNode(final AggregationProjectionSegment segment) {
if (null == segment) {
return Optional.empty();
}
@@ -59,8 +60,13 @@ public final class AggregationProjectionConverter implements SQLSegmentConverter
}
@Override
- public Optional<AggregationProjectionSegment> convertToSQLSegment(final SqlNode sqlNode) {
- return Optional.empty();
+ public Optional<AggregationProjectionSegment> convertToSQLSegment(final SqlBasicCall sqlBasicCall) {
+ if (null == sqlBasicCall) {
+ return Optional.empty();
+ }
+ AggregationType aggregationType = AggregationType.valueOf(sqlBasicCall.getOperator().getName());
+ String innerExpression = sqlBasicCall.toString().replace(sqlBasicCall.getOperator().getName(), "");
+ return Optional.of(new AggregationProjectionSegment(getStartIndex(sqlBasicCall), getStopIndex(sqlBasicCall), aggregationType, innerExpression));
}
private SqlAggFunction convertOperator(final String operator) {
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ColumnProjectionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ColumnProjectionConverter.java
index 1a0de30..9f48990 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ColumnProjectionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ColumnProjectionConverter.java
@@ -17,7 +17,7 @@
package org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl;
-import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlIdentifier;
import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
import org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl.ColumnConverter;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
@@ -27,15 +27,15 @@ import java.util.Optional;
/**
* Column projection converter.
*/
-public final class ColumnProjectionConverter implements SQLSegmentConverter<ColumnProjectionSegment, SqlNode> {
+public final class ColumnProjectionConverter implements SQLSegmentConverter<ColumnProjectionSegment, SqlIdentifier> {
@Override
- public Optional<SqlNode> convertToSQLNode(final ColumnProjectionSegment segment) {
+ public Optional<SqlIdentifier> convertToSQLNode(final ColumnProjectionSegment segment) {
return new ColumnConverter().convertToSQLNode(segment.getColumn());
}
@Override
- public Optional<ColumnProjectionSegment> convertToSQLSegment(final SqlNode sqlNode) {
+ public Optional<ColumnProjectionSegment> convertToSQLSegment(final SqlIdentifier sqlNode) {
return new ColumnConverter().convertToSQLSegment(sqlNode).map(ColumnProjectionSegment::new);
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ExpressionProjectionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ExpressionProjectionConverter.java
index 542c10b..23a8bec 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ExpressionProjectionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ExpressionProjectionConverter.java
@@ -21,6 +21,7 @@ import org.apache.calcite.sql.SqlBasicCall;
import org.apache.calcite.sql.SqlNode;
import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
import org.apache.shardingsphere.infra.optimize.converter.segment.expression.ExpressionConverter;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ExpressionProjectionSegment;
import java.util.Optional;
@@ -38,8 +39,8 @@ public final class ExpressionProjectionConverter implements SQLSegmentConverter<
@Override
public Optional<ExpressionProjectionSegment> convertToSQLSegment(final SqlNode sqlNode) {
if (sqlNode instanceof SqlBasicCall) {
- return Optional.of(new ExpressionProjectionSegment(sqlNode.getParserPosition().getColumnNum() - 1,
- sqlNode.getParserPosition().getEndColumnNum() - 1, sqlNode.toString(), new ExpressionConverter().convertToSQLSegment(sqlNode).orElse(null)));
+ ExpressionSegment expressionSegment = new ExpressionConverter().convertToSQLSegment(sqlNode).orElse(null);
+ return Optional.of(new ExpressionProjectionSegment(getStartIndex(sqlNode), getStopIndex(sqlNode), sqlNode.toString(), expressionSegment));
}
return Optional.empty();
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ShorthandProjectionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ShorthandProjectionConverter.java
index 532b7f5..84bc2e9 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ShorthandProjectionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ShorthandProjectionConverter.java
@@ -18,25 +18,34 @@
package org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl;
import org.apache.calcite.sql.SqlIdentifier;
-import org.apache.calcite.sql.SqlNode;
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.ShorthandProjectionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
import java.util.Optional;
/**
* Shorthand projection converter.
*/
-public final class ShorthandProjectionConverter implements SQLSegmentConverter<ShorthandProjectionSegment, SqlNode> {
+public final class ShorthandProjectionConverter implements SQLSegmentConverter<ShorthandProjectionSegment, SqlIdentifier> {
@Override
- public Optional<SqlNode> convertToSQLNode(final ShorthandProjectionSegment segment) {
+ public Optional<SqlIdentifier> convertToSQLNode(final ShorthandProjectionSegment segment) {
return null == segment ? Optional.empty() : Optional.of(SqlIdentifier.star(SqlParserPos.ZERO));
}
@Override
- public Optional<ShorthandProjectionSegment> convertToSQLSegment(final SqlNode sqlNode) {
- return Optional.empty();
+ public Optional<ShorthandProjectionSegment> convertToSQLSegment(final SqlIdentifier sqlIdentifier) {
+ if (null == sqlIdentifier) {
+ return Optional.empty();
+ }
+ ShorthandProjectionSegment result = new ShorthandProjectionSegment(getStartIndex(sqlIdentifier), getStopIndex(sqlIdentifier));
+ if (sqlIdentifier.names.size() > 1) {
+ SqlIdentifier owner = sqlIdentifier.getComponent(0);
+ result.setOwner(new OwnerSegment(getStartIndex(owner), getStopIndex(owner), new IdentifierValue(sqlIdentifier.names.get(0))));
+ }
+ return Optional.of(result);
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/SubqueryProjectionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/SubqueryProjectionConverter.java
index f35b14b..6a90a0e 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/SubqueryProjectionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/SubqueryProjectionConverter.java
@@ -17,14 +17,19 @@
package org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl;
+import org.apache.calcite.avatica.util.Quoting;
import org.apache.calcite.sql.SqlBasicCall;
import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlOrderBy;
+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.optimize.converter.segment.SQLSegmentConverter;
import org.apache.shardingsphere.infra.optimize.converter.statement.SelectStatementConverter;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.SubqueryProjectionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
import java.util.Collection;
import java.util.LinkedList;
@@ -53,6 +58,15 @@ public final class SubqueryProjectionConverter implements SQLSegmentConverter<Su
@Override
public Optional<SubqueryProjectionSegment> convertToSQLSegment(final SqlNode sqlNode) {
+ if (sqlNode instanceof SqlSelect || sqlNode instanceof SqlOrderBy) {
+ SelectStatement selectStatement = new SelectStatementConverter().convertToSQLStatement(sqlNode);
+ // FIXME subquery projection position returned by the CalCite parser does not contain two brackets
+ int startIndex = getStartIndex(sqlNode) - 1;
+ int stopIndex = getStopIndex(sqlNode) + 1;
+ String text = "(" + sqlNode + ")";
+ String originalText = text.replace("\n", " ").replace(Quoting.BACK_TICK.string, "");
+ return Optional.of(new SubqueryProjectionSegment(new SubquerySegment(startIndex, stopIndex, selectStatement), originalText));
+ }
return Optional.empty();
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/where/WhereConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/where/WhereConverter.java
index bb25c29..09c28f1 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/where/WhereConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/where/WhereConverter.java
@@ -29,6 +29,8 @@ import java.util.Optional;
*/
public final class WhereConverter implements SQLSegmentConverter<WhereSegment, SqlNode> {
+ private static final int WHERE_SEGMENT_LENGTH = 6;
+
@Override
public Optional<SqlNode> convertToSQLNode(final WhereSegment segment) {
return null == segment ? Optional.empty() : new ExpressionConverter().convertToSQLNode(segment.getExpr());
@@ -36,6 +38,11 @@ public final class WhereConverter implements SQLSegmentConverter<WhereSegment, S
@Override
public Optional<WhereSegment> convertToSQLSegment(final SqlNode sqlNode) {
- return Optional.empty();
+ if (null == sqlNode) {
+ return Optional.empty();
+ }
+ // FIXME Now sqlNode position returned by the CalCite parser does not contain WHERE and requires manual calculation
+ int startIndex = getStartIndex(sqlNode) - WHERE_SEGMENT_LENGTH;
+ return new ExpressionConverter().convertToSQLSegment(sqlNode).map(optional -> new WhereSegment(startIndex, optional.getStopIndex(), optional));
}
}