Files
erpnext/erpnext/tests/test_perf.py
Mihir Kandoi 549a24f7b9 ci(postgres): add a static pre-commit check for MySQL-only SQL
The Postgres test job is label-gated, so it does not run on every PR. This adds an
always-on pre-commit hook that statically flags the *mechanical* breaks: MySQL-only
functions (timestamp(date,time), timediff, str_to_date, date_format/add/sub,
group_concat, period_diff, SQL IF()), SHOW INDEX/TABLES/COLUMNS, single-quoted
aliases, UPDATE..JOIN, interpolated/f-string SQL carrying MySQL-isms,
set_value/db_set(<Check>, bool), and MySQL SHOW INDEX result keys.

It deliberately does NOT flag the framework auto-translations (ifnull->coalesce,
backtick/locate/REGEXP, .like()->ILIKE) nor the *semantic* divergences (loose GROUP
BY, case-sensitive ==/IN, NULL ordering, tiebreakers) — those need the test suite,
which remains the backstop. AST + structure-gated regex keep false positives near
zero (docstrings and prose skipped); '# pg-ok' exempts intentional MariaDB-only
branches. Scoped to erpnext/ excluding patches/. Includes a unit test of the checker.
2026-06-21 16:53:53 +05:30

54 lines
1.6 KiB
Python

import frappe
from erpnext.tests.utils import ERPNextTestSuite
INDEXED_FIELDS = {
"Bin": ["item_code"],
"GL Entry": ["voucher_no", "posting_date", "company", "party"],
"Purchase Order Item": ["item_code"],
}
def _is_leading_index_column(doctype: str, field: str) -> bool:
"""Whether `field` is the first column of some index on the doctype's table.
`SHOW INDEX` is MySQL-only; on Postgres read the leading key column (indkey[0])
from the pg_index catalog. Both check the same thing across engines.
"""
table = f"tab{doctype}"
if frappe.db.db_type == "postgres":
return bool(
frappe.db.sql(
"""
SELECT 1
FROM pg_index i
JOIN pg_class t ON t.oid = i.indrelid
JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = i.indkey[0]
WHERE t.relname = %s AND a.attname = %s
LIMIT 1
""",
(table, field),
)
)
# `table` is a trusted constant (from INDEXED_FIELDS); a table identifier can't be a %s
# placeholder in SHOW INDEX, so the f-string is unavoidable and safe here.
return bool(
frappe.db.sql( # pg-ok: MariaDB-only branch; Postgres is handled above via pg_index
f"""SHOW INDEX FROM `{table}` WHERE Column_name = %s AND Seq_in_index = 1""",
(field,),
)
)
class TestPerformance(ERPNextTestSuite):
def test_ensure_indexes(self):
# These fields are not explicitly indexed BUT they are prefix in some
# other composite index. If those are removed this test should be
# updated accordingly.
for doctype, fields in INDEXED_FIELDS.items():
for field in fields:
self.assertTrue(
_is_leading_index_column(doctype, field),
msg=f"{field} is not the leading column of any index on tab{doctype}",
)