def test_eq__dgraph_type(self) -> None: comparator = Eq( predicate="dgraph.type", value=VALUE, ) assert comparator.to_filter() == "type(value)" comparator = Eq( predicate="dgraph.type", value=Not(VALUE), ) assert comparator.to_filter() == "(NOT type(value))"
def test_eq__non_dgraph_type(self) -> None: comparator = Eq( predicate=PREDICATE, value=VALUE, ) assert comparator.to_filter() == "eq(pred, value)" comparator = Eq( predicate=PREDICATE, value=Not(VALUE), ) assert comparator.to_filter() == "(NOT eq(pred, value))"
def find_func(q: "Queryable", var_alloc: VarAllocator) -> str: """ `find_func` will look for the most optimal filter. * Singular EQ on a unique value * Multiple AND'd EQ on a unique value * Singular eq on a non-unique value * <todo, more optimized funcs> * Node type :param q: :return: """ multiple_and_u = None singular_eq_nu = None for (prop_name, or_filter) in q.property_filters(): for and_filter in or_filter: if len(and_filter) == 1 and ( (isinstance(and_filter[0], Eq) or isinstance(and_filter[0], IntEq)) and not and_filter[0].negated ): from copy import deepcopy if prop_name == "node_key": filter = deepcopy(and_filter[0]) v = var_alloc.alloc(Eq("node_key", filter.value)) filter.value = v return filter.to_filter() if prop_name == "uid": filter = deepcopy(and_filter[0]) v = var_alloc.alloc(Eq("uid", filter.value)) filter.value = v return filter.to_filter() singular_eq_nu = and_filter[0].to_filter() if multiple_and_u or singular_eq_nu: return multiple_and_u or singular_eq_nu return f"type({q.node_schema().self_type()})"
def find_func(q: "Queryable", var_alloc: VarAllocator) -> str: """ `find_func` will look for the most optimal filter. * Singular EQ on a unique value * Singular eq on a non-unique value * <todo, more optimized funcs> * Node type :param q: :return: """ and_filter: List[Cmp] singular_eq_nu = None for (prop_name, or_filter) in q.property_filters(): for and_filter in or_filter: if len(and_filter) == 1 and ((isinstance(and_filter[0], Eq) or isinstance(and_filter[0], IntEq)) and not and_filter[0].negated): filter = deepcopy(and_filter[0]) if prop_name == "node_key": filter.value = var_alloc.alloc(Eq("node_key", filter.value)) return filter.to_filter() elif prop_name == "uid": filter.value = var_alloc.alloc(Eq("uid", filter.value)) return filter.to_filter() else: filter.value = var_alloc.alloc( Eq(filter.predicate, filter.value)) singular_eq_nu = filter.to_filter() if singular_eq_nu: return singular_eq_nu return f"type({q.node_schema().self_type()})"
def with_node_key(self: Q, *, eq: str) -> Q: self._property_filters["node_key"] = [[Eq("node_key", eq)]] return self
def gen_query_parameterized( q: "Queryable", query_name: str, contains_node_key: str, depth: int, binding_modifier: Optional[str] = None, vars_alloc: Optional[VarAllocator] = None, ) -> Tuple[VarAllocator, str]: binding_modifier = binding_modifier or "" vars_alloc = vars_alloc or VarAllocator() bindings = [] var_queries = [] node_key_var = vars_alloc.alloc(Eq("node_key", contains_node_key)) for i, node in enumerate(traverse_query_iter(q)): func = f"eq(node_key, {node_key_var}), first: 1" binding = f"{binding_modifier}Binding{depth}_{i}" bindings.append(binding) var_name = "" if node._id == q._id: var_name = binding var_query, var_block = into_var_query( node, var_name, vars_alloc, func=func, binding=binding, root_node=q, ) var_queries.append(var_query) formatted_var_queries = "\n".join(var_queries) merged = type(q)() zip_graph(q, merged) __merged_filters, merged_query_block = into_query_block( merged, VarAllocator(), should_filter=False, should_alias=False, ) vars_list = into_vars_list(vars_alloc) coalescing_query_name, coalescing_query = gen_coalescing_query( merged, vars_alloc, query_name, bindings) query = f""" query {query_name}({vars_list}) {{ {formatted_var_queries} {coalescing_query} {query_name}(func: uid({coalescing_query_name}), first: 1) @cascade {{ {merged_query_block} }} }} """ return vars_alloc, query