Search in sources :

Example 6 with JoinCondition

use of org.apache.drill.common.logical.data.JoinCondition in project drill by apache.

the class DrillSemiJoinRel method implement.

@Override
public LogicalOperator implement(DrillImplementor implementor) {
    List<String> fields = new ArrayList<>();
    fields.addAll(getInput(0).getRowType().getFieldNames());
    fields.addAll(getInput(1).getRowType().getFieldNames());
    Preconditions.checkArgument(DrillJoinRel.isUnique(fields));
    final int leftCount = left.getRowType().getFieldCount();
    final List<String> leftFields = fields.subList(0, leftCount);
    final List<String> rightFields = fields.subList(leftCount, leftCount + right.getRowType().getFieldCount());
    final LogicalOperator leftOp = DrillJoinRel.implementInput(implementor, 0, 0, left, this, fields);
    final LogicalOperator rightOp = DrillJoinRel.implementInput(implementor, 1, leftCount, right, this, fields);
    Join.Builder builder = Join.builder();
    builder.type(joinType);
    builder.left(leftOp);
    builder.right(rightOp);
    List<JoinCondition> conditions = Lists.newArrayList();
    for (Pair<Integer, Integer> pair : Pair.zip(leftKeys, rightKeys)) {
        conditions.add(new JoinCondition(DrillJoinRel.EQUALITY_CONDITION, new FieldReference(leftFields.get(pair.left)), new FieldReference(rightFields.get(pair.right))));
    }
    return new LogicalSemiJoin(leftOp, rightOp, conditions, joinType);
}
Also used : FieldReference(org.apache.drill.common.expression.FieldReference) LogicalOperator(org.apache.drill.common.logical.data.LogicalOperator) ArrayList(java.util.ArrayList) Join(org.apache.drill.common.logical.data.Join) LogicalSemiJoin(org.apache.drill.common.logical.data.LogicalSemiJoin) LogicalSemiJoin(org.apache.drill.common.logical.data.LogicalSemiJoin) JoinCondition(org.apache.drill.common.logical.data.JoinCondition)

Example 7 with JoinCondition

use of org.apache.drill.common.logical.data.JoinCondition in project drill by apache.

the class HashJoinPrel method getHashJoinPop.

private PhysicalOperator getHashJoinPop(PhysicalPlanCreator creator, RelNode left, RelNode right, List<Integer> leftKeys, List<Integer> rightKeys, boolean isRowKeyJoin, int htControl) throws IOException {
    final List<String> fields = getRowType().getFieldNames();
    assert isUnique(fields);
    final List<String> leftFields = left.getRowType().getFieldNames();
    final List<String> rightFields = right.getRowType().getFieldNames();
    PhysicalOperator leftPop = ((Prel) left).getPhysicalOperator(creator);
    PhysicalOperator rightPop = ((Prel) right).getPhysicalOperator(creator);
    JoinRelType jtype = this.getJoinType();
    List<JoinCondition> conditions = Lists.newArrayList();
    buildJoinConditions(conditions, leftFields, rightFields, leftKeys, rightKeys);
    RuntimeFilterDef runtimeFilterDef = this.getRuntimeFilterDef();
    HashJoinPOP hjoin = new HashJoinPOP(leftPop, rightPop, conditions, jtype, isSemiJoin, runtimeFilterDef, isRowKeyJoin, htControl);
    return creator.addMetadata(this, hjoin);
}
Also used : JoinRelType(org.apache.calcite.rel.core.JoinRelType) PhysicalOperator(org.apache.drill.exec.physical.base.PhysicalOperator) HashJoinPOP(org.apache.drill.exec.physical.config.HashJoinPOP) RuntimeFilterDef(org.apache.drill.exec.work.filter.RuntimeFilterDef) JoinCondition(org.apache.drill.common.logical.data.JoinCondition)

Example 8 with JoinCondition

use of org.apache.drill.common.logical.data.JoinCondition in project drill by axbaretto.

the class JoinPrel method buildJoinConditions.

/**
 * Build the list of join conditions for this join.
 * A join condition is built only for equality and IS NOT DISTINCT FROM comparisons. The difference is:
 * null == null is FALSE whereas null IS NOT DISTINCT FROM null is TRUE
 * For a use case of the IS NOT DISTINCT FROM comparison, see
 * {@link org.apache.calcite.rel.rules.RemoveDistinctAggregateRule}
 * @param conditions populated list of join conditions
 * @param leftFields join fields from the left input
 * @param rightFields join fields from the right input
 */
protected void buildJoinConditions(List<JoinCondition> conditions, List<String> leftFields, List<String> rightFields, List<Integer> leftKeys, List<Integer> rightKeys) {
    List<RexNode> conjuncts = RelOptUtil.conjunctions(this.getCondition());
    short i = 0;
    for (Pair<Integer, Integer> pair : Pair.zip(leftKeys, rightKeys)) {
        final RexNode conditionExpr = conjuncts.get(i++);
        final SqlKind kind = conditionExpr.getKind();
        if (kind != SqlKind.EQUALS && kind != SqlKind.IS_NOT_DISTINCT_FROM) {
            throw UserException.unsupportedError().message("Unsupported comparator in join condition %s", conditionExpr).build(logger);
        }
        conditions.add(new JoinCondition(kind.toString(), FieldReference.getWithQuotedRef(leftFields.get(pair.left)), FieldReference.getWithQuotedRef(rightFields.get(pair.right))));
    }
}
Also used : SqlKind(org.apache.calcite.sql.SqlKind) RexNode(org.apache.calcite.rex.RexNode) JoinCondition(org.apache.drill.common.logical.data.JoinCondition)

Example 9 with JoinCondition

use of org.apache.drill.common.logical.data.JoinCondition in project drill by axbaretto.

the class HashJoinPrel method getHashJoinPop.

private PhysicalOperator getHashJoinPop(PhysicalPlanCreator creator, RelNode left, RelNode right, List<Integer> leftKeys, List<Integer> rightKeys) throws IOException {
    final List<String> fields = getRowType().getFieldNames();
    assert isUnique(fields);
    final List<String> leftFields = left.getRowType().getFieldNames();
    final List<String> rightFields = right.getRowType().getFieldNames();
    PhysicalOperator leftPop = ((Prel) left).getPhysicalOperator(creator);
    PhysicalOperator rightPop = ((Prel) right).getPhysicalOperator(creator);
    JoinRelType jtype = this.getJoinType();
    List<JoinCondition> conditions = Lists.newArrayList();
    buildJoinConditions(conditions, leftFields, rightFields, leftKeys, rightKeys);
    HashJoinPOP hjoin = new HashJoinPOP(leftPop, rightPop, conditions, jtype);
    return creator.addMetadata(this, hjoin);
}
Also used : JoinRelType(org.apache.calcite.rel.core.JoinRelType) PhysicalOperator(org.apache.drill.exec.physical.base.PhysicalOperator) HashJoinPOP(org.apache.drill.exec.physical.config.HashJoinPOP) JoinCondition(org.apache.drill.common.logical.data.JoinCondition)

Example 10 with JoinCondition

use of org.apache.drill.common.logical.data.JoinCondition in project drill by axbaretto.

the class MergeJoinBatch method generateNewWorker.

private JoinWorker generateNewWorker() throws ClassTransformationException, IOException, SchemaChangeException {
    final ClassGenerator<JoinWorker> cg = CodeGenerator.getRoot(JoinWorker.TEMPLATE_DEFINITION, context.getOptions());
    cg.getCodeGenerator().plainJavaCapable(true);
    // cg.getCodeGenerator().saveCodeForDebugging(true);
    final ErrorCollector collector = new ErrorCollectorImpl();
    // Generate members and initialization code
    // ///////////////////////////////////////
    // declare and assign JoinStatus member
    cg.setMappingSet(setupMapping);
    JClass joinStatusClass = cg.getModel().ref(JoinStatus.class);
    JVar joinStatus = cg.clazz.field(JMod.NONE, joinStatusClass, "status");
    cg.getSetupBlock().assign(JExpr._this().ref(joinStatus), JExpr.direct("status"));
    // declare and assign outgoing VectorContainer member
    JClass vectorContainerClass = cg.getModel().ref(VectorContainer.class);
    JVar outgoingVectorContainer = cg.clazz.field(JMod.NONE, vectorContainerClass, "outgoing");
    cg.getSetupBlock().assign(JExpr._this().ref(outgoingVectorContainer), JExpr.direct("outgoing"));
    // declare and assign incoming left RecordBatch member
    JClass recordBatchClass = cg.getModel().ref(RecordIterator.class);
    JVar incomingLeftRecordBatch = cg.clazz.field(JMod.NONE, recordBatchClass, "incomingLeft");
    cg.getSetupBlock().assign(JExpr._this().ref(incomingLeftRecordBatch), joinStatus.ref("left"));
    // declare and assign incoming right RecordBatch member
    JVar incomingRightRecordBatch = cg.clazz.field(JMod.NONE, recordBatchClass, "incomingRight");
    cg.getSetupBlock().assign(JExpr._this().ref(incomingRightRecordBatch), joinStatus.ref("right"));
    // declare 'incoming' member so VVReadExpr generated code can point to the left or right batch
    JVar incomingRecordBatch = cg.clazz.field(JMod.NONE, recordBatchClass, "incoming");
    /*
     * Materialize expressions on both sides of the join condition. Check if both the sides
     * have the same return type, if not then inject casts so that comparison function will work as
     * expected
     */
    LogicalExpression[] leftExpr = new LogicalExpression[conditions.size()];
    LogicalExpression[] rightExpr = new LogicalExpression[conditions.size()];
    IterOutcome lastLeftStatus = status.getLeftStatus();
    IterOutcome lastRightStatus = status.getRightStatus();
    for (int i = 0; i < conditions.size(); i++) {
        JoinCondition condition = conditions.get(i);
        leftExpr[i] = materializeExpression(condition.getLeft(), lastLeftStatus, leftIterator, collector);
        rightExpr[i] = materializeExpression(condition.getRight(), lastRightStatus, rightIterator, collector);
    }
    // call to throw an exception. In this case we can safely skip adding the casts
    if (lastRightStatus != IterOutcome.NONE) {
        JoinUtils.addLeastRestrictiveCasts(leftExpr, leftIterator, rightExpr, rightIterator, context);
    }
    // generate doCompare() method
    // ///////////////////////////////////////
    generateDoCompare(cg, incomingRecordBatch, leftExpr, incomingLeftRecordBatch, rightExpr, incomingRightRecordBatch, collector);
    // generate copyLeft()
    // ////////////////////
    cg.setMappingSet(copyLeftMapping);
    int vectorId = 0;
    if (worker == null || !status.left.finished()) {
        for (VectorWrapper<?> vw : leftIterator) {
            MajorType inputType = vw.getField().getType();
            MajorType outputType;
            if (joinType == JoinRelType.RIGHT && inputType.getMode() == DataMode.REQUIRED) {
                outputType = Types.overrideMode(inputType, DataMode.OPTIONAL);
            } else {
                outputType = inputType;
            }
            // TODO (DRILL-4011): Factor out CopyUtil and use it here.
            JVar vvIn = cg.declareVectorValueSetupAndMember("incomingLeft", new TypedFieldId(inputType, vectorId));
            JVar vvOut = cg.declareVectorValueSetupAndMember("outgoing", new TypedFieldId(outputType, vectorId));
            // todo: check result of copyFromSafe and grow allocation
            cg.getEvalBlock().add(vvOut.invoke("copyFromSafe").arg(copyLeftMapping.getValueReadIndex()).arg(copyLeftMapping.getValueWriteIndex()).arg(vvIn));
            cg.rotateBlock();
            ++vectorId;
        }
    }
    // generate copyRight()
    // /////////////////////
    cg.setMappingSet(copyRightMappping);
    int rightVectorBase = vectorId;
    if (status.getRightStatus() != IterOutcome.NONE && (worker == null || !status.right.finished())) {
        for (VectorWrapper<?> vw : rightIterator) {
            MajorType inputType = vw.getField().getType();
            MajorType outputType;
            if (joinType == JoinRelType.LEFT && inputType.getMode() == DataMode.REQUIRED) {
                outputType = Types.overrideMode(inputType, DataMode.OPTIONAL);
            } else {
                outputType = inputType;
            }
            // TODO (DRILL-4011): Factor out CopyUtil and use it here.
            JVar vvIn = cg.declareVectorValueSetupAndMember("incomingRight", new TypedFieldId(inputType, vectorId - rightVectorBase));
            JVar vvOut = cg.declareVectorValueSetupAndMember("outgoing", new TypedFieldId(outputType, vectorId));
            // todo: check result of copyFromSafe and grow allocation
            cg.getEvalBlock().add(vvOut.invoke("copyFromSafe").arg(copyRightMappping.getValueReadIndex()).arg(copyRightMappping.getValueWriteIndex()).arg(vvIn));
            cg.rotateBlock();
            ++vectorId;
        }
    }
    JoinWorker w = context.getImplementationClass(cg);
    w.setupJoin(context, status, this.container);
    return w;
}
Also used : JClass(com.sun.codemodel.JClass) MajorType(org.apache.drill.common.types.TypeProtos.MajorType) ErrorCollector(org.apache.drill.common.expression.ErrorCollector) JoinCondition(org.apache.drill.common.logical.data.JoinCondition) ErrorCollectorImpl(org.apache.drill.common.expression.ErrorCollectorImpl) LogicalExpression(org.apache.drill.common.expression.LogicalExpression) TypedFieldId(org.apache.drill.exec.record.TypedFieldId) JVar(com.sun.codemodel.JVar)

Aggregations

JoinCondition (org.apache.drill.common.logical.data.JoinCondition)14 JoinRelType (org.apache.calcite.rel.core.JoinRelType)5 PhysicalOperator (org.apache.drill.exec.physical.base.PhysicalOperator)5 HashJoinPOP (org.apache.drill.exec.physical.config.HashJoinPOP)5 ArrayList (java.util.ArrayList)4 RexNode (org.apache.calcite.rex.RexNode)4 JClass (com.sun.codemodel.JClass)2 JVar (com.sun.codemodel.JVar)2 RelNode (org.apache.calcite.rel.RelNode)2 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)2 SqlKind (org.apache.calcite.sql.SqlKind)2 ErrorCollector (org.apache.drill.common.expression.ErrorCollector)2 ErrorCollectorImpl (org.apache.drill.common.expression.ErrorCollectorImpl)2 LogicalExpression (org.apache.drill.common.expression.LogicalExpression)2 MajorType (org.apache.drill.common.types.TypeProtos.MajorType)2 MergeJoinPOP (org.apache.drill.exec.physical.config.MergeJoinPOP)2 MockRecordBatch (org.apache.drill.exec.physical.impl.MockRecordBatch)2 RecordBatch (org.apache.drill.exec.record.RecordBatch)2 TypedFieldId (org.apache.drill.exec.record.TypedFieldId)2 OperatorTest (org.apache.drill.categories.OperatorTest)1