You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2021/11/19 11:26:32 UTC
[shardingsphere] branch master updated: Support more query statements to convert between SQLStatement and SqlNode (#13661)
This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new f314a9d Support more query statements to convert between SQLStatement and SqlNode (#13661)
f314a9d is described below
commit f314a9d53b7c4b4ae369952c99523a40cdb1c27b
Author: liguoping <xd...@163.com>
AuthorDate: Fri Nov 19 19:25:46 2021 +0800
Support more query statements to convert between SQLStatement and SqlNode (#13661)
* has privileges or not
* select_alias_as_keyword support
* checkstyle
* [select_alias_as_keyword] move 2 to the left condition.
* [select_alias_as_keyword] add javadoc for ParameterMarkerExpressionConverter.
* [select_alias_as_keyword] rollback columnConverter
* 有 as 的情况下,重新获取projectionsSegmentStopIndex
* getProjectionsSegmentStopIndex final param
---
.../segment/expression/ExpressionConverter.java | 8 +++++
.../segment/expression/impl/ColumnConverter.java | 2 +-
.../impl/ParameterMarkerExpressionConverter.java} | 21 ++++++------
.../segment/projection/ProjectionsConverter.java | 16 +++++++--
.../projection/impl/ColumnProjectionConverter.java | 39 +++++++++++++++++++---
.../statement/SelectStatementConverter.java | 22 ++++++++++++
.../SQLNodeConvertEngineParameterizedTest.java | 1 +
7 files changed, 91 insertions(+), 18 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 92b6fb0..51e0ea6 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,6 +19,7 @@ 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.SqlDynamicParam;
import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.SqlLiteral;
import org.apache.calcite.sql.SqlNode;
@@ -35,6 +36,7 @@ import org.apache.shardingsphere.infra.optimize.converter.segment.expression.imp
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.ParameterMarkerExpressionConverter;
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;
@@ -45,6 +47,7 @@ import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.InExpres
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.simple.ParameterMarkerExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubqueryExpressionSegment;
import java.util.Optional;
@@ -78,6 +81,8 @@ public final class ExpressionConverter implements SQLSegmentConverter<Expression
return new InExpressionConverter().convertToSQLNode((InExpression) segment).map(optional -> optional);
} else if (segment instanceof BetweenExpression) {
return new BetweenExpressionConverter().convertToSQLNode((BetweenExpression) segment).map(optional -> optional);
+ } else if (segment instanceof ParameterMarkerExpressionSegment) {
+ return new ParameterMarkerExpressionConverter().convertToSQLNode((ParameterMarkerExpressionSegment) segment).map(optional -> optional);
}
throw new UnsupportedOperationException("unsupported TableSegment type: " + segment.getClass());
}
@@ -99,6 +104,9 @@ public final class ExpressionConverter implements SQLSegmentConverter<Expression
if (sqlNode instanceof SqlLiteral) {
return new LiteralExpressionConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
}
+ if (sqlNode instanceof SqlDynamicParam) {
+ return new ParameterMarkerExpressionConverter().convertToSQLSegment(sqlNode).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/ColumnConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ColumnConverter.java
index 14e8934..f113666 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
@@ -49,7 +49,7 @@ public final class ColumnConverter implements SQLSegmentConverter<ColumnSegment,
}
ImmutableList<String> names = sqlIdentifier.names;
if (1 == names.size()) {
- return Optional.of(new ColumnSegment(getStartIndex(sqlIdentifier), getStopIndex(sqlIdentifier), new IdentifierValue(names.get(0))));
+ 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);
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/expression/impl/ParameterMarkerExpressionConverter.java
similarity index 57%
copy from shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ColumnProjectionConverter.java
copy to shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ParameterMarkerExpressionConverter.java
index 9f48990..33ba472 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/expression/impl/ParameterMarkerExpressionConverter.java
@@ -15,27 +15,28 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl;
+package org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl;
-import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlDynamicParam;
+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.infra.optimize.converter.segment.expression.impl.ColumnConverter;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import java.util.Optional;
/**
- * Column projection converter.
+ * Parameter marker expression converter.
*/
-public final class ColumnProjectionConverter implements SQLSegmentConverter<ColumnProjectionSegment, SqlIdentifier> {
+public final class ParameterMarkerExpressionConverter implements SQLSegmentConverter<ParameterMarkerExpressionSegment, SqlNode> {
@Override
- public Optional<SqlIdentifier> convertToSQLNode(final ColumnProjectionSegment segment) {
- return new ColumnConverter().convertToSQLNode(segment.getColumn());
+ public Optional<SqlNode> convertToSQLNode(final ParameterMarkerExpressionSegment segment) {
+ return Optional.of(new SqlDynamicParam(segment.getParameterMarkerIndex(), SqlParserPos.ZERO));
}
@Override
- public Optional<ColumnProjectionSegment> convertToSQLSegment(final SqlIdentifier sqlNode) {
- return new ColumnConverter().convertToSQLSegment(sqlNode).map(ColumnProjectionSegment::new);
+ public Optional<ParameterMarkerExpressionSegment> convertToSQLSegment(final SqlNode sqlNode) {
+ return Optional.of(new ParameterMarkerExpressionSegment(getStartIndex(sqlNode), getStopIndex(sqlNode), ((SqlDynamicParam) sqlNode).getIndex()));
}
}
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 c35f705..dbf0afd 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
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.infra.optimize.converter.segment.projection;
import org.apache.calcite.sql.SqlBasicCall;
import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.SqlOrderBy;
@@ -60,7 +61,7 @@ public final class ProjectionsConverter implements SQLSegmentConverter<Projectio
private Optional<SqlNode> getProjectionSQLNode(final ProjectionSegment segment) {
if (segment instanceof ColumnProjectionSegment) {
- return new ColumnProjectionConverter().convertToSQLNode((ColumnProjectionSegment) segment).map(optional -> optional);
+ return new ColumnProjectionConverter().convertToSQLNode((ColumnProjectionSegment) segment);
} else if (segment instanceof ExpressionProjectionSegment) {
return new ExpressionProjectionConverter().convertToSQLNode((ExpressionProjectionSegment) segment);
} else if (segment instanceof ShorthandProjectionSegment) {
@@ -81,12 +82,20 @@ public final class ProjectionsConverter implements SQLSegmentConverter<Projectio
getProjectionSegment(each).ifPresent(projections::add);
}
int startIndex = projections.get(0).getStartIndex();
- int stopIndex = projections.get(projections.size() - 1).getStopIndex();
+ int stopIndex = getProjectionsSegmentStopIndex(sqlNodeList.get(sqlNodeList.size() - 1), projections.get(projections.size() - 1));
ProjectionsSegment result = new ProjectionsSegment(startIndex, stopIndex);
result.getProjections().addAll(projections);
return Optional.of(result);
}
+ private int getProjectionsSegmentStopIndex(final SqlNode lastSqlNode, final ProjectionSegment projectionSegment) {
+ int stopIndex = projectionSegment.getStopIndex();
+ if (lastSqlNode instanceof SqlBasicCall && SqlKind.AS == ((SqlBasicCall) lastSqlNode).getOperator().getKind()) {
+ stopIndex = getStopIndex(((SqlBasicCall) lastSqlNode).getOperandList().get(1));
+ }
+ return stopIndex;
+ }
+
private Optional<ProjectionSegment> getProjectionSegment(final SqlNode sqlNode) {
if (sqlNode instanceof SqlIdentifier) {
SqlIdentifier sqlIdentifier = (SqlIdentifier) sqlNode;
@@ -99,6 +108,9 @@ public final class ProjectionsConverter implements SQLSegmentConverter<Projectio
if (AggregationType.isAggregationType(sqlBasicCall.getOperator().getName())) {
return new AggregationProjectionConverter().convertToSQLSegment(sqlBasicCall).map(optional -> optional);
}
+ if (null != sqlBasicCall.getOperator() && SqlKind.AS == sqlBasicCall.getOperator().getKind()) {
+ return new ColumnProjectionConverter().convertToSQLSegment(sqlNode).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);
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 9f48990..e65cf6d 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,25 +17,54 @@
package org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl;
+import org.apache.calcite.sql.SqlAsOperator;
+import org.apache.calcite.sql.SqlBasicCall;
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.infra.optimize.converter.segment.expression.impl.ColumnConverter;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.AliasSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
+import java.util.List;
import java.util.Optional;
/**
* Column projection converter.
*/
-public final class ColumnProjectionConverter implements SQLSegmentConverter<ColumnProjectionSegment, SqlIdentifier> {
+public final class ColumnProjectionConverter implements SQLSegmentConverter<ColumnProjectionSegment, SqlNode> {
@Override
- public Optional<SqlIdentifier> convertToSQLNode(final ColumnProjectionSegment segment) {
- return new ColumnConverter().convertToSQLNode(segment.getColumn());
+ public Optional<SqlNode> convertToSQLNode(final ColumnProjectionSegment segment) {
+ if (segment.getAlias().isPresent()) {
+ Optional<SqlIdentifier> columnSqlIdentifier = new ColumnConverter().convertToSQLNode(segment.getColumn());
+ SqlIdentifier aliasSqlIdentifier = new SqlIdentifier(segment.getAlias().get(), SqlParserPos.ZERO);
+ return Optional.of(new SqlBasicCall(new SqlAsOperator(), new SqlNode[]{columnSqlIdentifier.get(), aliasSqlIdentifier}, SqlParserPos.ZERO));
+ }
+ return new ColumnConverter().convertToSQLNode(segment.getColumn()).map(optional -> optional);
}
@Override
- public Optional<ColumnProjectionSegment> convertToSQLSegment(final SqlIdentifier sqlNode) {
- return new ColumnConverter().convertToSQLSegment(sqlNode).map(ColumnProjectionSegment::new);
+ public Optional<ColumnProjectionSegment> convertToSQLSegment(final SqlNode sqlNode) {
+ if (sqlNode instanceof SqlBasicCall) {
+ List<SqlNode> operands = ((SqlBasicCall) sqlNode).getOperandList();
+ Optional<ColumnSegment> columnSegment = new ColumnConverter().convertToSQLSegment((SqlIdentifier) operands.get(0));
+ if (!columnSegment.isPresent()) {
+ return Optional.empty();
+ }
+ ColumnProjectionSegment columnProjectionSegment = new ColumnProjectionSegment(columnSegment.get());
+ if (2 == operands.size()) {
+ SqlIdentifier aliasSqlNode = (SqlIdentifier) operands.get(1);
+ columnProjectionSegment.setAlias(new AliasSegment(getStartIndex(aliasSqlNode), getStopIndex(aliasSqlNode), new IdentifierValue(aliasSqlNode.names.get(0))));
+ }
+ return Optional.of(columnProjectionSegment);
+ }
+ if (sqlNode instanceof SqlIdentifier) {
+ return new ColumnConverter().convertToSQLSegment((SqlIdentifier) sqlNode).map(ColumnProjectionSegment::new);
+ }
+ return Optional.empty();
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/statement/SelectStatementConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/statement/SelectStatementConverter.java
index 968e494..e3e2498 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/statement/SelectStatementConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/statement/SelectStatementConverter.java
@@ -32,6 +32,8 @@ import org.apache.shardingsphere.infra.optimize.converter.segment.projection.Dis
import org.apache.shardingsphere.infra.optimize.converter.segment.projection.ProjectionsConverter;
import org.apache.shardingsphere.infra.optimize.converter.segment.where.WhereConverter;
import org.apache.shardingsphere.sql.parser.sql.common.segment.SQLSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionsSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.PaginationValueSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.limit.LimitSegment;
@@ -90,10 +92,30 @@ public final class SelectStatementConverter implements SQLStatementConverter<Sel
new OrderByConverter().convertToSQLSegment(sqlOrderBy.orderList).ifPresent(result::setOrderBy);
createLimitSegment(sqlOrderBy, context).ifPresent(result::setLimit);
}
+ calculateParamCount(result, context);
result.setParameterCount(context.getParameterCount().get());
return result;
}
+ private void calculateParamCount(final MySQLSelectStatement result, final ConverterContext context) {
+ result.getWhere().ifPresent(whereSegment -> {
+ if (whereSegment.getExpr() instanceof BinaryOperationExpression) {
+ if (((BinaryOperationExpression) whereSegment.getExpr()).getLeft() instanceof ParameterMarkerExpressionSegment
+ || ((BinaryOperationExpression) whereSegment.getExpr()).getRight() instanceof ParameterMarkerExpressionSegment) {
+ context.getParameterCount().incrementAndGet();
+ }
+ }
+ });
+ result.getHaving().ifPresent(havingSegment -> {
+ if (havingSegment.getExpr() instanceof BinaryOperationExpression) {
+ if (((BinaryOperationExpression) havingSegment.getExpr()).getLeft() instanceof ParameterMarkerExpressionSegment
+ || ((BinaryOperationExpression) havingSegment.getExpr()).getRight() instanceof ParameterMarkerExpressionSegment) {
+ context.getParameterCount().incrementAndGet();
+ }
+ }
+ });
+ }
+
private Optional<LimitSegment> createLimitSegment(final SqlOrderBy sqlOrderBy, final ConverterContext context) {
if (null == sqlOrderBy.offset && null == sqlOrderBy.fetch) {
return Optional.empty();
diff --git a/shardingsphere-test/shardingsphere-optimize-test/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/engine/SQLNodeConvertEngineParameterizedTest.java b/shardingsphere-test/shardingsphere-optimize-test/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/engine/SQLNodeConvertEngineParameterizedTest.java
index 024042d..c46407b 100644
--- a/shardingsphere-test/shardingsphere-optimize-test/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/engine/SQLNodeConvertEngineParameterizedTest.java
+++ b/shardingsphere-test/shardingsphere-optimize-test/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/engine/SQLNodeConvertEngineParameterizedTest.java
@@ -83,6 +83,7 @@ public final class SQLNodeConvertEngineParameterizedTest {
SUPPORTED_SQL_CASE_IDS.add("select_group_by_with_limit");
SUPPORTED_SQL_CASE_IDS.add("select_left_outer_join_related_with_alias");
SUPPORTED_SQL_CASE_IDS.add("select_right_outer_join_related_with_alias");
+ SUPPORTED_SQL_CASE_IDS.add("select_alias_as_keyword");
}
private final String sqlCaseId;