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

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 119dc4d660d [fix](variables) change column type of @@autocommit to 
BIGINT (#33282)
119dc4d660d is described below

commit 119dc4d660de790f0e2f3509205d4c6ec61f766b
Author: Mingyu Chen <morning...@163.com>
AuthorDate: Sun Apr 7 16:24:29 2024 +0800

    [fix](variables) change column type of @@autocommit to BIGINT (#33282)
    
    Some of mysql connector (eg, dotnet MySQL.Data) rely on variable's column 
type to make connection.
    eg, `select @@autocommit` should with column type `BIGINT`, not `BIT`, 
otherwise it will throw error like:
    
    ```
    System.FormatException: The input string 'True' was not in a correct format.
       at System.Number.ThrowFormatException[TChar](ReadOnlySpan`1 value)
       at System.Convert.ToInt32(String value)
       at MySql.Data.MySqlClient.Driver.LoadCharacterSetsAsync(MySqlConnection 
connection, Boolean execAsync, CancellationToken cancellationToken)
       at MySql.Data.MySqlClient.Driver.ConfigureAsync(MySqlConnection 
connection, Boolean execAsync, CancellationToken cancellationToken)
       at MySql.Data.MySqlClient.MySqlConnection.OpenAsync(Boolean execAsync, 
CancellationToken cancellationToken)
       at MySql.Data.MySqlClient.MySqlConnection.Open()
    ```
    
    In this PR, I add a new field of `VarAttr`: `convertBoolToLongMethod`, if 
set, it will convert boolean to long.
    And set it for `autocommit`
---
 .../java/org/apache/doris/qe/SessionVariable.java  | 12 +--
 .../main/java/org/apache/doris/qe/VariableMgr.java | 97 +++++++++++++---------
 .../java/org/apache/doris/qe/VariableMgrTest.java  | 19 +++++
 3 files changed, 83 insertions(+), 45 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java 
b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
index a604238e0de..d8cea49d5c0 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
@@ -671,7 +671,9 @@ public class SessionVariable implements Serializable, 
Writable {
     public String resourceGroup = "";
 
     // this is used to make mysql client happy
-    @VariableMgr.VarAttr(name = AUTO_COMMIT)
+    // autocommit is actually a boolean value, but @@autocommit is type of 
BIGINT.
+    // So we need to set convertBoolToLongMethod to make "select @@autocommit" 
happy.
+    @VariableMgr.VarAttr(name = AUTO_COMMIT, convertBoolToLongMethod = 
"convertBoolToLong")
     public boolean autoCommit = true;
 
     // this is used to make c3p0 library happy
@@ -2026,10 +2028,6 @@ public class SessionVariable implements Serializable, 
Writable {
         return enableJoinReorderBasedCost;
     }
 
-    public boolean isAutoCommit() {
-        return autoCommit;
-    }
-
     public boolean enableMultiClusterSyncLoad() {
         return cloudEnableMultiClusterSyncLoad;
     }
@@ -2938,6 +2936,10 @@ public class SessionVariable implements Serializable, 
Writable {
         }
     }
 
+    public long convertBoolToLong(Boolean val) {
+        return val ? 1 : 0;
+    }
+
     public boolean isEnableFileCache() {
         return enableFileCache;
     }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/VariableMgr.java 
b/fe/fe-core/src/main/java/org/apache/doris/qe/VariableMgr.java
index 6e75f17a042..813301e3513 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/VariableMgr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/VariableMgr.java
@@ -35,6 +35,7 @@ import 
org.apache.doris.nereids.trees.expressions.literal.Literal;
 import org.apache.doris.persist.GlobalVarPersistInfo;
 
 import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSortedMap;
 import com.google.common.collect.Lists;
@@ -498,47 +499,61 @@ public class VariableMgr {
     }
 
     private static void fillValue(Object obj, Field field, VariableExpr desc) {
-        try {
-            switch (field.getType().getSimpleName()) {
-                case "boolean":
-                    desc.setType(Type.BOOLEAN);
-                    desc.setBoolValue(field.getBoolean(obj));
-                    break;
-                case "byte":
-                    desc.setType(Type.TINYINT);
-                    desc.setIntValue(field.getByte(obj));
-                    break;
-                case "short":
-                    desc.setType(Type.SMALLINT);
-                    desc.setIntValue(field.getShort(obj));
-                    break;
-                case "int":
-                    desc.setType(Type.INT);
-                    desc.setIntValue(field.getInt(obj));
-                    break;
-                case "long":
-                    desc.setType(Type.BIGINT);
-                    desc.setIntValue(field.getLong(obj));
-                    break;
-                case "float":
-                    desc.setType(Type.FLOAT);
-                    desc.setFloatValue(field.getFloat(obj));
-                    break;
-                case "double":
-                    desc.setType(Type.DOUBLE);
-                    desc.setFloatValue(field.getDouble(obj));
-                    break;
-                case "String":
-                    desc.setType(Type.VARCHAR);
-                    desc.setStringValue((String) field.get(obj));
-                    break;
-                default:
-                    desc.setType(Type.VARCHAR);
-                    desc.setStringValue("");
-                    break;
+        VarAttr attr = field.getAnnotation(VarAttr.class);
+        if (!Strings.isNullOrEmpty(attr.convertBoolToLongMethod())) {
+            try {
+                Preconditions.checkArgument(obj instanceof SessionVariable);
+                long val = (Long) 
SessionVariable.class.getDeclaredMethod(attr.convertBoolToLongMethod(), 
Boolean.class)
+                        .invoke(obj, field.getBoolean(obj));
+                desc.setType(Type.BIGINT);
+                desc.setIntValue(val);
+            } catch (Exception e) {
+                // should not happen
+                LOG.warn("failed to convert bool to long for var: {}", 
field.getName(), e);
+            }
+        } else {
+            try {
+                switch (field.getType().getSimpleName()) {
+                    case "boolean":
+                        desc.setType(Type.BOOLEAN);
+                        desc.setBoolValue(field.getBoolean(obj));
+                        break;
+                    case "byte":
+                        desc.setType(Type.TINYINT);
+                        desc.setIntValue(field.getByte(obj));
+                        break;
+                    case "short":
+                        desc.setType(Type.SMALLINT);
+                        desc.setIntValue(field.getShort(obj));
+                        break;
+                    case "int":
+                        desc.setType(Type.INT);
+                        desc.setIntValue(field.getInt(obj));
+                        break;
+                    case "long":
+                        desc.setType(Type.BIGINT);
+                        desc.setIntValue(field.getLong(obj));
+                        break;
+                    case "float":
+                        desc.setType(Type.FLOAT);
+                        desc.setFloatValue(field.getFloat(obj));
+                        break;
+                    case "double":
+                        desc.setType(Type.DOUBLE);
+                        desc.setFloatValue(field.getDouble(obj));
+                        break;
+                    case "String":
+                        desc.setType(Type.VARCHAR);
+                        desc.setStringValue((String) field.get(obj));
+                        break;
+                    default:
+                        desc.setType(Type.VARCHAR);
+                        desc.setStringValue("");
+                        break;
+                }
+            } catch (IllegalAccessException e) {
+                LOG.warn("Access failed.", e);
             }
-        } catch (IllegalAccessException e) {
-            LOG.warn("Access failed.", e);
         }
     }
 
@@ -790,6 +805,8 @@ public class VariableMgr {
 
         // Enum options for this config item, if it has.
         String[] options() default {};
+
+        String convertBoolToLongMethod() default "";
     }
 
     private static class VarContext {
diff --git a/fe/fe-core/src/test/java/org/apache/doris/qe/VariableMgrTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/qe/VariableMgrTest.java
index d08dc94454e..43628cdd05d 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/qe/VariableMgrTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/qe/VariableMgrTest.java
@@ -17,13 +17,16 @@
 
 package org.apache.doris.qe;
 
+import org.apache.doris.analysis.BoolLiteral;
 import org.apache.doris.analysis.CreateDbStmt;
+import org.apache.doris.analysis.IntLiteral;
 import org.apache.doris.analysis.SetStmt;
 import org.apache.doris.analysis.SetType;
 import org.apache.doris.analysis.SetVar;
 import org.apache.doris.analysis.StringLiteral;
 import org.apache.doris.analysis.VariableExpr;
 import org.apache.doris.catalog.Env;
+import org.apache.doris.catalog.Type;
 import org.apache.doris.common.Config;
 import org.apache.doris.common.DdlException;
 import org.apache.doris.common.UserException;
@@ -254,4 +257,20 @@ public class VariableMgrTest {
         SessionVariable defaultSessionVar = new SessionVariable();
         Assert.assertEquals(defaultSessionVar.enableProfile(), 
VariableMgr.newSessionVariable().enableProfile());
     }
+
+    @Test
+    public void testAutoCommitConvert() throws Exception {
+        // boolean var with ConvertBoolToLongMethod annotation
+        VariableExpr desc = new VariableExpr("autocommit");
+        SessionVariable var = new SessionVariable();
+        VariableMgr.fillValue(var, desc);
+        Assert.assertTrue(desc.getLiteralExpr() instanceof IntLiteral);
+        Assert.assertEquals(Type.BIGINT, desc.getType());
+
+        // normal boolean var
+        desc = new VariableExpr("enable_bucket_shuffle_join");
+        VariableMgr.fillValue(var, desc);
+        Assert.assertTrue(desc.getLiteralExpr() instanceof BoolLiteral);
+        Assert.assertEquals(Type.BOOLEAN, desc.getType());
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to