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 77f43c39d64 support oracle page with parameter cal expression (#30299)
77f43c39d64 is described below
commit 77f43c39d64bd341d75f92f04f2514cc5486a9e6
Author: Chuxin Chen <[email protected]>
AuthorDate: Tue Feb 27 09:09:39 2024 +0800
support oracle page with parameter cal expression (#30299)
* support oracle page with parameter cal expression
* support oracle page with parameter cal expression
---
.../select/pagination/PaginationContext.java | 6 ++
.../engine/RowNumberPaginationContextEngine.java | 11 ++-
.../rownum/ExpressionRowNumberValueSegment.java | 78 ++++++++++++++++++++++
.../ExpressionRowNumberValueSegmentTest.java | 53 +++++++++++++++
4 files changed, 145 insertions(+), 3 deletions(-)
diff --git
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/PaginationContext.java
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/PaginationContext.java
index 8fb79ddb64b..d6530bcc86f 100644
---
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/PaginationContext.java
+++
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/PaginationContext.java
@@ -23,6 +23,7 @@ import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.Nu
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.PaginationValueSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.ParameterMarkerPaginationValueSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.limit.LimitValueSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.rownum.ExpressionRowNumberValueSegment;
import java.util.List;
import java.util.Optional;
@@ -56,6 +57,9 @@ public final class PaginationContext {
Object obj = null == params || params.isEmpty() ? 0L :
params.get(((ParameterMarkerPaginationValueSegment)
paginationValueSegment).getParameterIndex());
return obj instanceof Long ? (long) obj : (int) obj;
}
+ if (paginationValueSegment instanceof ExpressionRowNumberValueSegment)
{
+ return ((ExpressionRowNumberValueSegment)
paginationValueSegment).getValue(params);
+ }
return ((NumberLiteralPaginationValueSegment)
paginationValueSegment).getValue();
}
@@ -107,6 +111,7 @@ public final class PaginationContext {
* @return offset parameter index
*/
public Optional<Integer> getOffsetParameterIndex() {
+ // TODO handle offsetSegment instance of
ExpressionRowNumberValueSegment
return offsetSegment instanceof ParameterMarkerPaginationValueSegment
? Optional.of(((ParameterMarkerPaginationValueSegment)
offsetSegment).getParameterIndex()) : Optional.empty();
}
@@ -116,6 +121,7 @@ public final class PaginationContext {
* @return row count parameter index
*/
public Optional<Integer> getRowCountParameterIndex() {
+ // TODO handle offsetSegment instance of
ExpressionRowNumberValueSegment
return rowCountSegment instanceof ParameterMarkerPaginationValueSegment
? Optional.of(((ParameterMarkerPaginationValueSegment)
rowCountSegment).getParameterIndex())
: Optional.empty();
diff --git
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/RowNumberPaginationContextEngine.java
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/RowNumberPaginationContextEngine.java
index 72d266e396a..2cc26aaa460 100644
---
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/RowNumberPaginationContextEngine.java
+++
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/RowNumberPaginationContextEngine.java
@@ -24,6 +24,7 @@ import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOp
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
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.pagination.rownum.ExpressionRowNumberValueSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.rownum.NumberLiteralRowNumberValueSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.rownum.ParameterMarkerRowNumberValueSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.rownum.RowNumberValueSegment;
@@ -137,8 +138,12 @@ public final class RowNumberPaginationContextEngine {
private RowNumberValueSegment createRowNumberValueSegment(final
ExpressionSegment expression, final boolean boundOpened) {
int startIndex = expression.getStartIndex();
int stopIndex = expression.getStopIndex();
- return expression instanceof LiteralExpressionSegment
- ? new NumberLiteralRowNumberValueSegment(startIndex,
stopIndex, (int) ((LiteralExpressionSegment) expression).getLiterals(),
boundOpened)
- : new ParameterMarkerRowNumberValueSegment(startIndex,
stopIndex, ((ParameterMarkerExpressionSegment)
expression).getParameterMarkerIndex(), boundOpened);
+ if (expression instanceof LiteralExpressionSegment) {
+ return new NumberLiteralRowNumberValueSegment(startIndex,
stopIndex, (int) ((LiteralExpressionSegment) expression).getLiterals(),
boundOpened);
+ }
+ if (expression instanceof ParameterMarkerExpressionSegment) {
+ return new ParameterMarkerRowNumberValueSegment(startIndex,
stopIndex, ((ParameterMarkerExpressionSegment)
expression).getParameterMarkerIndex(), boundOpened);
+ }
+ return new ExpressionRowNumberValueSegment(startIndex, stopIndex,
expression, boundOpened);
}
}
diff --git
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/pagination/rownum/ExpressionRowNumberValueSegment.java
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/pagination/rownum/ExpressionRowNumberValueSegment.java
new file mode 100644
index 00000000000..c077ec46a06
--- /dev/null
+++
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/pagination/rownum/ExpressionRowNumberValueSegment.java
@@ -0,0 +1,78 @@
+/*
+ * 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.sql.parser.sql.common.segment.dml.pagination.rownum;
+
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
+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 java.util.List;
+
+/**
+ * Row number value segment for expression.
+ */
+public final class ExpressionRowNumberValueSegment extends
RowNumberValueSegment {
+
+ private final ExpressionSegment expressionSegment;
+
+ public ExpressionRowNumberValueSegment(final int startIndex, final int
stopIndex, final ExpressionSegment expressionSegment, final boolean
boundOpened) {
+ super(startIndex, stopIndex, boundOpened);
+ this.expressionSegment = expressionSegment;
+ }
+
+ /**
+ * Get value.
+ *
+ * @param params parameters
+ * @return value
+ */
+ public Long getValue(final List<Object> params) {
+ return getValueFromExpression(expressionSegment, params);
+ }
+
+ private Long getValueFromExpression(final ExpressionSegment
expressionSegment, final List<Object> params) {
+ if (expressionSegment instanceof ParameterMarkerExpressionSegment) {
+ return null == params || params.isEmpty() ? 0L :
Long.parseLong(params.get(((ParameterMarkerExpressionSegment)
expressionSegment).getParameterMarkerIndex()).toString());
+ }
+ if (expressionSegment instanceof BinaryOperationExpression) {
+ return
getValueFromBinaryOperationExpression((BinaryOperationExpression)
expressionSegment, params);
+ }
+ if (expressionSegment instanceof LiteralExpressionSegment) {
+ return Long.parseLong(expressionSegment.getText());
+ }
+ throw new UnsupportedOperationException(String.format("Unsupported
expression: %s in page expression", expressionSegment.getClass().getName()));
+ }
+
+ private Long getValueFromBinaryOperationExpression(final
BinaryOperationExpression binaryOperationExpression, final List<Object> params)
{
+ String operator = binaryOperationExpression.getOperator();
+ Long leftValue =
getValueFromExpression(binaryOperationExpression.getLeft(), params);
+ Long rightValue =
getValueFromExpression(binaryOperationExpression.getRight(), params);
+ switch (operator) {
+ case "+":
+ return leftValue + rightValue;
+ case "-":
+ return leftValue - rightValue;
+ case "*":
+ return leftValue * rightValue;
+ case "/":
+ return leftValue / rightValue;
+ default:
+ throw new
UnsupportedOperationException(String.format("Unsupported operator: %s in page
expression", operator));
+ }
+ }
+}
diff --git
a/parser/sql/statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/pagination/rownum/ExpressionRowNumberValueSegmentTest.java
b/parser/sql/statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/pagination/rownum/ExpressionRowNumberValueSegmentTest.java
new file mode 100644
index 00000000000..0bb916e20f2
--- /dev/null
+++
b/parser/sql/statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/pagination/rownum/ExpressionRowNumberValueSegmentTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.sql.parser.sql.common.segment.dml.pagination.rownum;
+
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
+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.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+class ExpressionRowNumberValueSegmentTest {
+
+ @Test
+ void assertGetValueWithLiteralExpression() {
+ ExpressionRowNumberValueSegment actual = new
ExpressionRowNumberValueSegment(0, 0, new BinaryOperationExpression(0, 0, new
LiteralExpressionSegment(0, 0, 1),
+ new LiteralExpressionSegment(0, 0, 1), "+", "1 + 1"), false);
+ assertThat(actual.getValue(Collections.emptyList()), is(2L));
+ }
+
+ @Test
+ void assertGetValueWithParameterMarker() {
+ ExpressionRowNumberValueSegment actual = new
ExpressionRowNumberValueSegment(0, 0, new BinaryOperationExpression(0, 0, new
ParameterMarkerExpressionSegment(0, 0, 0),
+ new ParameterMarkerExpressionSegment(0, 0, 1), "+", "? + ?"),
false);
+ assertThat(actual.getValue(Arrays.asList(1, 1)), is(2L));
+ }
+
+ @Test
+ void assertGetValueWithMixed() {
+ ExpressionRowNumberValueSegment actual = new
ExpressionRowNumberValueSegment(0, 0, new BinaryOperationExpression(0, 0, new
LiteralExpressionSegment(0, 0, 1),
+ new BinaryOperationExpression(0, 0, new
ParameterMarkerExpressionSegment(0, 0, 0), new LiteralExpressionSegment(0, 0,
2), "+", "? + 2"), "+", "1 + ? + 2"), false);
+ assertThat(actual.getValue(Collections.singletonList(1)), is(4L));
+ }
+}