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 4ce37f5a1cd Support '2'::int statement in PostgreSQL and openGauss
(#37962)
4ce37f5a1cd is described below
commit 4ce37f5a1cd4efba9154da946794fd11a9e5b0f1
Author: Claire <[email protected]>
AuthorDate: Sun Feb 8 10:34:05 2026 +0800
Support '2'::int statement in PostgreSQL and openGauss (#37962)
* support new function
* realese-notes
* npe
* npe
* support Expression
* support new function
* update code
* update code
---
RELEASE-NOTES.md | 1 +
.../select/pagination/PaginationContext.java | 71 +++++++
.../segment/limit/PaginationValueSQLConverter.java | 12 +-
.../main/antlr4/imports/opengauss/DMLStatement.g4 | 6 +-
.../statement/OpenGaussStatementVisitor.java | 39 ++--
.../main/antlr4/imports/postgresql/DMLStatement.g4 | 6 +-
.../statement/PostgreSQLStatementVisitor.java | 39 ++--
.../ExpressionPaginationValueSegment.java | 28 +--
.../limit/ExpressionLimitValueSegment.java | 25 +--
.../asserts/segment/limit/LimitClauseAssert.java | 5 +
.../impl/limit/ExpectedPaginationValue.java | 3 +
.../parser/src/main/resources/case/dml/select.xml | 225 +++++++++++++++++++++
.../main/resources/sql/supported/dml/select.xml | 16 ++
13 files changed, 401 insertions(+), 75 deletions(-)
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 57ebd82d78b..7d1c30cdca7 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -10,6 +10,7 @@
2. SQL Parser: Fix escape '\' in SQL causing DialectSQLParsingException -
[#37943](https://github.com/apache/shardingsphere/pull/37943)
3. SQL Parser: Fix error parsing \l command SQL statement when front-end
protocol is og - [#37953](https://github.com/apache/shardingsphere/pull/37953)
4. SQL Parser:Fix SQLParsingException when using reserved word `order` in
ORDER BY clause - [#37958](https://github.com/apache/shardingsphere/pull/37958)
+5. SQL Parser:Support '2'::int statement in PostgreSQL and openGauss -
[#37962](https://github.com/apache/shardingsphere/pull/37962)
## Release 5.5.3
diff --git
a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/PaginationContext.java
b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/PaginationContext.java
index a468039d49a..d269e8a849a 100644
---
a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/PaginationContext.java
+++
b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/PaginationContext.java
@@ -19,9 +19,15 @@ package
org.apache.shardingsphere.infra.binder.context.segment.select.pagination
import lombok.Getter;
import
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BinaryOperationExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.CaseWhenExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.NumberLiteralPaginationValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.PaginationValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.ParameterMarkerPaginationValueSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.ExpressionPaginationValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.rownum.ExpressionRowNumberValueSegment;
@@ -63,9 +69,74 @@ public final class PaginationContext {
if (paginationValueSegment instanceof ExpressionRowNumberValueSegment)
{
return ((ExpressionRowNumberValueSegment)
paginationValueSegment).getValue(params);
}
+ if (paginationValueSegment instanceof
ExpressionPaginationValueSegment) {
+ Long result =
getValueFromExpression(((ExpressionPaginationValueSegment)
paginationValueSegment).getExpression(), params);
+ return result;
+ }
return ((NumberLiteralPaginationValueSegment)
paginationValueSegment).getValue();
}
+ private Long getValueFromExpression(final ExpressionSegment
expressionSegment, final List<Object> params) {
+ if (expressionSegment instanceof BinaryOperationExpression) {
+ return
getValueFromBinaryOperationExpression((BinaryOperationExpression)
expressionSegment, params);
+ }
+ if (expressionSegment instanceof CaseWhenExpression) {
+ return getValueFromCaseWhenExpression((CaseWhenExpression)
expressionSegment, params);
+ }
+ return null;
+ }
+
+ private Long getValueFromBinaryOperationExpression(final
BinaryOperationExpression binaryOperationExpression, final List<Object> params)
{
+ Long left =
getValueFromExpression(binaryOperationExpression.getLeft(), params);
+ Long right =
getValueFromExpression(binaryOperationExpression.getRight(), params);
+ if (null == left || null == right) {
+ return null;
+ }
+ switch (binaryOperationExpression.getOperator()) {
+ case "+":
+ return left + right;
+ case "-":
+ return left - right;
+ case "*":
+ return left * right;
+ case "/":
+ return 0L == right ? null : left / right;
+ default:
+ return null;
+ }
+ }
+
+ private Long getValueFromCaseWhenExpression(final CaseWhenExpression
caseWhenExpression, final List<Object> params) {
+ if (null != caseWhenExpression.getCaseExpr()) {
+ return null;
+ }
+ java.util.Iterator<ExpressionSegment> whenIterator =
caseWhenExpression.getWhenExprs().iterator();
+ java.util.Iterator<ExpressionSegment> thenIterator =
caseWhenExpression.getThenExprs().iterator();
+ while (whenIterator.hasNext() && thenIterator.hasNext()) {
+ Boolean whenValue =
getBooleanValueFromExpression(whenIterator.next(), params);
+ if (Boolean.TRUE.equals(whenValue)) {
+ return getValueFromExpression(thenIterator.next(), params);
+ }
+ thenIterator.next();
+ }
+ return null == caseWhenExpression.getElseExpr() ? null :
getValueFromExpression(caseWhenExpression.getElseExpr(), params);
+ }
+
+ private Boolean getBooleanValueFromExpression(final ExpressionSegment
expressionSegment, final List<Object> params) {
+ if (expressionSegment instanceof LiteralExpressionSegment) {
+ Object literals = ((LiteralExpressionSegment)
expressionSegment).getLiterals();
+ if (literals instanceof Boolean) {
+ return (Boolean) literals;
+ }
+ return null == literals ? null :
Boolean.parseBoolean(literals.toString());
+ }
+ if (expressionSegment instanceof ParameterMarkerExpressionSegment) {
+ Object obj = null == params || params.isEmpty() ? null :
params.get(((ParameterMarkerExpressionSegment)
expressionSegment).getParameterMarkerIndex());
+ return null == obj ? null : Boolean.parseBoolean(obj.toString());
+ }
+ return null;
+ }
+
/**
* Get offset segment.
*
diff --git
a/kernel/sql-federation/compiler/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/limit/PaginationValueSQLConverter.java
b/kernel/sql-federation/compiler/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/limit/PaginationValueSQLConverter.java
index 5cd3191af9a..14add58f9c4 100644
---
a/kernel/sql-federation/compiler/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/limit/PaginationValueSQLConverter.java
+++
b/kernel/sql-federation/compiler/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/limit/PaginationValueSQLConverter.java
@@ -23,9 +23,11 @@ import org.apache.calcite.sql.SqlDynamicParam;
import org.apache.calcite.sql.SqlLiteral;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.parser.SqlParserPos;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.ExpressionPaginationValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.NumberLiteralPaginationValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.PaginationValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.ParameterMarkerLimitValueSegment;
+import
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.ExpressionConverter;
import java.util.Optional;
@@ -42,9 +44,13 @@ public final class PaginationValueSQLConverter {
* @return SQL node
*/
public static Optional<SqlNode> convert(final PaginationValueSegment
segment) {
- return Optional.of(segment instanceof
NumberLiteralPaginationValueSegment
- ? getLiteralSQLNode((NumberLiteralPaginationValueSegment)
segment)
- : getParameterMarkerSQLNode((ParameterMarkerLimitValueSegment)
segment));
+ if (segment instanceof NumberLiteralPaginationValueSegment) {
+ return
Optional.of(getLiteralSQLNode((NumberLiteralPaginationValueSegment) segment));
+ }
+ if (segment instanceof ExpressionPaginationValueSegment) {
+ return
ExpressionConverter.convert(((ExpressionPaginationValueSegment)
segment).getExpression());
+ }
+ return
Optional.of(getParameterMarkerSQLNode((ParameterMarkerLimitValueSegment)
segment));
}
private static SqlNode getLiteralSQLNode(final
NumberLiteralPaginationValueSegment segment) {
diff --git
a/parser/sql/engine/dialect/opengauss/src/main/antlr4/imports/opengauss/DMLStatement.g4
b/parser/sql/engine/dialect/opengauss/src/main/antlr4/imports/opengauss/DMLStatement.g4
index 0fdc1759e9a..9d4cf614e17 100644
---
a/parser/sql/engine/dialect/opengauss/src/main/antlr4/imports/opengauss/DMLStatement.g4
+++
b/parser/sql/engine/dialect/opengauss/src/main/antlr4/imports/opengauss/DMLStatement.g4
@@ -231,15 +231,15 @@ offsetClause
selectLimitValue
: ALL
- | cExpr
+ | aExpr
;
selectOffsetValue
- : cExpr
+ : aExpr
;
selectFetchValue
- : cExpr
+ : aExpr
;
rowOrRows
diff --git
a/parser/sql/engine/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/engine/opengauss/visitor/statement/OpenGaussStatementVisitor.java
b/parser/sql/engine/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/engine/opengauss/visitor/statement/OpenGaussStatementVisitor.java
index 5528c5d7137..ea7b38f7885 100644
---
a/parser/sql/engine/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/engine/opengauss/visitor/statement/OpenGaussStatementVisitor.java
+++
b/parser/sql/engine/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/engine/opengauss/visitor/statement/OpenGaussStatementVisitor.java
@@ -167,6 +167,7 @@ import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.ite
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.OrderByItemSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitValueSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.ExpressionLimitValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.NumberLiteralLimitValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.ParameterMarkerLimitValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.HavingSegment;
@@ -444,7 +445,7 @@ public abstract class OpenGaussStatementVisitor extends
OpenGaussStatementParser
}
ExpressionSegment caseExpr = null == ctx.caseArg() ? null :
(ExpressionSegment) visit(ctx.caseArg().aExpr());
ExpressionSegment elseExpr = null == ctx.caseDefault() ? null :
(ExpressionSegment) visit(ctx.caseDefault().aExpr());
- return new CaseWhenExpression(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), caseExpr, whenExprs, thenExprs, elseExpr);
+ return new CaseWhenExpression(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), caseExpr, whenExprs, thenExprs, elseExpr,
getOriginalText(ctx));
}
@Override
@@ -1393,29 +1394,37 @@ public abstract class OpenGaussStatementVisitor extends
OpenGaussStatementParser
if (null != ctx.ALL()) {
return null;
}
- ASTNode astNode = visit(ctx.cExpr());
- if (astNode instanceof ParameterMarkerExpressionSegment) {
- return new
ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment)
astNode).getParameterMarkerIndex());
- }
- return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(), Long.parseLong(((ExpressionSegment)
astNode).getText()));
+ return createLimitValueSegment(ctx, (ExpressionSegment)
visit(ctx.aExpr()));
}
@Override
public ASTNode visitSelectOffsetValue(final SelectOffsetValueContext ctx) {
- ASTNode astNode = visit(ctx.cExpr());
- if (astNode instanceof ParameterMarkerExpressionSegment) {
- return new
ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment)
astNode).getParameterMarkerIndex());
- }
- return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(), Long.parseLong(((ExpressionSegment)
astNode).getText()));
+ return createLimitValueSegment(ctx, (ExpressionSegment)
visit(ctx.aExpr()));
}
@Override
public ASTNode visitSelectFetchValue(final SelectFetchValueContext ctx) {
- ASTNode astNode = visit(ctx.cExpr());
- if (astNode instanceof ParameterMarkerExpressionSegment) {
- return new
ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment)
astNode).getParameterMarkerIndex());
+ return createLimitValueSegment(ctx, (ExpressionSegment)
visit(ctx.aExpr()));
+ }
+
+ private LimitValueSegment createLimitValueSegment(final ParserRuleContext
ctx, final ExpressionSegment segment) {
+ if (segment instanceof ParameterMarkerExpressionSegment) {
+ return new
ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(),
+ ((ParameterMarkerExpressionSegment)
segment).getParameterMarkerIndex());
+ }
+ if (segment instanceof TypeCastExpression) {
+ return createLimitValueSegment(ctx, ((TypeCastExpression)
segment).getExpression());
+ }
+ if (segment instanceof LiteralExpressionSegment) {
+ Object literals = ((LiteralExpressionSegment)
segment).getLiterals();
+ if (null == literals) {
+ return ctx instanceof SelectOffsetValueContext
+ ? new
NumberLiteralLimitValueSegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(), 0L)
+ : null;
+ }
+ return new
NumberLiteralLimitValueSegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(), Long.parseLong(literals.toString()));
}
- return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(), Long.parseLong(((ExpressionSegment)
astNode).getText()));
+ return new ExpressionLimitValueSegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(), segment);
}
private LimitSegment createLimitSegmentWhenLimitAndOffset(final
SelectLimitContext ctx) {
diff --git
a/parser/sql/engine/dialect/postgresql/src/main/antlr4/imports/postgresql/DMLStatement.g4
b/parser/sql/engine/dialect/postgresql/src/main/antlr4/imports/postgresql/DMLStatement.g4
index 84810a50658..c11974f4465 100644
---
a/parser/sql/engine/dialect/postgresql/src/main/antlr4/imports/postgresql/DMLStatement.g4
+++
b/parser/sql/engine/dialect/postgresql/src/main/antlr4/imports/postgresql/DMLStatement.g4
@@ -233,16 +233,16 @@ offsetClause
;
selectLimitValue
- : cExpr
+ : aExpr
| ALL
;
selectOffsetValue
- : cExpr
+ : aExpr
;
selectFetchValue
- : cExpr
+ : aExpr
;
rowOrRows
diff --git
a/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
b/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
index baa911fc8a3..2a686e88638 100644
---
a/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
+++
b/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
@@ -168,6 +168,7 @@ import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.ite
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.OrderByItemSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitValueSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.ExpressionLimitValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.NumberLiteralLimitValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.ParameterMarkerLimitValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.HavingSegment;
@@ -445,7 +446,7 @@ public abstract class PostgreSQLStatementVisitor extends
PostgreSQLStatementPars
}
ExpressionSegment caseExpr = null == ctx.caseArg() ? null :
(ExpressionSegment) visit(ctx.caseArg().aExpr());
ExpressionSegment elseExpr = null == ctx.caseDefault() ? null :
(ExpressionSegment) visit(ctx.caseDefault().aExpr());
- return new CaseWhenExpression(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), caseExpr, whenExprs, thenExprs, elseExpr);
+ return new CaseWhenExpression(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), caseExpr, whenExprs, thenExprs, elseExpr,
getOriginalText(ctx));
}
@Override
@@ -1361,32 +1362,34 @@ public abstract class PostgreSQLStatementVisitor
extends PostgreSQLStatementPars
if (null != ctx.ALL()) {
return null;
}
- ASTNode astNode = visit(ctx.cExpr());
- if (astNode instanceof ParameterMarkerExpressionSegment) {
- return new
ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment)
astNode).getParameterMarkerIndex());
- }
- return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(),
- (null == ((ExpressionSegment) astNode).getText()) ? null :
Long.parseLong(((ExpressionSegment) astNode).getText()));
+ return createLimitValueSegment(ctx, (ExpressionSegment)
visit(ctx.aExpr()));
}
@Override
public ASTNode visitSelectOffsetValue(final SelectOffsetValueContext ctx) {
- ASTNode astNode = visit(ctx.cExpr());
- if (astNode instanceof ParameterMarkerExpressionSegment) {
- return new
ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment)
astNode).getParameterMarkerIndex());
- }
- return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(),
- (null == ((ExpressionSegment) astNode).getText()) ? null :
Long.parseLong(((ExpressionSegment) astNode).getText()));
+ return createLimitValueSegment(ctx, (ExpressionSegment)
visit(ctx.aExpr()));
}
@Override
public ASTNode visitSelectFetchValue(final SelectFetchValueContext ctx) {
- ASTNode astNode = visit(ctx.cExpr());
- if (astNode instanceof ParameterMarkerExpressionSegment) {
- return new
ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment)
astNode).getParameterMarkerIndex());
+ return createLimitValueSegment(ctx, (ExpressionSegment)
visit(ctx.aExpr()));
+ }
+
+ private LimitValueSegment createLimitValueSegment(final ParserRuleContext
ctx, final ExpressionSegment segment) {
+ if (segment instanceof ParameterMarkerExpressionSegment) {
+ return new
ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment)
segment).getParameterMarkerIndex());
+ }
+ if (segment instanceof TypeCastExpression) {
+ return createLimitValueSegment(ctx, ((TypeCastExpression)
segment).getExpression());
+ }
+ if (segment instanceof LiteralExpressionSegment) {
+ Object literals = ((LiteralExpressionSegment)
segment).getLiterals();
+ if (null == literals) {
+ return ctx instanceof SelectOffsetValueContext ? new
NumberLiteralLimitValueSegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(), 0L) : null;
+ }
+ return new
NumberLiteralLimitValueSegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(), Long.parseLong(literals.toString()));
}
- return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(),
- (null == ((ExpressionSegment) astNode).getText()) ? null :
Long.parseLong(((ExpressionSegment) astNode).getText()));
+ return new ExpressionLimitValueSegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(), segment);
}
private LimitSegment createLimitSegmentWhenLimitAndOffset(final
SelectLimitContext ctx) {
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/limit/ExpectedPaginationValue.java
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/dml/pagination/ExpressionPaginationValueSegment.java
similarity index 54%
copy from
test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/limit/ExpectedPaginationValue.java
copy to
parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/dml/pagination/ExpressionPaginationValueSegment.java
index a29e568fdc0..ac8d791328e 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/limit/ExpectedPaginationValue.java
+++
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/dml/pagination/ExpressionPaginationValueSegment.java
@@ -15,27 +15,19 @@
* limitations under the License.
*/
-package
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.limit;
+package
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination;
-import lombok.Getter;
-import lombok.Setter;
-import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.AbstractExpectedSQLSegment;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
/**
- * Expected pagination value.
+ * Pagination value segment for expression.
*/
-@XmlAccessorType(XmlAccessType.FIELD)
-@Getter
-@Setter
-public final class ExpectedPaginationValue extends AbstractExpectedSQLSegment {
-
- @XmlAttribute
- private Long value;
+public interface ExpressionPaginationValueSegment extends
PaginationValueSegment {
- @XmlAttribute(name = "parameter-index")
- private Integer parameterIndex;
+ /**
+ * Get expression segment.
+ *
+ * @return expression segment
+ */
+ ExpressionSegment getExpression();
}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/limit/ExpectedPaginationValue.java
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/dml/pagination/limit/ExpressionLimitValueSegment.java
similarity index 54%
copy from
test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/limit/ExpectedPaginationValue.java
copy to
parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/dml/pagination/limit/ExpressionLimitValueSegment.java
index a29e568fdc0..8da097054ef 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/limit/ExpectedPaginationValue.java
+++
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/dml/pagination/limit/ExpressionLimitValueSegment.java
@@ -15,27 +15,22 @@
* limitations under the License.
*/
-package
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.limit;
+package
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit;
import lombok.Getter;
-import lombok.Setter;
-import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.AbstractExpectedSQLSegment;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.ExpressionPaginationValueSegment;
/**
- * Expected pagination value.
+ * Limit value segment for expression.
*/
-@XmlAccessorType(XmlAccessType.FIELD)
@Getter
-@Setter
-public final class ExpectedPaginationValue extends AbstractExpectedSQLSegment {
+public final class ExpressionLimitValueSegment extends LimitValueSegment
implements ExpressionPaginationValueSegment {
- @XmlAttribute
- private Long value;
+ private final ExpressionSegment expression;
- @XmlAttribute(name = "parameter-index")
- private Integer parameterIndex;
+ public ExpressionLimitValueSegment(final int startIndex, final int
stopIndex, final ExpressionSegment expression) {
+ super(startIndex, stopIndex);
+ this.expression = expression;
+ }
}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/limit/LimitClauseAssert.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/limit/LimitClauseAssert.java
index 655159d21cd..dafb216f8ac 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/limit/LimitClauseAssert.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/limit/LimitClauseAssert.java
@@ -22,6 +22,7 @@ import lombok.NoArgsConstructor;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.NumberLiteralPaginationValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.PaginationValueSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.ParameterMarkerPaginationValueSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.ExpressionPaginationValueSegment;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.SQLSegmentAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.limit.ExpectedPaginationValue;
@@ -52,6 +53,8 @@ public final class LimitClauseAssert {
if (actual instanceof ParameterMarkerPaginationValueSegment) {
assertThat(assertContext.getText("Offset index assertion error: "),
((ParameterMarkerPaginationValueSegment)
actual).getParameterIndex(), is(expected.getParameterIndex()));
+ } else if (actual instanceof ExpressionPaginationValueSegment) {
+ assertThat(assertContext.getText("Offset expression assertion
error: "), ((ExpressionPaginationValueSegment)
actual).getExpression().getText(), is(expected.getExpression()));
} else {
assertThat(assertContext.getText("Offset value assertion error:
"), ((NumberLiteralPaginationValueSegment) actual).getValue(),
is(expected.getValue()));
}
@@ -73,6 +76,8 @@ public final class LimitClauseAssert {
if (SQLCaseType.PLACEHOLDER == assertContext.getCaseType()) {
assertThat(assertContext.getText("Row count index assertion error:
"),
((ParameterMarkerPaginationValueSegment)
actual).getParameterIndex(), is(expected.getParameterIndex()));
+ } else if (actual instanceof ExpressionPaginationValueSegment) {
+ assertThat(assertContext.getText("Row count expression assertion
error: "), ((ExpressionPaginationValueSegment)
actual).getExpression().getText(), is(expected.getExpression()));
} else {
assertThat(assertContext.getText("Row count value assertion error:
"), ((NumberLiteralPaginationValueSegment) actual).getValue(),
is(expected.getValue()));
}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/limit/ExpectedPaginationValue.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/limit/ExpectedPaginationValue.java
index a29e568fdc0..70026686012 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/limit/ExpectedPaginationValue.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/limit/ExpectedPaginationValue.java
@@ -36,6 +36,9 @@ public final class ExpectedPaginationValue extends
AbstractExpectedSQLSegment {
@XmlAttribute
private Long value;
+ @XmlAttribute
+ private String expression;
+
@XmlAttribute(name = "parameter-index")
private Integer parameterIndex;
}
diff --git a/test/it/parser/src/main/resources/case/dml/select.xml
b/test/it/parser/src/main/resources/case/dml/select.xml
index 43833d5a56d..cb0f0387d4a 100644
--- a/test/it/parser/src/main/resources/case/dml/select.xml
+++ b/test/it/parser/src/main/resources/case/dml/select.xml
@@ -13802,4 +13802,229 @@
<index-item index="1" start-index="291" stop-index="291"/>
</order-by>
</select>
+
+ <select sql-case-id="select_pg_int">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="30">
+ <row-count value="2" start-index="23" stop-index="30">
+ <type-cast-expression>
+ <expression>
+ <literal-expression value="2" start-index="23"
stop-index="25" />
+ </expression>
+ <data-type>int</data-type>
+ </type-cast-expression>
+ </row-count>
+ </limit>
+ </select>
+
+ <select sql-case-id="select_pg_offset_int">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="32">
+ <offset value="10" start-index="24" stop-index="32">
+ <type-cast-expression>
+ <expression>
+ <literal-expression value="10" start-index="25"
stop-index="27" />
+ </expression>
+ <data-type>int</data-type>
+ </type-cast-expression>
+ </offset>
+ </limit>
+ </select>
+
+ <select sql-case-id="select_pg_fetch_next_int">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <order-by start-index="17" stop-index="27">
+ <column-item name="id" order-direction="ASC" start-index="26"
stop-index="27" />
+ </order-by>
+ <limit start-index="29" stop-index="60">
+ <row-count value="10" start-index="40" stop-index="50">
+ <type-cast-expression>
+ <expression>
+ <literal-expression value="10" start-index="41"
stop-index="43" />
+ </expression>
+ <data-type>int</data-type>
+ </type-cast-expression>
+ </row-count>
+ </limit>
+ </select>
+
+ <select sql-case-id="select_limit_constant">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="24">
+ <row-count value="10" start-index="23" stop-index="24" />
+ </limit>
+ </select>
+
+ <select sql-case-id="select_limit_all">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="25" />
+ </select>
+
+ <select sql-case-id="select_limit_null">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="26" />
+ </select>
+
+ <select sql-case-id="select_limit_expression">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="29">
+ <row-count expression="5 + 3" start-index="23" stop-index="29" />
+ </limit>
+ </select>
+
+ <select sql-case-id="select_limit_cast">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="36">
+ <row-count value="8" start-index="23" stop-index="36" />
+ </limit>
+ </select>
+
+ <select sql-case-id="select_limit_subquery">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="48">
+ <row-count expression="(SELECT 6 FROM t4 LIMIT 1)"
start-index="23" stop-index="48" />
+ </limit>
+ </select>
+
+ <select sql-case-id="select_offset_constant">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="34">
+ <offset value="5" start-index="34" stop-index="34" />
+ </limit>
+ </select>
+
+ <select sql-case-id="select_offset_null">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="36">
+ <row-count value="10" start-index="23" stop-index="24" />
+ <offset value="0" start-index="33" stop-index="36">
+ <literal-expression value="NULL" start-index="33"
stop-index="36" />
+ </offset>
+ </limit>
+ </select>
+
+ <select sql-case-id="select_offset_expression">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="40">
+ <row-count value="10" start-index="23" stop-index="24" />
+ <offset expression="10 - 2" start-index="33" stop-index="40" />
+ </limit>
+ </select>
+
+ <select sql-case-id="select_offset_cast_string">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="40">
+ <row-count value="10" start-index="23" stop-index="24" />
+ <offset value="8" start-index="33" stop-index="40">
+ <type-cast-expression>
+ <expression>
+ <literal-expression value="8" start-index="33"
stop-index="35" />
+ </expression>
+ <data-type>int</data-type>
+ </type-cast-expression>
+ </offset>
+ </limit>
+ </select>
+
+ <select sql-case-id="select_limit_offset_combined">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="33">
+ <row-count value="5" start-index="23" stop-index="23" />
+ <offset value="10" start-index="32" stop-index="33" />
+ </limit>
+ </select>
+
+ <select sql-case-id="select_limit_parameter" parameters="1">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="23">
+ <row-count value="1" parameter-index="0" start-index="23"
stop-index="23" />
+ </limit>
+ </select>
+
+ <select sql-case-id="select_limit_complex_expr">
+ <from>
+ <simple-table name="t4" start-index="14" stop-index="15" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <limit start-index="17" stop-index="58">
+ <row-count expression="CASE WHEN true THEN 10 ELSE 20 END"
start-index="23" stop-index="58" />
+ </limit>
+ </select>
</sql-parser-test-cases>
diff --git a/test/it/parser/src/main/resources/sql/supported/dml/select.xml
b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
index 4a7d30cdd3e..e4d0deff06c 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
@@ -498,4 +498,20 @@
<sql-case id="select_order_by_order" value="SELECT id FROM test ORDER BY
`order` " db-types="MySQL,Hive,Doris,Presto" />
<sql-case id="select_order_by_order_two" value="SELECT id FROM t_test
ORDER BY t_test.order"
db-types="MySQL,Hive,Doris,SQLServer,Firebird,SQL92,Presto" />
<sql-case id="select_pg_database_info" value="SELECT d.datname as
"Name", pg_catalog.pg_get_userbyid(d.datdba) as "Owner",
pg_catalog.pg_encoding_to_char(d.encoding) as "Encoding",
d.datcollate as "Collate", d.datctype as "Ctype",
pg_catalog.array_to_string(d.datacl, E'\n') AS "Access privileges"
FROM pg_catalog.pg_database d ORDER BY 1;" db-types="openGauss" />
+ <sql-case id="select_pg_int" value="SELECT * FROM t4 LIMIT '2'::int;"
db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_pg_offset_int" value="SELECT * FROM t4 OFFSET
'10'::int;" db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_pg_fetch_next_int" value="SELECT * FROM t4 ORDER BY
id FETCH NEXT ('10'::int) ROWS ONLY;" db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_limit_constant" value="SELECT * FROM t4 LIMIT 10;"
db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_limit_all" value="SELECT * FROM t4 LIMIT ALL;"
db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_limit_null" value="SELECT * FROM t4 LIMIT NULL;"
db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_limit_cast" value="SELECT * FROM t4 LIMIT CAST(8 AS
int);" db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_limit_expression" value="SELECT * FROM t4 LIMIT (5 +
3);" db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_limit_subquery" value="SELECT * FROM t4 LIMIT (SELECT
6 FROM t4 LIMIT 1);" db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_offset_constant" value="SELECT * FROM t4 LIMIT ALL
OFFSET 5;" db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_offset_null" value="SELECT * FROM t4 LIMIT 10 OFFSET
NULL;" db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_offset_expression" value="SELECT * FROM t4 LIMIT 10
OFFSET (10 - 2);" db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_offset_cast_string" value="SELECT * FROM t4 LIMIT 10
OFFSET '8'::int;" db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_limit_offset_combined" value="SELECT * FROM t4 LIMIT
5 OFFSET 10;" db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_limit_parameter" value="SELECT * FROM t4 LIMIT ?;"
db-types="PostgreSQL,openGauss" />
+ <sql-case id="select_limit_complex_expr" value="SELECT * FROM t4 LIMIT
(CASE WHEN true THEN 10 ELSE 20 END);" db-types="PostgreSQL,openGauss" />
</sql-cases>