@Override public LogicalNode visitJoin(Context context, LogicalPlan plan, LogicalPlan.QueryBlock block, JoinNode node, Stack<LogicalNode> stack) throws TajoException { visit(context, plan, block, node.getLeftChild(), stack); visit(context, plan, block, node.getRightChild(), stack); if (node.hasJoinQual()) { ExprsVerifier.verify(context.state, node, node.getJoinQual()); } verifyProjectableOutputSchema(context, node); return node; }
@Override public LogicalNode visitJoin(StringBuilder sb, LogicalPlan plan, LogicalPlan.QueryBlock block, JoinNode joinNode, Stack<LogicalNode> stack) throws TajoException { stack.push(joinNode); sb.append("("); visit(sb, plan, block, joinNode.getLeftChild(), stack); sb.append(" ").append(getJoinNotation(joinNode.getJoinType())).append(" "); visit(sb, plan, block, joinNode.getRightChild(), stack); sb.append(")"); stack.pop(); return joinNode; }
private PhysicalExec createBestInnerJoinPlan(TaskAttemptContext context, JoinNode plan, PhysicalExec leftExec, PhysicalExec rightExec) throws IOException { boolean inMemoryHashJoin = false; if (checkIfInMemoryInnerJoinIsPossible(context, plan.getLeftChild(), true) || checkIfInMemoryInnerJoinIsPossible(context, plan.getRightChild(), false)) { inMemoryHashJoin = true; } if (inMemoryHashJoin) { LOG.info("Join (" + plan.getPID() +") chooses [In-memory Hash Join]"); // returns two PhysicalExec. smaller one is 0, and larger one is 1. PhysicalExec [] orderedChilds = switchJoinSidesIfNecessary(context, plan, leftExec, rightExec); return new HashJoinExec(context, plan, orderedChilds[1], orderedChilds[0]); } else { return createMergeInnerJoin(context, plan, leftExec, rightExec); } }
@Override public LogicalNode visitJoin(Object context, LogicalPlan plan, LogicalPlan.QueryBlock block, JoinNode joinNode, Stack<LogicalNode> stack) throws TajoException { if (joinNode.hasJoinQual()) { joinNode.setJoinQual(evalRewriter.visit(null, joinNode.getJoinQual(), new Stack<EvalNode>())); } return null; } }
public void init(JoinType joinType, LogicalNode left, LogicalNode right) { this.joinSpec.setType(joinType); setLeftChild(left); setRightChild(right); }
@Override public LogicalNode visitJoin(CompilationContext context, LogicalPlan plan, LogicalPlan.QueryBlock block, JoinNode node, Stack<LogicalNode> stack) throws TajoException { super.visitJoin(context, plan, block, node, stack); compileProjectableNode(context, node.getInSchema(), node); if (node.hasJoinQual()) { compileIfAbsent(context, node.getInSchema(), node.getJoinQual()); } return node; }
ExecutionBlock currentBlock; LogicalNode leftNode = joinNode.getLeftChild(); LogicalNode rightNode = joinNode.getRightChild(); if (joinNode.getJoinType() != JoinType.CROSS) { joinColumns = PlannerUtil.joinJoinKeyForEachTable(joinNode.getJoinQual(), leftNode.getOutSchema(), rightNode.getOutSchema(), false); ScanNode rightScan = buildInputExecutor(masterPlan.getLogicalPlan(), rightChannel); joinNode.setLeftChild(leftScan); joinNode.setRightChild(rightScan); currentBlock.setPlan(joinNode);
private static JoinNode convertJoin(OverridableConf context, EvalContext evalContext, Map<Integer, LogicalNode> nodeMap, PlanProto.LogicalNode protoNode) { PlanProto.JoinNode joinProto = protoNode.getJoin(); JoinNode join = new JoinNode(protoNode.getNodeId()); join.setLeftChild(nodeMap.get(joinProto.getLeftChildSeq())); join.setRightChild(nodeMap.get(joinProto.getRightChilSeq())); join.setJoinType(convertJoinType(joinProto.getJoinType())); join.setInSchema(convertSchema(protoNode.getInSchema())); join.setOutSchema(convertSchema(protoNode.getOutSchema())); if (joinProto.hasJoinQual()) { join.setJoinQual(EvalNodeDeserializer.deserialize(context, evalContext, joinProto.getJoinQual())); } if (joinProto.getExistsTargets()) { join.setTargets(convertTargets(context, evalContext, joinProto.getTargetsList())); } return join; }
throw new TajoRuntimeException(new NotImplementedException("Not-in subquery")); JoinNode joinNode = new JoinNode(plan.newPID()); joinNode.init(joinType, baseRelation, subqueryEval.getSubQueryNode()); joinNode.setJoinQual(buildJoinCondition(leftEval, subqueryEval.getSubQueryNode())); ProjectionNode projectionNode = PlannerUtil.findTopNode(subqueryEval.getSubQueryNode(), NodeType.PROJECTION); Schema inSchema = SchemaUtil.merge(joinNode.getLeftChild().getOutSchema(), joinNode.getRightChild().getOutSchema()); joinNode.setInSchema(inSchema); joinNode.setOutSchema(node.getOutSchema()); joinNode.setTargets(targets);
@Override public RESULT visitJoin(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, JoinNode node, Stack<LogicalNode> stack) throws TajoException { stack.push(node); RESULT result = visit(context, plan, block, node.getLeftChild(), stack); visit(context, plan, block, node.getRightChild(), stack); stack.pop(); return result; }
@Override public LogicalNode visitJoin(PlanShapeFixerContext context, LogicalPlan plan, LogicalPlan.QueryBlock block, JoinNode node, Stack<LogicalNode> stack) throws TajoException { super.visitJoin(context, plan, block, node, stack); int rightChildNum = context.childNumbers.pop(); int leftChildNum = context.childNumbers.pop(); if (node.hasTargets()) { node.setTargets(sortTargets(node.getTargets())); } if (node.hasJoinQual()) { node.setJoinQual(sortQual(node.getJoinQual())); } context.childNumbers.push(rightChildNum + leftChildNum); return null; }
@Override public LogicalNode visitJoin(SerializeContext context, LogicalPlan plan, LogicalPlan.QueryBlock block, JoinNode join, Stack<LogicalNode> stack) throws TajoException { super.visitJoin(context, plan, block, join, stack); int [] childIds = registerGetChildIds(context, join); // building itself PlanProto.JoinNode.Builder joinBuilder = PlanProto.JoinNode.newBuilder(); joinBuilder.setJoinType(convertJoinType(join.getJoinType())); joinBuilder.setLeftChildSeq(childIds[0]); joinBuilder.setRightChilSeq(childIds[1]); if (join.hasJoinQual()) { joinBuilder.setJoinQual(EvalNodeSerializer.serialize(join.getJoinQual())); } if (join.hasTargets()) { joinBuilder.setExistsTargets(true); joinBuilder.addAllTargets(ProtoUtil.<PlanProto.Target>toProtoObjects(join.getTargets().toArray(new ProtoObject[join.getTargets().size()]))); } else { joinBuilder.setExistsTargets(false); } PlanProto.LogicalNode.Builder nodeBuilder = createNodeBuilder(context, join); nodeBuilder.setJoin(joinBuilder); context.treeBuilder.addNodes(nodeBuilder); return join; }
@Override public LogicalNode visitJoin(GlobalPlanContext context, LogicalPlan plan, LogicalPlan.QueryBlock block, JoinNode node, Stack<LogicalNode> stack) throws TajoException { LogicalNode leftChild = visit(context, plan, block, node.getLeftChild(), stack); ExecutionBlock leftChildBlock = context.execBlockMap.get(leftChild.getPID()); LogicalNode rightChild = visit(context, plan, block, node.getRightChild(), stack); ExecutionBlock rightChildBlock = context.execBlockMap.get(rightChild.getPID()); if (node.getJoinType() == JoinType.LEFT_OUTER) { leftChildBlock.setPreservedRow(); rightChildBlock.setNullSuppllying(); } else if (node.getJoinType() == JoinType.RIGHT_OUTER) { leftChildBlock.setNullSuppllying(); rightChildBlock.setPreservedRow(); } else if (node.getJoinType() == JoinType.FULL_OUTER) { leftChildBlock.setPreservedRow(); leftChildBlock.setNullSuppllying(); rightChildBlock.setPreservedRow(); rightChildBlock.setNullSuppllying(); } ExecutionBlock newExecBlock = buildJoinPlan(context, node, leftChildBlock, rightChildBlock); context.execBlockMap.put(node.getPID(), newExecBlock); return node; }
joinNode.setJoinType(join.getJoinType()); joinNode.setLeftChild(left); joinNode.setRightChild(right); merged = SchemaUtil.merge(left.getOutSchema(), right.getOutSchema()); joinNode.setInSchema(merged); targets.add(block.namedExprsMgr.getTarget(newAddedExpr, true)); joinNode.setTargets(targets.toArray(new Target[targets.size()])); joinNode.setJoinQual(njCond); } else if (join.hasQual()) { // otherwise, the given join conditions are set joinNode.setJoinQual(joinCondition);
public RightOuterMergeJoinExec(TaskAttemptContext context, JoinNode plan, PhysicalExec outer, PhysicalExec inner, SortSpec[] outerSortKey, SortSpec[] innerSortKey) { super(context, plan, outer, inner); Preconditions.checkArgument(plan.hasJoinQual(), "Sort-merge join is only used for the equi-join, " + "but there is no join condition"); final int INITIAL_TUPLE_SLOT = context.getQueryContext().getInt(SessionVars.JOIN_HASH_TABLE_SIZE); this.leftTupleSlots = new TupleList(INITIAL_TUPLE_SLOT); this.innerTupleSlots = new TupleList(INITIAL_TUPLE_SLOT); SortSpec[][] sortSpecs = new SortSpec[2][]; sortSpecs[0] = outerSortKey; sortSpecs[1] = innerSortKey; this.joinComparator = new JoinTupleComparator(outer.getSchema(), inner.getSchema(), sortSpecs); this.tupleComparator = PhysicalPlanUtil.getComparatorsFromJoinQual( plan.getJoinQual(), outer.getSchema(), inner.getSchema()); leftNumCols = outer.getSchema().size(); nullPaddedTuple = NullTuple.create(leftNumCols); }
private PhysicalExec createRightOuterMergeJoinPlan(TaskAttemptContext context, JoinNode plan, PhysicalExec leftExec, PhysicalExec rightExec) throws IOException { //the left operand is too large, so opt for merge join implementation LOG.info("Right Outer Join (" + plan.getPID() +") chooses [Merge Join]."); SortSpec[][] sortSpecs2 = PlannerUtil.getSortKeysFromJoinQual( plan.getJoinQual(), leftExec.getSchema(), rightExec.getSchema()); SortNode leftSortNode2 = LogicalPlan.createNodeWithoutPID(SortNode.class); leftSortNode2.setSortSpecs(sortSpecs2[0]); leftSortNode2.setInSchema(leftExec.getSchema()); leftSortNode2.setOutSchema(leftExec.getSchema()); ExternalSortExec outerSort2 = new ExternalSortExec(context, leftSortNode2, leftExec); SortNode rightSortNode2 = LogicalPlan.createNodeWithoutPID(SortNode.class); rightSortNode2.setSortSpecs(sortSpecs2[1]); rightSortNode2.setInSchema(rightExec.getSchema()); rightSortNode2.setOutSchema(rightExec.getSchema()); ExternalSortExec innerSort2 = new ExternalSortExec(context, rightSortNode2, rightExec); return new RightOuterMergeJoinExec(context, plan, outerSort2, innerSort2, sortSpecs2[0], sortSpecs2[1]); }
@Override public PlanString getPlanString() { PlanString planStr = new PlanString(this).appendTitle("(").appendTitle(joinSpec.getType().name()).appendTitle(")"); if (hasJoinQual()) { planStr.addExplan("Join Cond: " + joinSpec.getSingletonPredicate().toString()); } if (hasTargets()) { planStr.addExplan("target list: ").appendExplain(StringUtils.join(targets, ", ")); } planStr.addDetail("out schema: " + getOutSchema()); planStr.addDetail("in schema: " + getInSchema()); return planStr; }
JoinNode joinNode = new JoinNode(0); ScanNode scanNode2 = new ScanNode(0); scanNode2.init(CatalogUtil.newTableDesc("in2", schema, joinNode.setLeftChild(scanNode); joinNode.setRightChild(scanNode2);
public HashJoinExec(TaskAttemptContext context, JoinNode plan, PhysicalExec leftExec, PhysicalExec rightExec) { super(context, plan, leftExec, rightExec); isCrossJoin = plan.getJoinType().equals(JoinType.CROSS); }
private LogicalNode createCartesianProduct(PlanContext context, LogicalNode left, LogicalNode right) throws TajoException { LogicalPlan plan = context.plan; QueryBlock block = context.queryBlock; Schema merged = SchemaUtil.merge(left.getOutSchema(), right.getOutSchema()); JoinNode join = plan.createNode(JoinNode.class); join.init(JoinType.CROSS, left, right); join.setInSchema(merged); block.addJoinType(join.getJoinType()); EvalNode evalNode; List<String> newlyEvaluatedExprs = new ArrayList<>(); for (Iterator<NamedExpr> it = block.namedExprsMgr.getIteratorForUnevaluatedExprs(); it.hasNext();) { NamedExpr namedExpr = it.next(); try { evalNode = exprAnnotator.createEvalNode(context, namedExpr.getExpr(), NameResolvingMode.LEGACY); if (EvalTreeUtil.findDistinctAggFunction(evalNode).size() == 0 && EvalTreeUtil.findWindowFunction(evalNode).size() == 0) { block.namedExprsMgr.markAsEvaluated(namedExpr.getAlias(), evalNode); newlyEvaluatedExprs.add(namedExpr.getAlias()); } } catch (UndefinedColumnException ve) {} } List<Target> targets = new ArrayList<>(PlannerUtil.schemaToTargets(merged)); for (String newAddedExpr : newlyEvaluatedExprs) { targets.add(block.namedExprsMgr.getTarget(newAddedExpr, true)); } join.setTargets(targets); return join; }