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 b5218e8b731 Optimize MySQL INSERT INTO VALUES AS row_alias parse 
SQLStatement (#36680)
b5218e8b731 is described below

commit b5218e8b731acb09482ebe6808759dd1329d4f61
Author: chakkk309 <[email protected]>
AuthorDate: Sat Dec 20 11:11:34 2025 +0800

    Optimize MySQL INSERT INTO VALUES AS row_alias parse SQLStatement (#36680)
    
    * optimize MySQL INSERT INTO VALUES AS row_alias parse SQLStatement
    
    * apply spotless
    
    * fix checkstyle
    
    * optimize MySQL INSERT AS syntax implementation
    
    * fix: MySQL parser compilation errors in visitInsertBody method
---
 .../src/main/antlr4/imports/mysql/DMLStatement.g4  |  24 ++-
 .../visitor/statement/MySQLStatementVisitor.java   |  89 +++++++++--
 .../segment/dml/assignment/RowAliasSegment.java    |  52 ++++++
 .../dml/assignment/ValueReferenceSegment.java      |  52 ++++++
 .../core/statement/type/dml/InsertStatement.java   |  12 ++
 .../segment/assignment/RowAliasSegmentAssert.java  |  61 +++++++
 .../assignment/ValueReferenceSegmentAssert.java    |  55 +++++++
 .../dml/standard/type/InsertStatementAssert.java   |  13 ++
 .../segment/impl/assignment/ExpectedRowAlias.java  |  43 +++++
 .../impl/assignment/ExpectedValueReference.java    |  52 ++++++
 .../dml/standard/InsertStatementTestCase.java      |   4 +
 .../parser/src/main/resources/case/dml/insert.xml  | 175 ++++++++++++++++++---
 .../main/resources/sql/supported/dml/insert.xml    |   7 +-
 13 files changed, 605 insertions(+), 34 deletions(-)

diff --git 
a/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/DMLStatement.g4 
b/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/DMLStatement.g4
index a8941a1c35e..42a3d086a71 100644
--- 
a/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/DMLStatement.g4
+++ 
b/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/DMLStatement.g4
@@ -20,7 +20,13 @@ grammar DMLStatement;
 import BaseRule;
 
 insert
-    : INSERT insertSpecification INTO? tableName partitionNames? 
(insertValuesClause | setAssignmentsClause | insertSelectClause) 
onDuplicateKeyClause? returningClause?
+    : INSERT insertSpecification INTO? tableName partitionNames? insertBody 
onDuplicateKeyClause? returningClause?
+    ;
+
+insertBody
+    : insertValuesClause
+    | setAssignmentsClause valueReference?
+    | insertSelectClause valueReference?
     ;
 
 insertSpecification
@@ -47,8 +53,12 @@ insertSelectClause
     : valueReference? (LP_ fields? RP_)? (LP_ select RP_ | select)
     ;
 
+rowAlias
+    : AS alias derivedColumns?
+    ;
+
 onDuplicateKeyClause
-    : (AS identifier derivedColumns?)?  ON DUPLICATE KEY UPDATE assignment 
(COMMA_ assignment)*
+    : ON DUPLICATE KEY UPDATE assignment (COMMA_ assignment)*
     ;
 
 valueReference
@@ -88,7 +98,15 @@ assignment
     ;
 
 setAssignmentsClause
-    : SET assignment (COMMA_ assignment)*
+    : SET assignmentList setRowAlias?
+    ;
+
+assignmentList
+    : assignment (COMMA_ assignment)*
+    ;
+
+setRowAlias
+    : AS alias derivedColumns?
     ;
 
 assignmentValues
diff --git 
a/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitor.java
 
b/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitor.java
index 68d4d3b108b..dcf94f84892 100644
--- 
a/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitor.java
+++ 
b/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitor.java
@@ -74,6 +74,7 @@ import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.HavingC
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.HexadecimalLiteralsContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.IdentifierContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.IndexNameContext;
+import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.InsertBodyContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.InsertContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.InsertIdentifierContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.InsertSelectClauseContext;
@@ -115,12 +116,15 @@ import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.Regular
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ReplaceContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ReplaceSelectClauseContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ReplaceValuesClauseContext;
+import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.RowAliasContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.RowConstructorListContext;
+import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ValueReferenceContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SelectContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SelectSpecificationContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SelectWithIntoContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SeparatorNameContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SetAssignmentsClauseContext;
+import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SetRowAliasContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ShorthandRegularFunctionContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SimpleExprContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SingleTableClauseContext;
@@ -171,6 +175,8 @@ import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.Returning
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.ColumnAssignmentSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.InsertValuesSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.SetAssignmentSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.RowAliasSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.ValueReferenceSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.InsertColumnsSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.OnDuplicateKeyColumnsSegment;
@@ -1479,15 +1485,7 @@ public abstract class MySQLStatementVisitor extends 
MySQLStatementBaseVisitor<AS
     @Override
     public ASTNode visitInsert(final InsertContext ctx) {
         // TODO :FIXME, since there is no segment for insertValuesClause, 
InsertStatement is created by sub rule.
-        InsertStatement result;
-        if (null != ctx.insertValuesClause()) {
-            result = (InsertStatement) visit(ctx.insertValuesClause());
-        } else if (null != ctx.insertSelectClause()) {
-            result = (InsertStatement) visit(ctx.insertSelectClause());
-        } else {
-            result = new InsertStatement(databaseType);
-            result.setSetAssignment((SetAssignmentSegment) 
visit(ctx.setAssignmentsClause()));
-        }
+        InsertStatement result = (InsertStatement) visit(ctx.insertBody());
         if (null != ctx.onDuplicateKeyClause()) {
             result.setOnDuplicateKeyColumns((OnDuplicateKeyColumnsSegment) 
visit(ctx.onDuplicateKeyClause()));
         }
@@ -1500,6 +1498,29 @@ public abstract class MySQLStatementVisitor extends 
MySQLStatementBaseVisitor<AS
         return result;
     }
     
+    @Override
+    public ASTNode visitInsertBody(final InsertBodyContext ctx) {
+        InsertStatement result;
+        if (null != ctx.insertValuesClause()) {
+            result = (InsertStatement) visit(ctx.insertValuesClause());
+        } else if (null != ctx.insertSelectClause()) {
+            result = (InsertStatement) visit(ctx.insertSelectClause());
+            if (null != ctx.valueReference()) {
+                result.setValueReference((ValueReferenceSegment) 
visit(ctx.valueReference()));
+            }
+        } else {
+            result = new InsertStatement(databaseType);
+            result.setSetAssignment((SetAssignmentSegment) 
visit(ctx.setAssignmentsClause()));
+            if (null != ctx.valueReference()) {
+                result.setValueReference((ValueReferenceSegment) 
visit(ctx.valueReference()));
+            }
+            if (null == ctx.valueReference() && null != 
ctx.setAssignmentsClause().setRowAlias()) {
+                
result.setValueReference(createValueReferenceFromSetRowAlias(ctx.setAssignmentsClause().setRowAlias()));
+            }
+        }
+        return result;
+    }
+    
     @Override
     public ASTNode visitInsertSelectClause(final InsertSelectClauseContext 
ctx) {
         InsertStatement result = new InsertStatement(databaseType);
@@ -1516,6 +1537,20 @@ public abstract class MySQLStatementVisitor extends 
MySQLStatementBaseVisitor<AS
         return result;
     }
     
+    private ValueReferenceSegment createValueReferenceFromSetRowAlias(final 
SetRowAliasContext ctx) {
+        AliasSegment alias = (AliasSegment) visit(ctx.alias());
+        Collection<ColumnSegment> derivedColumns = null;
+        if (null != ctx.derivedColumns()) {
+            derivedColumns = new LinkedList<>();
+            for (AliasContext each : ctx.derivedColumns().alias()) {
+                AliasSegment aliasSegment = (AliasSegment) visit(each);
+                ColumnSegment column = new 
ColumnSegment(each.getStart().getStartIndex(), each.getStop().getStopIndex(), 
aliasSegment.getIdentifier());
+                derivedColumns.add(column);
+            }
+        }
+        return new ValueReferenceSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), alias, derivedColumns);
+    }
+    
     private SubquerySegment createInsertSelectSegment(final 
InsertSelectClauseContext ctx) {
         SelectStatement selectStatement = (SelectStatement) 
visit(ctx.select());
         selectStatement.addParameterMarkers(getParameterMarkerSegments());
@@ -1534,6 +1569,10 @@ public abstract class MySQLStatementVisitor extends 
MySQLStatementBaseVisitor<AS
         } else {
             result.setInsertColumns(new 
InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 
1, Collections.emptyList()));
         }
+        if (null != ctx.valueReference()) {
+            ValueReferenceSegment valueRef = (ValueReferenceSegment) 
visit(ctx.valueReference());
+            result.setValueReference(valueRef);
+        }
         Collection<InsertValuesSegment> insertValuesSegments =
                 null == ctx.rowConstructorList() ? 
createInsertValuesSegments(ctx.assignmentValues()) : 
createRowConstructorList(ctx.rowConstructorList());
         result.getValues().addAll(insertValuesSegments);
@@ -1548,6 +1587,36 @@ public abstract class MySQLStatementVisitor extends 
MySQLStatementBaseVisitor<AS
         return result;
     }
     
+    @Override
+    public ASTNode visitRowAlias(final RowAliasContext ctx) {
+        AliasSegment alias = (AliasSegment) visit(ctx.alias());
+        Collection<ColumnSegment> derivedColumns = null;
+        if (null != ctx.derivedColumns()) {
+            derivedColumns = new LinkedList<>();
+            for (AliasContext each : ctx.derivedColumns().alias()) {
+                AliasSegment aliasSegment = (AliasSegment) visit(each);
+                ColumnSegment column = new 
ColumnSegment(each.getStart().getStartIndex(), each.getStop().getStopIndex(), 
aliasSegment.getIdentifier());
+                derivedColumns.add(column);
+            }
+        }
+        return new RowAliasSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), alias, derivedColumns);
+    }
+    
+    @Override
+    public ASTNode visitValueReference(final ValueReferenceContext ctx) {
+        AliasSegment alias = (AliasSegment) visit(ctx.alias());
+        Collection<ColumnSegment> derivedColumns = null;
+        if (null != ctx.derivedColumns()) {
+            derivedColumns = new LinkedList<>();
+            for (AliasContext each : ctx.derivedColumns().alias()) {
+                AliasSegment aliasSegment = (AliasSegment) visit(each);
+                ColumnSegment column = new 
ColumnSegment(each.getStart().getStartIndex(), each.getStop().getStopIndex(), 
aliasSegment.getIdentifier());
+                derivedColumns.add(column);
+            }
+        }
+        return new ValueReferenceSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), alias, derivedColumns);
+    }
+    
     @Override
     public ASTNode visitOnDuplicateKeyClause(final OnDuplicateKeyClauseContext 
ctx) {
         Collection<ColumnAssignmentSegment> columns = new LinkedList<>();
@@ -1648,7 +1717,7 @@ public abstract class MySQLStatementVisitor extends 
MySQLStatementBaseVisitor<AS
     @Override
     public ASTNode visitSetAssignmentsClause(final SetAssignmentsClauseContext 
ctx) {
         Collection<ColumnAssignmentSegment> assignments = new LinkedList<>();
-        for (AssignmentContext each : ctx.assignment()) {
+        for (AssignmentContext each : ctx.assignmentList().assignment()) {
             assignments.add((ColumnAssignmentSegment) visit(each));
         }
         return new SetAssignmentSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), assignments);
diff --git 
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/dml/assignment/RowAliasSegment.java
 
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/dml/assignment/RowAliasSegment.java
new file mode 100644
index 00000000000..cc7f6ba8f3d
--- /dev/null
+++ 
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/dml/assignment/RowAliasSegment.java
@@ -0,0 +1,52 @@
+/*
+ * 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.statement.core.segment.dml.assignment;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.SQLSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.AliasSegment;
+
+import java.util.Collection;
+import java.util.Optional;
+
+/**
+ * Row alias segment for INSERT INTO VALUES AS row_alias syntax.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class RowAliasSegment implements SQLSegment {
+    
+    private final int startIndex;
+    
+    private final int stopIndex;
+    
+    private final AliasSegment alias;
+    
+    private final Collection<ColumnSegment> derivedColumns;
+    
+    /**
+     * Get derived columns.
+     *
+     * @return derived columns
+     */
+    public Optional<Collection<ColumnSegment>> getDerivedColumns() {
+        return Optional.ofNullable(derivedColumns);
+    }
+}
diff --git 
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/dml/assignment/ValueReferenceSegment.java
 
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/dml/assignment/ValueReferenceSegment.java
new file mode 100644
index 00000000000..1f4553af797
--- /dev/null
+++ 
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/dml/assignment/ValueReferenceSegment.java
@@ -0,0 +1,52 @@
+/*
+ * 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.statement.core.segment.dml.assignment;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.SQLSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.AliasSegment;
+
+import java.util.Collection;
+import java.util.Optional;
+
+/**
+ * Value reference segment for INSERT INTO VALUES AS alias syntax.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class ValueReferenceSegment implements SQLSegment {
+    
+    private final int startIndex;
+    
+    private final int stopIndex;
+    
+    private final AliasSegment alias;
+    
+    private final Collection<ColumnSegment> derivedColumns;
+    
+    /**
+     * Get derived columns.
+     *
+     * @return derived columns
+     */
+    public Optional<Collection<ColumnSegment>> getDerivedColumns() {
+        return Optional.ofNullable(derivedColumns);
+    }
+}
diff --git 
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/dml/InsertStatement.java
 
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/dml/InsertStatement.java
index e1430b26d13..cbc91315831 100644
--- 
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/dml/InsertStatement.java
+++ 
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/dml/InsertStatement.java
@@ -23,6 +23,7 @@ import 
org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.ReturningSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.InsertValuesSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.SetAssignmentSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.ValueReferenceSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.InsertColumnsSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.OnDuplicateKeyColumnsSegment;
@@ -62,6 +63,8 @@ public final class InsertStatement extends DMLStatement {
     
     private OnDuplicateKeyColumnsSegment onDuplicateKeyColumns;
     
+    private ValueReferenceSegment valueReference;
+    
     private ReturningSegment returning;
     
     private OutputSegment output;
@@ -139,6 +142,15 @@ public final class InsertStatement extends DMLStatement {
         return Optional.ofNullable(onDuplicateKeyColumns);
     }
     
+    /**
+     * Get value reference.
+     *
+     * @return value reference
+     */
+    public Optional<ValueReferenceSegment> getValueReference() {
+        return Optional.ofNullable(valueReference);
+    }
+    
     /**
      * Get set assignment.
      *
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/assignment/RowAliasSegmentAssert.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/assignment/RowAliasSegmentAssert.java
new file mode 100644
index 00000000000..4813a9becba
--- /dev/null
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/assignment/RowAliasSegmentAssert.java
@@ -0,0 +1,61 @@
+/*
+ * 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.assignment;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.RowAliasSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
+import 
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext;
+import 
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.column.ColumnAssert;
+import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.assignment.ExpectedRowAlias;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * Row alias segment assert.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class RowAliasSegmentAssert {
+    
+    /**
+     * Assert actual row alias segment is correct with expected row alias.
+     *
+     * @param assertContext assert context
+     * @param actual actual row alias segment
+     * @param expected expected row alias
+     */
+    public static void assertIs(final SQLCaseAssertContext assertContext, 
final RowAliasSegment actual, final ExpectedRowAlias expected) {
+        assertThat(assertContext.getText("Row alias name assertion error: "), 
actual.getAlias().getIdentifier().getValue(), is(expected.getAlias()));
+        if (null != expected.getDerivedColumns() && 
!expected.getDerivedColumns().isEmpty()) {
+            assertThat(assertContext.getText("Row alias derived columns size 
assertion error: "),
+                    actual.getDerivedColumns().isPresent(), is(true));
+            assertThat(assertContext.getText("Row alias derived columns size 
assertion error: "),
+                    actual.getDerivedColumns().get().size(), 
is(expected.getDerivedColumns().size()));
+            int count = 0;
+            for (ColumnSegment each : actual.getDerivedColumns().get()) {
+                ColumnAssert.assertIs(assertContext, each, 
expected.getDerivedColumns().get(count));
+                count++;
+            }
+        } else {
+            assertThat(assertContext.getText("Row alias derived columns 
assertion error: "),
+                    actual.getDerivedColumns().isPresent(), is(false));
+        }
+    }
+}
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/assignment/ValueReferenceSegmentAssert.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/assignment/ValueReferenceSegmentAssert.java
new file mode 100644
index 00000000000..97e64cd79f7
--- /dev/null
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/assignment/ValueReferenceSegmentAssert.java
@@ -0,0 +1,55 @@
+/*
+ * 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.assignment;
+
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.ValueReferenceSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
+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.column.ColumnAssert;
+import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.assignment.ExpectedValueReference;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * Value reference segment assert.
+ */
+public final class ValueReferenceSegmentAssert {
+    
+    /**
+     * Assert actual value reference segment is correct with expected value 
reference.
+     *
+     * @param assertContext assert context
+     * @param actual actual value reference segment
+     * @param expected expected value reference
+     */
+    public static void assertIs(final SQLCaseAssertContext assertContext, 
final ValueReferenceSegment actual, final ExpectedValueReference expected) {
+        assertThat(assertContext.getText("Value reference name assertion 
error: "), actual.getAlias().getIdentifier().getValue(), 
is(expected.getAlias()));
+        SQLSegmentAssert.assertIs(assertContext, actual, expected);
+        if (expected.getDerivedColumns().isPresent() && 
actual.getDerivedColumns().isPresent()) {
+            assertThat(assertContext.getText("Value reference derived columns 
size assertion error: "),
+                    actual.getDerivedColumns().get().size(), 
is(expected.getDerivedColumns().get().size()));
+            int index = 0;
+            for (ColumnSegment each : actual.getDerivedColumns().get()) {
+                ColumnAssert.assertIs(assertContext, each, 
expected.getDerivedColumns().get().get(index));
+                index++;
+            }
+        }
+    }
+}
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/standard/type/InsertStatementAssert.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/standard/type/InsertStatementAssert.java
index 6e8cf087317..a53269f0812 100644
--- 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/standard/type/InsertStatementAssert.java
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dml/standard/type/InsertStatementAssert.java
@@ -21,6 +21,7 @@ import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.ReturningSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.SetAssignmentSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.ValueReferenceSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.OnDuplicateKeyColumnsSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.exec.ExecSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
@@ -41,6 +42,7 @@ import 
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.ins
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.insert.MultiTableConditionalIntoClauseAssert;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.insert.MultiTableInsertIntoClauseAssert;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.insert.OnDuplicateKeyColumnsAssert;
+import 
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.assignment.ValueReferenceSegmentAssert;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.output.OutputClauseAssert;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.parameter.ParameterMarkerAssert;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.returning.ReturningClauseAssert;
@@ -77,6 +79,7 @@ public final class InsertStatementAssert {
         assertSetClause(assertContext, actual, expected);
         assertInsertSelectClause(assertContext, actual, expected);
         assertOnDuplicateKeyColumns(assertContext, actual, expected);
+        assertValueReference(assertContext, actual, expected);
         assertWithClause(assertContext, actual, expected);
         assertOutputClause(assertContext, actual, expected);
         assertMultiTableInsertType(assertContext, actual, expected);
@@ -154,6 +157,16 @@ public final class InsertStatementAssert {
         }
     }
     
+    private static void assertValueReference(final SQLCaseAssertContext 
assertContext, final InsertStatement actual, final InsertStatementTestCase 
expected) {
+        Optional<ValueReferenceSegment> valueReferenceSegment = 
actual.getValueReference();
+        if (null == expected.getValueReference()) {
+            assertFalse(valueReferenceSegment.isPresent(), 
assertContext.getText("Actual value reference segment should not exist."));
+        } else {
+            assertTrue(valueReferenceSegment.isPresent(), 
assertContext.getText("Actual value reference segment should exist."));
+            ValueReferenceSegmentAssert.assertIs(assertContext, 
valueReferenceSegment.get(), expected.getValueReference());
+        }
+    }
+    
     private static void assertWithClause(final SQLCaseAssertContext 
assertContext, final InsertStatement actual, final InsertStatementTestCase 
expected) {
         Optional<WithSegment> withSegment = actual.getWith();
         if (null == expected.getWithClause()) {
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/assignment/ExpectedRowAlias.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/assignment/ExpectedRowAlias.java
new file mode 100644
index 00000000000..054b2ddb039
--- /dev/null
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/assignment/ExpectedRowAlias.java
@@ -0,0 +1,43 @@
+/*
+ * 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.assignment;
+
+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.column.ExpectedColumn;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Expected row alias.
+ */
+@Getter
+@Setter
+public final class ExpectedRowAlias extends AbstractExpectedSQLSegment {
+    
+    @XmlElement
+    private String alias;
+    
+    @XmlElementWrapper(name = "derived-columns")
+    @XmlElement(name = "column")
+    private final List<ExpectedColumn> derivedColumns = new LinkedList<>();
+}
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/assignment/ExpectedValueReference.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/assignment/ExpectedValueReference.java
new file mode 100644
index 00000000000..7071734e2f0
--- /dev/null
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/assignment/ExpectedValueReference.java
@@ -0,0 +1,52 @@
+/*
+ * 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.assignment;
+
+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.column.ExpectedColumn;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Expected value reference.
+ */
+@Getter
+@Setter
+public final class ExpectedValueReference extends AbstractExpectedSQLSegment {
+    
+    @XmlAttribute
+    private String alias;
+    
+    @XmlElement(name = "derived-column")
+    private List<ExpectedColumn> derivedColumns = new LinkedList<>();
+    
+    /**
+     * Get derived columns.
+     *
+     * @return derived columns
+     */
+    public Optional<List<ExpectedColumn>> getDerivedColumns() {
+        return derivedColumns.isEmpty() ? Optional.empty() : 
Optional.of(derivedColumns);
+    }
+}
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/standard/InsertStatementTestCase.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/standard/InsertStatementTestCase.java
index f94b8e57fae..6b36007aea1 100644
--- 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/standard/InsertStatementTestCase.java
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/dml/standard/InsertStatementTestCase.java
@@ -31,6 +31,7 @@ import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.s
 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.ExpectedReturningClause;
+import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.assignment.ExpectedValueReference;
 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.ExpectedSimpleTable;
@@ -67,6 +68,9 @@ public final class InsertStatementTestCase extends 
SQLParserTestCase {
     @XmlElement(name = "on-duplicate-key-columns")
     private ExpectedOnDuplicateKeyColumns onDuplicateKeyColumns;
     
+    @XmlElement(name = "value-reference")
+    private ExpectedValueReference valueReference;
+    
     @XmlElement(name = "with")
     private ExpectedWithClause withClause;
     
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 c05597e7b6e..8be1af68441 100644
--- a/test/it/parser/src/main/resources/case/dml/insert.xml
+++ b/test/it/parser/src/main/resources/case/dml/insert.xml
@@ -490,7 +490,7 @@
     </insert>
     <insert sql-case-id="insert_duplicate_key_update">
         <table name="t_order" start-index="12" stop-index="18" />
-        <set start-index="20" stop-index="34" literal-stop-index="34">
+        <set start-index="20" stop-index="39" literal-stop-index="39">
             <assignment>
                 <column name="b" start-index="24" stop-index="24" />
                 <assignment-value>
@@ -504,7 +504,8 @@
                 </assignment-value>
             </assignment>
         </set>
-        <on-duplicate-key-columns start-index="43" stop-index="76" 
literal-start-index="36" literal-stop-index="76">
+        <value-reference alias="n" start-index="36" stop-index="39"/>
+        <on-duplicate-key-columns start-index="41" stop-index="76" 
literal-start-index="41" literal-stop-index="76">
             <assignment start-index="65" stop-index="69">
                 <column name="b" start-index="65" stop-index="65"  />
                 <assignment-value>
@@ -4178,35 +4179,169 @@
         <on-duplicate-key-columns start-index="42" stop-index="73"/>
     </insert>
 
-    <insert sql-case-id="insert_on_duplicate_key_with_column_aliases">
+
+    <insert sql-case-id="insert_values_with_value_reference">
+        <table name="t" start-index="12" stop-index="12"/>
+        <columns start-index="13" stop-index="13"/>
+        <values>
+            <value>
+                <assignment-value>
+                    <literal-expression value="1" start-index="22" 
stop-index="22"/>
+                </assignment-value>
+                <assignment-value>
+                    <literal-expression value="2" start-index="24" 
stop-index="24"/>
+                </assignment-value>
+            </value>
+        </values>
+        <value-reference alias="new_alias" start-index="27" stop-index="38"/>
+    </insert>
+
+    <insert sql-case-id="insert_values_with_column_aliases">
         <table name="t" start-index="12" stop-index="12"/>
-        <set start-index="14" stop-index="24">
+        <columns start-index="13" stop-index="13"/>
+        <values>
+            <value>
+                <assignment-value>
+                    <literal-expression value="1" start-index="22" 
stop-index="22"/>
+                </assignment-value>
+                <assignment-value>
+                    <literal-expression value="2" start-index="24" 
stop-index="24"/>
+                </assignment-value>
+            </value>
+        </values>
+        <value-reference alias="new_alias" start-index="27" stop-index="43">
+            <derived-column name="a" start-index="40" stop-index="40"/>
+            <derived-column name="b" start-index="42" stop-index="42"/>
+        </value-reference>
+    </insert>
+
+    <insert sql-case-id="insert_values_as_on_duplicate_key">
+        <table name="t" start-index="12" stop-index="12"/>
+        <columns start-index="13" stop-index="13"/>
+        <values>
+            <value>
+                <assignment-value>
+                    <literal-expression value="1" start-index="22" 
stop-index="22"/>
+                </assignment-value>
+                <assignment-value>
+                    <literal-expression value="2" start-index="24" 
stop-index="24"/>
+                </assignment-value>
+            </value>
+        </values>
+        <value-reference alias="new_alias" start-index="27" stop-index="38"/>
+        <on-duplicate-key-columns start-index="40" stop-index="76">
+            <assignment start-index="64" stop-index="76">
+                <column name="a" start-index="64" stop-index="64"/>
+                <assignment-value>
+                    <column name="a" start-index="66" stop-index="76">
+                        <owner name="new_alias" start-index="66" 
stop-index="74"/>
+                    </column>
+                </assignment-value>
+            </assignment>
+        </on-duplicate-key-columns>
+    </insert>
+
+    <insert sql-case-id="insert_values_as_with_columns_duplicate">
+        <table name="t" start-index="12" stop-index="12"/>
+        <columns start-index="13" stop-index="13"/>
+        <values>
+            <value>
+                <assignment-value>
+                    <literal-expression value="1" start-index="22" 
stop-index="22"/>
+                </assignment-value>
+                <assignment-value>
+                    <literal-expression value="2" start-index="24" 
stop-index="24"/>
+                </assignment-value>
+            </value>
+        </values>
+        <value-reference alias="new_alias" start-index="27" stop-index="43">
+            <derived-column name="a" start-index="40" stop-index="40"/>
+            <derived-column name="b" start-index="42" stop-index="42"/>
+        </value-reference>
+        <on-duplicate-key-columns start-index="45" stop-index="96">
+            <assignment start-index="69" stop-index="81">
+                <column name="a" start-index="69" stop-index="69"/>
+                <assignment-value>
+                    <column name="a" start-index="71" stop-index="81">
+                        <owner name="new_alias" start-index="71" 
stop-index="79"/>
+                    </column>
+                </assignment-value>
+            </assignment>
+            <assignment start-index="84" stop-index="96">
+                <column name="b" start-index="84" stop-index="84"/>
+                <assignment-value>
+                    <column name="b" start-index="86" stop-index="96">
+                        <owner name="new_alias" start-index="86" 
stop-index="94"/>
+                    </column>
+                </assignment-value>
+            </assignment>
+        </on-duplicate-key-columns>
+    </insert>
+
+    <insert sql-case-id="insert_set_as_on_duplicate_key">
+        <table name="t" start-index="12" stop-index="12"/>
+        <set start-index="14" stop-index="38">
             <assignment>
-                <column name="a" start-index="18" stop-index="18" />
+                <column name="a" start-index="18" stop-index="18"/>
                 <assignment-value>
-                    <literal-expression value="9" literal-start-index="20" 
literal-stop-index="20" />
+                    <literal-expression value="1" start-index="20" 
stop-index="20"/>
                 </assignment-value>
             </assignment>
             <assignment>
-                <column name="b" start-index="22" stop-index="22"/>
+                <column name="b" start-index="23" stop-index="23"/>
                 <assignment-value>
-                    <literal-expression value="5" start-index="24" 
stop-index="24"/>
+                    <literal-expression value="2" start-index="25" 
stop-index="25"/>
                 </assignment-value>
             </assignment>
         </set>
-        <on-duplicate-key-columns start-index="26" stop-index="66">
-            <assignment start-index="62" stop-index="66">
-                <column name="a" start-index="62" stop-index="62"  />
+        <value-reference alias="new_alias" start-index="27" stop-index="38"/>
+        <on-duplicate-key-columns start-index="40" stop-index="76">
+            <assignment start-index="64" stop-index="76">
+                <column name="a" start-index="64" stop-index="64"/>
                 <assignment-value>
-                    <binary-operation-expression start-index="64" 
stop-index="66">
-                        <operator>+</operator>
-                        <left>
-                            <column name="m" start-index="64" stop-index="64"/>
-                        </left>
-                        <right>
-                            <column name="n" start-index="66" stop-index="66"/>
-                        </right>
-                    </binary-operation-expression>
+                    <column name="a" start-index="66" stop-index="76">
+                        <owner name="new_alias" start-index="66" 
stop-index="74"/>
+                    </column>
+                </assignment-value>
+            </assignment>
+        </on-duplicate-key-columns>
+    </insert>
+
+    <insert sql-case-id="insert_set_as_with_columns_duplicate">
+        <table name="t" start-index="12" stop-index="12"/>
+        <set start-index="14" stop-index="43">
+            <assignment>
+                <column name="a" start-index="18" stop-index="18"/>
+                <assignment-value>
+                    <literal-expression value="1" start-index="20" 
stop-index="20"/>
+                </assignment-value>
+            </assignment>
+            <assignment>
+                <column name="b" start-index="23" stop-index="23"/>
+                <assignment-value>
+                    <literal-expression value="2" start-index="25" 
stop-index="25"/>
+                </assignment-value>
+            </assignment>
+        </set>
+        <value-reference alias="new_alias" start-index="27" stop-index="43">
+            <derived-column name="a" start-index="40" stop-index="40"/>
+            <derived-column name="b" start-index="42" stop-index="42"/>
+        </value-reference>
+        <on-duplicate-key-columns start-index="45" stop-index="96">
+            <assignment start-index="69" stop-index="81">
+                <column name="a" start-index="69" stop-index="69"/>
+                <assignment-value>
+                    <column name="a" start-index="71" stop-index="81">
+                        <owner name="new_alias" start-index="71" 
stop-index="79"/>
+                    </column>
+                </assignment-value>
+            </assignment>
+            <assignment start-index="84" stop-index="96">
+                <column name="b" start-index="84" stop-index="84"/>
+                <assignment-value>
+                    <column name="b" start-index="86" stop-index="96">
+                        <owner name="new_alias" start-index="86" 
stop-index="94"/>
+                    </column>
                 </assignment-value>
             </assignment>
         </on-duplicate-key-columns>
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 7a9fa17c777..f31e49825b5 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
@@ -150,7 +150,12 @@
     <sql-case id="insert_into_with_multi_nchar" value="INSERT INTO 
Production.UnitMeasure VALUES (N'FT2', N'Square Feet ', '20080923'), (N'Y', 
N'Yards', '20080923'), (N'Y3', N'Cubic Yards', '20080923')" 
db-types="SQLServer"/>
     <sql-case id="insert_into_with_select_with_merge" value="INSERT INTO 
Production.ZeroInventory (DeletedProductID, RemovedOnDate) SELECT ProductID, 
GETDATE() FROM (MERGE Production.ProductInventory AS pi USING (SELECT 
ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail AS sod JOIN 
Sales.SalesOrderHeader AS soh ON sod.SalesOrderID = soh.SalesOrderID AND 
soh.OrderDate = '20070401' GROUP BY ProductID) AS src (ProductID, OrderQty) ON 
(pi.ProductID = src.ProductID) WHEN MATCHED AND pi.Quan [...]
     <sql-case id="insert_into_with_conflict_action_do_nothing" value="INSERT 
INTO sj_event(event_id) VALUES (?) ON CONFLICT(event_id) DO NOTHING" 
db-types="PostgreSQL"/>
-    <sql-case id="insert_on_duplicate_key_with_column_aliases" value="INSERT 
INTO t SET a=9,b=5 AS new(m,n) ON DUPLICATE KEY UPDATE a=m+n" db-types="MySQL"/>
+    <sql-case id="insert_values_with_value_reference" value="INSERT INTO t 
VALUES (1,2) AS new_alias" db-types="MySQL"/>
+    <sql-case id="insert_values_with_column_aliases" value="INSERT INTO t 
VALUES (1,2) AS new_alias(a,b)" db-types="MySQL"/>
+    <sql-case id="insert_values_as_on_duplicate_key" value="INSERT INTO t 
VALUES (1,2) AS new_alias ON DUPLICATE KEY UPDATE a=new_alias.a" 
db-types="MySQL"/>
+    <sql-case id="insert_values_as_with_columns_duplicate" value="INSERT INTO 
t VALUES (1,2) AS new_alias(a,b) ON DUPLICATE KEY UPDATE a=new_alias.a, 
b=new_alias.b" db-types="MySQL"/>
+    <sql-case id="insert_set_as_on_duplicate_key" value="INSERT INTO t SET 
a=1, b=2 AS new_alias ON DUPLICATE KEY UPDATE a=new_alias.a" db-types="MySQL"/>
+    <sql-case id="insert_set_as_with_columns_duplicate" value="INSERT INTO t 
SET a=1, b=2 AS new_alias(a,b) ON DUPLICATE KEY UPDATE a=new_alias.a, 
b=new_alias.b" db-types="MySQL"/>
     <sql-case id="insert_with_aes_encrypt" value="INSERT INTO 
t_order_item(item_id,encrypt) VALUES (1,AES_ENCRYPT('text','key_str'))" 
db-types="MySQL" />
     <sql-case id="insert_on_duplicate_key_update_with_values" value="INSERT 
INTO table (a,b,c) VALUES (1,2,3),(4,5,6) ON DUPLICATE KEY UPDATE 
c=VALUES(a)+VALUES(b);" db-types="MySQL" />
     <sql-case id="insert_returning_expressions" value="INSERT INTO t2 (id) 
VALUES (2),(3) RETURNING id,t&amp;t" db-types="MySQL,Firebird" />

Reply via email to