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 d4a07d3cc64 Support sql federation bit_count function for mysql 
(#31701)
d4a07d3cc64 is described below

commit d4a07d3cc646a561d72c43e516d3a10cfbe82e80
Author: niu niu <[email protected]>
AuthorDate: Sat Jun 15 19:38:39 2024 +0800

    Support sql federation bit_count function for mysql (#31701)
    
    * Support sql federation bit_count function for mysql
    
    * Format comment
---
 .../converter/impl/MySQLColumnTypeConverter.java   |  2 +-
 .../function/mysql/MySQLBitCountFunction.java      | 67 ++++++++++++++++++++++
 .../planner/util/SQLFederationFunctionUtils.java   |  2 +
 .../resources/cases/dql/dql-integration-select.xml | 28 +++++++++
 4 files changed, 98 insertions(+), 1 deletion(-)

diff --git 
a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/converter/impl/MySQLColumnTypeConverter.java
 
b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/converter/impl/MySQLColumnTypeConverter.java
index 9f620ca7ebc..c1c0064cb33 100644
--- 
a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/converter/impl/MySQLColumnTypeConverter.java
+++ 
b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/converter/impl/MySQLColumnTypeConverter.java
@@ -35,7 +35,7 @@ public final class MySQLColumnTypeConverter implements 
SQLFederationColumnTypeCo
     
     @Override
     public int convertColumnType(final int columnType) {
-        if (SqlTypeName.BOOLEAN.getJdbcOrdinal() == columnType) {
+        if (SqlTypeName.BOOLEAN.getJdbcOrdinal() == columnType || 
SqlTypeName.ANY.getJdbcOrdinal() == columnType) {
             return SqlTypeName.VARCHAR.getJdbcOrdinal();
         }
         return columnType;
diff --git 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/function/mysql/MySQLBitCountFunction.java
 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/function/mysql/MySQLBitCountFunction.java
new file mode 100644
index 00000000000..2eb0e4fbdc2
--- /dev/null
+++ 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/function/mysql/MySQLBitCountFunction.java
@@ -0,0 +1,67 @@
+/*
+ * 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.sqlfederation.optimizer.function.mysql;
+
+import org.apache.calcite.util.BitString;
+import org.apache.commons.lang3.StringUtils;
+
+import java.math.BigInteger;
+
+/**
+ * MySQL bit count function.
+ */
+public final class MySQLBitCountFunction {
+    
+    /**
+     * Bit count.
+     *
+     * @param value value
+     * @return bit count
+     */
+    public static Object bitCount(final Object value) {
+        if (null == value) {
+            return 0;
+        }
+        if (value instanceof byte[]) {
+            return bitCount((byte[]) value);
+        }
+        if (value instanceof String) {
+            return StringUtils.isNumeric((String) value) ? 
Long.bitCount(Long.parseLong((String) value)) : 0;
+        }
+        if (value instanceof BigInteger) {
+            return ((BigInteger) value).bitCount();
+        }
+        if (value instanceof Integer) {
+            return Integer.bitCount((Integer) value);
+        }
+        if (value instanceof Long) {
+            return Long.bitCount((Long) value);
+        }
+        return 0;
+    }
+    
+    private static long bitCount(final byte[] byteValue) {
+        long result = 0;
+        for (char each : 
BitString.createFromBytes(byteValue).toBitString().toCharArray()) {
+            if ('1' == each) {
+                result++;
+            }
+        }
+        return result;
+    }
+}
diff --git 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/planner/util/SQLFederationFunctionUtils.java
 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/planner/util/SQLFederationFunctionUtils.java
index 8b6122a1b69..084dc911363 100644
--- 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/planner/util/SQLFederationFunctionUtils.java
+++ 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/planner/util/SQLFederationFunctionUtils.java
@@ -22,6 +22,7 @@ import lombok.NoArgsConstructor;
 import org.apache.calcite.schema.SchemaPlus;
 import org.apache.calcite.schema.impl.ScalarFunctionImpl;
 import org.apache.shardingsphere.infra.autogen.version.ShardingSphereVersion;
+import 
org.apache.shardingsphere.sqlfederation.optimizer.function.mysql.MySQLBitCountFunction;
 
 /**
  * SQL federation function utility class.
@@ -48,6 +49,7 @@ public final class SQLFederationFunctionUtils {
         schemaPlus.add("pg_catalog.gs_password_deadline", 
ScalarFunctionImpl.create(SQLFederationFunctionUtils.class, 
"gsPasswordDeadline"));
         schemaPlus.add("pg_catalog.intervaltonum", 
ScalarFunctionImpl.create(SQLFederationFunctionUtils.class, "intervalToNum"));
         schemaPlus.add("pg_catalog.gs_password_notifyTime", 
ScalarFunctionImpl.create(SQLFederationFunctionUtils.class, 
"gsPasswordNotifyTime"));
+        schemaPlus.add("bit_count", 
ScalarFunctionImpl.create(MySQLBitCountFunction.class, "bitCount"));
         if ("pg_catalog".equalsIgnoreCase(schemaName)) {
             schemaPlus.add("pg_catalog.pg_table_is_visible", 
ScalarFunctionImpl.create(SQLFederationFunctionUtils.class, 
"pgTableIsVisible"));
             schemaPlus.add("pg_catalog.pg_get_userbyid", 
ScalarFunctionImpl.create(SQLFederationFunctionUtils.class, "pgGetUserById"));
diff --git 
a/test/e2e/sql/src/test/resources/cases/dql/dql-integration-select.xml 
b/test/e2e/sql/src/test/resources/cases/dql/dql-integration-select.xml
index 28f6989dcf9..5b29a32db6f 100644
--- a/test/e2e/sql/src/test/resources/cases/dql/dql-integration-select.xml
+++ b/test/e2e/sql/src/test/resources/cases/dql/dql-integration-select.xml
@@ -304,4 +304,32 @@
     <test-case sql="SELECT type_bit, type_blob, type_mediumblob, 
type_longblob, type_binary, type_varbinary FROM t_product_extend" 
db-types="MySQL" scenario-types="db_tbl_sql_federation">
         <assertion expected-data-source-name="read_dataset" />
     </test-case>
+    
+    <test-case sql="SELECT bit_count(123456), bit_count('123456'), 
bit_count('abcdefg'), BIT_COUNT('abcdef1234'), bit_count(''), bit_count(1 + 1)" 
db-types="MySQL" scenario-types="db_tbl_sql_federation">
+        <assertion expected-data-source-name="read_dataset" />
+    </test-case>
+    
+    <test-case sql="SELECT bit_count(type_int), bit_count(type_smallint), 
bit_count(type_decimal), bit_count(type_float), bit_count(type_double), 
bit_count(type_bit),
+                    bit_count(type_tinyint), bit_count(type_mediumint), 
bit_count(type_bigint), bit_count(type_date), bit_count(type_time), 
bit_count(type_datetime),
+                    bit_count(type_timestamp), bit_count(type_year), 
bit_count(type_char), bit_count(type_text), bit_count(type_varchar), 
bit_count(type_longtext),
+                    bit_count(type_longblob), bit_count(type_mediumtext), 
bit_count(type_mediumblob), bit_count(type_binary), bit_count(type_varbinary), 
bit_count(type_blob),
+                    bit_count(type_enum), bit_count(type_set), 
bit_count(type_json), bit_count(type_unsigned_int), 
bit_count(type_unsigned_bigint), bit_count(type_unsigned_tinyint),
+                    bit_count(type_unsigned_smallint), 
bit_count(type_unsigned_float), bit_count(type_unsigned_double), 
bit_count(type_unsigned_decimal) FROM t_product_extend" db-types="MySQL" 
scenario-types="db_tbl_sql_federation">
+        <assertion expected-data-source-name="read_dataset" />
+    </test-case>
+    
+    <test-case sql="SELECT t4.order_id, t3.item_id, bit_count(t4.order_id), 
bit_count(t3.item_id), t2.* FROM t_product t1
+                    INNER JOIN (
+                                SELECT product_id, bit_count(type_int), 
bit_count(type_smallint), bit_count(type_decimal), bit_count(type_float),
+                                bit_count(type_double), bit_count(type_bit), 
bit_count(type_tinyint), bit_count(type_mediumint), bit_count(type_bigint),
+                                bit_count(type_date), bit_count(type_time), 
bit_count(type_datetime), bit_count(type_timestamp), bit_count(type_year),
+                                bit_count(type_char), bit_count(type_text), 
bit_count(type_varchar), bit_count(type_longtext), bit_count(type_longblob),
+                                bit_count(type_mediumtext), 
bit_count(type_mediumblob), bit_count(type_binary), bit_count(type_varbinary),
+                                bit_count(type_blob), bit_count(type_enum), 
bit_count(type_set), bit_count(type_json), bit_count(type_unsigned_int),
+                                bit_count(type_unsigned_bigint), 
bit_count(type_unsigned_tinyint), bit_count(type_unsigned_smallint), 
bit_count(type_unsigned_float),
+                                bit_count(type_unsigned_double), 
bit_count(type_unsigned_decimal) FROM t_product_extend
+                               ) t2 ON t1.product_id = t2.product_id
+                    INNER JOIN t_order_item t3 ON t2.product_id = 
t3.product_id INNER JOIN t_order t4 ON t4.order_id = t3.order_id order by 
t1.product_id" db-types="MySQL" scenario-types="db_tbl_sql_federation">
+        <assertion expected-data-source-name="read_dataset" />
+    </test-case>
 </integration-test-cases>

Reply via email to