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 e0b43378876 Support parsing SQL Server UPDATE OPENQUERY sql #29184
(#29950)
e0b43378876 is described below
commit e0b43378876b543ea1ec946196a39d4f7321b296
Author: yydeng626 <[email protected]>
AuthorDate: Thu Feb 1 21:09:48 2024 -0600
Support parsing SQL Server UPDATE OPENQUERY sql #29184 (#29950)
* Support parsing SQL Server UPDATE OPENQUERY sql #29184
* Support parsing SQL Server UPDATE OPENQUERY sql #29184
* remove debug info
* add update output assert
* FIX CODE STYLE
---
.../src/main/antlr4/imports/sqlserver/BaseRule.g4 | 8 +-
.../main/antlr4/imports/sqlserver/DMLStatement.g4 | 3 +-
.../src/main/antlr4/imports/sqlserver/Keyword.g4 | 4 +
.../statement/SQLServerStatementVisitor.java | 6 +
.../handler/dml/UpdateStatementHandler.java | 26 +++
.../sqlserver/dml/SQLServerUpdateStatement.java | 12 ++
.../statement/dml/impl/UpdateStatementAssert.java | 13 ++
.../statement/dml/UpdateStatementTestCase.java | 4 +
.../parser/src/main/resources/case/dml/update.xml | 183 +++++++++++++++++++++
.../main/resources/sql/supported/dml/update.xml | 5 +
10 files changed, 261 insertions(+), 3 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 a760a7b0838..e73ed6dcee8 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
@@ -121,7 +121,7 @@ unreservedWord
| 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 | INPUT | YEAR
- | TIMESTAMP | TRIM | USER | RIGHT
+ | TIMESTAMP | TRIM | USER | RIGHT | WRITE
;
databaseName
@@ -312,7 +312,11 @@ distinct
;
specialFunction
- : conversionFunction | charFunction | openJsonFunction | jsonFunction |
openRowSetFunction | windowFunction | approxFunction
+ : conversionFunction | charFunction | openJsonFunction | jsonFunction |
openRowSetFunction | windowFunction | approxFunction | openDatasourceFunction
+ ;
+
+openDatasourceFunction
+ : (OPENDATASOURCE LP_ expr COMMA_ expr RP_) (DOT_ tableName)?
;
approxFunction
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 3eb7cbb040b..16e844ed23a 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
@@ -48,7 +48,7 @@ exec
;
update
- : withClause? UPDATE top? tableReferences withTableHint?
setAssignmentsClause whereClause? optionHint?
+ : withClause? UPDATE top? tableReferences withTableHint?
setAssignmentsClause outputClause? whereClause? optionHint?
;
assignment
@@ -61,6 +61,7 @@ setAssignmentsClause
assignmentValues
: LP_ assignmentValue (COMMA_ assignmentValue)* RP_
+ | assignmentValue
| LP_ RP_
;
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 bcc4057ded1..01bfe662a7a 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
@@ -799,3 +799,7 @@ APPROX_PERCENTILE_DISC
WITHIN
: W I T H I N
;
+
+OPENDATASOURCE
+ : O P E N D A T A S O U R C E
+ ;
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 2add26ef715..dd02b2841fd 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
@@ -1264,6 +1264,9 @@ public abstract class SQLServerStatementVisitor extends
SQLServerStatementBaseVi
if (null != ctx.optionHint()) {
result.setOptionHintSegment((OptionHintSegment)
visit(ctx.optionHint()));
}
+ if (null != ctx.outputClause()) {
+ result.setOutputSegment((OutputSegment) visit(ctx.outputClause()));
+ }
result.addParameterMarkerSegments(getParameterMarkerSegments());
return result;
}
@@ -1330,6 +1333,9 @@ public abstract class SQLServerStatementVisitor extends
SQLServerStatementBaseVi
if (null != ctx.whereClause()) {
result.setWhere((WhereSegment) visit(ctx.whereClause()));
}
+ if (null != ctx.outputClause()) {
+ result.setOutputSegment((OutputSegment) visit(ctx.outputClause()));
+ }
result.addParameterMarkerSegments(getParameterMarkerSegments());
return result;
}
diff --git
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/handler/dml/UpdateStatementHandler.java
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/handler/dml/UpdateStatementHandler.java
index 4e294f914bc..73a8aeda547 100644
---
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/handler/dml/UpdateStatementHandler.java
+++
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/handler/dml/UpdateStatementHandler.java
@@ -22,6 +22,7 @@ import lombok.NoArgsConstructor;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.OrderBySegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.limit.LimitSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment;
+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.UpdateStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.handler.SQLStatementHandler;
@@ -152,4 +153,29 @@ public final class UpdateStatementHandler implements
SQLStatementHandler {
((OracleUpdateStatement)
updateStatement).setDeleteWhere(deleteWhereSegment);
}
}
+
+ /**
+ * Get output segment.
+ *
+ * @param updateStatement update statement
+ * @return output segment
+ */
+ public static Optional<OutputSegment> getOutputSegment(final
UpdateStatement updateStatement) {
+ if (updateStatement instanceof SQLServerStatement) {
+ return ((SQLServerUpdateStatement)
updateStatement).getOutputSegment();
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Set output segment.
+ *
+ * @param updateStatement update statement
+ * @param outputSegment output segment
+ */
+ public static void setOutputSegment(final UpdateStatement updateStatement,
final OutputSegment outputSegment) {
+ if (updateStatement instanceof SQLServerStatement) {
+ ((SQLServerUpdateStatement)
updateStatement).setOutputSegment(outputSegment);
+ }
+ }
}
diff --git
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerUpdateStatement.java
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerUpdateStatement.java
index 78d972aff39..5e8eb86612d 100644
---
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerUpdateStatement.java
+++
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/sqlserver/dml/SQLServerUpdateStatement.java
@@ -18,6 +18,7 @@
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.UpdateStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.segment.sqlserver.hint.OptionHintSegment;
@@ -38,6 +39,8 @@ public final class SQLServerUpdateStatement extends
UpdateStatement implements S
private OptionHintSegment optionHintSegment;
+ private OutputSegment outputSegment;
+
/**
* Get with segment.
*
@@ -64,4 +67,13 @@ public final class SQLServerUpdateStatement extends
UpdateStatement implements S
public Optional<OptionHintSegment> getOptionHintSegment() {
return Optional.ofNullable(optionHintSegment);
}
+
+ /**
+ * Get output segment.
+ *
+ * @return output segment.
+ */
+ public Optional<OutputSegment> getOutputSegment() {
+ return Optional.ofNullable(outputSegment);
+ }
}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/impl/UpdateStatementAssert.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/impl/UpdateStatementAssert.java
index 7ba324b9486..1cb3b3b35b9 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/impl/UpdateStatementAssert.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/impl/UpdateStatementAssert.java
@@ -21,6 +21,7 @@ import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.OrderBySegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.limit.LimitSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OutputSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.UpdateStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.handler.dml.UpdateStatementHandler;
import
org.apache.shardingsphere.sql.parser.sql.dialect.segment.sqlserver.hint.OptionHintSegment;
@@ -28,6 +29,7 @@ import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAsse
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.SQLSegmentAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.limit.LimitClauseAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.orderby.OrderByClauseAssert;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.output.OutputClauseAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.set.SetClauseAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.table.TableAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.where.WhereClauseAssert;
@@ -61,6 +63,7 @@ public final class UpdateStatementAssert {
assertOrderByClause(assertContext, actual, expected);
assertLimitClause(assertContext, actual, expected);
assertOptionHint(assertContext, actual, expected);
+ assertOutputClause(assertContext, actual, expected);
}
private static void assertTable(final SQLCaseAssertContext assertContext,
final UpdateStatement actual, final UpdateStatementTestCase expected) {
@@ -115,4 +118,14 @@ public final class UpdateStatementAssert {
SQLSegmentAssert.assertIs(assertContext, optionHintSegment.get(),
expected.getOptionHint());
}
}
+
+ private static void assertOutputClause(final SQLCaseAssertContext
assertContext, final UpdateStatement actual, final UpdateStatementTestCase
expected) {
+ Optional<OutputSegment> outputSegment =
UpdateStatementHandler.getOutputSegment(actual);
+ if (null == expected.getOutputClause()) {
+ assertFalse(outputSegment.isPresent(),
assertContext.getText("Actual output segment should not exist."));
+ } else {
+ assertTrue(outputSegment.isPresent(),
assertContext.getText("Actual output segment should exist."));
+ OutputClauseAssert.assertIs(assertContext, outputSegment.get(),
expected.getOutputClause());
+ }
+ }
}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/UpdateStatementTestCase.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/UpdateStatementTestCase.java
index 8672fc8c950..6d46d455f7d 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/UpdateStatementTestCase.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/UpdateStatementTestCase.java
@@ -22,6 +22,7 @@ import lombok.Setter;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.hint.ExpectedOptionHint;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.limit.ExpectedLimitClause;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.orderby.ExpectedOrderByClause;
+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;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.table.ExpectedTable;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.where.ExpectedWhereClause;
@@ -53,4 +54,7 @@ public final class UpdateStatementTestCase extends
SQLParserTestCase {
@XmlElement(name = "option-hint")
private ExpectedOptionHint optionHint;
+
+ @XmlElement(name = "output")
+ private ExpectedOutputClause outputClause;
}
diff --git a/test/it/parser/src/main/resources/case/dml/update.xml
b/test/it/parser/src/main/resources/case/dml/update.xml
index 28c5d5bdc3c..ab717e8f7ac 100644
--- a/test/it/parser/src/main/resources/case/dml/update.xml
+++ b/test/it/parser/src/main/resources/case/dml/update.xml
@@ -1713,4 +1713,187 @@
</from>
</set>
</update>
+
+ <update sql-case-id="update_with_open_query_function">
+ <table start-index="7" stop-index="106">
+ <function-table start-index="7" stop-index="106">
+ <table-function function-name="OPENQUERY" text="OPENQUERY
(MyLinkedServer, 'SELECT GroupName FROM HumanResources.Department WHERE
DepartmentID = 4')">
+ <parameter>
+ <column name="MyLinkedServer" start-index="18"
stop-index="31" />
+ </parameter>
+ <parameter>
+ <literal-expression value="SELECT GroupName FROM
HumanResources.Department WHERE DepartmentID = 4" start-index="34"
stop-index="105" />
+ </parameter>
+ </table-function>
+ </function-table>
+ </table>
+ <set start-index="108" stop-index="144">
+ <assignment start-index="112" stop-index="144">
+ <column name="GroupName" start-index="112" stop-index="120" />
+ <assignment-value>
+ <literal-expression value="Sales and Marketing"
start-index="124" stop-index="144" />
+ </assignment-value>
+ </assignment>
+ </set>
+ </update>
+
+ <update sql-case-id="update_with_open_datasource_function">
+ <table start-index="7" stop-index="130">
+ <function-table start-index="7" stop-index="130">
+ <table-function function-name="OPENDATASOURCE"
text="OPENDATASOURCE('SQLNCLI', 'Data Source=<server name>;Integrated
Security=SSPI').AdventureWorks2022.HumanResources.Department" />
+ </function-table>
+ </table>
+ <set start-index="132" stop-index="168">
+ <assignment>
+ <column name="GroupName" start-index="136" stop-index="144" />
+ <assignment-value>
+ <literal-expression value="Sales and Marketing"
start-index="148" stop-index="168" />
+ </assignment-value>
+ </assignment>
+ </set>
+ <where start-index="170" stop-index="191">
+ <expr>
+ <binary-operation-expression start-index="176"
stop-index="191">
+ <left>
+ <column name="DepartmentID" start-index="176"
stop-index="187" />
+ </left>
+ <right>
+ <literal-expression value="4" start-index="191"
stop-index="191" />
+ </right>
+ <operator>=</operator>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </update>
+
+ <update sql-case-id="update_with_write_function_and_output_clause">
+ <table start-index="7" stop-index="25">
+ <simple-table name="Document" start-index="7" stop-index="25">
+ <owner name="Production" start-index="7" stop-index="16" />
+ </simple-table>
+ </table>
+ <set start-index="27" stop-index="72">
+ <assignment start-index="31" stop-index="72">
+ <column name="DocumentSummary" start-index="31"
stop-index="45" />
+ <assignment-value>
+ <function function-name="WRITE" text="WRITE
(N'features',28,10)" start-index="48" stop-index="72">
+ <parameter>
+ <literal-expression value="features"
start-index="55" stop-index="65" />
+ </parameter>
+ <parameter>
+ <literal-expression value="28" start-index="67"
stop-index="68" />
+ </parameter>
+ <parameter>
+ <literal-expression value="10" start-index="70"
stop-index="71" />
+ </parameter>
+ </function>
+ </assignment-value>
+ </assignment>
+ </set>
+ <output start-index="74" stop-index="146">
+ <output-table name="@MyTableVar" start-index="136"
stop-index="146" />
+ <output-columns>
+ <column-projection name="DocumentSummary" start-index="81"
stop-index="103" />
+ <column-projection name="DocumentSummary" start-index="106"
stop-index="129" />
+ </output-columns>
+ </output>
+ <where start-index="148" stop-index="200">
+ <expr>
+ <binary-operation-expression start-index="154"
stop-index="200">
+ <left>
+ <column name="Title" start-index="154"
stop-index="158" />
+ </left>
+ <right>
+ <literal-expression value="Front Reflector Bracket
Installation" start-index="162" stop-index="200" />
+ </right>
+ <operator>=</operator>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </update>
+
+ <update sql-case-id="update_with_open_rowset_function_and_subquery">
+ <table start-index="7" stop-index="29">
+ <simple-table name="ProductPhoto" start-index="7" stop-index="29">
+ <owner name="Production" start-index="7" stop-index="16" />
+ </simple-table>
+ </table>
+ <set start-index="31" stop-index="118">
+ <assignment start-index="35" stop-index="118">
+ <column name="ThumbNailPhoto" start-index="35" stop-index="48"
/>
+ <assignment-value>
+ <subquery start-index="52" stop-index="118">
+ <select>
+ <projections start-index="61" stop-index="61">
+ <shorthand-projection start-index="61"
stop-index="61" />
+ </projections>
+ <from start-index="69" stop-index="111">
+ <function-table table-alias="x"
start-index="69" stop-index="111">
+ <table-function function-name="OPENROWSET"
text="OPENROWSET(BULK 'c:Tires.jpg', SINGLE_BLOB)">
+ <parameter>
+ <literal-expression
value="c:Tires.jpg" start-index="85" stop-index="97" />
+ </parameter>
+ <parameter>
+ <column name="SINGLE_BLOB"
start-index="100" stop-index="110" />
+ </parameter>
+ </table-function>
+ </function-table>
+ </from>
+ </select>
+ </subquery>
+ </assignment-value>
+ </assignment>
+ </set>
+ <where start-index="120" stop-index="143">
+ <expr>
+ <binary-operation-expression start-index="126"
stop-index="143">
+ <left>
+ <column name="ProductPhotoID" start-index="126"
stop-index="139" />
+ </left>
+ <right>
+ <literal-expression value="1" start-index="143"
stop-index="143" />
+ </right>
+ <operator>=</operator>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </update>
+
+ <update sql-case-id="update_with_filestream">
+ <table start-index="7" stop-index="25">
+ <simple-table name="Records" start-index="7" stop-index="25">
+ <owner name="dbo" start-index="15" stop-index="17">
+ <owner name="Archive" start-index="7" stop-index="13" />
+ </owner>
+ </simple-table>
+ </table>
+ <set start-index="27" stop-index="72">
+ <assignment start-index="31" stop-index="72">
+ <column name="Chart" start-delimiter="[" end-delimiter="]"
start-index="31" stop-index="37" />
+ <assignment-value>
+ <function function-name="CAST" text="CAST('Xray 1' as
VARBINARY(max))" start-index="41" stop-index="72">
+ <parameter>
+ <literal-expression value="Xray 1"
start-index="46" stop-index="53" />
+ </parameter>
+ <parameter>
+ <data-type value="VARBINARY" start-index="58"
stop-index="71" />
+ </parameter>
+ </function>
+ </assignment-value>
+ </assignment>
+ </set>
+ <where start-index="74" stop-index="97">
+ <expr>
+ <binary-operation-expression start-index="80" stop-index="97">
+ <left>
+ <column name="SerialNumber" start-delimiter="["
end-delimiter="]" start-index="80" stop-index="93" />
+ </left>
+ <right>
+ <literal-expression value="2" start-index="97"
stop-index="97" />
+ </right>
+ <operator>=</operator>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </update>
</sql-parser-test-cases>
diff --git a/test/it/parser/src/main/resources/sql/supported/dml/update.xml
b/test/it/parser/src/main/resources/sql/supported/dml/update.xml
index e39c9d0ce75..1693c49e63a 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/update.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/update.xml
@@ -53,4 +53,9 @@
<sql-case id="update_with_option_hint" value="UPDATE Production.Product
SET ListPrice = ListPrice * 1.10 WHERE ProductNumber LIKE @Product OPTION
(OPTIMIZE FOR (@Product = 'BK-%'))" db-types="SQLServer"/>
<sql-case id="update_sales_table_with_subquery" value="UPDATE
YearlyTotalSales SET YearlySalesAmount=(SELECT SUM(SalesAmount) FROM
FactInternetSales WHERE OrderDateKey >=20040000 AND OrderDateKey < 20050000)
WHERE Year=2004" db-types="SQLServer"/>
<sql-case id="update_with_inner_join_and_database_table_column"
value="UPDATE dbo.Table2 SET dbo.Table2.ColB = dbo.Table2.ColB +
dbo.Table1.ColB FROM dbo.Table2 INNER JOIN dbo.Table1 ON (dbo.Table2.ColA =
dbo.Table1.ColA)" db-types="SQLServer"/>
+ <sql-case id="update_with_open_query_function" value="UPDATE OPENQUERY
(MyLinkedServer, 'SELECT GroupName FROM HumanResources.Department WHERE
DepartmentID = 4') SET GroupName = 'Sales and Marketing'" db-types="SQLServer"/>
+ <sql-case id="update_with_open_datasource_function" value="UPDATE
OPENDATASOURCE('SQLNCLI', 'Data Source=<server name>;Integrated
Security=SSPI').AdventureWorks2022.HumanResources.Department SET GroupName =
'Sales and Marketing' WHERE DepartmentID = 4" db-types="SQLServer"/>
+ <sql-case id="update_with_write_function_and_output_clause" value="UPDATE
Production.Document SET DocumentSummary .WRITE (N'features',28,10) OUTPUT
deleted.DocumentSummary, inserted.DocumentSummary INTO @MyTableVar WHERE Title
= N'Front Reflector Bracket Installation'" db-types="SQLServer"/>
+ <sql-case id="update_with_open_rowset_function_and_subquery" value="UPDATE
Production.ProductPhoto SET ThumbNailPhoto = ( SELECT * FROM OPENROWSET(BULK
'c:Tires.jpg', SINGLE_BLOB) AS x ) WHERE ProductPhotoID = 1"
db-types="SQLServer"/>
+ <sql-case id="update_with_filestream" value="UPDATE Archive.dbo.Records
SET [Chart] = CAST('Xray 1' as VARBINARY(max)) WHERE [SerialNumber] = 2"
db-types="SQLServer"/>
</sql-cases>