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 4213df242c9 Support parsing SQL Server select into segment (#29860)
4213df242c9 is described below
commit 4213df242c9834329194f8742010db230a0af11c
Author: LotusMoon <[email protected]>
AuthorDate: Fri Jan 26 14:48:42 2024 +0800
Support parsing SQL Server select into segment (#29860)
* Support parsing SQL Server default schema
* Support parsing SQL Server select into segment
* add visit into segment
* apply spotless apply
* Add a new line between javadoc and param doc
---
.../src/main/antlr4/imports/sqlserver/BaseRule.g4 | 25 ++--
.../main/antlr4/imports/sqlserver/DMLStatement.g4 | 6 +-
.../antlr4/imports/sqlserver/SQLServerKeyword.g4 | 8 ++
.../statement/SQLServerStatementVisitor.java | 34 ++++-
.../handler/dml/SelectStatementHandler.java | 32 ++++-
.../sqlserver/dml/SQLServerSelectStatement.java | 12 ++
.../statement/dml/impl/SelectStatementAssert.java | 12 ++
.../statement/dml/SelectStatementTestCase.java | 3 +
.../main/resources/case/dml/select-group-by.xml | 14 ++
.../src/main/resources/case/dml/select-into.xml | 77 +++++++++++
.../main/resources/case/dml/select-sub-query.xml | 148 +++++++++++++++++++++
.../sql/supported/dml/select-group-by.xml | 1 +
.../resources/sql/supported/dml/select-into.xml | 2 +
.../sql/supported/dml/select-sub-query.xml | 3 +
14 files changed, 356 insertions(+), 21 deletions(-)
diff --git
a/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/BaseRule.g4
b/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/BaseRule.g4
index 5efe8ba0cae..c4f086dbd4a 100644
--- a/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/BaseRule.g4
+++ b/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/BaseRule.g4
@@ -120,7 +120,7 @@ unreservedWord
| DATA_RETENTION | TEMPORAL_HISTORY_RETENTION | EDITION |
MIXED_PAGE_ALLOCATION | DISABLED | ALLOWED | HADR | MULTI_USER |
RESTRICTED_USER | SINGLE_USER | OFFLINE | EMERGENCY | SUSPEND |
DATE_CORRELATION_OPTIMIZATION
| ELASTIC_POOL | SERVICE_OBJECTIVE | DATABASE_NAME | ALLOW_CONNECTIONS |
GEO | NAMED | DATEFIRST | BACKUP_STORAGE_REDUNDANCY |
FORCE_FAILOVER_ALLOW_DATA_LOSS | SECONDARY | FAILOVER |
DEFAULT_FULLTEXT_LANGUAGE
| DEFAULT_LANGUAGE | INLINE | NESTED_TRIGGERS | TRANSFORM_NOISE_WORDS |
TWO_DIGIT_YEAR_CUTOFF | PERSISTENT_LOG_BUFFER | DIRECTORY_NAME | DATEFORMAT |
DELAYED_DURABILITY | TRANSFER | SCHEMA | PASSWORD | AUTHORIZATION
- | MEMBER | SEARCH | TEXT | SECOND | PRECISION | VIEWS | PROVIDER | COLUMNS
| SUBSTRING | RETURNS | SIZE | CONTAINS | MONTH
+ | MEMBER | SEARCH | TEXT | SECOND | PRECISION | VIEWS | PROVIDER | COLUMNS
| SUBSTRING | RETURNS | SIZE | CONTAINS | MONTH | INPUT
;
databaseName
@@ -311,7 +311,20 @@ distinct
;
specialFunction
- : castFunction | charFunction | convertFunction | openJsonFunction |
jsonFunction | openRowSetFunction
+ : conversionFunction | charFunction | openJsonFunction | jsonFunction |
openRowSetFunction
+ ;
+
+conversionFunction
+ : castFunction
+ | convertFunction
+ ;
+
+castFunction
+ : (CAST | TRY_CAST) LP_ expr AS dataType RP_
+ ;
+
+convertFunction
+ : (CONVERT | TRY_CONVERT) LP_ dataType COMMA_ expr (COMMA_ NUMBER_)? RP_
;
jsonFunction
@@ -334,14 +347,6 @@ jsonNullClause
: NULL ON NULL | ABSENT ON NULL
;
-castFunction
- : CAST LP_ expr AS dataType RP_
- ;
-
-convertFunction
- : CONVERT LP_ dataType COMMA_ expr (COMMA_ NUMBER_)? RP_
- ;
-
charFunction
: CHAR LP_ expr (COMMA_ expr)* (USING ignoredIdentifier)? RP_
;
diff --git
a/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/DMLStatement.g4
b/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/DMLStatement.g4
index a635ce3a3a1..c449cc91143 100644
---
a/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/DMLStatement.g4
+++
b/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/DMLStatement.g4
@@ -93,7 +93,7 @@ aggregationClause
;
selectClause
- : selectWithClause? SELECT duplicateSpecification? projections fromClause?
whereClause? groupByClause? havingClause? orderByClause? forClause?
+ : selectWithClause? SELECT duplicateSpecification? projections intoClause?
fromClause? whereClause? groupByClause? havingClause? orderByClause? forClause?
;
duplicateSpecification
@@ -127,6 +127,10 @@ qualifiedShorthand
: identifier DOT_ASTERISK_
;
+intoClause
+ : INTO tableName
+ ;
+
fromClause
: FROM tableReferences
;
diff --git
a/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/SQLServerKeyword.g4
b/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/SQLServerKeyword.g4
index 55937733a6e..ff4385b0e36 100644
---
a/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/SQLServerKeyword.g4
+++
b/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/SQLServerKeyword.g4
@@ -1950,3 +1950,11 @@ OPENJSON
OPENROWSET
: O P E N R O W S E T
;
+
+TRY_CAST
+ : T R Y UL_ C A S T
+ ;
+
+TRY_CONVERT
+ : T R Y UL_ C O N V E R T
+ ;
diff --git
a/parser/sql/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/SQLServerStatementVisitor.java
b/parser/sql/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/SQLServerStatementVisitor.java
index ffe0b2ba610..044d083672f 100644
---
a/parser/sql/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/SQLServerStatementVisitor.java
+++
b/parser/sql/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/SQLServerStatementVisitor.java
@@ -124,6 +124,8 @@ import
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.Pro
import
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OpenJsonFunctionContext;
import
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.TableHintLimitedContext;
import
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OpenRowSetFunctionContext;
+import
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ConversionFunctionContext;
+import
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.IntoClauseContext;
import org.apache.shardingsphere.sql.parser.sql.common.enums.AggregationType;
import org.apache.shardingsphere.sql.parser.sql.common.enums.JoinType;
import org.apache.shardingsphere.sql.parser.sql.common.enums.OrderDirection;
@@ -657,11 +659,8 @@ public abstract class SQLServerStatementVisitor extends
SQLServerStatementBaseVi
@Override
public final ASTNode visitSpecialFunction(final SpecialFunctionContext
ctx) {
- if (null != ctx.castFunction()) {
- return visit(ctx.castFunction());
- }
- if (null != ctx.convertFunction()) {
- return visit(ctx.convertFunction());
+ if (null != ctx.conversionFunction()) {
+ return visit(ctx.conversionFunction());
}
if (null != ctx.charFunction()) {
return visit(ctx.charFunction());
@@ -678,6 +677,17 @@ public abstract class SQLServerStatementVisitor extends
SQLServerStatementBaseVi
return new FunctionSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), ctx.getChild(0).getChild(0).getText(),
getOriginalText(ctx));
}
+ @Override
+ public final ASTNode visitConversionFunction(final
ConversionFunctionContext ctx) {
+ if (null != ctx.castFunction()) {
+ return visit(ctx.castFunction());
+ }
+ if (null != ctx.convertFunction()) {
+ return visit(ctx.convertFunction());
+ }
+ return new FunctionSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), ctx.getChild(0).getChild(0).getText(),
getOriginalText(ctx));
+ }
+
@Override
public final ASTNode visitJsonFunction(final JsonFunctionContext ctx) {
if (null != ctx.jsonArrayFunction()) {
@@ -735,7 +745,8 @@ public abstract class SQLServerStatementVisitor extends
SQLServerStatementBaseVi
@Override
public final ASTNode visitCastFunction(final CastFunctionContext ctx) {
calculateParameterCount(Collections.singleton(ctx.expr()));
- FunctionSegment result = new
FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(),
ctx.CAST().getText(), getOriginalText(ctx));
+ String functionName = null != ctx.CAST() ? ctx.CAST().getText() :
ctx.TRY_CAST().getText();
+ FunctionSegment result = new
FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(),
functionName, getOriginalText(ctx));
ASTNode exprSegment = visit(ctx.expr());
if (exprSegment instanceof ColumnSegment) {
result.getParameters().add((ColumnSegment) exprSegment);
@@ -748,7 +759,8 @@ public abstract class SQLServerStatementVisitor extends
SQLServerStatementBaseVi
@Override
public ASTNode visitConvertFunction(final ConvertFunctionContext ctx) {
- FunctionSegment result = new
FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(),
ctx.CONVERT().getText(), getOriginalText(ctx));
+ String functionName = null != ctx.CONVERT() ? ctx.CONVERT().getText()
: ctx.TRY_CONVERT().getText();
+ FunctionSegment result = new
FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(),
functionName, getOriginalText(ctx));
result.getParameters().add((DataTypeSegment) visit(ctx.dataType()));
result.getParameters().add((ExpressionSegment) visit(ctx.expr()));
if (null != ctx.NUMBER_()) {
@@ -884,6 +896,9 @@ public abstract class SQLServerStatementVisitor extends
SQLServerStatementBaseVi
if (null != ctx.duplicateSpecification()) {
result.getProjections().setDistinctRow(isDistinct(ctx));
}
+ if (null != ctx.intoClause()) {
+ result.setIntoSegment((TableSegment) visit(ctx.intoClause()));
+ }
if (null != ctx.fromClause()) {
TableSegment tableSource = (TableSegment)
visit(ctx.fromClause().tableReferences());
result.setFrom(tableSource);
@@ -1409,6 +1424,11 @@ public abstract class SQLServerStatementVisitor extends
SQLServerStatementBaseVi
return null != alias && alias.getStopIndex() >
sqlSegment.getStopIndex() ? alias.getStopIndex() : sqlSegment.getStopIndex();
}
+ @Override
+ public ASTNode visitIntoClause(final IntoClauseContext ctx) {
+ return visit(ctx.tableName());
+ }
+
@Override
public ASTNode visitFromClause(final FromClauseContext ctx) {
return visit(ctx.tableReferences());
diff --git
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/handler/dml/SelectStatementHandler.java
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/handler/dml/SelectStatementHandler.java
index db1a92b0866..0ef8bfd3151 100644
---
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/handler/dml/SelectStatementHandler.java
+++
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/handler/dml/SelectStatementHandler.java
@@ -24,6 +24,7 @@ import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.Loc
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.ModelSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WindowSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WithSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.handler.SQLStatementHandler;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLSelectStatement;
@@ -114,7 +115,7 @@ public final class SelectStatementHandler implements
SQLStatementHandler {
/**
* Set lock segment.
- *
+ *
* @param selectStatement select statement
* @param lockSegment lock segment
*/
@@ -191,7 +192,7 @@ public final class SelectStatementHandler implements
SQLStatementHandler {
/**
* Set with segment.
- *
+ *
* @param selectStatement select statement
* @param withSegment with segment
*/
@@ -222,7 +223,7 @@ public final class SelectStatementHandler implements
SQLStatementHandler {
/**
* Set model segment.
- *
+ *
* @param selectStatement select statement
* @param modelSegment model segment
*/
@@ -231,4 +232,29 @@ public final class SelectStatementHandler implements
SQLStatementHandler {
((OracleSelectStatement)
selectStatement).setModelSegment(modelSegment);
}
}
+
+ /**
+ * Get into segment.
+ *
+ * @param selectStatement select statement
+ * @return into table segment
+ */
+ public static Optional<TableSegment> getIntoSegment(final SelectStatement
selectStatement) {
+ if (selectStatement instanceof SQLServerSelectStatement) {
+ return ((SQLServerSelectStatement)
selectStatement).getIntoSegment();
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Set into segment.
+ *
+ * @param selectStatement select statement
+ * @param intoSegment table into segment
+ */
+ public static void setIntoSegment(final SelectStatement selectStatement,
final TableSegment intoSegment) {
+ if (selectStatement instanceof SQLServerSelectStatement) {
+ ((SQLServerSelectStatement)
selectStatement).setIntoSegment(intoSegment);
+ }
+ }
}
diff --git
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerSelectStatement.java
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerSelectStatement.java
index 39892b4691f..2800c7980f2 100644
---
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerSelectStatement.java
+++
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerSelectStatement.java
@@ -20,6 +20,7 @@ package
org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dml
import lombok.Setter;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.limit.LimitSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WithSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.SQLServerStatement;
@@ -35,6 +36,8 @@ public final class SQLServerSelectStatement extends
SelectStatement implements S
private WithSegment withSegment;
+ private TableSegment intoSegment;
+
/**
* Get order by segment.
*
@@ -52,4 +55,13 @@ public final class SQLServerSelectStatement extends
SelectStatement implements S
public Optional<WithSegment> getWithSegment() {
return Optional.ofNullable(withSegment);
}
+
+ /**
+ * Get into segment.
+ *
+ * @return into segment
+ */
+ public Optional<TableSegment> getIntoSegment() {
+ return Optional.ofNullable(intoSegment);
+ }
}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/impl/SelectStatementAssert.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/impl/SelectStatementAssert.java
index f8a7c913d9e..9f68346f80e 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/impl/SelectStatementAssert.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/impl/SelectStatementAssert.java
@@ -26,6 +26,7 @@ import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.ModelSegm
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WindowSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WithSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.handler.dml.SelectStatementHandler;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLSelectStatement;
@@ -77,6 +78,7 @@ public final class SelectStatementAssert {
assertWithClause(assertContext, actual, expected);
assertCombineClause(assertContext, actual, expected);
assertModelClause(assertContext, actual, expected);
+ assertIntoClause(assertContext, actual, expected);
}
private static void assertWindowClause(final SQLCaseAssertContext
assertContext, final SelectStatement actual, final SelectStatementTestCase
expected) {
@@ -202,4 +204,14 @@ public final class SelectStatementAssert {
ModelClauseAssert.assertIs(assertContext, modelSegment.get(),
expected.getModelClause());
}
}
+
+ private static void assertIntoClause(final SQLCaseAssertContext
assertContext, final SelectStatement actual, final SelectStatementTestCase
expected) {
+ Optional<TableSegment> intoSegment =
SelectStatementHandler.getIntoSegment(actual);
+ if (null == expected.getIntoClause()) {
+ assertFalse(intoSegment.isPresent(), assertContext.getText("Actual
into segment should not exist."));
+ } else {
+ assertTrue(intoSegment.isPresent(), assertContext.getText("Actual
into segment should exist."));
+ TableAssert.assertIs(assertContext, intoSegment.get(),
expected.getIntoClause());
+ }
+ }
}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/SelectStatementTestCase.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/SelectStatementTestCase.java
index a82e738bfe1..4fdd5755c55 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/SelectStatementTestCase.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/SelectStatementTestCase.java
@@ -80,4 +80,7 @@ public final class SelectStatementTestCase extends
SQLParserTestCase {
@XmlElement(name = "model")
private ExpectedModelClause modelClause;
+
+ @XmlElement(name = "into")
+ private ExpectedTable intoClause;
}
diff --git a/test/it/parser/src/main/resources/case/dml/select-group-by.xml
b/test/it/parser/src/main/resources/case/dml/select-group-by.xml
index b3702d8f894..3481eae446f 100644
--- a/test/it/parser/src/main/resources/case/dml/select-group-by.xml
+++ b/test/it/parser/src/main/resources/case/dml/select-group-by.xml
@@ -910,4 +910,18 @@
<expression-item expression="DATEPART(yyyy,OrderDate)"
order-direction="ASC" start-index="197" stop-index="220" />
</order-by>
</select>
+
+ <select sql-case-id="select_from_input_table">
+ <projections start-index="7" stop-index="14">
+ <aggregation-projection type="COUNT" expression="count(*)"
start-index="7" stop-index="14"/>
+ </projections>
+ <from start-index="21" stop-index="25">
+ <simple-table name="input" start-index="21" stop-index="25"/>
+ </from>
+ <group-by>
+ <column-item name="PartitionId" order-direction="ASC"
start-index="36" stop-index="46"/>
+ <column-item name="clusterid" order-direction="ASC"
start-index="49" stop-index="57"/>
+ <column-item name="tumblingwindow" order-direction="ASC"
start-index="60" stop-index="73"/>
+ </group-by>
+ </select>
</sql-parser-test-cases>
diff --git a/test/it/parser/src/main/resources/case/dml/select-into.xml
b/test/it/parser/src/main/resources/case/dml/select-into.xml
index 1e0a8746771..af6b5650eba 100644
--- a/test/it/parser/src/main/resources/case/dml/select-into.xml
+++ b/test/it/parser/src/main/resources/case/dml/select-into.xml
@@ -210,4 +210,81 @@
<simple-table name="table_or_view_name" start-index="50"
stop-index="67" literal-start-index="50" literal-stop-index="67" />
</from>
</select>
+
+ <select sql-case-id="select_into_table_with_try_cast_function">
+ <projections start-index="7" stop-index="108">
+ <column-projection name="temperature" start-index="7"
stop-index="25">
+ <owner name="machine" start-index="7" stop-index="13"/>
+ </column-projection>
+ <expression-projection
text="udf.ASAEdgeUDFDemo_Class1_SquareFunction(try_cast(machine.temperature as
bigint))" start-index="28" stop-index="108">
+ <expr>
+ <function
function-name="udf.ASAEdgeUDFDemo_Class1_SquareFunction"
text="udf.ASAEdgeUDFDemo_Class1_SquareFunction(try_cast(machine.temperature as
bigint))" start-index="28" stop-index="108">
+ <parameter>
+ <function function-name="try_cast"
text="try_cast(machine.temperature as bigint)" start-index="69"
stop-index="107">
+ <parameter>
+ <column name="temperature"
start-index="78" stop-index="96">
+ <owner name="machine" start-index="78"
stop-index="84"/>
+ </column>
+ </parameter>
+ <parameter>
+ <data-type value="bigint"
start-index="101" stop-index="106" />
+ </parameter>
+ </function>
+ </parameter>
+ </function>
+ </expr>
+ </expression-projection>
+ </projections>
+ <into>
+ <simple-table name="Output" start-index="115" stop-index="120"/>
+ </into>
+ <from>
+ <simple-table name="Input" start-index="127" stop-index="131"/>
+ </from>
+ </select>
+
+ <select sql-case-id="select_into_table_before_from">
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7"/>
+ </projections>
+ <into>
+ <simple-table name="NewProducts" start-index="14" stop-index="28">
+ <owner name="dbo" start-index="14" stop-index="16"/>
+ </simple-table>
+ </into>
+ <from start-index="35" stop-index="52">
+ <simple-table name="Product" start-index="35" stop-index="52">
+ <owner name="Production" start-index="35" stop-index="44"/>
+ </simple-table>
+ </from>
+ <where start-index="54" stop-index="95">
+ <expr>
+ <binary-operation-expression start-index="60" stop-index="95">
+ <left>
+ <binary-operation-expression start-index="60"
stop-index="74">
+ <left>
+ <column name="ListPrice" start-index="60"
stop-index="68"/>
+ </left>
+ <right>
+ <common-expression literal-text="$25"
start-index="72" stop-index="74" />
+ </right>
+ <operator>></operator>
+ </binary-operation-expression>
+ </left>
+ <right>
+ <binary-operation-expression start-index="80"
stop-index="95">
+ <left>
+ <column name="ListPrice" start-index="80"
stop-index="88"/>
+ </left>
+ <right>
+ <common-expression literal-text="$100"
start-index="92" stop-index="95" />
+ </right>
+ <operator><</operator>
+ </binary-operation-expression>
+ </right>
+ <operator>AND</operator>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </select>
</sql-parser-test-cases>
diff --git a/test/it/parser/src/main/resources/case/dml/select-sub-query.xml
b/test/it/parser/src/main/resources/case/dml/select-sub-query.xml
index 43631b45468..87b6690b263 100644
--- a/test/it/parser/src/main/resources/case/dml/select-sub-query.xml
+++ b/test/it/parser/src/main/resources/case/dml/select-sub-query.xml
@@ -702,4 +702,152 @@
</expr>
</where>
</select>
+
+ <select sql-case-id="select_sub_query_with_cast_function">
+ <projections start-index="7" stop-index="125">
+ <column-projection name="BusinessEntityID" start-delimiter="["
end-delimiter="]" start-index="7" stop-index="53" alias="BusinessEntityID">
+ <owner name="T1_1" start-delimiter="[" end-delimiter="]"
start-index="7" stop-index="12"/>
+ </column-projection>
+ <column-projection name="rowguid" start-delimiter="["
end-delimiter="]" start-index="56" stop-index="84" alias="rowguid">
+ <owner name="T1_1" start-delimiter="[" end-delimiter="]"
start-index="56" stop-index="61"/>
+ </column-projection>
+ <column-projection name="ModifiedDate" start-delimiter="["
end-delimiter="]" start-index="87" stop-index="125" alias="ModifiedDate">
+ <owner name="T1_1" start-delimiter="[" end-delimiter="]"
start-index="87" stop-index="92"/>
+ </column-projection>
+ </projections>
+ <from start-index="133" stop-index="378">
+ <subquery-table alias="T1_1">
+ <subquery start-index="133" stop-index="378">
+ <select>
+ <projections start-index="141" stop-index="259">
+ <column-projection name="BusinessEntityID"
start-delimiter="[" end-delimiter="]" start-index="141" stop-index="187"
alias="BusinessEntityID">
+ <owner name="T2_1" start-delimiter="["
end-delimiter="]" start-index="141" stop-index="146"/>
+ </column-projection>
+ <column-projection name="rowguid"
start-delimiter="[" end-delimiter="]" start-index="190" stop-index="218"
alias="rowguid">
+ <owner name="T2_1" start-delimiter="["
end-delimiter="]" start-index="190" stop-index="195"/>
+ </column-projection>
+ <column-projection name="ModifiedDate"
start-delimiter="[" end-delimiter="]" start-index="221" stop-index="259"
alias="ModifiedDate">
+ <owner name="T2_1" start-delimiter="["
end-delimiter="]" start-index="221" stop-index="226"/>
+ </column-projection>
+ </projections>
+ <from start-index="266" stop-index="319">
+ <simple-table name="BusinessEntity"
start-delimiter="[" end-delimiter="]" start-index="266" stop-index="319"
alias="T2_1">
+ <owner name="Person" start-delimiter="["
end-delimiter="]" start-index="287" stop-index="294">
+ <owner name="AdventureWorks2022"
start-delimiter="[" end-delimiter="]" start-index="266" stop-index="285"/>
+ </owner>
+ </simple-table>
+ </from>
+ <where start-index="321" stop-index="377">
+ <expr>
+ <binary-operation-expression start-index="328"
stop-index="376">
+ <left>
+ <column name="BusinessEntityID"
start-delimiter="[" end-delimiter="]" start-index="328" stop-index="352">
+ <owner name="T2_1"
start-delimiter="[" end-delimiter="]" start-index="328" stop-index="333"/>
+ </column>
+ </left>
+ <right>
+ <function function-name="CAST"
text="CAST ((17907) AS INT)" start-index="356" stop-index="376">
+ <parameter>
+ <literal-expression
value="17907" start-index="363" stop-index="367"/>
+ </parameter>
+ <parameter>
+ <data-type value="INT"
start-index="373" stop-index="375"/>
+ </parameter>
+ </function>
+ </right>
+ <operator>=</operator>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </select>
+ </subquery>
+ </subquery-table>
+ </from>
+ </select>
+
+ <select sql-case-id="select_sub_query_with_inner_join">
+ <projections start-index="7" stop-index="88">
+ <column-projection name="BusinessEntityID" start-delimiter="["
end-delimiter="]" start-index="7" stop-index="53" alias="BusinessEntityID">
+ <owner name="T1_1" start-index="7" stop-index="12"
start-delimiter="[" end-delimiter="]"/>
+ </column-projection>
+ <column-projection name="AddressID" start-index="56"
stop-index="88" start-delimiter="[" end-delimiter="]" alias="AddressID">
+ <owner name="T1_1" start-index="56" stop-index="61"
start-delimiter="[" end-delimiter="]"/>
+ </column-projection>
+ </projections>
+ <from>
+ <subquery-table alias="T1_1">
+ <subquery start-index="95" stop-index="377">
+ <select>
+ <projections start-index="103" stop-index="184">
+ <column-projection name="BusinessEntityID"
start-index="103" stop-index="149" start-delimiter="[" end-delimiter="]"
alias="BusinessEntityID">
+ <owner name="T2_2" start-index="103"
stop-index="108" start-delimiter="[" end-delimiter="]"/>
+ </column-projection>
+ <column-projection name="AddressID"
start-index="152" stop-index="184" start-delimiter="[" end-delimiter="]"
alias="AddressID">
+ <owner name="T2_1" start-index="152"
stop-index="157" start-delimiter="[" end-delimiter="]"/>
+ </column-projection>
+ </projections>
+ <from>
+ <join-table join-type="INNER">
+ <left>
+ <simple-table name="BusinessEntityAddress"
start-index="191" stop-index="251" start-delimiter="[" end-delimiter="]"
alias="T2_1">
+ <owner name="Person" start-index="212"
stop-index="219" start-delimiter="[" end-delimiter="]">
+ <owner name="AdventureWorks2022"
start-index="191" stop-index="210" start-delimiter="[" end-delimiter="]"/>
+ </owner>
+ </simple-table>
+ </left>
+ <right>
+ <simple-table name="BusinessEntity"
start-index="264" stop-index="317" start-delimiter="[" end-delimiter="]"
alias="T2_2">
+ <owner name="Person" start-index="285"
stop-index="292" start-delimiter="[" end-delimiter="]">
+ <owner name="AdventureWorks2022"
start-index="264" stop-index="283" start-delimiter="[" end-delimiter="]"/>
+ </owner>
+ </simple-table>
+ </right>
+ <on-condition>
+ <binary-operation-expression
start-index="323" stop-index="375">
+ <left>
+ <column name="BusinessEntityID"
start-index="323" stop-index="347" start-delimiter="[" end-delimiter="]">
+ <owner name="T2_1"
start-index="323" stop-index="328" start-delimiter="[" end-delimiter="]"/>
+ </column>
+ </left>
+ <operator>=</operator>
+ <right>
+ <column name="BusinessEntityID"
start-index="351" stop-index="375" start-delimiter="[" end-delimiter="]">
+ <owner name="T2_2"
start-index="351" stop-index="356" start-delimiter="[" end-delimiter="]"/>
+ </column>
+ </right>
+ </binary-operation-expression>
+ </on-condition>
+ </join-table>
+ </from>
+ </select>
+ </subquery>
+ </subquery-table>
+ </from>
+ </select>
+
+ <select sql-case-id="select_sub_query_with_sum">
+ <projections start-index="7" stop-index="27">
+ <column-projection name="col" start-index="7" stop-index="27"
start-delimiter="[" end-delimiter="]" alias="col">
+ <owner name="T1_1" start-index="7" stop-index="12"
start-delimiter="[" end-delimiter="]"/>
+ </column-projection>
+ </projections>
+ <from>
+ <subquery-table alias="T1_1">
+ <subquery>
+ <select>
+ <projections start-index="42" stop-index="72">
+ <aggregation-projection
expression="SUM([T2_1].[Quantity])" type="SUM" start-index="42" stop-index="63"
alias="col"/>
+ </projections>
+ <from>
+ <simple-table name="ProductInventory"
start-index="79" stop-index="138" start-delimiter="[" end-delimiter="]"
alias="T2_1">
+ <owner name="Production" start-index="100"
stop-index="111" start-delimiter="[" end-delimiter="]">
+ <owner name="AdventureWorks2022"
start-index="79" stop-index="98" start-delimiter="[" end-delimiter="]"/>
+ </owner>
+ </simple-table>
+ </from>
+ </select>
+ </subquery>
+ </subquery-table>
+ </from>
+ </select>
</sql-parser-test-cases>
diff --git
a/test/it/parser/src/main/resources/sql/supported/dml/select-group-by.xml
b/test/it/parser/src/main/resources/sql/supported/dml/select-group-by.xml
index 4ff1bfc6d5d..706efb3f22e 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select-group-by.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select-group-by.xml
@@ -43,4 +43,5 @@
<sql-case id="select_with_event_group_by_with_having_order_by"
value="SELECT c.name, Count(*) AS [Count-Per-Column-Repeated-Name] FROM
sys.syscolumns AS c JOIN sys.sysobjects AS o ON o.id = c.id WHERE o.type =
'V' AND c.name like '%event%' GROUP BY c.name HAVING Count(*) >= 3 ORDER BY
c.name" db-types="SQLServer" />
<sql-case id="select_with_datepart_group_by_with_order_by" value="SELECT
DATEPART(yyyy,OrderDate) AS N'Year', SUM(TotalDue) AS N'Total Order Amount'
FROM Sales.SalesOrderHeader GROUP BY DATEPART(yyyy,OrderDate) ORDER BY
DATEPART(yyyy,OrderDate)" db-types="SQLServer"/>
<sql-case id="select_with_datepart_group_by_with_having_order_by"
value="SELECT DATEPART(yyyy,OrderDate) AS N'Year', SUM(TotalDue) AS N'Total
Order Amount' FROM Sales.SalesOrderHeader GROUP BY DATEPART(yyyy,OrderDate)
HAVING DATEPART(yyyy,OrderDate) >= N'2003' ORDER BY
DATEPART(yyyy,OrderDate)" db-types="SQLServer"/>
+ <sql-case id="select_from_input_table" value="SELECT count(*) FROM input
GROUP BY PartitionId, clusterid, tumblingwindow;" db-types="SQLServer"/>
</sql-cases>
diff --git
a/test/it/parser/src/main/resources/sql/supported/dml/select-into.xml
b/test/it/parser/src/main/resources/sql/supported/dml/select-into.xml
index 9ff9bc84874..ff233be1aac 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select-into.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select-into.xml
@@ -29,4 +29,6 @@
<sql-case id="select_into_with_lock_before_into" value="SELECT status FROM
t_order WHERE order_id = ? FOR UPDATE INTO @var1" db-types="MySQL" />
<sql-case id="select_into_param_without_at" value="SELECT 1 INTO a"
db-types="MySQL" />
<sql-case id="select_into_with_variable" value="SELECT select_list INTO
record_variable_name FROM table_or_view_name" db-types="Oracle" />
+ <sql-case id="select_into_table_with_try_cast_function" value="SELECT
machine.temperature,
udf.ASAEdgeUDFDemo_Class1_SquareFunction(try_cast(machine.temperature as
bigint)) INTO Output FROM Input;" db-types="SQLServer"/>
+ <sql-case id="select_into_table_before_from" value="SELECT * INTO
dbo.NewProducts FROM Production.Product WHERE ListPrice > $25 AND ListPrice
< $100;" db-types="SQLServer"/>
</sql-cases>
diff --git
a/test/it/parser/src/main/resources/sql/supported/dml/select-sub-query.xml
b/test/it/parser/src/main/resources/sql/supported/dml/select-sub-query.xml
index 20c797a6d87..09e8559dfb2 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select-sub-query.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select-sub-query.xml
@@ -33,4 +33,7 @@
<sql-case id="select_with_exist_subquery_condition" value="SELECT
t_order_federate.order_id, t_order_federate.user_id FROM t_order_federate WHERE
EXISTS (SELECT * FROM t_user_info WHERE t_order_federate.user_id =
t_user_info.user_id)" db-types="MySQL, PostgreSQL,openGauss" />
<sql-case id="select_with_not_exist_subquery_condition" value="SELECT
t_order_federate.order_id, t_order_federate.user_id FROM t_order_federate WHERE
NOT EXISTS (SELECT * FROM t_user_info WHERE t_order_federate.user_id =
t_user_info.user_id)" db-types="MySQL" />
<sql-case id="select_with_exist_string_split_subquery" value="SELECT
ProductId, Name, Tags FROM Product WHERE EXISTS (SELECT * FROM
STRING_SPLIT(Tags, ',') WHERE value IN ('clothing', 'road'))"
db-types="SQLServer"/>
+ <sql-case id="select_sub_query_with_cast_function" value="SELECT
[T1_1].[BusinessEntityID] AS [BusinessEntityID], [T1_1].[rowguid] AS [rowguid],
[T1_1].[ModifiedDate] AS [ModifiedDate] FROM (SELECT [T2_1].[BusinessEntityID]
AS [BusinessEntityID], [T2_1].[rowguid] AS [rowguid], [T2_1].[ModifiedDate] AS
[ModifiedDate] FROM [AdventureWorks2022].[Person].[BusinessEntity] AS T2_1
WHERE ([T2_1].[BusinessEntityID] = CAST ((17907) AS INT))) AS T1_1"
db-types="SQLServer"/>
+ <sql-case id="select_sub_query_with_inner_join" value="SELECT
[T1_1].[BusinessEntityID] AS [BusinessEntityID], [T1_1].[AddressID] AS
[AddressID] FROM (SELECT [T2_2].[BusinessEntityID] AS [BusinessEntityID],
[T2_1].[AddressID] AS [AddressID] FROM
[AdventureWorks2022].[Person].[BusinessEntityAddress] AS T2_1 INNER JOIN
[AdventureWorks2022].[Person].[BusinessEntity] AS T2_2 ON
([T2_1].[BusinessEntityID] = [T2_2].[BusinessEntityID])) AS T1_1"
db-types="SQLServer"/>
+ <sql-case id="select_sub_query_with_sum" value="SELECT [T1_1].[col] AS
[col] FROM (SELECT SUM([T2_1].[Quantity]) AS [col] FROM
[AdventureWorks2022].[Production].[ProductInventory] AS T2_1) AS T1_1"
db-types="SQLServer"/>
</sql-cases>