mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-14 07:01:56 +00:00
fix(accounts): cast non-text Account fields for LIKE filters (Postgres)
Financial Report Template calculation_formula filters are user-authored and only validated for field existence + operator membership, not that a like/ilike operator targets a text field. A filter such as ["is_group", "like", "1"] builds `is_group ILIKE '%1%'`; PostgreSQL has no LIKE/ILIKE operator for a smallint/int/numeric column (`operator does not exist: smallint ~~* unknown`) and aborts the report, while MariaDB implicitly casts the numeric column to text and matches. For like-family operators, cast a numeric/Check Account field to varchar (`Cast_(field, "varchar")`), reproducing MariaDB's implicit numeric->text coercion on both engines. Text-field filters (the normal account_name/ account_number case) are left untouched, so MariaDB output is unchanged.
This commit is contained in:
@@ -12,8 +12,9 @@ from typing import Any, Union
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.database.operator_map import OPERATOR_MAP
|
||||
from frappe.model import numeric_fieldtypes
|
||||
from frappe.query_builder import Case
|
||||
from frappe.query_builder.functions import Sum
|
||||
from frappe.query_builder.functions import Cast_, Sum
|
||||
from frappe.utils import cstr, date_diff, flt, getdate
|
||||
from frappe.utils.xlsxutils import XLSXMetadata, XLSXStyleBuilder
|
||||
from pypika.terms import Bracket, LiteralValue
|
||||
@@ -864,8 +865,15 @@ class FilterExpressionParser:
|
||||
field = getattr(table, field_name, None)
|
||||
operator_fn = OPERATOR_MAP.get(operator.casefold())
|
||||
|
||||
if "like" in operator.casefold() and "%" not in value:
|
||||
value = f"%{value}%"
|
||||
if "like" in operator.casefold():
|
||||
if "%" not in value:
|
||||
value = f"%{value}%"
|
||||
# Postgres has no LIKE/ILIKE operator for non-text columns; MariaDB implicitly casts
|
||||
# the numeric column to text. Cast a numeric/Check Account field to varchar so the
|
||||
# match runs on both engines and reproduces MariaDB's result.
|
||||
meta_field = frappe.get_meta("Account").get_field(field_name)
|
||||
if meta_field and meta_field.fieldtype in numeric_fieldtypes:
|
||||
field = Cast_(field, "varchar")
|
||||
|
||||
return operator_fn(field, value)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user