use of org.apache.drill.common.expression.ErrorCollectorImpl in project drill by axbaretto.
the class ChainedHashTable method createAndSetupHashTable.
public HashTable createAndSetupHashTable(TypedFieldId[] outKeyFieldIds, int numPartitions) throws ClassTransformationException, IOException, SchemaChangeException {
CodeGenerator<HashTable> top = CodeGenerator.get(HashTable.TEMPLATE_DEFINITION, context.getOptions());
top.plainJavaCapable(true);
// Uncomment out this line to debug the generated code.
// This code is called from generated code, so to step into this code,
// persist the code generated in HashAggBatch also.
// top.saveCodeForDebugging(true);
// use a subclass
top.preferPlainJava(true);
ClassGenerator<HashTable> cg = top.getRoot();
ClassGenerator<HashTable> cgInner = cg.getInnerGenerator("BatchHolder");
LogicalExpression[] keyExprsBuild = new LogicalExpression[htConfig.getKeyExprsBuild().size()];
LogicalExpression[] keyExprsProbe = null;
boolean isProbe = (htConfig.getKeyExprsProbe() != null);
if (isProbe) {
keyExprsProbe = new LogicalExpression[htConfig.getKeyExprsProbe().size()];
}
ErrorCollector collector = new ErrorCollectorImpl();
// original ht container from which others may be cloned
VectorContainer htContainerOrig = new VectorContainer();
TypedFieldId[] htKeyFieldIds = new TypedFieldId[htConfig.getKeyExprsBuild().size()];
int i = 0;
for (NamedExpression ne : htConfig.getKeyExprsBuild()) {
final LogicalExpression expr = ExpressionTreeMaterializer.materialize(ne.getExpr(), incomingBuild, collector, context.getFunctionRegistry());
if (collector.hasErrors()) {
throw new SchemaChangeException("Failure while materializing expression. " + collector.toErrorString());
}
if (expr == null) {
continue;
}
keyExprsBuild[i] = expr;
i++;
}
if (isProbe) {
i = 0;
for (NamedExpression ne : htConfig.getKeyExprsProbe()) {
final LogicalExpression expr = ExpressionTreeMaterializer.materialize(ne.getExpr(), incomingProbe, collector, context.getFunctionRegistry());
if (collector.hasErrors()) {
throw new SchemaChangeException("Failure while materializing expression. " + collector.toErrorString());
}
if (expr == null) {
continue;
}
keyExprsProbe[i] = expr;
i++;
}
JoinUtils.addLeastRestrictiveCasts(keyExprsProbe, incomingProbe, keyExprsBuild, incomingBuild, context);
}
i = 0;
/*
* Once the implicit casts have been added, create the value vectors for the corresponding
* type and add it to the hash table's container.
* Note: Adding implicit casts may have a minor impact on the memory foot print. For example
* if we have a join condition with bigint on the probe side and int on the build side then
* after this change we will be allocating a bigint vector in the hashtable instead of an int
* vector.
*/
for (NamedExpression ne : htConfig.getKeyExprsBuild()) {
LogicalExpression expr = keyExprsBuild[i];
final MaterializedField outputField = MaterializedField.create(ne.getRef().getLastSegment().getNameSegment().getPath(), expr.getMajorType());
@SuppressWarnings("resource") ValueVector vv = TypeHelper.getNewVector(outputField, allocator);
htKeyFieldIds[i] = htContainerOrig.add(vv);
i++;
}
// generate code for isKeyMatch(), setValue(), getHash() and outputRecordKeys()
setupIsKeyMatchInternal(cgInner, KeyMatchIncomingBuildMapping, KeyMatchHtableMapping, keyExprsBuild, htConfig.getComparators(), htKeyFieldIds);
setupIsKeyMatchInternal(cgInner, KeyMatchIncomingProbeMapping, KeyMatchHtableProbeMapping, keyExprsProbe, htConfig.getComparators(), htKeyFieldIds);
setupSetValue(cgInner, keyExprsBuild, htKeyFieldIds);
if (outgoing != null) {
if (outKeyFieldIds.length > htConfig.getKeyExprsBuild().size()) {
throw new IllegalArgumentException("Mismatched number of output key fields.");
}
}
setupOutputRecordKeys(cgInner, htKeyFieldIds, outKeyFieldIds);
setupGetHash(cg, /* use top level code generator for getHash */
GetHashIncomingBuildMapping, incomingBuild, keyExprsBuild, false);
setupGetHash(cg, /* use top level code generator for getHash */
GetHashIncomingProbeMapping, incomingProbe, keyExprsProbe, true);
HashTable ht = context.getImplementationClass(top);
ht.setup(htConfig, allocator, incomingBuild, incomingProbe, outgoing, htContainerOrig);
return ht;
}
use of org.apache.drill.common.expression.ErrorCollectorImpl in project drill by axbaretto.
the class FilterRecordBatch method generateSV4Filterer.
protected Filterer generateSV4Filterer() throws SchemaChangeException {
final ErrorCollector collector = new ErrorCollectorImpl();
final List<TransferPair> transfers = Lists.newArrayList();
final ClassGenerator<Filterer> cg = CodeGenerator.getRoot(Filterer.TEMPLATE_DEFINITION4, context.getOptions());
final LogicalExpression expr = ExpressionTreeMaterializer.materialize(popConfig.getExpr(), incoming, collector, context.getFunctionRegistry());
if (collector.hasErrors()) {
throw new SchemaChangeException(String.format("Failure while trying to materialize incoming schema. Errors:\n %s.", collector.toErrorString()));
}
cg.addExpr(new ReturnValueExpression(expr), ClassGenerator.BlkCreateMode.FALSE);
for (final VectorWrapper<?> vw : incoming) {
for (final ValueVector vv : vw.getValueVectors()) {
final TransferPair pair = vv.getTransferPair(oContext.getAllocator());
container.add(pair.getTo());
transfers.add(pair);
}
}
// allocate outgoing sv4
container.buildSchema(SelectionVectorMode.FOUR_BYTE);
try {
final TransferPair[] tx = transfers.toArray(new TransferPair[transfers.size()]);
final Filterer filter = context.getImplementationClass(cg);
filter.setup(context, incoming, this, tx);
return filter;
} catch (ClassTransformationException | IOException e) {
throw new SchemaChangeException("Failure while attempting to load generated class", e);
}
}
use of org.apache.drill.common.expression.ErrorCollectorImpl 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;
}
use of org.apache.drill.common.expression.ErrorCollectorImpl in project drill by axbaretto.
the class NestedLoopJoinBatch method setupWorker.
/**
* Method generates the runtime code needed for NLJ. Other than the setup method to set the input and output value
* vector references we implement three more methods
* 1. doEval() -> Evaluates if record from left side matches record from the right side
* 2. emitLeft() -> Project record from the left side
* 3. emitRight() -> Project record from the right side (which is a hyper container)
* @return the runtime generated class that implements the NestedLoopJoin interface
*/
private NestedLoopJoin setupWorker() throws IOException, ClassTransformationException, SchemaChangeException {
final CodeGenerator<NestedLoopJoin> nLJCodeGenerator = CodeGenerator.get(NestedLoopJoin.TEMPLATE_DEFINITION, context.getOptions());
nLJCodeGenerator.plainJavaCapable(true);
// Uncomment out this line to debug the generated code.
// nLJCodeGenerator.saveCodeForDebugging(true);
final ClassGenerator<NestedLoopJoin> nLJClassGenerator = nLJCodeGenerator.getRoot();
// generate doEval
final ErrorCollector collector = new ErrorCollectorImpl();
/*
Logical expression may contain fields from left and right batches. During code generation (materialization)
we need to indicate from which input field should be taken.
Non-equality joins can belong to one of below categories. For example:
1. Join on non-equality join predicates:
select * from t1 inner join t2 on (t1.c1 between t2.c1 AND t2.c2) AND (...)
2. Join with an OR predicate:
select * from t1 inner join t2 on on t1.c1 = t2.c1 OR t1.c2 = t2.c2
*/
Map<VectorAccessible, BatchReference> batches = ImmutableMap.<VectorAccessible, BatchReference>builder().put(left, new BatchReference("leftBatch", "leftIndex")).put(rightContainer, new BatchReference("rightContainer", "rightBatchIndex", "rightRecordIndexWithinBatch")).build();
LogicalExpression materialize = ExpressionTreeMaterializer.materialize(popConfig.getCondition(), batches, collector, context.getFunctionRegistry(), false, false);
if (collector.hasErrors()) {
throw new SchemaChangeException(String.format("Failure while trying to materialize join condition. Errors:\n %s.", collector.toErrorString()));
}
nLJClassGenerator.addExpr(new ReturnValueExpression(materialize), ClassGenerator.BlkCreateMode.FALSE);
// generate emitLeft
nLJClassGenerator.setMappingSet(emitLeftMapping);
JExpression outIndex = JExpr.direct("outIndex");
JExpression leftIndex = JExpr.direct("leftIndex");
int fieldId = 0;
int outputFieldId = 0;
if (leftSchema != null) {
// Set the input and output value vector references corresponding to the left batch
for (MaterializedField field : leftSchema) {
final TypeProtos.MajorType fieldType = field.getType();
// Add the vector to the output container
container.addOrGet(field);
JVar inVV = nLJClassGenerator.declareVectorValueSetupAndMember("leftBatch", new TypedFieldId(fieldType, false, fieldId));
JVar outVV = nLJClassGenerator.declareVectorValueSetupAndMember("outgoing", new TypedFieldId(fieldType, false, outputFieldId));
nLJClassGenerator.getEvalBlock().add(outVV.invoke("copyFromSafe").arg(leftIndex).arg(outIndex).arg(inVV));
nLJClassGenerator.rotateBlock();
fieldId++;
outputFieldId++;
}
}
// generate emitRight
fieldId = 0;
nLJClassGenerator.setMappingSet(emitRightMapping);
JExpression batchIndex = JExpr.direct("batchIndex");
JExpression recordIndexWithinBatch = JExpr.direct("recordIndexWithinBatch");
if (rightSchema != null) {
// Set the input and output value vector references corresponding to the right batch
for (MaterializedField field : rightSchema) {
final TypeProtos.MajorType inputType = field.getType();
TypeProtos.MajorType outputType;
// if join type is LEFT, make sure right batch output fields data mode is optional
if (popConfig.getJoinType() == JoinRelType.LEFT && inputType.getMode() == TypeProtos.DataMode.REQUIRED) {
outputType = Types.overrideMode(inputType, TypeProtos.DataMode.OPTIONAL);
} else {
outputType = inputType;
}
MaterializedField newField = MaterializedField.create(field.getName(), outputType);
container.addOrGet(newField);
JVar inVV = nLJClassGenerator.declareVectorValueSetupAndMember("rightContainer", new TypedFieldId(inputType, true, fieldId));
JVar outVV = nLJClassGenerator.declareVectorValueSetupAndMember("outgoing", new TypedFieldId(outputType, false, outputFieldId));
nLJClassGenerator.getEvalBlock().add(outVV.invoke("copyFromSafe").arg(recordIndexWithinBatch).arg(outIndex).arg(inVV.component(batchIndex)));
nLJClassGenerator.rotateBlock();
fieldId++;
outputFieldId++;
}
}
return context.getImplementationClass(nLJCodeGenerator);
}
use of org.apache.drill.common.expression.ErrorCollectorImpl in project drill by apache.
the class ExpressionInterpreterTest method evalExprWithInterpreter.
private ValueVector evalExprWithInterpreter(String expression, RecordBatch batch, Drillbit bit) throws Exception {
final LogicalExpression expr = parseExpr(expression);
final ErrorCollector error = new ErrorCollectorImpl();
final LogicalExpression materializedExpr = ExpressionTreeMaterializer.materialize(expr, batch, error, bit.getContext().getFunctionImplementationRegistry());
if (error.getErrorCount() != 0) {
logger.error("Failure while materializing expression [{}]. Errors: {}", expression, error);
assertEquals(0, error.getErrorCount());
}
final MaterializedField outputField = MaterializedField.create("outCol", materializedExpr.getMajorType());
final ValueVector vector = TypeHelper.getNewVector(outputField, bit.getContext().getAllocator());
vector.allocateNewSafe();
InterpreterEvaluator.evaluate(batch, vector, materializedExpr);
return vector;
}
Aggregations