Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: handle index error for JSON columns #1205

Merged
merged 1 commit into from
Apr 16, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 24 additions & 15 deletions docker-jans-persistence-loader/scripts/sql_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from pathlib import Path

from ldif import LDIFParser
from sqlalchemy.exc import NotSupportedError
from sqlalchemy.exc import OperationalError

from jans.pycloudlib.persistence.sql import SQLClient
Expand Down Expand Up @@ -190,21 +189,31 @@ def create_mysql_indexes(self, table_name: str, column_mapping: dict):
query = f"CREATE INDEX {self.client.quoted_id(index_name)} ON {self.client.quoted_id(table_name)} ({self.client.quoted_id(column_name)})"
self.client.create_index(query)
else:
for i, index_str in enumerate(self.sql_indexes["__common__"]["JSON"], start=1):
index_str_fmt = Template(index_str).safe_substitute({
"field": column_name, # "data_type": column_type,
})
name = f"{table_name}_json_{i}"
query = f"ALTER TABLE {self.client.quoted_id(table_name)} ADD INDEX {self.client.quoted_id(name)} (({index_str_fmt}))"

try:
if self.client.server_version < "8.0":
# prior to MySQL 8.0, CASTing on index creation will raise SQL syntax error;
# switch to virtual column instead
for i in range(4):
index_str_fmt = f"{column_name}_mem_idx_{i}"
query = " ".join([
f"ALTER TABLE {self.client.quoted_id(table_name)}",
f"ADD COLUMN {self.client.quoted_id(index_str_fmt)} CHAR(128) AS ({column_name}->'$.v[{i}]')",
f", ADD INDEX ({self.client.quoted_id(index_str_fmt)})"
])
try:
self.client.create_index(query)
except OperationalError as exc:
# re-raise exception if the code isn't one of the following code
# 1060 - duplicate column error
if exc.orig.args[0] not in [1060]:
raise exc
else:
for i, index_str in enumerate(self.sql_indexes["__common__"]["JSON"], start=1):
index_str_fmt = Template(index_str).safe_substitute({
"field": column_name, # "data_type": column_type,
})
name = f"{table_name}_json_{i}"
query = f"ALTER TABLE {self.client.quoted_id(table_name)} ADD INDEX {self.client.quoted_id(name)} (({index_str_fmt}))"
self.client.create_index(query)
except (NotSupportedError, OperationalError) as exc:
# some MySQL versions don't support JSON array (NotSupportedError)
# also some of them don't support functional index that returns
# JSON or Geometry value
msg = exc.orig.args[1]
logger.warning(f"Failed to create index {name} for {table_name}.{column_name} column; reason={msg}")

for i, custom in enumerate(self.sql_indexes.get(table_name, {}).get("custom", []), start=1):
# jansPerson table has unsupported custom index expressions that need to be skipped if mysql < 8.0
Expand Down