Via https://github.com/frappe/frappe/pull/16107version-14
@@ -1,10 +1,12 @@ | |||||
from datetime import timedelta | from datetime import timedelta | ||||
from typing import Any, Dict, Optional | from typing import Any, Dict, Optional | ||||
from frappe.utils.data import format_timedelta | |||||
from pypika.terms import Function, ValueWrapper | |||||
from pypika.queries import QueryBuilder | |||||
from pypika.terms import Criterion, Function, ValueWrapper | |||||
from pypika.utils import format_alias_sql | from pypika.utils import format_alias_sql | ||||
from frappe.utils.data import format_timedelta | |||||
class NamedParameterWrapper: | class NamedParameterWrapper: | ||||
"""Utility class to hold parameter values and keys""" | """Utility class to hold parameter values and keys""" | ||||
@@ -100,3 +102,12 @@ class ParameterizedFunction(Function): | |||||
) | ) | ||||
return function_sql | return function_sql | ||||
class subqry(Criterion): | |||||
def __init__(self, subq: QueryBuilder, alias: Optional[str] = None,) -> None: | |||||
super().__init__(alias) | |||||
self.subq = subq | |||||
def get_sql(self, **kwg: Any) -> str: | |||||
kwg["subquery"] = True | |||||
return self.subq.get_sql(**kwg) |
@@ -295,6 +295,8 @@ class NestedSet(Document): | |||||
def get_root_of(doctype): | def get_root_of(doctype): | ||||
"""Get root element of a DocType with a tree structure""" | """Get root element of a DocType with a tree structure""" | ||||
from frappe.query_builder.functions import Count | from frappe.query_builder.functions import Count | ||||
from frappe.query_builder.terms import subqry | |||||
Table = DocType(doctype) | Table = DocType(doctype) | ||||
t1 = Table.as_("t1") | t1 = Table.as_("t1") | ||||
t2 = Table.as_("t2") | t2 = Table.as_("t2") | ||||
@@ -303,7 +305,7 @@ def get_root_of(doctype): | |||||
(t2.lft < t1.lft) & (t2.rgt > t1.rgt) | (t2.lft < t1.lft) & (t2.rgt > t1.rgt) | ||||
) | ) | ||||
result = frappe.qb.from_(t1).select(t1.name).where( | result = frappe.qb.from_(t1).select(t1.name).where( | ||||
(subq == 0) & (t1.rgt > t1.lft) # depends on https://github.com/frappe/frappe/pull/16107 | |||||
(subqry(subq) == 0) & (t1.rgt > t1.lft) | |||||
).run() | ).run() | ||||
return result[0][0] if result else None | return result[0][0] if result else None | ||||