Bladeren bron

Merge pull request #18297 from frappe/mergify/bp/version-14-hotfix/pr-18262

fix: correct index syncing (backport #18262)
version-14
Ankush Menat 2 jaren geleden
committed by GitHub
bovenliggende
commit
0bb1f29af5
Geen bekende sleutel gevonden voor deze handtekening in de database GPG sleutel-ID: 4AEE18F83AFDEB23
2 gewijzigde bestanden met toevoegingen van 46 en 36 verwijderingen
  1. +32
    -0
      frappe/database/mariadb/database.py
  2. +14
    -36
      frappe/database/mariadb/schema.py

+ 32
- 0
frappe/database/mariadb/database.py Bestand weergeven

@@ -301,6 +301,7 @@ class MariaDBDatabase(MariaDBConnectionUtil, MariaDBExceptionUtil, Database):
where table_name="{table_name}" where table_name="{table_name}"
and column_name=columns.column_name and column_name=columns.column_name
and NON_UNIQUE=1 and NON_UNIQUE=1
and Seq_in_index = 1
limit 1 limit 1
), 0) as 'index', ), 0) as 'index',
column_key = 'UNI' as 'unique' column_key = 'UNI' as 'unique'
@@ -319,6 +320,37 @@ class MariaDBDatabase(MariaDBConnectionUtil, MariaDBExceptionUtil, Database):
) )
) )


def get_column_index(
self, table_name: str, fieldname: str, unique: bool = False
) -> frappe._dict | None:
"""Check if column exists for a specific fields in specified order.

This differs from db.has_index because it doesn't rely on index name but columns inside an
index.
"""

indexes = self.sql(
f"""SHOW INDEX FROM `{table_name}`
WHERE Column_name = "{fieldname}"
AND Seq_in_index = 1
AND Non_unique={int(not unique)}
""",
as_dict=True,
)

# Same index can be part of clustered index which contains more fields
# We don't want those.
for index in indexes:
clustered_index = self.sql(
f"""SHOW INDEX FROM `{table_name}`
WHERE Key_name = "{index.Key_name}"
AND Seq_in_index = 2
""",
as_dict=True,
)
if not clustered_index:
return index

def add_index(self, doctype: str, fields: list, index_name: str = None): def add_index(self, doctype: str, fields: list, index_name: str = None):
"""Creates an index with given fields if not already created. """Creates an index with given fields if not already created.
Index name will be `fieldname1_fieldname2_index`""" Index name will be `fieldname1_fieldname2_index`"""


+ 14
- 36
frappe/database/mariadb/schema.py Bestand weergeven

@@ -84,45 +84,23 @@ class MariaDBTable(DBTable):


for col in self.add_index: for col in self.add_index:
# if index key does not exists # if index key does not exists
if not frappe.db.has_index(self.table_name, col.fieldname + "_index"):
if not frappe.db.get_column_index(self.table_name, col.fieldname, unique=False):
add_index_query.append(f"ADD INDEX `{col.fieldname}_index`(`{col.fieldname}`)") add_index_query.append(f"ADD INDEX `{col.fieldname}_index`(`{col.fieldname}`)")


for col in self.drop_index + self.drop_unique: for col in self.drop_index + self.drop_unique:
if col.fieldname != "name": # primary key
current_column = self.current_columns.get(col.fieldname.lower())
unique_constraint_changed = current_column.unique != col.unique
if unique_constraint_changed and not col.unique:
# nosemgrep
unique_index_record = frappe.db.sql(
"""
SHOW INDEX FROM `{}`
WHERE Key_name=%s
AND Non_unique=0
""".format(
self.table_name
),
(col.fieldname),
as_dict=1,
)
if unique_index_record:
drop_index_query.append(f"DROP INDEX `{unique_index_record[0].Key_name}`")
index_constraint_changed = current_column.index != col.set_index
# if index key exists
if index_constraint_changed and not col.set_index:
# nosemgrep
index_record = frappe.db.sql(
"""
SHOW INDEX FROM `{}`
WHERE Key_name=%s
AND Non_unique=1
""".format(
self.table_name
),
(col.fieldname + "_index"),
as_dict=1,
)
if index_record:
drop_index_query.append(f"DROP INDEX `{index_record[0].Key_name}`")
if col.fieldname == "name":
continue

current_column = self.current_columns.get(col.fieldname.lower())
unique_constraint_changed = current_column.unique != col.unique
if unique_constraint_changed and not col.unique:
if unique_index := frappe.db.get_column_index(self.table_name, col.fieldname, unique=True):
drop_index_query.append(f"DROP INDEX `{unique_index.Key_name}`")

index_constraint_changed = current_column.index != col.set_index
if index_constraint_changed and not col.set_index:
if index_record := frappe.db.get_column_index(self.table_name, col.fieldname, unique=False):
drop_index_query.append(f"DROP INDEX `{index_record.Key_name}`")


try: try:
for query_parts in [add_column_query, modify_column_query, add_index_query, drop_index_query]: for query_parts in [add_column_query, modify_column_query, add_index_query, drop_index_query]:


Laden…
Annuleren
Opslaan