Skip to content

Commit aff54de

Browse files
fix: handle missing EXPRESSION column in get_indexes_sql()
The EXPRESSION column in information_schema.STATISTICS only exists in MySQL 8.0.13+. Add a fallback query without EXPRESSION for MySQL < 8.0.13 and MariaDB. heading.py catches the error and retries with the fallback. Fixes #1436
1 parent dacf5ce commit aff54de

2 files changed

Lines changed: 32 additions & 5 deletions

File tree

src/datajoint/adapters/mysql.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,8 +737,10 @@ def parse_foreign_key_error(self, error_message: str) -> dict[str, str | list[st
737737
def get_indexes_sql(self, schema_name: str, table_name: str) -> str:
738738
"""Query to get index definitions.
739739
740-
Note: For MySQL 8.0+, EXPRESSION column contains the expression for
740+
Note: For MySQL 8.0.13+, EXPRESSION column contains the expression for
741741
functional indexes. COLUMN_NAME is NULL for such indexes.
742+
On MySQL < 8.0.13 and MariaDB, the EXPRESSION column does not exist;
743+
heading.py falls back to get_indexes_sql_fallback() in that case.
742744
"""
743745
return (
744746
f"SELECT INDEX_NAME as index_name, "
@@ -751,6 +753,19 @@ def get_indexes_sql(self, schema_name: str, table_name: str) -> str:
751753
f"ORDER BY index_name, seq_in_index"
752754
)
753755

756+
def get_indexes_sql_fallback(self, schema_name: str, table_name: str) -> str:
757+
"""Fallback index query for MySQL < 8.0.13 and MariaDB (no EXPRESSION column)."""
758+
return (
759+
f"SELECT INDEX_NAME as index_name, "
760+
f"COLUMN_NAME as column_name, "
761+
f"NON_UNIQUE as non_unique, SEQ_IN_INDEX as seq_in_index "
762+
f"FROM information_schema.statistics "
763+
f"WHERE table_schema = {self.quote_string(schema_name)} "
764+
f"AND table_name = {self.quote_string(table_name)} "
765+
f"AND index_name != 'PRIMARY' "
766+
f"ORDER BY index_name, seq_in_index"
767+
)
768+
754769
def parse_column_info(self, row: dict[str, Any]) -> dict[str, Any]:
755770
"""
756771
Parse MySQL SHOW FULL COLUMNS output into standardized format.

src/datajoint/heading.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -551,10 +551,22 @@ def _init_from_database(self) -> None:
551551

552552
# Read and tabulate secondary indexes
553553
keys = defaultdict(dict)
554-
for item in conn.query(
555-
adapter.get_indexes_sql(database, table_name),
556-
as_dict=True,
557-
):
554+
try:
555+
index_rows = conn.query(
556+
adapter.get_indexes_sql(database, table_name),
557+
as_dict=True,
558+
)
559+
except Exception:
560+
# Fall back for MySQL < 8.0.13 / MariaDB (no EXPRESSION column)
561+
index_rows = (
562+
conn.query(
563+
adapter.get_indexes_sql_fallback(database, table_name),
564+
as_dict=True,
565+
)
566+
if hasattr(adapter, "get_indexes_sql_fallback")
567+
else []
568+
)
569+
for item in index_rows:
558570
# Note: adapter.get_indexes_sql() already filters out PRIMARY key
559571
# MySQL/PostgreSQL adapters return: index_name, column_name, non_unique
560572
index_name = item.get("index_name") or item.get("Key_name")

0 commit comments

Comments
 (0)