def get_logical_plan(self, body): if isinstance(body, UnionBlock): subplans = [] for ggp in body.triples: subplan = self.get_logical_plan(ggp) if subplan: subplans.append(subplan) if len(subplans) == 1: # No need for an additional union here return subplans[0] else: return LogicalUnion(subplans, Xunion) elif isinstance(body, JoinBlock): if body.bgp: l_plan = self.iterative_dynamic_programming1(body.triples) elif len(body.triples) == 1: return self.get_logical_plan(body.triples[0]) else: left_plan = self.get_logical_plan(body.triples[0]) right_plan = self.get_logical_plan(body.triples[1]) l_plan = LogicalPlan(left_plan, right_plan, Fjoin) return l_plan elif isinstance(body, Optional): plan = self.get_logical_plan(body.triples) return plan
def decompostion_to_plan(self, decomposition): access_plans = [] filters = [] for subplan in decomposition: if isinstance(subplan, Filter): filters.append(subplan) else: if isinstance(subplan, BGP): access_plans.append(LogicalPlan(subplan)) else: access_plans.append(LogicalPlan(subplan)) self.bgp_count.append(float(len(subplan))) todo = sorted(access_plans, key=lambda x: x.cardinality) plan = todo[0] todo.remove(plan) root = True while len(todo): for i in range(len(todo)): if len(plan.variables.intersection(todo[i].variables)) > 0: join_operator = self.get_physical_join_operator( plan, todo[i]) if root and plan.is_basic_graph_pattern and join_operator == Xnjoin: plan = LogicalUnion([plan]) plan = LogicalPlan(plan, todo[i], join_operator) plan.compute_cardinality(self.cardinality_estimation) todo.remove(todo[i]) root = False break else: # In case we cannot find another join able triple pattern next_tp = todo[0] join_operator = self.get_physical_join_operator(plan, next_tp) plan = LogicalPlan(plan, next_tp, join_operator) plan.compute_cardinality(self.cardinality_estimation) todo.remove(next_tp) plan.filters = filters return plan
def get_logical_plan_simple(self, body): if isinstance(body, UnionBlock): subplans = [] for ggp in body.triples: subplan = self.get_logical_plan(ggp) if subplan: subplans.append(subplan) if len(subplans) == 1: # No need for an additional union here return subplans[0] else: return LogicalUnion(subplans, Xunion) elif isinstance(body, JoinBlock): if body.bgp: l_plan = self.optimize_bgp(body.triples) elif len(body.triples) == 1: return self.get_logical_plan(body.triples[0]) elif len(body.triples) == 2 and isinstance(body.triples[1], Optional): # Get operator for Optional # TODO: Handle case with several optionals left_plan = self.get_logical_plan(body.triples[0]) right_plan = self.get_logical_plan(body.triples[1]) operator = self.get_optional_operator(left_plan, right_plan) l_plan = LogicalPlan(left_plan, right_plan, operator) return l_plan else: left_plan = self.get_logical_plan(body.triples[0]) right_plan = self.get_logical_plan(body.triples[1]) l_plan = LogicalPlan(left_plan, right_plan, Fjoin) return l_plan elif isinstance(body, Optional): plan = self.get_logical_plan(body.triples) return plan return None
def union_subplans(self, subplans): if len(subplans) == 1: return subplans[0] else: return LogicalUnion(subplans, Xunion)