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 55065b7e94f Support parsing SQL Server SELECT name, sql (#29627)
55065b7e94f is described below
commit 55065b7e94f03a36953da6e6bf516039c0c548e2
Author: yydeng626 <[email protected]>
AuthorDate: Fri Jan 5 17:22:11 2024 +0800
Support parsing SQL Server SELECT name, sql (#29627)
* draft
* Support parsing SQL Server SELECT name, sql
* remove test parser
* fix test error
* fix code style check
* fix code style
* fix code style
---
.../src/main/antlr4/imports/sqlserver/BaseRule.g4 | 2 +-
.../main/antlr4/imports/sqlserver/DMLStatement.g4 | 10 +++-
.../src/main/antlr4/imports/sqlserver/Keyword.g4 | 3 +
.../statement/SQLServerStatementVisitor.java | 40 +++++++++++++
.../sql/parser/sql/common/enums/JoinType.java | 2 +-
.../handler/dml/InsertStatementHandler.java | 26 +++++++++
.../segment/sqlserver/exec/ExecSegment.java | 45 +++++++++++++++
...tStatement.java => SQLServerCallStatement.java} | 41 +++++--------
.../sqlserver/dml/SQLServerInsertStatement.java | 12 ++++
.../segment/insert/InsertExecClauseAssert.java | 67 ++++++++++++++++++++++
.../statement/dml/impl/InsertStatementAssert.java | 13 +++++
.../jaxb/segment/impl/exec/ExpectedExecClause.java | 46 +++++++++++++++
.../statement/dml/InsertStatementTestCase.java | 8 ++-
.../parser/src/main/resources/case/dml/insert.xml | 35 +++++++++++
.../resources/case/dml/select-special-function.xml | 42 +++++++++++++-
.../main/resources/case/dml/select-sub-query.xml | 46 +++++++++++++++
.../parser/src/main/resources/case/dml/select.xml | 13 +++++
.../main/resources/sql/supported/dml/insert.xml | 1 +
.../sql/supported/dml/select-special-function.xml | 1 +
.../sql/supported/dml/select-sub-query.xml | 1 +
.../main/resources/sql/supported/dml/select.xml | 1 +
21 files changed, 420 insertions(+), 35 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 b9cc46d59e3..1934827c85b 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
+ | MEMBER | SEARCH | TEXT | SECOND | PRECISION | VIEWS | PROVIDER
;
databaseName
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 1f9fa961ff7..aee7775a9c5 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
@@ -20,7 +20,7 @@ grammar DMLStatement;
import BaseRule;
insert
- : withClause? INSERT top? INTO? tableName (AS? alias)? (insertDefaultValue
| insertValuesClause | insertSelectClause)
+ : withClause? INSERT top? INTO? tableName (AS? alias)? (insertDefaultValue
| insertValuesClause | insertSelectClause | insertExecClause)
;
insertDefaultValue
@@ -35,6 +35,14 @@ insertSelectClause
: columnNames? outputClause? select
;
+insertExecClause
+ : columnNames? exec
+ ;
+
+exec
+ : (EXEC | EXECUTE) procedureName (expr (COMMA_ expr)*)?
+ ;
+
update
: withClause? UPDATE top? tableReferences setAssignmentsClause
whereClause? (OPTION queryHint)?
;
diff --git
a/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/Keyword.g4
b/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/Keyword.g4
index 66c214d290c..1eb79442040 100644
--- a/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/Keyword.g4
+++ b/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/Keyword.g4
@@ -692,3 +692,6 @@ WITHOUT
: W I T H O U T
;
+APPLY
+ : A P P L Y
+ ;
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 1d4579d08ef..a4b06d510f3 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
@@ -107,6 +107,9 @@ import
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.Upd
import
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ViewNameContext;
import
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.WhereClauseContext;
import
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.WithClauseContext;
+import
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.InsertExecClauseContext;
+import
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ExecContext;
+import
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ProcedureNameContext;
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;
@@ -115,6 +118,7 @@ import
org.apache.shardingsphere.sql.parser.sql.common.segment.SQLSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.constraint.ConstraintSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.index.IndexNameSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.index.IndexSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.routine.FunctionNameSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.InsertValuesSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment;
@@ -181,6 +185,7 @@ import
org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.Number
import
org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.OtherLiteralValue;
import
org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.StringLiteralValue;
import
org.apache.shardingsphere.sql.parser.sql.common.value.parametermarker.ParameterMarkerValue;
+import
org.apache.shardingsphere.sql.parser.sql.dialect.segment.sqlserver.exec.ExecSegment;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.ddl.SQLServerCreateTableStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dml.SQLServerDeleteStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dml.SQLServerInsertStatement;
@@ -914,6 +919,8 @@ public abstract class SQLServerStatementVisitor extends
SQLServerStatementBaseVi
result = (SQLServerInsertStatement)
visit(ctx.insertDefaultValue());
} else if (null != ctx.insertValuesClause()) {
result = (SQLServerInsertStatement)
visit(ctx.insertValuesClause());
+ } else if (null != ctx.insertExecClause()) {
+ result = (SQLServerInsertStatement) visit(ctx.insertExecClause());
} else {
result = (SQLServerInsertStatement)
visit(ctx.insertSelectClause());
}
@@ -935,6 +942,39 @@ public abstract class SQLServerStatementVisitor extends
SQLServerStatementBaseVi
return result;
}
+ @Override
+ public ASTNode visitInsertExecClause(final InsertExecClauseContext ctx) {
+ SQLServerInsertStatement result = new SQLServerInsertStatement();
+ result.setInsertColumns(createInsertColumns(ctx.columnNames(),
ctx.start.getStartIndex()));
+ result.setExecSegment((ExecSegment) visit(ctx.exec()));
+ return result;
+ }
+
+ @Override
+ public ASTNode visitExec(final ExecContext ctx) {
+ ExecSegment result = new ExecSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex());
+ if (null != ctx.procedureName()) {
+ result.setProcedureName((FunctionNameSegment)
visitProcedureName(ctx.procedureName()));
+ }
+ if (null != ctx.expr()) {
+ Collection<ExpressionSegment> items = new LinkedList<>();
+ for (ExprContext each : ctx.expr()) {
+ items.add((ExpressionSegment) visit(each));
+ }
+ result.getExpressionSegments().addAll(items);
+ }
+ return result;
+ }
+
+ @Override
+ public ASTNode visitProcedureName(final ProcedureNameContext ctx) {
+ FunctionNameSegment result = new
FunctionNameSegment(ctx.name().start.getStartIndex(),
ctx.name().stop.getStopIndex(), (IdentifierValue) visit(ctx.name()));
+ if (null != ctx.owner()) {
+ result.setOwner(new
OwnerSegment(ctx.owner().start.getStartIndex(),
ctx.owner().stop.getStopIndex(), (IdentifierValue) visit(ctx.owner())));
+ }
+ return result;
+ }
+
@Override
public ASTNode visitOutputClause(final OutputClauseContext ctx) {
OutputSegment result = new OutputSegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex());
diff --git
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/enums/JoinType.java
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/enums/JoinType.java
index b714ce63a29..15adb192ac0 100644
---
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/enums/JoinType.java
+++
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/enums/JoinType.java
@@ -22,5 +22,5 @@ package org.apache.shardingsphere.sql.parser.sql.common.enums;
*/
public enum JoinType {
- INNER, FULL, CROSS, LEFT, RIGHT, COMMA
+ INNER, FULL, CROSS, LEFT, RIGHT, COMMA, APPLY
}
diff --git
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/handler/dml/InsertStatementHandler.java
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/handler/dml/InsertStatementHandler.java
index 65bcfbe39bf..2a63293f29c 100644
---
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/handler/dml/InsertStatementHandler.java
+++
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/handler/dml/InsertStatementHandler.java
@@ -30,6 +30,7 @@ import
org.apache.shardingsphere.sql.parser.sql.dialect.handler.SQLStatementHand
import
org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.table.MultiTableConditionalIntoSegment;
import
org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.table.MultiTableInsertIntoSegment;
import
org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.table.MultiTableInsertType;
+import
org.apache.shardingsphere.sql.parser.sql.dialect.segment.sqlserver.exec.ExecSegment;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLInsertStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.opengauss.dml.OpenGaussInsertStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.dml.OracleInsertStatement;
@@ -295,4 +296,29 @@ public final class InsertStatementHandler implements
SQLStatementHandler {
((OracleInsertStatement) insertStatement).setWhere(whereSegment);
}
}
+
+ /**
+ * Get execute segment.
+ *
+ * @param insertStatement insert statement
+ * @return execute segment
+ */
+ public static Optional<ExecSegment> getExecSegment(final InsertStatement
insertStatement) {
+ if (insertStatement instanceof SQLServerInsertStatement) {
+ return ((SQLServerInsertStatement)
insertStatement).getExecSegment();
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Set execute segment.
+ *
+ * @param insertStatement insert statement
+ * @param execSegment execute segment
+ */
+ public static void setExecSegment(final InsertStatement insertStatement,
final ExecSegment execSegment) {
+ if (insertStatement instanceof SQLServerInsertStatement) {
+ ((SQLServerInsertStatement)
insertStatement).setExecSegment(execSegment);
+ }
+ }
}
diff --git
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/segment/sqlserver/exec/ExecSegment.java
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/segment/sqlserver/exec/ExecSegment.java
new file mode 100644
index 00000000000..ba65da6abdc
--- /dev/null
+++
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/segment/sqlserver/exec/ExecSegment.java
@@ -0,0 +1,45 @@
+/*
+ * 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.dialect.segment.sqlserver.exec;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.SQLSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.routine.FunctionNameSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+/**
+ * Execute segment.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class ExecSegment implements SQLSegment {
+
+ private final int startIndex;
+
+ private final int stopIndex;
+
+ @Setter
+ private FunctionNameSegment procedureName;
+
+ private final Collection<ExpressionSegment> expressionSegments = new
LinkedList<>();
+}
diff --git
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerInsertStatement.java
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerCallStatement.java
similarity index 55%
copy from
parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerInsertStatement.java
copy to
parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerCallStatement.java
index 501188f0242..67018882664 100644
---
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerInsertStatement.java
+++
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerCallStatement.java
@@ -17,39 +17,24 @@
package
org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dml;
-import lombok.Setter;
-import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OutputSegment;
-import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WithSegment;
-import
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.InsertStatement;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.CallStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.SQLServerStatement;
-import java.util.Optional;
+import java.util.List;
/**
- * SQLServer insert statement.
+ * SQLServer call statement.
*/
-@Setter
-public final class SQLServerInsertStatement extends InsertStatement implements
SQLServerStatement {
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter
+public final class SQLServerCallStatement extends CallStatement implements
SQLServerStatement {
- private WithSegment withSegment;
+ private String procedureName;
- private OutputSegment outputSegment;
-
- /**
- * Get with segment.
- *
- * @return with segment.
- */
- public Optional<WithSegment> getWithSegment() {
- return Optional.ofNullable(withSegment);
- }
-
- /**
- * Get output segment.
- *
- * @return output segment.
- */
- public Optional<OutputSegment> getOutputSegment() {
- return Optional.ofNullable(outputSegment);
- }
+ private List<ExpressionSegment> parameters;
}
diff --git
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerInsertStatement.java
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerInsertStatement.java
index 501188f0242..aa4e9cbe5a0 100644
---
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerInsertStatement.java
+++
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerInsertStatement.java
@@ -21,6 +21,7 @@ import lombok.Setter;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OutputSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WithSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.InsertStatement;
+import
org.apache.shardingsphere.sql.parser.sql.dialect.segment.sqlserver.exec.ExecSegment;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.SQLServerStatement;
import java.util.Optional;
@@ -35,6 +36,8 @@ public final class SQLServerInsertStatement extends
InsertStatement implements S
private OutputSegment outputSegment;
+ private ExecSegment execSegment;
+
/**
* Get with segment.
*
@@ -52,4 +55,13 @@ public final class SQLServerInsertStatement extends
InsertStatement implements S
public Optional<OutputSegment> getOutputSegment() {
return Optional.ofNullable(outputSegment);
}
+
+ /**
+ * Get execute segment.
+ *
+ * @return execute segment.
+ */
+ public Optional<ExecSegment> getExecSegment() {
+ return Optional.ofNullable(execSegment);
+ }
}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/insert/InsertExecClauseAssert.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/insert/InsertExecClauseAssert.java
new file mode 100644
index 00000000000..940bacbe85f
--- /dev/null
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/insert/InsertExecClauseAssert.java
@@ -0,0 +1,67 @@
+/*
+ * 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.asserts.segment.insert;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.sql.dialect.segment.sqlserver.exec.ExecSegment;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.SQLSegmentAssert;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.expression.ExpressionAssert;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.owner.OwnerAssert;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.exec.ExpectedExecClause;
+import org.hamcrest.CoreMatchers;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Insert execute clause assert.
+ **/
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class InsertExecClauseAssert {
+
+ /**
+ * Assert actual execute segment is correct with expected execute clause.
+ *
+ * @param assertContext assert context
+ * @param actual actual execute segment
+ * @param expected expected execute clause
+ */
+ public static void assertIs(final SQLCaseAssertContext assertContext,
final ExecSegment actual, final ExpectedExecClause expected) {
+ assertThat(assertContext.getText("exec procedure name assertion error:
"), actual.getProcedureName().getIdentifier().getValue(),
CoreMatchers.is(expected.getName()));
+ if (null == expected.getOwner()) {
+ assertFalse(actual.getProcedureName().getOwner().isPresent(),
assertContext.getText("Actual owner should not exist."));
+ } else {
+ assertTrue(actual.getProcedureName().getOwner().isPresent(),
assertContext.getText("Actual owner should exist."));
+ OwnerAssert.assertIs(assertContext,
actual.getProcedureName().getOwner().get(), expected.getOwner());
+ }
+ if (null == expected.getParameters()) {
+ assertThat(assertContext.getText("exec procedure parameters
assertion error: "), actual.getExpressionSegments().size(),
CoreMatchers.is(expected.getParameters().size()));
+ } else {
+ int count = 0;
+ for (ExpressionSegment expressionSegment :
actual.getExpressionSegments()) {
+ ExpressionAssert.assertExpression(assertContext,
expressionSegment, expected.getParameters().get(count));
+ count++;
+ }
+ }
+ SQLSegmentAssert.assertIs(assertContext, actual, expected);
+ }
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/impl/InsertStatementAssert.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/impl/InsertStatementAssert.java
index 6e8895ccbfd..6ec82b77b70 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/impl/InsertStatementAssert.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/impl/InsertStatementAssert.java
@@ -29,7 +29,9 @@ import
org.apache.shardingsphere.sql.parser.sql.dialect.handler.dml.InsertStatem
import
org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.table.MultiTableConditionalIntoSegment;
import
org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.table.MultiTableInsertIntoSegment;
import
org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.table.MultiTableInsertType;
+import
org.apache.shardingsphere.sql.parser.sql.dialect.segment.sqlserver.exec.ExecSegment;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.insert.InsertExecClauseAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.insert.InsertColumnsClauseAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.insert.InsertValuesClauseAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.insert.MultiTableConditionalIntoClauseAssert;
@@ -77,6 +79,7 @@ public final class InsertStatementAssert {
assertMultiTableInsertIntoClause(assertContext, actual, expected);
assertMultiTableConditionalIntoClause(assertContext, actual, expected);
assertReturningClause(assertContext, actual, expected);
+ assertInsertExecClause(assertContext, actual, expected);
}
private static void assertTable(final SQLCaseAssertContext assertContext,
final InsertStatement actual, final InsertStatementTestCase expected) {
@@ -195,4 +198,14 @@ public final class InsertStatementAssert {
ReturningClauseAssert.assertIs(assertContext,
returningSegment.get(), expected.getReturningClause());
}
}
+
+ private static void assertInsertExecClause(final SQLCaseAssertContext
assertContext, final InsertStatement actual, final InsertStatementTestCase
expected) {
+ Optional<ExecSegment> execSegment =
InsertStatementHandler.getExecSegment(actual);
+ if (null == expected.getExecClause()) {
+ assertFalse(execSegment.isPresent(), assertContext.getText("Actual
exec segment should not exist."));
+ } else {
+ assertTrue(execSegment.isPresent(), assertContext.getText("Actual
exec segment should exist."));
+ InsertExecClauseAssert.assertIs(assertContext, execSegment.get(),
expected.getExecClause());
+ }
+ }
}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/exec/ExpectedExecClause.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/exec/ExpectedExecClause.java
new file mode 100644
index 00000000000..656103482ef
--- /dev/null
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/exec/ExpectedExecClause.java
@@ -0,0 +1,46 @@
+/*
+ * 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.exec;
+
+import lombok.Getter;
+import lombok.Setter;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.AbstractExpectedSQLSegment;
+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.table.ExpectedOwner;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Expected execute clause.
+ */
+@Getter
+@Setter
+public final class ExpectedExecClause extends AbstractExpectedSQLSegment {
+
+ @XmlAttribute
+ private String name;
+
+ @XmlElement
+ private ExpectedOwner owner;
+
+ @XmlElement(name = "parameter")
+ private final List<ExpectedExpression> parameters = new LinkedList<>();
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/InsertStatementTestCase.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/InsertStatementTestCase.java
index 404e58ad87f..f2796de3263 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/InsertStatementTestCase.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/InsertStatementTestCase.java
@@ -20,12 +20,13 @@ package
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.
import lombok.Getter;
import lombok.Setter;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.SQLParserTestCase;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.exec.ExpectedExecClause;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.insert.ExpectedInsertColumnsClause;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.insert.ExpectedInsertValuesClause;
-import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.insert.ExpectedMultiTableConditionalIntoClause;
-import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.insert.ExpectedMultiTableInsertIntoClause;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.insert.ExpectedMultiTableInsertType;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.insert.ExpectedOnDuplicateKeyColumns;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.insert.ExpectedMultiTableInsertIntoClause;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.insert.ExpectedMultiTableConditionalIntoClause;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.insert.ExpectedReturningClause;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.output.ExpectedOutputClause;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.set.ExpectedSetClause;
@@ -83,4 +84,7 @@ public final class InsertStatementTestCase extends
SQLParserTestCase {
@XmlElement(name = "where")
private ExpectedWhereClause whereClause;
+
+ @XmlElement(name = "exec")
+ private ExpectedExecClause execClause;
}
diff --git a/test/it/parser/src/main/resources/case/dml/insert.xml
b/test/it/parser/src/main/resources/case/dml/insert.xml
index cf0a00f588b..14ce407ad7c 100644
--- a/test/it/parser/src/main/resources/case/dml/insert.xml
+++ b/test/it/parser/src/main/resources/case/dml/insert.xml
@@ -3026,4 +3026,39 @@
</from>
</select>
</insert>
+
+ <insert sql-case-id="insert_with_exec">
+ <table name="iris_rx_data" start-index="12" stop-index="23" />
+ <columns start-index="25" stop-index="98">
+ <column name="Sepal.Length" start-delimiter="""
end-delimiter=""" start-index="26" stop-index="39"/>
+ <column name="Sepal.Width" start-delimiter="""
end-delimiter=""" start-index="42" stop-index="54"/>
+ <column name="Petal.Length" start-delimiter="""
end-delimiter=""" start-index="57" stop-index="70"/>
+ <column name="Petal.Width" start-delimiter="""
end-delimiter=""" start-index="73" stop-index="85"/>
+ <column name="Species" start-delimiter="""
end-delimiter=""" start-index="89" stop-index="97"/>
+ </columns>
+ <exec name="sp_execute_external_script" start-index="100"
stop-index="183">
+ <parameter>
+ <binary-operation-expression start-index="135"
stop-index="150">
+ <left>
+ <column start-index="135" stop-index="143"
name="@language" />
+ </left>
+ <operator>=</operator>
+ <right>
+ <literal-expression value="R" start-index="147"
stop-index="150" />
+ </right>
+ </binary-operation-expression>
+ </parameter>
+ <parameter>
+ <binary-operation-expression start-index="154"
stop-index="183">
+ <left>
+ <column start-index="154" stop-index="160"
name="@script" />
+ </left>
+ <operator>=</operator>
+ <right>
+ <literal-expression value="iris_data <- iris"
start-index="164" stop-index="183" />
+ </right>
+ </binary-operation-expression>
+ </parameter>
+ </exec>
+ </insert>
</sql-parser-test-cases>
diff --git
a/test/it/parser/src/main/resources/case/dml/select-special-function.xml
b/test/it/parser/src/main/resources/case/dml/select-special-function.xml
index 44ef9346357..9704599ec4b 100644
--- a/test/it/parser/src/main/resources/case/dml/select-special-function.xml
+++ b/test/it/parser/src/main/resources/case/dml/select-special-function.xml
@@ -462,7 +462,7 @@
<simple-table name="t_order" start-index="29" stop-index="35" />
</from>
</select>
-
+
<select sql-case-id="select_with_lead_and_lag_function">
<projections start-index="7" stop-index="123" literal-start-index="7"
literal-stop-index="123">
<column-projection name="hire_date" start-index="7"
stop-index="15" literal-start-index="7" literal-stop-index="15" />
@@ -571,7 +571,7 @@
<column-item name="customer_id" order-direction="ASC"
start-index="80" stop-index="90" literal-start-index="80"
literal-stop-index="90" />
</order-by>
</select>
-
+
<select sql-case-id="select_pivot">
<projections start-index="7" stop-index="7">
<shorthand-projection start-index="7" stop-index="7"/>
@@ -591,4 +591,42 @@
</subquery-table>
</from>
</select>
+
+ <select sql-case-id="select_string_split_function">
+ <from>
+ <join-table join-type="CROSS">
+ <left>
+ <simple-table name="Product" start-index="59"
stop-index="65" />
+ </left>
+ <right>
+ <function-table>
+ <table-function function-name="STRING_SPLIT"
text="STRING_SPLIT(Tags, ',')"/>
+ </function-table>
+ </right>
+ </join-table>
+ </from>
+ <projections start-index="7" stop-index="52">
+ <column-projection name="value" alias="tag" start-index="7"
stop-index="18" />
+ <aggregation-projection type="COUNT" expression="COUNT(*)"
start-index="21" stop-index="28" alias="number_of_articles"/>
+ </projections>
+ <group-by>
+ <column-item name="value" start-index="112" stop-index="116"/>
+ </group-by>
+ <having start-index="118" stop-index="136">
+ <expr>
+ <binary-operation-expression start-index="125"
stop-index="136">
+ <left>
+ <aggregation-projection type="COUNT"
expression="COUNT(*)" start-index="125" stop-index="132"/>
+ </left>
+ <operator>></operator>
+ <right>
+ <literal-expression start-index="136" stop-index="136"
value="2"/>
+ </right>
+ </binary-operation-expression>
+ </expr>
+ </having>
+ <order-by>
+ <expression-item expression="COUNT(*)" order-direction="DESC"
start-index="147" stop-index="154"/>
+ </order-by>
+ </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 f07dc554277..43631b45468 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
@@ -656,4 +656,50 @@
</expr>
</where>
</select>
+
+ <select sql-case-id="select_with_exist_string_split_subquery">
+ <projections start-index="7" stop-index="27">
+ <column-projection name="ProductId" start-index="7"
stop-index="15" />
+ <column-projection name="Name" start-index="18" stop-index="21" />
+ <column-projection name="Tags" start-index="24" stop-index="27" />
+ </projections>
+ <from start-index="34" stop-index="40">
+ <simple-table name="Product" start-index="34" stop-index="40"/>
+ </from>
+ <where start-index="42" stop-index="129">
+ <expr>
+ <subquery start-index="48" stop-index="129">
+ <select>
+ <projections start-index="63" stop-index="63">
+ <shorthand-projection start-index="63"
stop-index="63" />
+ </projections>
+ <from start-index="70" stop-index="92">
+ <function-table>
+ <table-function
function-name="STRING_SPLIT" text="STRING_SPLIT(Tags, ',')"/>
+ </function-table>
+ </from>
+ <where start-index="94" stop-index="128">
+ <expr>
+ <in-expression start-index="100"
stop-index="128">
+ <left>
+ <column name="value"
start-index="100" stop-index="104" />
+ </left>
+ <right>
+ <list-expression start-index="109"
stop-index="128">
+ <items>
+ <literal-expression
value="clothing" start-index="110" stop-index="119"/>
+ </items>
+ <items>
+ <literal-expression
value="road" start-index="122" stop-index="127"/>
+ </items>
+ </list-expression>
+ </right>
+ </in-expression>
+ </expr>
+ </where>
+ </select>
+ </subquery>
+ </expr>
+ </where>
+ </select>
</sql-parser-test-cases>
diff --git a/test/it/parser/src/main/resources/case/dml/select.xml
b/test/it/parser/src/main/resources/case/dml/select.xml
index f133b8efec0..25a46d41758 100644
--- a/test/it/parser/src/main/resources/case/dml/select.xml
+++ b/test/it/parser/src/main/resources/case/dml/select.xml
@@ -7682,6 +7682,19 @@
</projections>
</select>
+ <select sql-case-id="select_with_unreserved_column">
+ <from>
+ <simple-table name="servers" start-index="38" stop-index="48">
+ <owner name="sys" start-index="38" stop-index="40"/>
+ </simple-table>
+ </from>
+ <projections start-index="7" stop-index="31">
+ <column-projection name="name" start-index="7" stop-index="10"/>
+ <column-projection name="server_id" start-index="13"
stop-index="21"/>
+ <column-projection name="provider" start-index="24"
stop-index="31"/>
+ </projections>
+ </select>
+
<select sql-case-id="select_with_count_temp_table">
<from>
<simple-table name="#Test" start-index="41" stop-index="45" />
diff --git a/test/it/parser/src/main/resources/sql/supported/dml/insert.xml
b/test/it/parser/src/main/resources/sql/supported/dml/insert.xml
index 3e01695c742..de9d8a43261 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/insert.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/insert.xml
@@ -108,5 +108,6 @@
<sql-case id="insert_with_nchar_3" value="INSERT INTO dbo.T1 VALUES (3,
N'Randolph')" db-types="SQLServer"/>
<sql-case id="insert_with_batch_nchar" value="INSERT INTO
TestSchema.Employees (Name, Location) VALUES (N'Jared', N'Australia'),
(N'Nikita', N'India'), (N'Tom', N'Germany')" db-types="SQLServer"/>
<sql-case id="insert_with_data_base_name" value="INSERT INTO
AdventureWorks2022.dbo.VariableTest(Col1) VALUES('$(tablename)')"
db-types="SQLServer"/>
+ <sql-case id="insert_with_exec" value="INSERT INTO iris_rx_data
("Sepal.Length", "Sepal.Width", "Petal.Length",
"Petal.Width" , "Species") EXECUTE
sp_execute_external_script @language = N'R' , @script = N'iris_data <-
iris'" db-types="SQLServer"/>
<sql-case id="insert_with_db_schema_name" value="INSERT INTO
ContosoWarehouse.dbo.Affiliation SELECT * FROM My_Lakehouse.dbo.Affiliation"
db-types="SQLServer"/>
</sql-cases>
diff --git
a/test/it/parser/src/main/resources/sql/supported/dml/select-special-function.xml
b/test/it/parser/src/main/resources/sql/supported/dml/select-special-function.xml
index 33706e16d67..382afdca059 100644
---
a/test/it/parser/src/main/resources/sql/supported/dml/select-special-function.xml
+++
b/test/it/parser/src/main/resources/sql/supported/dml/select-special-function.xml
@@ -44,4 +44,5 @@
<sql-case id="select_sys_xml_agg" value="SELECT
SYS_XMLAGG(SYS_XMLGEN(last_name)) XMLAGG FROM employees WHERE last_name LIKE
'R%' ORDER BY xmlagg;" db-types="Oracle" />
<sql-case id="select_set_function" value="SELECT customer_id,
SET(cust_address_ntab) address FROM customers_demo ORDER BY customer_id;"
db-types="Oracle" />
<sql-case id="select_pivot" value="SELECT * FROM (SELECT * FROM sales)
PIVOT (SUM(amount) FOR month IN ('Jan', 'Feb'))" db-types="Oracle"/>
+ <sql-case id="select_string_split_function" value="SELECT value as tag,
COUNT(*) AS [number_of_articles] FROM Product CROSS APPLY STRING_SPLIT(Tags,
',') GROUP BY value HAVING COUNT(*) > 2 ORDER BY COUNT(*) DESC"
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 0bc79bdd0b3..20c797a6d87 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
@@ -32,4 +32,5 @@
<sql-case id="select_with_between_and_subquery_condition" value="SELECT
t_order_federate.order_id, t_order_federate.user_id FROM t_order_federate WHERE
user_id BETWEEN (SELECT user_id FROM t_user_info WHERE information = 'before')
AND (SELECT user_id FROM t_user_info WHERE information = 'after')" />
<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-cases>
diff --git a/test/it/parser/src/main/resources/sql/supported/dml/select.xml
b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
index 50185cd9fc3..fd6938b456c 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
@@ -232,6 +232,7 @@
<sql-case id="select_with_user_updatable_columns" value="SELECT
column_name, updatable FROM user_updatable_columns WHERE table_name =
'LOCATIONS_VIEW' ORDER BY column_name, updatable" db-types="Oracle" />
<sql-case id="select_with_script_variables" value="SELECT x.$(ColumnName)
FROM Person.Person x WHERE x.BusinessEntityID > 5" db-types="SQLServer" />
<sql-case id="select_not_expression" value="select !0,NOT 0=1,!(0=0),1 AND
1,1 && 0,0 OR 1,1 || NULL, 1=1 or 1=1 and 1=0" db-types="MySQL" />
+ <sql-case id="select_with_unreserved_column" value="SELECT name,
server_id, provider FROM sys.servers" db-types="SQLServer" />
<sql-case id="select_with_count_temp_table" value="SELECT COUNT(*) AS
[Number of rows] FROM #Test" db-types="SQLServer"/>
<sql-case id="select_with_bracket_alias" value="SELECT obj1.name AS
[XEvent-name], col2.name AS [XEvent-column], obj1.description AS [Descr-name],
col2.description AS [Descr-column] FROM sys.dm_xe_objects AS obj1 INNER JOIN
sys.dm_xe_object_columns AS col2 ON col2.object_name = obj1.name ORDER BY
obj1.name, col2.name" db-types="SQLServer"/>
<sql-case id="select_with_cross_apply" value="SELECT query = a.text,
start_time, percent_complete, eta =
dateadd(second,estimated_completion_time/1000, getdate()) FROM
sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) a WHERE
r.command = 'RESTORE DATABASE'" db-types="SQLServer"/>