diff --git a/frappe/query_builder/functions.py b/frappe/query_builder/functions.py index 98cd501be2..1776abb029 100644 --- a/frappe/query_builder/functions.py +++ b/frappe/query_builder/functions.py @@ -2,7 +2,7 @@ from datetime import time from enum import Enum from pypika.functions import * -from pypika.terms import Arithmetic, ArithmeticExpression, CustomFunction, Function +from pypika.terms import Arithmetic, ArithmeticExpression, CustomFunction, Function, Term import frappe from frappe.query_builder.custom import ( @@ -118,6 +118,47 @@ UnixTimestamp = ImportMapper( ) +class _MariaDBJSONExtract(Function): + def __init__(self, field, path, **kwargs): + super().__init__("JSON_EXTRACT", field, path, **kwargs) + + +class _MariaDBJSONValue(Function): + def __init__(self, field, path, **kwargs): + super().__init__("JSON_UNQUOTE", _MariaDBJSONExtract(field, path), **kwargs) + + +class _MariaDBJSONContains(Function): + def __init__(self, target, candidate, **kwargs): + from pypika.terms import JSON + + if not isinstance(candidate, Term): + candidate = JSON(candidate) + super().__init__("JSON_CONTAINS", target, candidate, **kwargs) + + +JSONExtract = ImportMapper( + { + db_type_is.MARIADB: _MariaDBJSONExtract, + db_type_is.POSTGRES: lambda field, path, **kw: field.get_json_value(path), + } +) + +JSONValue = ImportMapper( + { + db_type_is.MARIADB: _MariaDBJSONValue, + db_type_is.POSTGRES: lambda field, path, **kw: field.get_text_value(path), + } +) + +JSONContains = ImportMapper( + { + db_type_is.MARIADB: _MariaDBJSONContains, + db_type_is.POSTGRES: lambda target, candidate, **kw: target.contains(candidate), + } +) + + class Cast_(Function): def __init__(self, value, as_type, alias=None): if frappe.db.db_type == "mariadb" and (