mistercrunch commented on code in PR #35297:
URL: https://github.com/apache/superset/pull/35297#discussion_r2380579025


##########
superset/db_engine_specs/mysql.py:
##########
@@ -260,6 +272,67 @@ def get_datatype(cls, type_code: Any) -> Optional[str]:
     def epoch_to_dttm(cls) -> str:
         return "from_unixtime({col})"
 
+    @classmethod
+    def _is_boolean_column(cls, col_desc: tuple[Any, ...]) -> bool:
+        """Check if a cursor column description represents a boolean column."""
+        type_code = col_desc[1] if len(col_desc) > 1 else None
+        display_size = col_desc[2] if len(col_desc) > 2 else None
+
+        # Only process FIELD_TYPE.TINY (type_code 1)
+        if type_code != 1:
+            return False
+
+        # Explicit width 1 indicates TINYINT(1)/BOOLEAN
+        if display_size == 1:
+            return True
+
+        # Check SQLAlchemy type string (some drivers provide it at index 4)
+        if len(col_desc) > 4 and isinstance(col_desc[4], str):
+            sqla_type_str = col_desc[4].lower()
+            return any(marker in sqla_type_str for marker in ["bool", 
"tinyint(1)"])
+
+        return False
+
+    @classmethod
+    def fetch_data(cls, cursor: Any, limit: int | None = None) -> 
list[tuple[Any, ...]]:
+        """
+        Fetch data from cursor, converting MySQL TINYINT(1) values to Python 
booleans.
+
+        MySQL stores BOOLEAN as TINYINT(1), but returns 0/1 integers instead of
+        True/False. This method detects TINYINT(1) columns using multiple 
reliable
+        markers and converts their values to proper Python booleans.
+        """
+        data = super().fetch_data(cursor, limit)
+        if not cursor.description:
+            return data
+
+        # Find TINYINT(1) columns
+        bool_column_indices = [
+            i
+            for i, col_desc in enumerate(cursor.description)
+            if cls._is_boolean_column(col_desc)
+        ]
+
+        # Convert 0/1 to True/False for boolean columns
+        if bool_column_indices:
+            converted_data = []
+            for row in data:
+                new_row = list(row)
+                for col_idx in bool_column_indices:
+                    if new_row[col_idx] is not None:
+                        # Normalize different value types before boolean 
conversion
+                        # bool("0") returns True, but we need False for MySQL 
boolean
+                        value = new_row[col_idx]
+                        if isinstance(value, (str, bytes)):
+                            value = int(value)
+                        elif isinstance(value, Decimal):
+                            value = int(value)
+                        new_row[col_idx] = bool(value)

Review Comment:
   Unless @betodealmeida can think of a better way



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to