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=&lt;server name&gt;;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 &lt; 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=&lt;server name&gt;;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>

Reply via email to