/////////////////////////////////////////
// declare and assign JoinStatus member
cg.setMappingSet(SETUP_MAPPING);
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(RecordBatch.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 value vector readers from join expression
final LogicalExpression materializedLeftExpr = ExpressionTreeMaterializer.materialize(leftFieldExpr, left, collector);
if (collector.hasErrors())
throw new ClassTransformationException(String.format(
"Failure while trying to materialize incoming left field. Errors:\n %s.", collector.toErrorString()));
final LogicalExpression materializedRightExpr = ExpressionTreeMaterializer.materialize(rightFieldExpr, right, collector);
if (collector.hasErrors())
throw new ClassTransformationException(String.format(
"Failure while trying to materialize incoming right field. Errors:\n %s.", collector.toErrorString()));
// generate compare()
////////////////////////
cg.setMappingSet(COMPARE_MAPPING);
cg.getSetupBlock().assign(JExpr._this().ref(incomingRecordBatch), JExpr._this().ref(incomingLeftRecordBatch));
CodeGenerator.HoldingContainer compareLeftExprHolder = cg.addExpr(materializedLeftExpr, false);
cg.setMappingSet(COMPARE_RIGHT_MAPPING);
cg.getSetupBlock().assign(JExpr._this().ref(incomingRecordBatch), JExpr._this().ref(incomingRightRecordBatch));
CodeGenerator.HoldingContainer compareRightExprHolder = cg.addExpr(materializedRightExpr, false);
if (compareLeftExprHolder.isOptional() && compareRightExprHolder.isOptional()) {
// handle null == null
cg.getEvalBlock()._if(compareLeftExprHolder.getIsSet().eq(JExpr.lit(0))
.cand(compareRightExprHolder.getIsSet().eq(JExpr.lit(0))))
._then()
._return(JExpr.lit(0));
// handle null == !null
cg.getEvalBlock()._if(compareLeftExprHolder.getIsSet().eq(JExpr.lit(0))
.cor(compareRightExprHolder.getIsSet().eq(JExpr.lit(0))))
._then()
._return(JExpr.lit(1));
} else if (compareLeftExprHolder.isOptional()) {
// handle null == required (null is less than any value)
cg.getEvalBlock()._if(compareLeftExprHolder.getIsSet().eq(JExpr.lit(0)))
._then()
._return(JExpr.lit(-1));
} else if (compareRightExprHolder.isOptional()) {
// handle required == null (null is less than any value)
cg.getEvalBlock()._if(compareRightExprHolder.getIsSet().eq(JExpr.lit(0)))
._then()
._return(JExpr.lit(1));
}
FunctionCall f = new FunctionCall(ComparatorFunctions.COMPARE_TO, ImmutableList.of((LogicalExpression) new HoldingContainerExpression(compareLeftExprHolder), (LogicalExpression) new HoldingContainerExpression(compareRightExprHolder)), ExpressionPosition.UNKNOWN);
cg.addExpr(new ReturnValueExpression(f, false), false);
//
// // equality
// cg.getEvalBlock()._if(compareLeftExprHolder.getValue().eq(compareRightExprHolder.getValue()))
// ._then()
// ._return(JExpr.lit(0));
// // less than
// cg.getEvalBlock()._if(compareLeftExprHolder.getValue().lt(compareRightExprHolder.getValue()))
// ._then()
// ._return(JExpr.lit(-1));
// // greater than
// cg.getEvalBlock()._return(JExpr.lit(1));
// generate compareNextLeftKey()
////////////////////////////////
cg.setMappingSet(COMPARE_LEFT_MAPPING);
cg.getSetupBlock().assign(JExpr._this().ref(incomingRecordBatch), JExpr._this().ref(incomingLeftRecordBatch));
// int nextLeftIndex = leftIndex + 1;
cg.getEvalBlock().decl(JType.parse(cg.getModel(), "int"), "nextLeftIndex", JExpr.direct("leftIndex").plus(JExpr.lit(1)));
// check if the next key is in this batch
cg.getEvalBlock()._if(joinStatus.invoke("isNextLeftPositionInCurrentBatch").eq(JExpr.lit(false)))
._then()
._return(JExpr.lit(-1));
// generate VV read expressions
CodeGenerator.HoldingContainer compareThisLeftExprHolder = cg.addExpr(materializedLeftExpr, false);
cg.setMappingSet(COMPARE_NEXT_LEFT_MAPPING); // change mapping from 'leftIndex' to 'nextLeftIndex'
CodeGenerator.HoldingContainer compareNextLeftExprHolder = cg.addExpr(materializedLeftExpr, false);
if (compareThisLeftExprHolder.isOptional()) {
// handle null == null
cg.getEvalBlock()._if(compareThisLeftExprHolder.getIsSet().eq(JExpr.lit(0))
.cand(compareNextLeftExprHolder.getIsSet().eq(JExpr.lit(0))))
._then()
._return(JExpr.lit(0));
// handle null == !null
cg.getEvalBlock()._if(compareThisLeftExprHolder.getIsSet().eq(JExpr.lit(0))
.cor(compareNextLeftExprHolder.getIsSet().eq(JExpr.lit(0))))
._then()
._return(JExpr.lit(1));
}
// check value equality
cg.getEvalBlock()._if(compareThisLeftExprHolder.getValue().eq(compareNextLeftExprHolder.getValue()))
._then()
._return(JExpr.lit(0));
// no match if reached
cg.getEvalBlock()._return(JExpr.lit(1));
// generate copyLeft()
//////////////////////
cg.setMappingSet(COPY_LEFT_MAPPING);
int vectorId = 0;
for (VectorWrapper<?> vw : left) {
JVar vvIn = cg.declareVectorValueSetupAndMember("incomingLeft",
new TypedFieldId(vw.getField().getType(), vectorId));
JVar vvOut = cg.declareVectorValueSetupAndMember("outgoing",
new TypedFieldId(vw.getField().getType(),vectorId));
// todo: check result of copyFromSafe and grow allocation
cg.getEvalBlock().add(vvOut.invoke("copyFromSafe")
.arg(COPY_LEFT_MAPPING.getValueReadIndex())
.arg(COPY_LEFT_MAPPING.getValueWriteIndex())
.arg(vvIn));
++vectorId;
}
cg.getEvalBlock()._return(JExpr.lit(true));
// generate copyRight()
///////////////////////
cg.setMappingSet(COPY_RIGHT_MAPPING);
int rightVectorBase = vectorId;
for (VectorWrapper<?> vw : right) {
JVar vvIn = cg.declareVectorValueSetupAndMember("incomingRight",
new TypedFieldId(vw.getField().getType(), vectorId - rightVectorBase));
JVar vvOut = cg.declareVectorValueSetupAndMember("outgoing",
new TypedFieldId(vw.getField().getType(),vectorId));
// todo: check result of copyFromSafe and grow allocation
cg.getEvalBlock().add(vvOut.invoke("copyFromSafe")
.arg(COPY_RIGHT_MAPPING.getValueReadIndex())
.arg(COPY_RIGHT_MAPPING.getValueWriteIndex())
.arg(vvIn));
++vectorId;
}