blob: 4cf02be51ec112c5b7d5a77cd15f2b26039fe9ca [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.drill.exec.expr;
import io.netty.buffer.DrillBuf;
import org.apache.drill.common.types.TypeProtos.MajorType;
import org.apache.drill.common.types.TypeProtos.MinorType;
import org.apache.drill.exec.expr.ClassGenerator.HoldingContainer;
import com.sun.codemodel.JBlock;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JExpression;
import com.sun.codemodel.JInvocation;
import com.sun.codemodel.JVar;
public class GetSetVectorHelper {
/**
* Generates the code to read a vector into a holder. Example: <pre><code>
* NullableBigIntHolder out3 = new NullableBigIntHolder();
* {
* out3 .isSet = vv0 [((leftIndex)>>> 16)].getAccessor().isSet(((leftIndex)& 65535));
* if (out3 .isSet == 1) {
* out3 .value = vv0 [((leftIndex)>>> 16)].getAccessor().get(((leftIndex)& 65535));
* }
* }</code></pre>
*/
public static void read(MajorType type, JExpression vector, JBlock eval, HoldingContainer out, JCodeModel model,
JExpression indexVariable) {
JInvocation getValueAccessor = vector.invoke("getAccessor");
switch(type.getMode()){
case OPTIONAL:
eval.assign(out.getIsSet(), getValueAccessor.invoke("isSet").arg(indexVariable));
eval = eval._if(out.getIsSet().eq(JExpr.lit(1)))._then();
// fall through
case REQUIRED:
switch (type.getMinorType()) {
case BIGINT:
case FLOAT4:
case FLOAT8:
case INT:
case MONEY:
case SMALLINT:
case TINYINT:
case UINT1:
case UINT2:
case UINT4:
case UINT8:
case INTERVALYEAR:
case DATE:
case TIME:
case TIMESTAMP:
case BIT:
eval.assign(out.getValue(), getValueAccessor.invoke("get").arg(indexVariable));
return;
case DECIMAL9:
case DECIMAL18:
eval.assign(out.getHolder().ref("scale"), vector.invoke("getField").invoke("getScale"));
eval.assign(out.getHolder().ref("precision"), vector.invoke("getField").invoke("getPrecision"));
eval.assign(out.getValue(), getValueAccessor.invoke("get").arg(indexVariable));
return;
case DECIMAL28DENSE:
case DECIMAL28SPARSE:
case DECIMAL38DENSE:
case DECIMAL38SPARSE:
eval.assign(out.getHolder().ref("scale"), vector.invoke("getField").invoke("getScale"));
eval.assign(out.getHolder().ref("precision"), vector.invoke("getField").invoke("getPrecision"));
eval.assign(out.getHolder().ref("start"), JExpr.lit(TypeHelper.getSize(type)).mul(indexVariable));
eval.assign(out.getHolder().ref("buffer"), vector.invoke("getBuffer"));
return;
case VARDECIMAL: {
eval.assign(out.getHolder().ref("buffer"), vector.invoke("getBuffer"));
JVar se = eval.decl(model.LONG, "startEnd", getValueAccessor.invoke("getStartEnd").arg(indexVariable));
eval.assign(out.getHolder().ref("start"), JExpr.cast(model._ref(int.class), se));
eval.assign(out.getHolder().ref("end"), JExpr.cast(model._ref(int.class), se.shr(JExpr.lit(32))));
eval.assign(out.getHolder().ref("scale"), vector.invoke("getField").invoke("getScale"));
eval.assign(out.getHolder().ref("precision"), vector.invoke("getField").invoke("getPrecision"));
return;
}
case INTERVAL: {
JVar start = eval.decl(model.INT, "start", JExpr.lit(TypeHelper.getSize(type)).mul(indexVariable));
JVar data = eval.decl(model.ref(DrillBuf.class), "data", vector.invoke("getBuffer"));
eval.assign(out.getHolder().ref("months"), data.invoke("getInt").arg(start));
eval.assign(out.getHolder().ref("days"), data.invoke("getInt").arg(start.plus(JExpr.lit(4))));
eval.assign(out.getHolder().ref("milliseconds"), data.invoke("getInt").arg(start.plus(JExpr.lit(8))));
return;
}
case INTERVALDAY: {
JVar start = eval.decl(model.INT, "start", JExpr.lit(TypeHelper.getSize(type)).mul(indexVariable));
eval.assign(out.getHolder().ref("days"), vector.invoke("getBuffer").invoke("getInt").arg(start));
eval.assign(out.getHolder().ref("milliseconds"), vector.invoke("getBuffer").invoke("getInt").arg(start.plus(JExpr.lit(4))));
return;
}
case VAR16CHAR:
case VARBINARY:
case VARCHAR: {
eval.assign(out.getHolder().ref("buffer"), vector.invoke("getBuffer"));
JVar se = eval.decl(model.LONG, "startEnd", getValueAccessor.invoke("getStartEnd").arg(indexVariable));
eval.assign(out.getHolder().ref("start"), JExpr.cast(model._ref(int.class), se));
eval.assign(out.getHolder().ref("end"), JExpr.cast(model._ref(int.class), se.shr(JExpr.lit(32))));
return;
}
default:
}
default:
}
// fallback.
eval.add(getValueAccessor.invoke("get").arg(indexVariable).arg(out.getHolder()));
}
public static JInvocation write(MajorType type, JVar vector, HoldingContainer in, JExpression indexVariable, String setMethodName) {
JInvocation setMethod = vector.invoke("getMutator").invoke(setMethodName).arg(indexVariable);
if (type.getMinorType() == MinorType.UNION) {
return setMethod.arg(in.getHolder());
}
switch(type.getMode()){
case OPTIONAL:
setMethod = setMethod.arg(in.f("isSet"));
// Fall through
case REQUIRED:
switch (type.getMinorType()) {
case BIGINT:
case FLOAT4:
case FLOAT8:
case INT:
case MONEY:
case SMALLINT:
case TINYINT:
case UINT1:
case UINT2:
case UINT4:
case UINT8:
case INTERVALYEAR:
case DATE:
case TIME:
case TIMESTAMP:
case BIT:
case DECIMAL9:
case DECIMAL18:
return setMethod
.arg(in.getValue());
case DECIMAL28DENSE:
case DECIMAL28SPARSE:
case DECIMAL38DENSE:
case DECIMAL38SPARSE:
return setMethod
.arg(in.f("start"))
.arg(in.f("buffer"));
case INTERVAL:{
return setMethod
.arg(in.f("months"))
.arg(in.f("days"))
.arg(in.f("milliseconds"));
}
case INTERVALDAY: {
return setMethod
.arg(in.f("days"))
.arg(in.f("milliseconds"));
}
case VAR16CHAR:
case VARBINARY:
case VARCHAR:
case VARDECIMAL:
return setMethod
.arg(in.f("start"))
.arg(in.f("end"))
.arg(in.f("buffer"));
default:
}
default:
}
return setMethod.arg(in.getHolder());
}
}