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 c27e8da6bf2 Support bind functionSegment (#28226)
c27e8da6bf2 is described below
commit c27e8da6bf22aa17151e43df8c6e0a51bd1548c7
Author: Chuxin Chen <[email protected]>
AuthorDate: Wed Aug 23 10:54:26 2023 +0800
Support bind functionSegment (#28226)
---
.../expression/ExpressionSegmentBinder.java | 5 ++
.../impl/FunctionExpressionSegmentBinder.java | 54 ++++++++++++++++++++++
.../statement/SelectStatementBinderTest.java | 24 ++++++++++
3 files changed, 83 insertions(+)
diff --git
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/ExpressionSegmentBinder.java
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/ExpressionSegmentBinder.java
index 6d262c4026f..01108f954a4 100644
---
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/ExpressionSegmentBinder.java
+++
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/ExpressionSegmentBinder.java
@@ -22,6 +22,7 @@ import lombok.NoArgsConstructor;
import
org.apache.shardingsphere.infra.binder.segment.expression.impl.BinaryOperationExpressionBinder;
import
org.apache.shardingsphere.infra.binder.segment.expression.impl.ColumnSegmentBinder;
import
org.apache.shardingsphere.infra.binder.segment.expression.impl.ExistsSubqueryExpressionBinder;
+import
org.apache.shardingsphere.infra.binder.segment.expression.impl.FunctionExpressionSegmentBinder;
import
org.apache.shardingsphere.infra.binder.segment.expression.impl.InExpressionBinder;
import
org.apache.shardingsphere.infra.binder.segment.expression.impl.NotExpressionBinder;
import
org.apache.shardingsphere.infra.binder.segment.expression.impl.SubqueryExpressionSegmentBinder;
@@ -31,6 +32,7 @@ import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.Column
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.FunctionSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.InExpression;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.NotExpression;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubqueryExpressionSegment;
@@ -72,6 +74,9 @@ public final class ExpressionSegmentBinder {
if (segment instanceof ColumnSegment) {
return ColumnSegmentBinder.bind((ColumnSegment) segment,
statementBinderContext, tableBinderContexts, outerTableBinderContexts);
}
+ if (segment instanceof FunctionSegment) {
+ return FunctionExpressionSegmentBinder.bind((FunctionSegment)
segment, statementBinderContext, tableBinderContexts, outerTableBinderContexts);
+ }
// TODO support more ExpressionSegment bind
return segment;
}
diff --git
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/FunctionExpressionSegmentBinder.java
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/FunctionExpressionSegmentBinder.java
new file mode 100644
index 00000000000..7eba90e82b0
--- /dev/null
+++
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/FunctionExpressionSegmentBinder.java
@@ -0,0 +1,54 @@
+/*
+ * 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.binder.segment.expression.impl;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import
org.apache.shardingsphere.infra.binder.segment.expression.ExpressionSegmentBinder;
+import
org.apache.shardingsphere.infra.binder.segment.from.TableSegmentBinderContext;
+import
org.apache.shardingsphere.infra.binder.statement.SQLStatementBinderContext;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment;
+
+import java.util.Map;
+
+/**
+ * Function expression binder.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class FunctionExpressionSegmentBinder {
+
+ /**
+ * Bind function expression with metadata.
+ *
+ * @param segment function expression segment
+ * @param statementBinderContext statement binder context
+ * @param tableBinderContexts table binder contexts
+ * @param outerTableBinderContexts outer table binder contexts
+ * @return function segment
+ */
+ public static FunctionSegment bind(final FunctionSegment segment, final
SQLStatementBinderContext statementBinderContext,
+ final Map<String,
TableSegmentBinderContext> tableBinderContexts, final Map<String,
TableSegmentBinderContext> outerTableBinderContexts) {
+ FunctionSegment result = new FunctionSegment(segment.getStartIndex(),
segment.getStopIndex(), segment.getFunctionName(), segment.getText());
+ result.setOwner(segment.getOwner());
+ for (ExpressionSegment each : segment.getParameters()) {
+ result.getParameters().add(ExpressionSegmentBinder.bind(each,
statementBinderContext, tableBinderContexts, outerTableBinderContexts));
+ }
+ return result;
+ }
+}
diff --git
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/SelectStatementBinderTest.java
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/SelectStatementBinderTest.java
index 3318f3af2f2..e5a2cfa9f9d 100644
---
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/SelectStatementBinderTest.java
+++
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/SelectStatementBinderTest.java
@@ -23,9 +23,13 @@ import
org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereColumn;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
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.predicate.WhereSegment;
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.statement.dml.SelectStatement;
@@ -39,8 +43,10 @@ import java.util.Arrays;
import java.util.List;
import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -60,6 +66,7 @@ class SelectStatementBinderTest {
projections.getProjections().add(statusProjection);
SimpleTableSegment simpleTableSegment = new SimpleTableSegment(new
TableNameSegment(0, 0, new IdentifierValue("t_order")));
selectStatement.setFrom(simpleTableSegment);
+ selectStatement.setWhere(mockWhereSegment());
SelectStatement actual = new
SelectStatementBinder().bind(selectStatement, createMetaData(),
DefaultDatabase.LOGIC_NAME);
assertThat(actual, not(selectStatement));
assertThat(actual.getFrom(), not(selectStatement.getFrom()));
@@ -77,6 +84,23 @@ class SelectStatementBinderTest {
assertThat(actualProjections.get(2), not(statusProjection));
assertThat(actualProjections.get(2),
instanceOf(ColumnProjectionSegment.class));
assertThat(((ColumnProjectionSegment)
actualProjections.get(2)).getColumn(), not(statusProjection.getColumn()));
+ assertTrue(actual.getWhere().isPresent());
+ assertThat(actual.getWhere().get(), not(selectStatement.getWhere()));
+ assertThat(actual.getWhere().get(), instanceOf(WhereSegment.class));
+ assertTrue(selectStatement.getWhere().isPresent());
+ assertThat(actual.getWhere().get().getExpr(),
not(selectStatement.getWhere().get().getExpr()));
+ assertThat(actual.getWhere().get().getExpr(),
instanceOf(BinaryOperationExpression.class));
+ assertThat(((BinaryOperationExpression)
actual.getWhere().get().getExpr()).getLeft(),
instanceOf(FunctionSegment.class));
+ assertThat(((FunctionSegment) ((BinaryOperationExpression)
actual.getWhere().get().getExpr()).getLeft()).getParameters().iterator().next(),
instanceOf(ColumnSegment.class));
+ assertThat(((ColumnSegment) ((FunctionSegment)
((BinaryOperationExpression)
actual.getWhere().get().getExpr()).getLeft()).getParameters().iterator().next())
+ .getColumnBoundedInfo().getOriginalTable().getValue(),
is("t_order"));
+ }
+
+ private static WhereSegment mockWhereSegment() {
+ FunctionSegment functionSegment = new FunctionSegment(0, 0, "nvl",
"nvl(status, 0)");
+ functionSegment.getParameters().add(new ColumnSegment(0, 0, new
IdentifierValue("status")));
+ functionSegment.getParameters().add(new LiteralExpressionSegment(0, 0,
0));
+ return new WhereSegment(0, 0, new BinaryOperationExpression(0, 0,
functionSegment, new LiteralExpressionSegment(0, 0, 0), "=", "nvl(status, 0) =
0"));
}
private ShardingSphereMetaData createMetaData() {