use of org.apache.drill.exec.vector.complex.writer.BaseWriter.ComplexWriter 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 org.apache.drill.exec.vector.complex.writer.BaseWriter.ComplexWriter in project drill by apache.
the class ProjectRecordBatch method setValueCount.
private void setValueCount(final int count) {
for (final ValueVector v : allocationVectors) {
final ValueVector.Mutator m = v.getMutator();
m.setValueCount(count);
}
if (complexWriters == null) {
return;
}
for (final ComplexWriter writer : complexWriters) {
writer.setValueCount(count);
}
}
use of org.apache.drill.exec.vector.complex.writer.BaseWriter.ComplexWriter in project drill by apache.
the class FlattenRecordBatch method setValueCount.
private void setValueCount(int count) {
for (ValueVector v : allocationVectors) {
ValueVector.Mutator m = v.getMutator();
m.setValueCount(count);
}
if (complexWriters == null) {
return;
}
for (ComplexWriter writer : complexWriters) {
writer.setValueCount(count);
}
}
use of org.apache.drill.exec.vector.complex.writer.BaseWriter.ComplexWriter in project drill by apache.
the class FunctionConverter method getHolder.
public <T extends DrillFunc> DrillFuncHolder getHolder(AnnotatedClassDescriptor func, ClassLoader classLoader) {
FunctionTemplate template = func.getAnnotationProxy(FunctionTemplate.class);
if (template == null) {
return failure("Class does not declare FunctionTemplate annotation.", func);
}
String name = template.name();
List<String> names = Arrays.asList(template.names());
if (name.isEmpty() && names.isEmpty()) {
// none set
return failure("Must define 'name' or 'names'", func);
}
if (!name.isEmpty() && !names.isEmpty()) {
// both are set
return failure("Must use only one annotations 'name' or 'names', not both", func);
}
// start by getting field information.
List<ValueReference> params = Lists.newArrayList();
List<WorkspaceReference> workspaceFields = Lists.newArrayList();
ValueReference outputField = null;
for (FieldDescriptor field : func.getFields()) {
Param param = field.getAnnotationProxy(Param.class);
Output output = field.getAnnotationProxy(Output.class);
Workspace workspace = field.getAnnotationProxy(Workspace.class);
Inject inject = field.getAnnotationProxy(Inject.class);
Annotation[] annotations = { param, output, workspace, inject };
int annotationCount = 0;
for (Annotation annotationDescriptor : annotations) {
if (annotationDescriptor != null) {
annotationCount += 1;
}
}
if (annotationCount == 0) {
return failure("The field must be either a @Param, @Output, @Inject or @Workspace field.", func, field);
} else if (annotationCount > 1) {
return failure("The field must be only one of @Param, @Output, @Inject or @Workspace. It currently has more than one of these annotations.", func, field);
}
// TODO(Julien): verify there are a few of those and we can load them
Class<?> fieldClass = field.getFieldClass();
if (param != null || output != null) {
// Special processing for @Param FieldReader
if (param != null && FieldReader.class.isAssignableFrom(fieldClass)) {
params.add(ValueReference.createFieldReaderRef(field.getName()));
continue;
}
// Special processing for @Output ComplexWriter
if (output != null && ComplexWriter.class.isAssignableFrom(fieldClass)) {
if (outputField != null) {
return failure("You've declared more than one @Output field. You must declare one and only @Output field per Function class.", func, field);
} else {
outputField = ValueReference.createComplexWriterRef(field.getName());
}
continue;
}
// check that param and output are value holders.
if (!ValueHolder.class.isAssignableFrom(fieldClass)) {
return failure(String.format("The field doesn't holds value of type %s which does not implement the ValueHolder interface. All fields of type @Param or @Output must extend this interface..", fieldClass), func, field);
}
// get the type field from the value holder.
MajorType type = null;
try {
type = getStaticFieldValue("TYPE", fieldClass, MajorType.class);
} catch (Exception e) {
return failure("Failure while trying to access the ValueHolder's TYPE static variable. All ValueHolders must contain a static TYPE variable that defines their MajorType.", e, func, field);
}
ValueReference p = new ValueReference(type, field.getName());
if (param != null) {
p.setConstant(param.constant());
params.add(p);
} else {
if (outputField != null) {
return failure("You've declared more than one @Output field. You must declare one and only @Output field per Function class.", func, field);
} else {
outputField = p;
}
}
} else {
// workspace work.
boolean isInject = inject != null;
if (isInject && UdfUtilities.INJECTABLE_GETTER_METHODS.get(fieldClass) == null) {
return failure(String.format("A %s cannot be injected into a %s," + " available injectable classes are: %s.", fieldClass, DrillFunc.class.getSimpleName(), Joiner.on(",").join(UdfUtilities.INJECTABLE_GETTER_METHODS.keySet())), func, field);
}
WorkspaceReference wsReference = new WorkspaceReference(fieldClass, field.getName(), isInject);
if (!isInject && template.scope() == FunctionScope.POINT_AGGREGATE && !ValueHolder.class.isAssignableFrom(fieldClass)) {
return failure(String.format("Aggregate function '%s' workspace variable '%s' is of type '%s'. Please change it to Holder type.", func.getClassName(), field.getName(), fieldClass), func, field);
}
//If the workspace var is of Holder type, get its MajorType and assign to WorkspaceReference.
if (ValueHolder.class.isAssignableFrom(fieldClass)) {
MajorType majorType = null;
try {
majorType = getStaticFieldValue("TYPE", fieldClass, MajorType.class);
} catch (Exception e) {
return failure("Failure while trying to access the ValueHolder's TYPE static variable. All ValueHolders must contain a static TYPE variable that defines their MajorType.", e, func, field);
}
wsReference.setMajorType(majorType);
}
workspaceFields.add(wsReference);
}
}
if (outputField == null) {
return failure("This function declares zero output fields. A function must declare one output field.", func);
}
FunctionInitializer initializer = new FunctionInitializer(func.getClassName(), classLoader);
try {
// return holder
ValueReference[] ps = params.toArray(new ValueReference[params.size()]);
WorkspaceReference[] works = workspaceFields.toArray(new WorkspaceReference[workspaceFields.size()]);
FunctionAttributes functionAttributes = new FunctionAttributes(template, ps, outputField, works);
switch(template.scope()) {
case POINT_AGGREGATE:
return new DrillAggFuncHolder(functionAttributes, initializer);
case SIMPLE:
return outputField.isComplexWriter() ? new DrillComplexWriterFuncHolder(functionAttributes, initializer) : new DrillSimpleFuncHolder(functionAttributes, initializer);
case HOLISTIC_AGGREGATE:
case RANGE_AGGREGATE:
default:
return failure("Unsupported Function Type.", func);
}
} catch (Exception | NoSuchFieldError | AbstractMethodError ex) {
return failure("Failure while creating function holder.", ex, func);
}
}
use of org.apache.drill.exec.vector.complex.writer.BaseWriter.ComplexWriter in project drill by apache.
the class TestPromotableWriter method list.
@Test
public void list() throws Exception {
BufferAllocator allocator = RootAllocatorFactory.newRoot(DrillConfig.create());
TestOutputMutator output = new TestOutputMutator(allocator);
ComplexWriter rootWriter = new VectorContainerWriter(output, true);
MapWriter writer = rootWriter.rootAsMap();
rootWriter.setPosition(0);
{
writer.map("map").bigInt("a").writeBigInt(1);
}
rootWriter.setPosition(1);
{
writer.map("map").float4("a").writeFloat4(2.0f);
}
rootWriter.setPosition(2);
{
writer.map("map").list("a").startList();
writer.map("map").list("a").endList();
}
rootWriter.setPosition(3);
{
writer.map("map").list("a").startList();
writer.map("map").list("a").bigInt().writeBigInt(3);
writer.map("map").list("a").float4().writeFloat4(4);
writer.map("map").list("a").endList();
}
rootWriter.setValueCount(4);
BatchPrinter.printBatch(output.getContainer());
}
Aggregations