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

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


The following commit(s) were added to refs/heads/master by this push:
     new 609d28ba645 fix the binary function: from_base64, from_base32 (#17466)
609d28ba645 is described below

commit 609d28ba645e59777633f1a2122869b2a18129ef
Author: alpass163 <[email protected]>
AuthorDate: Tue Apr 14 08:52:16 2026 +0800

    fix the binary function: from_base64, from_base32 (#17466)
---
 .../query/recent/scalar/IoTDBFromBase32ColumnFunctionIT.java |  4 ++++
 .../query/recent/scalar/IoTDBFromBase64ColumnFunctionIT.java | 12 +++++++++---
 .../column/unary/scalar/factory/CodecStrategiesFactory.java  |  7 ++++++-
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/scalar/IoTDBFromBase32ColumnFunctionIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/scalar/IoTDBFromBase32ColumnFunctionIT.java
index 3c916279258..5e4dfedf662 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/scalar/IoTDBFromBase32ColumnFunctionIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/scalar/IoTDBFromBase32ColumnFunctionIT.java
@@ -80,6 +80,8 @@ public class IoTDBFromBase32ColumnFunctionIT {
         // Case 10: Optional padding test (decoder should handle missing 
padding)
         // 'foo' (0x666f6f) -> Base32 without padding: MZXW6
         "INSERT INTO table1(time, c_text, c_string) VALUES (10, 'MZXW6', 
'MZXW6')",
+        // case 11: lower case
+        "INSERT INTO table1(time, c_text, c_string) VALUES (11, 'mzxw6', 
'mzxw6')",
       };
 
   @BeforeClass
@@ -119,6 +121,8 @@ public class IoTDBFromBase32ColumnFunctionIT {
           "1970-01-01T00:00:00.009Z,0x666f6f6201,0x666f6f6201,",
           // 10. Optional padding
           "1970-01-01T00:00:00.010Z,0x666f6f,0x666f6f,",
+          // 11. lower case will be considered as upper case
+          "1970-01-01T00:00:00.011Z,0x666f6f,0x666f6f,",
         };
 
     tableResultSetEqualTest(
diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/scalar/IoTDBFromBase64ColumnFunctionIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/scalar/IoTDBFromBase64ColumnFunctionIT.java
index 653d045d580..dcfdde02265 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/scalar/IoTDBFromBase64ColumnFunctionIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/scalar/IoTDBFromBase64ColumnFunctionIT.java
@@ -54,7 +54,8 @@ public class IoTDBFromBase64ColumnFunctionIT {
         "INSERT INTO table1(time, c_text, c_string) VALUES (3, '', '')",
         "INSERT INTO table1(time, c_int) VALUES (4, 404)",
         // invalid base64
-        "INSERT INTO table1(time, c_text, c_string) VALUES (5, 'not_base64', 
'not_base64')"
+        "INSERT INTO table1(time, c_text, c_string) VALUES (5, 'not_base64', 
'not_base64')",
+        "INSERT INTO table1(time, c_text, c_string) VALUES (6, 'abc', 'abc')"
       };
 
   @BeforeClass
@@ -95,10 +96,15 @@ public class IoTDBFromBase64ColumnFunctionIT {
   public void testFromBase64OnInvalidBase64() {
     String expectedErrorMessage =
         TSStatusCode.SEMANTIC_ERROR.getStatusCode()
-            + ": Failed to execute function 'from_base64' due to an invalid 
input format. Problematic value: not_base64";
+            + ": Failed to execute function 'from_base64' due to an invalid 
input format. Problematic value: ";
     tableAssertTestFail(
         "SELECT from_base64(c_text) FROM table1 WHERE time = 5",
-        expectedErrorMessage,
+        expectedErrorMessage + "not_base64",
+        DATABASE_NAME);
+
+    tableAssertTestFail(
+        "SELECT from_base64(c_text) FROM table1 WHERE time = 6",
+        expectedErrorMessage + "abc",
         DATABASE_NAME);
   }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/factory/CodecStrategiesFactory.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/factory/CodecStrategiesFactory.java
index 546a8286d04..e7539011491 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/factory/CodecStrategiesFactory.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/factory/CodecStrategiesFactory.java
@@ -46,6 +46,10 @@ public final class CodecStrategiesFactory {
   public static final CodecStrategy FROM_BASE64 =
       (input) -> {
         try {
+          if (input.length % 4 != 0) {
+            throw new SemanticException(
+                "Base64 length must be a multiple of 4 (including padding 
'=')");
+          }
           return Base64.getDecoder().decode(input);
         } catch (IllegalArgumentException e) {
           // wrap the specific exception in dependency into a general one for 
uniform handling in
@@ -71,7 +75,8 @@ public final class CodecStrategiesFactory {
   public static final CodecStrategy FROM_BASE32 =
       (input) -> {
         try {
-          return GUAVA_BASE32_ENCODING.decode(new String(input, 
TSFileConfig.STRING_CHARSET));
+          return GUAVA_BASE32_ENCODING.decode(
+              new String(input, TSFileConfig.STRING_CHARSET).toUpperCase());
         } catch (IllegalArgumentException e) {
           throw new SemanticException("decode base32 error");
         }

Reply via email to