use of com.sun.codemodel.JClass in project groovy-cps by cloudbees.
the class Translator method translate.
/**
* Transforms a single class.
*/
public void translate(String fqcn, String outfqcn, String sourceJarName) throws JClassAlreadyExistsException {
final JDefinedClass $output = codeModel._class(outfqcn);
$output.annotate(Generated.class).param("value", Translator.class.getName()).param("date", new Date().toString()).param("comments", "based on " + sourceJarName);
$output.annotate(SuppressWarnings.class).param("value", "rawtypes");
$output.constructor(JMod.PRIVATE);
CompilationUnitTree dgmCut = getDefaultGroovyMethodCompilationUnitTree(parsed, fqcn);
overloadsResolved.clear();
ClassSymbol dgm = (ClassSymbol) elements.getTypeElement(fqcn);
dgm.accept(new ElementScanner7<Void, Void>() {
@Override
public Void visitExecutable(ExecutableElement e, Void __) {
if (translatable.contains(fqcn + "." + e)) {
overloadsResolved.put(mangledName(e), e);
}
// TODO else if it is public and has a Closure argument, translate to a form that just throws UnsupportedOperationException when called in CPS mode
return null;
}
}, null);
// TODO verify that we actually found everything listed in translatables
overloadsResolved.forEach((overloadResolved, e) -> {
try {
translateMethod(dgmCut, e, $output, fqcn, overloadResolved);
} catch (Exception x) {
throw new RuntimeException("Unable to transform " + fqcn + "." + e, x);
}
});
/*
private static MethodLocation loc(String methodName) {
return new MethodLocation(CpsDefaultGroovyMethods.class,methodName);
}
*/
JClass $MethodLocation = codeModel.ref("com.cloudbees.groovy.cps.MethodLocation");
$output.method(JMod.PRIVATE | JMod.STATIC, $MethodLocation, "loc").tap(m -> {
JVar $methodName = m.param(String.class, "methodName");
m.body()._return(JExpr._new($MethodLocation).arg($output.dotclass()).arg($methodName));
});
}
use of com.sun.codemodel.JClass in project groovy-cps by cloudbees.
the class Translator method translateMethod.
/**
* @param e
* Method in {@code fqcn} to translate.
*/
private void translateMethod(final CompilationUnitTree cut, ExecutableElement e, JDefinedClass $output, String fqcn, String overloadResolved) {
String methodName = n(e);
boolean isPublic = e.getModifiers().contains(Modifier.PUBLIC);
JMethod delegating = $output.method(isPublic ? JMod.PUBLIC | JMod.STATIC : JMod.STATIC, (JType) null, methodName);
JMethod m = $output.method(JMod.PRIVATE | JMod.STATIC, (JType) null, overloadResolved);
Map<String, JTypeVar> typeVars = new HashMap<>();
e.getTypeParameters().forEach(p -> {
String name = n(p);
JTypeVar typeVar = delegating.generify(name);
JTypeVar typeVar2 = m.generify(name);
p.getBounds().forEach(b -> {
JClass binding = (JClass) t(b, typeVars);
typeVar.bound(binding);
typeVar2.bound(binding);
});
typeVars.put(name, typeVar);
});
JType type = t(e.getReturnType(), typeVars);
delegating.type(type);
m.type(type);
List<JVar> delegatingParams = new ArrayList<>();
List<JVar> params = new ArrayList<>();
e.getParameters().forEach(p -> {
JType paramType = t(p.asType(), typeVars);
delegatingParams.add(e.isVarArgs() && p == e.getParameters().get(e.getParameters().size() - 1) ? delegating.varParam(paramType.elementType(), n(p)) : delegating.param(paramType, n(p)));
params.add(m.param(paramType, n(p)));
});
e.getThrownTypes().forEach(ex -> {
delegating._throws((JClass) t(ex));
m._throws((JClass) t(ex));
});
boolean returnsVoid = e.getReturnType().getKind() == TypeKind.VOID;
if (isPublic) {
// preamble
/*
If the call to this method happen outside CPS code, execute normally via DefaultGroovyMethods
*/
delegating.body()._if(JOp.cand(JOp.not($Caller.staticInvoke("isAsynchronous").tap(inv -> {
inv.arg(delegatingParams.get(0));
inv.arg(methodName);
for (int i = 1; i < delegatingParams.size(); i++) inv.arg(delegatingParams.get(i));
})), JOp.not($Caller.staticInvoke("isAsynchronous").arg($output.dotclass()).arg(methodName).args(params))))._then().tap(blk -> {
JClass $WhateverGroovyMethods = codeModel.ref(fqcn);
JInvocation forward = $WhateverGroovyMethods.staticInvoke(methodName).args(delegatingParams);
if (returnsVoid) {
blk.add(forward);
blk._return();
} else {
blk._return(forward);
}
});
}
JInvocation delegateCall = $output.staticInvoke(overloadResolved);
if (returnsVoid) {
delegating.body().add(delegateCall);
} else {
delegating.body()._return(delegateCall);
}
delegatingParams.forEach(p -> delegateCall.arg(p));
JVar $b = m.body().decl($Builder, "b", JExpr._new($Builder).arg(JExpr.invoke("loc").arg(methodName)));
JInvocation f = JExpr._new($CpsFunction);
// parameter names
f.arg(codeModel.ref(Arrays.class).staticInvoke("asList").tap(inv -> {
e.getParameters().forEach(p -> inv.arg(n(p)));
}));
// translate the method body into an expression that invokes Builder
f.arg(trees.getTree(e).getBody().accept(new SimpleTreeVisitor<JExpression, Void>() {
private JExpression visit(Tree t) {
if (t == null)
return JExpr._null();
return visit(t, null);
}
/**
* Maps a symbol to its source location.
*/
private JExpression loc(Tree t) {
long pos = trees.getSourcePositions().getStartPosition(cut, t);
return JExpr.lit((int) cut.getLineMap().getLineNumber(pos));
}
@Override
public JExpression visitWhileLoop(WhileLoopTree wt, Void __) {
return $b.invoke("while_").arg(// TODO: label
JExpr._null()).arg(visit(wt.getCondition())).arg(visit(wt.getStatement()));
}
@Override
public JExpression visitMethodInvocation(MethodInvocationTree mt, Void __) {
ExpressionTree ms = mt.getMethodSelect();
JInvocation inv;
if (ms instanceof MemberSelectTree) {
MemberSelectTree mst = (MemberSelectTree) ms;
inv = $b.invoke("functionCall").arg(loc(mt)).arg(visit(mst.getExpression())).arg(n(mst.getIdentifier()));
} else if (ms instanceof JCIdent) {
// invocation without object selection, like foo(bar,zot)
JCIdent it = (JCIdent) ms;
if (!it.sym.owner.toString().equals(fqcn)) {
// static import
inv = $b.invoke("functionCall").arg(loc(mt)).arg($b.invoke("constant").arg(t(it.sym.owner.type).dotclass())).arg(n(it));
} else {
// invocation on this class
String overloadResolved = mangledName((Symbol.MethodSymbol) it.sym);
Optional<? extends Element> callSite = elements.getTypeElement(fqcn).getEnclosedElements().stream().filter(e -> e.getKind() == ElementKind.METHOD && mangledName((ExecutableElement) e).equals(overloadResolved)).findAny();
if (callSite.isPresent()) {
ExecutableElement e = (ExecutableElement) callSite.get();
if (e.getModifiers().contains(Modifier.PUBLIC) && !e.isVarArgs() && !e.getParameters().stream().anyMatch(p -> types.isAssignable(p.asType(), closureType))) {
// Delegate to the standard version.
inv = $b.invoke("staticCall").arg(loc(mt)).arg(t(it.sym.owner.type).dotclass()).arg(n(e));
} else if (overloadsResolved.containsKey(overloadResolved)) {
// Private, so delegate to our mangled version.
inv = $b.invoke("staticCall").arg(loc(mt)).arg($output.dotclass()).arg(overloadResolved);
} else {
throw new IllegalStateException("Not yet translating a " + e.getModifiers() + " method; translatable.txt might need to include: " + fqcn + "." + e);
}
} else {
throw new IllegalStateException("Could not find self-call site " + overloadResolved + " for " + mt);
}
}
} else {
// TODO: figure out what can come here
throw new UnsupportedOperationException(ms.toString());
}
mt.getArguments().forEach(a -> inv.arg(visit(a)));
return inv;
}
@Override
public JExpression visitVariable(VariableTree vt, Void __) {
return $b.invoke("declareVariable").arg(loc(vt)).arg(erasure(vt).dotclass()).arg(n(vt)).arg(visit(vt.getInitializer()));
}
@Override
public JExpression visitIdentifier(IdentifierTree it, Void __) {
JCIdent idt = (JCIdent) it;
return idt.sym.accept(new DefaultSymbolVisitor<JExpression, Void>() {
@Override
public JExpression visitClassSymbol(ClassSymbol cs, Void __) {
return $b.invoke("constant").arg(t(cs.asType()).dotclass());
}
@Override
public JExpression visitVarSymbol(VarSymbol s, Void __) {
return $b.invoke("localVariable").arg(n(s.name));
}
@Override
public JExpression visitSymbol(Symbol s, Void __) {
throw new UnsupportedOperationException(s.toString());
}
}, __);
}
@Override
public JExpression visitBlock(BlockTree bt, Void __) {
JInvocation inv = $b.invoke("block");
bt.getStatements().forEach(s -> inv.arg(visit(s)));
return inv;
}
@Override
public JExpression visitReturn(ReturnTree rt, Void __) {
return $b.invoke("return_").arg(visit(rt.getExpression()));
}
/**
* When used outside {@link MethodInvocationTree}, this is property access.
*/
@Override
public JExpression visitMemberSelect(MemberSelectTree mt, Void __) {
return $b.invoke("property").arg(loc(mt)).arg(visit(mt.getExpression())).arg(n(mt.getIdentifier()));
}
@Override
public JExpression visitTypeCast(TypeCastTree tt, Void __) {
return $b.invoke("cast").arg(loc(tt)).arg(visit(tt.getExpression())).arg(erasure(tt.getType()).dotclass()).arg(JExpr.lit(false));
}
@Override
public JExpression visitIf(IfTree it, Void __) {
JInvocation inv = $b.invoke("if_").arg(visit(it.getCondition())).arg(visit(it.getThenStatement()));
if (it.getElseStatement() != null)
inv.arg(visit(it.getElseStatement()));
return inv;
}
@Override
public JExpression visitNewClass(NewClassTree nt, Void __) {
// TODO: outer class
if (nt.getEnclosingExpression() != null)
throw new UnsupportedOperationException();
return $b.invoke("new_").tap(inv -> {
inv.arg(loc(nt));
inv.arg(t(((JCTree) nt).type).dotclass());
nt.getArguments().forEach(et -> inv.arg(visit(et)));
});
}
@Override
public JExpression visitExpressionStatement(ExpressionStatementTree et, Void __) {
return visit(et.getExpression());
}
@Override
public JExpression visitLiteral(LiteralTree lt, Void __) {
return $b.invoke("constant").arg(JExpr.literal(lt.getValue()));
}
@Override
public JExpression visitParenthesized(ParenthesizedTree pt, Void __) {
return visit(pt.getExpression());
}
@Override
public JExpression visitBinary(BinaryTree bt, Void __) {
return $b.invoke(opName(bt.getKind())).arg(loc(bt)).arg(visit(bt.getLeftOperand())).arg(visit(bt.getRightOperand()));
}
@Override
public JExpression visitUnary(UnaryTree ut, Void __) {
return $b.invoke(opName(ut.getKind())).arg(loc(ut)).arg(visit(ut.getExpression()));
}
@Override
public JExpression visitCompoundAssignment(CompoundAssignmentTree ct, Void __) {
return $b.invoke(opName(ct.getKind())).arg(loc(ct)).arg(visit(ct.getVariable())).arg(visit(ct.getExpression()));
}
private String opName(Kind kind) {
switch(kind) {
case EQUAL_TO:
return "compareEqual";
case NOT_EQUAL_TO:
return "compareNotEqual";
case LESS_THAN_EQUAL:
return "lessThanEqual";
case LESS_THAN:
return "lessThan";
case GREATER_THAN_EQUAL:
return "greaterThanEqual";
case GREATER_THAN:
return "greaterThan";
case PREFIX_INCREMENT:
return "prefixInc";
case POSTFIX_INCREMENT:
return "postfixInc";
case POSTFIX_DECREMENT:
return "postfixDec";
case LOGICAL_COMPLEMENT:
return "not";
case CONDITIONAL_OR:
return "logicalOr";
case CONDITIONAL_AND:
return "logicalAnd";
case PLUS:
return "plus";
case PLUS_ASSIGNMENT:
return "plusEqual";
case MINUS:
return "minus";
case MINUS_ASSIGNMENT:
return "minusEqual";
}
throw new UnsupportedOperationException(kind.toString());
}
@Override
public JExpression visitAssignment(AssignmentTree at, Void __) {
return $b.invoke("assign").arg(loc(at)).arg(visit(at.getVariable())).arg(visit(at.getExpression()));
}
@Override
public JExpression visitNewArray(NewArrayTree nt, Void __) {
if (nt.getInitializers() != null) {
return $b.invoke("newArrayFromInitializers").tap(inv -> {
nt.getInitializers().forEach(d -> inv.arg(visit(d)));
});
} else {
return $b.invoke("newArray").tap(inv -> {
inv.arg(loc(nt));
inv.arg(t(nt.getType()).dotclass());
nt.getDimensions().forEach(d -> inv.arg(visit(d)));
});
}
}
@Override
public JExpression visitForLoop(ForLoopTree ft, Void __) {
return $b.invoke("forLoop").arg(JExpr._null()).arg($b.invoke("sequence").tap(inv -> ft.getInitializer().forEach(i -> inv.arg(visit(i))))).arg(visit(ft.getCondition())).arg($b.invoke("sequence").tap(inv -> ft.getUpdate().forEach(i -> inv.arg(visit(i))))).arg(visit(ft.getStatement()));
}
@Override
public JExpression visitEnhancedForLoop(EnhancedForLoopTree et, Void __) {
return $b.invoke("forInLoop").arg(loc(et)).arg(JExpr._null()).arg(erasure(et.getVariable()).dotclass()).arg(n(et.getVariable())).arg(visit(et.getExpression())).arg(visit(et.getStatement()));
}
@Override
public JExpression visitArrayAccess(ArrayAccessTree at, Void __) {
return $b.invoke("array").arg(loc(at)).arg(visit(at.getExpression())).arg(visit(at.getIndex()));
}
@Override
public JExpression visitBreak(BreakTree node, Void __) {
if (node.getLabel() != null)
throw new UnsupportedOperationException();
return $b.invoke("break_").arg(JExpr._null());
}
@Override
public JExpression visitContinue(ContinueTree node, Void aVoid) {
if (node.getLabel() != null)
throw new UnsupportedOperationException();
return $b.invoke("continue_").arg(JExpr._null());
}
@Override
public JExpression visitInstanceOf(InstanceOfTree it, Void __) {
return $b.invoke("instanceOf").arg(loc(it)).arg(visit(it.getExpression())).arg($b.invoke("constant").arg(t(it.getType()).dotclass()));
}
@Override
public JExpression visitThrow(ThrowTree tt, Void __) {
return $b.invoke("throw_").arg(loc(tt)).arg(visit(tt.getExpression()));
}
@Override
public JExpression visitDoWhileLoop(DoWhileLoopTree dt, Void __) {
return $b.invoke("doWhile").arg(JExpr._null()).arg(visit(dt.getStatement())).arg(visit(dt.getCondition()));
}
@Override
public JExpression visitConditionalExpression(ConditionalExpressionTree ct, Void __) {
return $b.invoke("ternaryOp").arg(visit(ct.getCondition())).arg(visit(ct.getTrueExpression())).arg(visit(ct.getFalseExpression()));
}
@Override
public JExpression visitTry(TryTree tt, Void __) {
return $b.invoke("tryCatch").arg(visit(tt.getBlock())).arg(visit(tt.getFinallyBlock())).tap(inv -> tt.getCatches().forEach(ct -> JExpr._new($CatchExpression).arg(t(ct.getParameter()).dotclass()).arg(n(ct.getParameter())).arg(visit(ct.getBlock()))));
}
@Override
protected JExpression defaultAction(Tree node, Void aVoid) {
throw new UnsupportedOperationException(node.toString());
}
}, null));
JVar $f = m.body().decl($CpsFunction, "f", f);
m.body()._throw(JExpr._new($CpsCallableInvocation).arg($f).arg(JExpr._null()).args(params));
}
use of com.sun.codemodel.JClass in project drill by apache.
the class DrillAggFuncHolder method addProtectedBlockHA.
/*
* This is customized version of "addProtectedBlock" for hash aggregation. It take one additional parameter "wsIndexVariable".
*/
private void addProtectedBlockHA(ClassGenerator<?> g, JBlock sub, String body, HoldingContainer[] inputVariables, JVar[] workspaceJVars, JExpression wsIndexVariable) {
if (inputVariables != null) {
for (int i = 0; i < inputVariables.length; i++) {
ValueReference parameter = getParameters()[i];
HoldingContainer inputVariable = inputVariables[i];
sub.decl(inputVariable.getHolder().type(), parameter.getName(), inputVariable.getHolder());
}
}
JVar[] internalVars = new JVar[workspaceJVars.length];
for (int i = 0; i < workspaceJVars.length; i++) {
if (getWorkspaceVars()[i].isInject()) {
internalVars[i] = sub.decl(g.getModel()._ref(getWorkspaceVars()[i].getType()), getWorkspaceVars()[i].getName(), workspaceJVars[i]);
continue;
}
//sub.assign(workspaceJVars[i], JExpr._new(g.getHolderType(workspaceVars[i].majorType)));
//Access workspaceVar through workspace vector.
JInvocation getValueAccessor = g.getWorkspaceVectors().get(getWorkspaceVars()[i]).invoke("getAccessor").invoke("get");
if (Types.usesHolderForGet(getWorkspaceVars()[i].getMajorType())) {
sub.add(getValueAccessor.arg(wsIndexVariable).arg(workspaceJVars[i]));
} else {
sub.assign(workspaceJVars[i].ref("value"), getValueAccessor.arg(wsIndexVariable));
}
internalVars[i] = sub.decl(g.getHolderType(getWorkspaceVars()[i].getMajorType()), getWorkspaceVars()[i].getName(), workspaceJVars[i]);
}
Preconditions.checkNotNull(body);
sub.directStatement(body);
// reassign workspace variables back.
for (int i = 0; i < workspaceJVars.length; i++) {
sub.assign(workspaceJVars[i], internalVars[i]);
// Injected buffers are not stored as vectors skip storing them in vectors
if (getWorkspaceVars()[i].isInject()) {
continue;
}
//Change workspaceVar through workspace vector.
JInvocation setMeth;
MajorType type = getWorkspaceVars()[i].getMajorType();
if (Types.usesHolderForGet(type)) {
setMeth = g.getWorkspaceVectors().get(getWorkspaceVars()[i]).invoke("getMutator").invoke("setSafe").arg(wsIndexVariable).arg(workspaceJVars[i]);
} else {
if (!Types.isFixedWidthType(type) || Types.isRepeated(type)) {
setMeth = g.getWorkspaceVectors().get(getWorkspaceVars()[i]).invoke("getMutator").invoke("setSafe").arg(wsIndexVariable).arg(workspaceJVars[i].ref("value"));
} else {
setMeth = g.getWorkspaceVectors().get(getWorkspaceVars()[i]).invoke("getMutator").invoke("set").arg(wsIndexVariable).arg(workspaceJVars[i].ref("value"));
}
}
sub.add(setMeth);
JClass drillRunTimeException = g.getModel().ref(DrillRuntimeException.class);
}
}
use of com.sun.codemodel.JClass in project drill by apache.
the class DrillComplexWriterFuncHolder method generateEvalBody.
@Override
protected HoldingContainer generateEvalBody(ClassGenerator<?> classGenerator, HoldingContainer[] inputVariables, String body, JVar[] workspaceJVars, FieldReference fieldReference) {
classGenerator.getEvalBlock().directStatement(String.format("//---- start of eval portion of %s function. ----//", getRegisteredNames()[0]));
JBlock sub = new JBlock(true, true);
JBlock topSub = sub;
JVar complexWriter = classGenerator.declareClassField("complexWriter", classGenerator.getModel()._ref(ComplexWriter.class));
JInvocation container = classGenerator.getMappingSet().getOutgoing().invoke("getOutgoingContainer");
//Default name is "col", if not passed in a reference name for the output vector.
String refName = fieldReference == null ? "col" : fieldReference.getRootSegment().getPath();
JClass cwClass = classGenerator.getModel().ref(VectorAccessibleComplexWriter.class);
classGenerator.getSetupBlock().assign(complexWriter, cwClass.staticInvoke("getWriter").arg(refName).arg(container));
JClass projBatchClass = classGenerator.getModel().ref(ProjectRecordBatch.class);
JExpression projBatch = JExpr.cast(projBatchClass, classGenerator.getMappingSet().getOutgoing());
classGenerator.getSetupBlock().add(projBatch.invoke("addComplexWriter").arg(complexWriter));
classGenerator.getEvalBlock().add(complexWriter.invoke("setPosition").arg(classGenerator.getMappingSet().getValueWriteIndex()));
sub.decl(classGenerator.getModel()._ref(ComplexWriter.class), getReturnValue().getName(), complexWriter);
// add the subblock after the out declaration.
classGenerator.getEvalBlock().add(topSub);
addProtectedBlock(classGenerator, sub, body, inputVariables, workspaceJVars, false);
// JConditional jc = classGenerator.getEvalBlock()._if(complexWriter.invoke("ok").not());
// jc._then().add(complexWriter.invoke("reset"));
//jc._then().directStatement("System.out.println(\"debug : write ok fail!, inIndex = \" + inIndex);");
// jc._then()._return(JExpr.FALSE);
//jc._else().directStatement("System.out.println(\"debug : write successful, inIndex = \" + inIndex);");
classGenerator.getEvalBlock().directStatement(String.format("//---- end of eval portion of %s function. ----//", getRegisteredNames()[0]));
return null;
}
use of com.sun.codemodel.JClass in project drill by apache.
the class MergeJoinBatch method generateNewWorker.
private JoinWorker generateNewWorker() throws ClassTransformationException, IOException, SchemaChangeException {
final ClassGenerator<JoinWorker> cg = CodeGenerator.getRoot(JoinWorker.TEMPLATE_DEFINITION, context.getFunctionRegistry(), context.getOptions());
cg.getCodeGenerator().plainJavaCapable(true);
// Uncomment out this line to debug the generated code.
// 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;
}
Aggregations