private HoldingContainer visitValueVectorReadExpression(ValueVectorReadExpression e, ClassGenerator<?> generator)
throws RuntimeException {
// declare value vector
JExpression vv1 = generator.declareVectorValueSetupAndMember(generator.getMappingSet().getIncoming(),
e.getFieldId());
JExpression indexVariable = generator.getMappingSet().getValueReadIndex();
JExpression componentVariable = indexVariable.shrz(JExpr.lit(16));
if (e.isSuperReader()) {
vv1 = (vv1.component(componentVariable));
indexVariable = indexVariable.band(JExpr.lit((int) Character.MAX_VALUE));
}
// evaluation work.
HoldingContainer out = generator.declare(e.getMajorType());
final boolean primitive = !Types.usesHolderForGet(e.getMajorType());
final boolean hasReadPath = e.hasReadPath();
final boolean complex = Types.isComplex(e.getMajorType());
final boolean repeated = Types.isRepeated(e.getMajorType());
int[] fieldIds = e.getFieldId().getFieldIds();
for (int i = 1; i < fieldIds.length; i++) {
}
if (!hasReadPath && !complex) {
JInvocation getValueAccessor = vv1.invoke("getAccessor").invoke("get");
JInvocation getValueAccessor2 = vv1.invoke("getAccessor");
JBlock eval = new JBlock();
if (primitive) {
eval.assign(out.getValue(), getValueAccessor.arg(indexVariable));
} else {
eval.add(getValueAccessor.arg(indexVariable).arg(out.getHolder()));
}
if (out.isOptional()) {
JBlock blk = generator.getEvalBlock();
blk.assign(out.getIsSet(), getValueAccessor2.invoke("isSet").arg(indexVariable));
JConditional jc = blk._if(out.getIsSet().eq(JExpr.lit(1)));
jc._then().add(eval);
} else {
generator.getEvalBlock().add(eval);
}
} else {
JExpression vector = e.isSuperReader() ? vv1.component(componentVariable) : vv1;
JExpression expr = vector.invoke("getAccessor").invoke("getReader");
PathSegment seg = e.getReadPath();
JVar isNull = null;
boolean isNullReaderLikely = isNullReaderLikely(seg, complex || repeated);
if (isNullReaderLikely) {
isNull = generator.getEvalBlock().decl(generator.getModel().INT, generator.getNextVar("isNull"), JExpr.lit(0));
}
JLabel label = generator.getEvalBlock().label("complex");
JBlock eval = generator.getEvalBlock().block();
// position to the correct value.
eval.add(expr.invoke("setPosition").arg(indexVariable));
int listNum = 0;
while (seg != null) {
if (seg.isArray()) {
// stop once we get to the last segment and the final type is neither complex nor repeated (map, list, repeated list).
// In case of non-complex and non-repeated type, we return Holder, in stead of FieldReader.
if (seg.isLastPath() && !complex && !repeated)
break;
JVar list = generator.declareClassField("list", generator.getModel()._ref(FieldReader.class));
eval.assign(list, expr);
// if this is an array, set a single position for the expression to
// allow us to read the right data lower down.
JVar desiredIndex = eval.decl(generator.getModel().INT, "desiredIndex" + listNum,
JExpr.lit(seg.getArraySegment().getIndex()));
// start with negative one so that we are at zero after first call
// to next.
JVar currentIndex = eval.decl(generator.getModel().INT, "currentIndex" + listNum, JExpr.lit(-1));
eval._while( //
currentIndex.lt(desiredIndex) //
.cand(list.invoke("next"))).body().assign(currentIndex, currentIndex.plus(JExpr.lit(1)));
JBlock ifNoVal = eval._if(desiredIndex.ne(currentIndex))._then().block();
if (out.isOptional()) {
ifNoVal.assign(out.getIsSet(), JExpr.lit(0));
}
ifNoVal.assign(isNull, JExpr.lit(1));
ifNoVal._break(label);
expr = list.invoke("reader");
listNum++;
} else {
JExpression fieldName = JExpr.lit(seg.getNameSegment().getPath());
expr = expr.invoke("reader").arg(fieldName);
}
seg = seg.getChild();
}
if (complex || repeated) {
MajorType finalType = e.getFieldId().getFinalType();
// //
JVar complexReader = generator.declareClassField("reader", generator.getModel()._ref(FieldReader.class));
if (isNullReaderLikely) {
JConditional jc = generator.getEvalBlock()._if(isNull.eq(JExpr.lit(0)));
JClass nrClass = generator.getModel().ref(org.apache.drill.exec.vector.complex.impl.NullReader.class);
JExpression nullReader = nrClass.staticRef("INSTANCE");
jc._then().assign(complexReader, expr);
jc._else().assign(complexReader, nullReader);
} else {
eval.assign(complexReader, expr);