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>&gt;</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>&lt;</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) &gt;= 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 &gt; $25 AND ListPrice 
&lt; $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>


Reply via email to