This is an automated email from the ASF dual-hosted git repository.

morrysnow pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-2.0 by this push:
     new d34ef4dcddf [fix](Nereids) update assignment column name should case 
insensitive (#30072)
d34ef4dcddf is described below

commit d34ef4dcddf1d88e9ba4b34e67265176cda37b26
Author: morrySnow <[email protected]>
AuthorDate: Thu Jan 25 14:55:03 2024 +0800

    [fix](Nereids) update assignment column name should case insensitive 
(#30072)
    
    pick from master PR #30071
---
 .../doris/nereids/rules/analysis/SlotBinder.java   | 34 ++++++++++--------
 .../trees/plans/commands/UpdateCommand.java        | 41 +++++++++++++++++++---
 .../nereids_p0/update/update_unique_table.groovy   | 12 ++++++-
 3 files changed, 67 insertions(+), 20 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SlotBinder.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SlotBinder.java
index 57d84610cfd..39bc3074cb9 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SlotBinder.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SlotBinder.java
@@ -53,7 +53,10 @@ import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
-class SlotBinder extends SubExprAnalyzer {
+/**
+ * SlotBinder is used to bind slot
+ */
+public class SlotBinder extends SubExprAnalyzer {
     /*
     bounded={table.a, a}
     unbound=a
@@ -260,18 +263,6 @@ class SlotBinder extends SubExprAnalyzer {
         return new BoundStar(slots);
     }
 
-    private boolean compareDbNameIgnoreClusterName(String unBoundDbName, 
String boundedDbName) {
-        if (unBoundDbName.equalsIgnoreCase(boundedDbName)) {
-            return true;
-        }
-        // boundedDbName example
-        int idx = boundedDbName.indexOf(ClusterNamespace.CLUSTER_DELIMITER);
-        if (idx > -1) {
-            return unBoundDbName.equalsIgnoreCase(boundedDbName.substring(idx 
+ 1));
-        }
-        return false;
-    }
-
     private List<Slot> bindSlot(UnboundSlot unboundSlot, List<Slot> 
boundSlots) {
         return boundSlots.stream().distinct().filter(boundSlot -> {
             List<String> nameParts = unboundSlot.getNameParts();
@@ -311,7 +302,22 @@ class SlotBinder extends SubExprAnalyzer {
         }).collect(Collectors.toList());
     }
 
-    private boolean sameTableName(String boundSlot, String unboundSlot) {
+    /**
+     * compareDbNameIgnoreClusterName.
+     */
+    public static boolean compareDbNameIgnoreClusterName(String unBoundDbName, 
String boundedDbName) {
+        if (unBoundDbName.equalsIgnoreCase(boundedDbName)) {
+            return true;
+        }
+        // boundedDbName example
+        int idx = boundedDbName.indexOf(ClusterNamespace.CLUSTER_DELIMITER);
+        if (idx > -1) {
+            return unBoundDbName.equalsIgnoreCase(boundedDbName.substring(idx 
+ 1));
+        }
+        return false;
+    }
+
+    public static boolean sameTableName(String boundSlot, String unboundSlot) {
         if (Config.lower_case_table_names != 1) {
             return boundSlot.equals(unboundSlot);
         } else {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/UpdateCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/UpdateCommand.java
index 92f3fb21ee5..79ed4055ce9 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/UpdateCommand.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/UpdateCommand.java
@@ -22,10 +22,11 @@ import org.apache.doris.catalog.KeysType;
 import org.apache.doris.catalog.OlapTable;
 import org.apache.doris.catalog.Table;
 import org.apache.doris.catalog.TableIf;
-import org.apache.doris.common.AnalysisException;
+import org.apache.doris.nereids.analyzer.UnboundAlias;
 import org.apache.doris.nereids.analyzer.UnboundOlapTableSink;
 import org.apache.doris.nereids.analyzer.UnboundSlot;
-import org.apache.doris.nereids.trees.expressions.Alias;
+import org.apache.doris.nereids.exceptions.AnalysisException;
+import org.apache.doris.nereids.rules.analysis.SlotBinder;
 import org.apache.doris.nereids.trees.expressions.EqualTo;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.NamedExpression;
@@ -94,12 +95,13 @@ public class UpdateCommand extends Command implements 
ForwardWithSync, Explainab
     /**
      * add LogicalOlapTableSink node, public for test.
      */
-    public LogicalPlan completeQueryPlan(ConnectContext ctx, LogicalPlan 
logicalQuery) throws AnalysisException {
+    public LogicalPlan completeQueryPlan(ConnectContext ctx, LogicalPlan 
logicalQuery) {
         checkTable(ctx);
 
-        Map<String, Expression> colNameToExpression = Maps.newHashMap();
+        Map<String, Expression> colNameToExpression = 
Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
         for (EqualTo equalTo : assignments) {
             List<String> nameParts = ((UnboundSlot) 
equalTo.left()).getNameParts();
+            checkAssignmentColumn(ctx, nameParts);
             colNameToExpression.put(nameParts.get(nameParts.size() - 1), 
equalTo.right());
         }
         List<NamedExpression> selectItems = Lists.newArrayList();
@@ -112,11 +114,16 @@ public class UpdateCommand extends Command implements 
ForwardWithSync, Explainab
                 Expression expr = colNameToExpression.get(column.getName());
                 selectItems.add(expr instanceof UnboundSlot
                         ? ((NamedExpression) expr)
-                        : new Alias(expr));
+                        : new UnboundAlias(expr));
+                colNameToExpression.remove(column.getName());
             } else {
                 selectItems.add(new UnboundSlot(tableName, column.getName()));
             }
         }
+        if (!colNameToExpression.isEmpty()) {
+            throw new AnalysisException("unknown column in assignment list: "
+                    + String.join(", ", colNameToExpression.keySet()));
+        }
 
         logicalQuery = new LogicalProject<>(selectItems, logicalQuery);
         if (cte.isPresent()) {
@@ -128,6 +135,30 @@ public class UpdateCommand extends Command implements 
ForwardWithSync, Explainab
                 ImmutableList.of(), logicalQuery);
     }
 
+    private void checkAssignmentColumn(ConnectContext ctx, List<String> 
columnNameParts) {
+        if (columnNameParts.size() <= 1) {
+            return;
+        }
+        String dbName = null;
+        String tableName = null;
+        if (columnNameParts.size() == 3) {
+            dbName = columnNameParts.get(0);
+            tableName = columnNameParts.get(1);
+        } else if (columnNameParts.size() == 2) {
+            tableName = columnNameParts.get(0);
+        } else {
+            throw new AnalysisException("column in assignment list is invalid, 
" + String.join(".", columnNameParts));
+        }
+        if (dbName != null && this.tableAlias != null) {
+            throw new AnalysisException("column in assignment list is invalid, 
" + String.join(".", columnNameParts));
+        }
+        List<String> tableQualifier = RelationUtil.getQualifierName(ctx, 
nameParts);
+        if (!SlotBinder.sameTableName(tableAlias == null ? 
tableQualifier.get(2) : tableAlias, tableName)
+                || (dbName != null && 
SlotBinder.compareDbNameIgnoreClusterName(tableQualifier.get(1), dbName))) {
+            throw new AnalysisException("column in assignment list is invalid, 
" + String.join(".", columnNameParts));
+        }
+    }
+
     private void checkTable(ConnectContext ctx) throws AnalysisException {
         if (ctx.getSessionVariable().isInDebugMode()) {
             throw new AnalysisException("Update is forbidden since current 
session is in debug mode."
diff --git 
a/regression-test/suites/nereids_p0/update/update_unique_table.groovy 
b/regression-test/suites/nereids_p0/update/update_unique_table.groovy
index 59ea06b10b8..e84b3033c6b 100644
--- a/regression-test/suites/nereids_p0/update/update_unique_table.groovy
+++ b/regression-test/suites/nereids_p0/update/update_unique_table.groovy
@@ -95,10 +95,20 @@ suite('update_unique_table') {
 
     sql '''
         update t1
-        set t1.c1 = t2.c1, t1.c3 = t2.c3 * 100
+        set t1.C1 = t2.c1, t1.c3 = t2.c3 * 100
         from t2 inner join t3 on t2.id = t3.id
         where t1.id = t2.id;
     '''
 
     qt_sql 'select * from t1 order by id'
+
+    test {
+        sql '''update t1 set t.c1 = 1 where t1.c1 = 1;'''
+        exception ""
+    }
+
+    test {
+        sql '''update t1 t set t1.c1 = 1 where t1.c1 = 1;'''
+        exception ""
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to