This is an automated email from the ASF dual-hosted git repository.
chengzhang 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 684b73718b7 Support Oracle Interval Expression (#27470)
684b73718b7 is described below
commit 684b73718b71c491acc51d96146bcfda5001930b
Author: Zichao <[email protected]>
AuthorDate: Wed Jul 26 17:40:30 2023 +1200
Support Oracle Interval Expression (#27470)
---
.../src/main/antlr4/imports/oracle/BaseRule.g4 | 22 +++++-
.../visitor/statement/OracleStatementVisitor.java | 53 +++++++++++++++
.../statement/type/OracleDMLStatementVisitor.java | 12 ++++
.../dml/expr/IntervalDayToSecondExpression.java | 52 ++++++++++++++
.../dml/expr/IntervalYearToMonthExpression.java | 49 ++++++++++++++
.../dml/item/IntervalExpressionProjection.java | 55 +++++++++++++++
.../segment/expression/ExpressionAssert.java | 79 ++++++++++++++++++++++
.../jaxb/segment/impl/expr/ExpectedExpression.java | 3 +
.../ExpectedIntervalDayToSecondExpression.java | 47 +++++++++++++
.../impl/expr/ExpectedIntervalExpression.java | 48 +++++++++++++
.../ExpectedIntervalYearToMonthExpression.java | 44 ++++++++++++
.../main/resources/case/dml/select-expression.xml | 24 +++++++
.../sql/supported/dml/select-expression.xml | 1 +
13 files changed, 486 insertions(+), 3 deletions(-)
diff --git
a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
index 02407dd05b0..9b212ab3407 100644
--- a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
+++ b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
@@ -661,12 +661,12 @@ bitExpr
| bitExpr SIGNED_LEFT_SHIFT_ bitExpr
| bitExpr SIGNED_RIGHT_SHIFT_ bitExpr
| bitExpr PLUS_ bitExpr
+ | simpleExpr
| bitExpr MINUS_ bitExpr
| bitExpr ASTERISK_ bitExpr
| bitExpr SLASH_ bitExpr
| bitExpr MOD_ bitExpr
| bitExpr CARET_ bitExpr
- | simpleExpr
;
simpleExpr
@@ -790,7 +790,7 @@ regularFunctionName
;
joinOperator
- : LP_ PLUS_ RP_
+ : LP_ PLUS_ RP_
;
caseExpression
@@ -886,7 +886,23 @@ elseClause
;
intervalExpression
- : LP_ expr MINUS_ expr RP_ (DAY (LP_ NUMBER_ RP_)? TO SECOND (LP_ NUMBER_
RP_)? | YEAR (LP_ NUMBER_ RP_)? TO MONTH)
+ : LP_ expr MINUS_ expr RP_ (intervalDayToSecondExpression |
intervalYearToMonthExpression)
+ ;
+
+intervalDayToSecondExpression
+ : DAY (LP_ leadingFieldPrecision RP_)? TO SECOND (LP_
fractionalSecondPrecision RP_)?
+ ;
+
+intervalYearToMonthExpression
+ : YEAR (LP_ leadingFieldPrecision RP_)? TO MONTH
+ ;
+
+leadingFieldPrecision
+ : INTEGER_
+ ;
+
+fractionalSecondPrecision
+ : INTEGER_
;
objectAccessExpression
diff --git
a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/OracleStatementVisitor.java
b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/OracleStatementVisitor.java
index 50f69257f97..7ddca6a0ea3 100644
---
a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/OracleStatementVisitor.java
+++
b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/OracleStatementVisitor.java
@@ -48,6 +48,9 @@ import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.Hexade
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.IdentifierContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.IndexNameContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.IndexTypeNameContext;
+import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.IntervalDayToSecondExpressionContext;
+import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.IntervalExpressionContext;
+import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.IntervalYearToMonthExpressionContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.LiteralsContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.NullValueLiteralsContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.NumberLiteralsContext;
@@ -57,6 +60,7 @@ import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.OwnerC
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.PackageNameContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ParameterMarkerContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.PredicateContext;
+import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.PrivateExprOfDbContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.RegularFunctionContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SchemaNameContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SimpleExprContext;
@@ -99,6 +103,9 @@ import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.Datetime
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.IntervalDayToSecondExpression;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.IntervalExpressionProjection;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.IntervalYearToMonthExpression;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ListExpression;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.NotExpression;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.XmlNameSpaceStringAsIdentifierSegment;
@@ -507,9 +514,55 @@ public abstract class OracleStatementVisitor extends
OracleStatementBaseVisitor<
return null == ctx.joinOperator() ? visit(ctx.columnName())
: new ColumnWithJoinOperatorSegment(startIndex, stopIndex,
(ColumnSegment) visitColumnName(ctx.columnName()),
ctx.joinOperator().getText());
}
+ if (null != ctx.privateExprOfDb()) {
+ return visit(ctx.privateExprOfDb());
+ }
return new CommonExpressionSegment(startIndex, stopIndex,
ctx.getText());
}
+ @Override
+ public ASTNode visitPrivateExprOfDb(final PrivateExprOfDbContext ctx) {
+ if (null != ctx.intervalExpression()) {
+ return visit(ctx.intervalExpression());
+ }
+ return super.visitPrivateExprOfDb(ctx);
+ }
+
+ @Override
+ public ASTNode visitIntervalExpression(final IntervalExpressionContext
ctx) {
+ IntervalExpressionProjection result = new
IntervalExpressionProjection(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (ExpressionSegment) visit(ctx.expr(0)),
+ (ExpressionSegment) visit(ctx.MINUS_()), (ExpressionSegment)
visit(ctx.expr(1)));
+ if (null != ctx.intervalDayToSecondExpression()) {
+ result.setDayToSecondExpression((IntervalDayToSecondExpression)
visit(ctx.intervalDayToSecondExpression()));
+ } else {
+ result.setYearToMonthExpression((IntervalYearToMonthExpression)
visit(ctx.intervalYearToMonthExpression()));
+ }
+ return result;
+ }
+
+ @Override
+ public ASTNode visitIntervalDayToSecondExpression(final
IntervalDayToSecondExpressionContext ctx) {
+ IntervalDayToSecondExpression result = new
IntervalDayToSecondExpression(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(),
+ ctx.DAY().getText(), ctx.TO().getText(),
ctx.SECOND().getText());
+ if (null != ctx.leadingFieldPrecision()) {
+
result.setLeadingFieldPrecision(Integer.parseInt(ctx.leadingFieldPrecision().INTEGER_().getText()));
+ }
+ if (null != ctx.fractionalSecondPrecision()) {
+
result.setFractionalSecondPrecision(Integer.parseInt(ctx.fractionalSecondPrecision().getText()));
+ }
+ return result;
+ }
+
+ @Override
+ public ASTNode visitIntervalYearToMonthExpression(final
IntervalYearToMonthExpressionContext ctx) {
+ IntervalYearToMonthExpression result = new
IntervalYearToMonthExpression(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(),
+ ctx.YEAR().getText(), ctx.TO().getText(),
ctx.MONTH().getText());
+ if (null != ctx.leadingFieldPrecision()) {
+
result.setLeadingFieldPrecision(Integer.parseInt(ctx.leadingFieldPrecision().INTEGER_().getText()));
+ }
+ return result;
+ }
+
@Override
public final ASTNode visitFunctionCall(final FunctionCallContext ctx) {
if (null != ctx.aggregationFunction()) {
diff --git
a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
index 1829cfafbca..01803f301a4 100644
---
a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
+++
b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
@@ -115,6 +115,7 @@ import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOp
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.DatetimeExpression;
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.item.IntervalExpressionProjection;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.XmlPiFunctionSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.XmlQueryAndExistsFunctionSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.XmlSerializeFunctionSegment;
@@ -733,6 +734,17 @@ public final class OracleDMLStatementVisitor extends
OracleStatementVisitor impl
((AliasAvailable) projection).setAlias(alias);
return projection;
}
+ if (projection instanceof IntervalExpressionProjection) {
+ IntervalExpressionProjection intervalExpressionProjection =
(IntervalExpressionProjection) projection;
+ IntervalExpressionProjection result = new
IntervalExpressionProjection(intervalExpressionProjection.getStartIndex(),
intervalExpressionProjection.getStopIndex(),
+ intervalExpressionProjection.getLeft(),
intervalExpressionProjection.getMinus(),
intervalExpressionProjection.getRight());
+ if (null !=
intervalExpressionProjection.getDayToSecondExpression()) {
+
result.setDayToSecondExpression(intervalExpressionProjection.getDayToSecondExpression());
+ } else {
+
result.setYearToMonthExpression(intervalExpressionProjection.getYearToMonthExpression());
+ }
+ return result;
+ }
LiteralExpressionSegment column = (LiteralExpressionSegment)
projection;
ExpressionProjectionSegment result = null == alias
? new ExpressionProjectionSegment(column.getStartIndex(),
column.getStopIndex(), String.valueOf(column.getLiterals()), column)
diff --git
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/expr/IntervalDayToSecondExpression.java
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/expr/IntervalDayToSecondExpression.java
new file mode 100644
index 00000000000..dd972002ef5
--- /dev/null
+++
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/expr/IntervalDayToSecondExpression.java
@@ -0,0 +1,52 @@
+/*
+ * 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.expr;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+
+/**
+ * Between expression.
+ */
+@RequiredArgsConstructor
+@Getter
+@Setter
+public final class IntervalDayToSecondExpression implements ExpressionSegment {
+
+ private final int startIndex;
+
+ private final int stopIndex;
+
+ private final String day;
+
+ private final String to;
+
+ private final String second;
+
+ @Setter
+ private Integer leadingFieldPrecision;
+
+ @Setter
+ private Integer fractionalSecondPrecision;
+
+ @Override
+ public String getText() {
+ return null;
+ }
+}
diff --git
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/expr/IntervalYearToMonthExpression.java
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/expr/IntervalYearToMonthExpression.java
new file mode 100644
index 00000000000..a7e22d53f52
--- /dev/null
+++
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/expr/IntervalYearToMonthExpression.java
@@ -0,0 +1,49 @@
+/*
+ * 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.expr;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+
+/**
+ * Interval year to month expression.
+ */
+@RequiredArgsConstructor
+@Getter
+@Setter
+public final class IntervalYearToMonthExpression implements ExpressionSegment {
+
+ private final int startIndex;
+
+ private final int stopIndex;
+
+ private final String year;
+
+ private final String to;
+
+ private final String month;
+
+ @Setter
+ private Integer leadingFieldPrecision;
+
+ @Override
+ public String getText() {
+ return null;
+ }
+}
diff --git
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/item/IntervalExpressionProjection.java
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/item/IntervalExpressionProjection.java
new file mode 100644
index 00000000000..5871e52a93f
--- /dev/null
+++
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/item/IntervalExpressionProjection.java
@@ -0,0 +1,55 @@
+/*
+ * 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.item;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.IntervalDayToSecondExpression;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.IntervalYearToMonthExpression;
+
+/**
+ * Between expression.
+ */
+@RequiredArgsConstructor
+@Getter
+@Setter
+public final class IntervalExpressionProjection implements ExpressionSegment,
ProjectionSegment {
+
+ private final int startIndex;
+
+ private final int stopIndex;
+
+ private final ExpressionSegment left;
+
+ private final ExpressionSegment minus;
+
+ private final ExpressionSegment right;
+
+ @Setter
+ private IntervalDayToSecondExpression dayToSecondExpression;
+
+ @Setter
+ private IntervalYearToMonthExpression yearToMonthExpression;
+
+ @Override
+ public String getText() {
+ return minus.getText();
+ }
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/expression/ExpressionAssert.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/expression/ExpressionAssert.java
index 86ebb930ac9..e65dd42cbe3 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/expression/ExpressionAssert.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/expression/ExpressionAssert.java
@@ -30,6 +30,9 @@ import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.Expressi
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExtractArgExpression;
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.IntervalDayToSecondExpression;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.IntervalExpressionProjection;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.IntervalYearToMonthExpression;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ListExpression;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.MatchAgainstExpression;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.NotExpression;
@@ -62,6 +65,9 @@ import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.s
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedExpression;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedExtractArgExpression;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedInExpression;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedIntervalDayToSecondExpression;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedIntervalExpression;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedIntervalYearToMonthExpression;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedListExpression;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedMatchExpression;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedNotExpression;
@@ -79,6 +85,7 @@ import java.util.Iterator;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
@@ -421,6 +428,76 @@ public final class ExpressionAssert {
}
}
+ /**
+ * Assert expression by actual expression segment class type.
+ *
+ * @param assertContext assert context
+ * @param actual actual interval expression
+ * @param expected expected interval expression
+ */
+ private static void assertIntervalExpression(final SQLCaseAssertContext
assertContext, final IntervalExpressionProjection actual, final
ExpectedIntervalExpression expected) {
+ if (null == expected) {
+ assertNull(actual, assertContext.getText("Actual interval
expression should not exist."));
+ } else {
+ assertNotNull(actual, assertContext.getText("Actual interval
expression should exist"));
+ assertExpression(assertContext, actual.getLeft(),
expected.getLeft());
+ assertExpression(assertContext, actual.getRight(),
expected.getRight());
+ assertExpression(assertContext, actual.getMinus(),
expected.getOperator());
+ if (null != actual.getDayToSecondExpression()) {
+ assertIntervalDayToSecondExpression(assertContext,
actual.getDayToSecondExpression(), expected.getDayToSecondExpression());
+ } else {
+ assertIntervalYearToMonthExpression(assertContext,
actual.getYearToMonthExpression(), expected.getYearToMonthExpression());
+ }
+ }
+ }
+
+ /**
+ * Assert expression by actual expression segment class type.
+ *
+ * @param assertContext assert context
+ * @param actual actual interval day to second expression
+ * @param expected expected interval day to second expression
+ */
+ private static void assertIntervalDayToSecondExpression(final
SQLCaseAssertContext assertContext,
+ final
IntervalDayToSecondExpression actual, final
ExpectedIntervalDayToSecondExpression expected) {
+ if (null == expected) {
+ assertNull(actual, assertContext.getText("Actual interval
expression should not exist."));
+ } else {
+ assertNotNull(actual, assertContext.getText("Actual interval
expression should exist"));
+ if (null != actual.getLeadingFieldPrecision()) {
+ assertEquals(actual.getLeadingFieldPrecision(),
expected.getLeadingFieldPrecision());
+ } else {
+ assertNull(expected.getLeadingFieldPrecision(),
assertContext.getText("Actual leading field precision should not exist."));
+ }
+ if (null != actual.getFractionalSecondPrecision()) {
+ assertEquals(actual.getFractionalSecondPrecision(),
expected.getFractionalSecondPrecision());
+ } else {
+ assertNull(expected.getFractionalSecondPrecision(),
assertContext.getText("Actual fractional second precision should not exist."));
+ }
+ }
+ }
+
+ /**
+ * Assert expression by actual expression segment class type.
+ *
+ * @param assertContext assert context
+ * @param actual actual interval year to month expression
+ * @param expected expected interval year to month expression
+ */
+ private static void assertIntervalYearToMonthExpression(final
SQLCaseAssertContext assertContext,
+ final
IntervalYearToMonthExpression actual, final
ExpectedIntervalYearToMonthExpression expected) {
+ if (null == expected) {
+ assertNull(actual, assertContext.getText("Actual interval
expression should not exist."));
+ } else {
+ assertNotNull(actual, assertContext.getText("Actual interval
expression should exist"));
+ if (null != actual.getLeadingFieldPrecision()) {
+ assertEquals(actual.getLeadingFieldPrecision(),
expected.getLeadingFieldPrecision());
+ } else {
+ assertNull(expected.getLeadingFieldPrecision(),
assertContext.getText("Actual leading field precision should not exist."));
+ }
+ }
+ }
+
/**
* Assert expression by actual expression segment class type.
*
@@ -482,6 +559,8 @@ public final class ExpressionAssert {
assertMatchSegment(assertContext, (MatchAgainstExpression) actual,
expected.getMatchExpression());
} else if (actual instanceof ColumnWithJoinOperatorSegment) {
ColumnWithJoinOperatorAssert.assertIs(assertContext,
(ColumnWithJoinOperatorSegment) actual,
expected.getColumnWithJoinOperatorSegment());
+ } else if (actual instanceof IntervalExpressionProjection) {
+ assertIntervalExpression(assertContext,
(IntervalExpressionProjection) actual, expected.getIntervalExpression());
} else {
throw new UnsupportedOperationException(String.format("Unsupported
expression: %s", actual.getClass().getName()));
}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedExpression.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedExpression.java
index 1a11a857ad7..08d66195e4b 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedExpression.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedExpression.java
@@ -107,4 +107,7 @@ public final class ExpectedExpression extends
AbstractExpectedSQLSegment {
@XmlElement(name = "colum-with-join-operator-segment")
private ExpectedColumnWithJoinOperatorSegment
columnWithJoinOperatorSegment;
+
+ @XmlElement(name = "interval-expression")
+ private ExpectedIntervalExpression intervalExpression;
}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedIntervalDayToSecondExpression.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedIntervalDayToSecondExpression.java
new file mode 100644
index 00000000000..e505247a8fb
--- /dev/null
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedIntervalDayToSecondExpression.java
@@ -0,0 +1,47 @@
+/*
+ * 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.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr;
+
+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.XmlElement;
+
+/**
+ * Expected interval day to second expression.
+ */
+@Getter
+@Setter
+public class ExpectedIntervalDayToSecondExpression extends
AbstractExpectedSQLSegment implements ExpectedExpressionSegment {
+
+ @XmlElement
+ private String day;
+
+ @XmlElement
+ private String to;
+
+ @XmlElement
+ private String second;
+
+ @XmlElement(name = "leading-field-precision")
+ private Integer leadingFieldPrecision;
+
+ @XmlElement(name = "fractional-second-precision")
+ private Integer fractionalSecondPrecision;
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedIntervalExpression.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedIntervalExpression.java
new file mode 100644
index 00000000000..22543b3d5ab
--- /dev/null
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedIntervalExpression.java
@@ -0,0 +1,48 @@
+/*
+ * 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.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr;
+
+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.XmlElement;
+
+/**
+ * Expected match expression.
+ */
+@Getter
+@Setter
+public class ExpectedIntervalExpression extends AbstractExpectedSQLSegment
implements ExpectedExpressionSegment {
+
+ @XmlElement
+ private ExpectedExpression left;
+
+ @XmlElement
+ private ExpectedExpression right;
+
+ @XmlElement
+ private ExpectedExpression operator;
+
+ @XmlElement(name = "interval-day-to-second-expr")
+ private ExpectedIntervalDayToSecondExpression dayToSecondExpression;
+
+ @XmlElement(name = "interval-year-to-month-expr")
+ private ExpectedIntervalYearToMonthExpression yearToMonthExpression;
+
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedIntervalYearToMonthExpression.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedIntervalYearToMonthExpression.java
new file mode 100644
index 00000000000..73a6497c563
--- /dev/null
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedIntervalYearToMonthExpression.java
@@ -0,0 +1,44 @@
+/*
+ * 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.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr;
+
+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.XmlElement;
+
+/**
+ * Expected interval day to second expression.
+ */
+@Getter
+@Setter
+public class ExpectedIntervalYearToMonthExpression extends
AbstractExpectedSQLSegment implements ExpectedExpressionSegment {
+
+ @XmlElement
+ private String year;
+
+ @XmlElement
+ private String to;
+
+ @XmlElement
+ private String month;
+
+ @XmlElement(name = "leading-field-precision")
+ private Integer leadingFieldPrecision;
+}
diff --git a/test/it/parser/src/main/resources/case/dml/select-expression.xml
b/test/it/parser/src/main/resources/case/dml/select-expression.xml
index c2f46ecb29b..998704efef7 100644
--- a/test/it/parser/src/main/resources/case/dml/select-expression.xml
+++ b/test/it/parser/src/main/resources/case/dml/select-expression.xml
@@ -2595,4 +2595,28 @@
<simple-table name="V$LOGMNR_CONTENTS" start-index="70"
stop-index="86" />
</from>
</select>
+
+ <select sql-case-id="select_interval_day_to_second_expression">
+ <projections start-index="7" stop-index="50">
+ <expression-projection text="(SYSTIMESTAMP - order_date) DAY(9) TO
SECOND" start-index="7" stop-index="50">
+ <function>
+ <interval-expression>
+ <left>
+ <column name="SYSTIMESTAMP" start-index=""
stop-index=""/>
+ </left>
+ <operator>-</operator>
+ <right>
+ <column name="order_date" start-index=""
stop-index="" />
+ </right>
+ <interval-day-to-second-expr>
+
<leading-field-precision>9</leading-field-precision>
+ </interval-day-to-second-expr>
+ </interval-expression>
+ </function>
+ </expression-projection>
+ </projections>
+ <from>
+ <simple-table name="orders" start-index="57" stop-index="62" />
+ </from>
+ </select>
</sql-parser-test-cases>
diff --git
a/test/it/parser/src/main/resources/sql/supported/dml/select-expression.xml
b/test/it/parser/src/main/resources/sql/supported/dml/select-expression.xml
index 239ff3623d9..9ba0539ecdf 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select-expression.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select-expression.xml
@@ -106,4 +106,5 @@
<sql-case id="select_datetime_expression" value="SELECT SYSTIMESTAMP AT
TIME ZONE 'UTC' FROM DUAL;" db-types="Oracle" />
<sql-case id="select_between_expression" value="SELECT item_id BETWEEN 1
AND order_id, status FROM t_order_item;" db-types="MySQL" />
<sql-case id="select_dbms_logmnr_mine_value_regular_function"
value="SELECT DBMS_LOGMNR.MINE_VALUE(UNDO_VALUE, 'HR.EMPLOYEES.SALARY') FROM
V$LOGMNR_CONTENTS;" db-types="Oracle" />
+ <sql-case id="select_interval_day_to_second_expression" value="SELECT
(SYSTIMESTAMP - order_date) DAY(9) TO SECOND FROM orders" db-types="Oracle" />
</sql-cases>