public PlanNode resolve(GroupReference groupReference) { return getNode(groupReference.getGroupId()); }
@Override public void checkTimeoutNotExhausted() { context.checkTimeoutNotExhausted(); }
public static Builder builder() { return new Builder(); }
private static <T> RuleApplication applyRule(Rule<T> rule, PlanNode planNode, Rule.Context context) { PlanNodeMatcher matcher = new PlanNodeMatcher(context.getLookup()); Match<T> match = matcher.match(rule.getPattern(), planNode); Rule.Result result; if (!rule.isEnabled(context.getSession()) || match.isEmpty()) { result = Rule.Result.empty(); } else { result = rule.apply(match.value(), match.captures(), context); } return new RuleApplication(context.getLookup(), context.getStatsProvider(), context.getSymbolAllocator().getTypes(), result); }
@Test public void testInitialization() { PlanNode plan = node(node()); Memo memo = new Memo(idAllocator, plan); assertEquals(memo.getGroupCount(), 2); assertMatchesStructure(plan, memo.extract()); }
private int insertRecursive(PlanNode node) { if (node instanceof GroupReference) { return ((GroupReference) node).getGroupId(); } int group = nextGroupId(); PlanNode rewritten = insertChildrenAndRewrite(node); groups.put(group, Group.withMember(rewritten)); incrementReferenceCounts(rewritten, group); return group; }
private PlanNode extract(PlanNode node) { return resolveGroupReferences(node, Lookup.from(planNode -> Stream.of(this.resolve(planNode)))); }
@Override public Result apply(JoinNode joinNode, Captures captures, Context context) { JoinDistributionType joinDistributionType = getJoinDistributionType(context.getSession()); if (joinDistributionType == AUTOMATIC) { return Result.ofPlanNode(getCostBasedJoin(joinNode, context)); } return Result.ofPlanNode(getSyntacticOrderJoin(joinNode, context, joinDistributionType)); }
private boolean exploreChildren(int group, Context context, Matcher matcher) { boolean progress = false; PlanNode expression = context.memo.getNode(group); for (PlanNode child : expression.getSources()) { checkState(child instanceof GroupReference, "Expected child to be a group reference. Found: " + child.getClass().getName()); if (exploreGroup(((GroupReference) child).getGroupId(), context, matcher)) { progress = true; } } return progress; }
@Override public Result apply(ProjectNode project, Captures captures, Context context) { if (isIdentityProjection(project)) { return Result.ofPlanNode(project.getSource()); } PlanNode projectNode = new ProjectNode(context.getIdAllocator().getNextId(), project, Assignments.identity(project.getOutputSymbols())); return Result.ofPlanNode(projectNode); }
@Override public Result apply(ProjectNode node, Captures captures, Context context) { warnings.stream() .forEach(context.getWarningCollector()::add); return Result.empty(); } }
private boolean exploreGroup(int group, Context context, Matcher matcher) { // tracks whether this group or any children groups change as // this method executes boolean progress = exploreNode(group, context, matcher); while (exploreChildren(group, context, matcher)) { progress = true; // if children changed, try current group again // in case we can match additional rules if (!exploreNode(group, context, matcher)) { // no additional matches, so bail out break; } } return progress; }
@Override public Lookup getLookup() { return noLookup(); }
@Override public Result apply(PlanNode node, Captures captures, Context context) { return Result.empty(); }
@Override public PlanNode replaceChildren(List<PlanNode> newChildren) { return new GenericNode(getId(), newChildren); } }
private boolean wasRuleApplied() { return !result.isEmpty(); }
static Group withMember(PlanNode member) { return new Group(member); }
public PlanNode getNode(int group) { return getGroup(group).membership; }
private int getChildGroup(Memo memo, int group) { PlanNode node = memo.getNode(group); GroupReference child = (GroupReference) node.getSources().get(0); return child.getGroupId(); }