You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by ja...@apache.org on 2014/08/29 01:34:09 UTC
[20/47] Switch to DrillBuf Add @Inject DrillBuf Move comparison
functions to memory sensitive ones Add scalar replacement functionality for
value holders Simplify date parsing function Add local compiled code caching
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/compile/bytecode/ValueHolderReplacementVisitor.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/bytecode/ValueHolderReplacementVisitor.java b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/bytecode/ValueHolderReplacementVisitor.java
new file mode 100644
index 0000000..2cec537
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/bytecode/ValueHolderReplacementVisitor.java
@@ -0,0 +1,75 @@
+/**
+ * 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.compile.bytecode;
+
+import java.io.PrintWriter;
+
+import org.apache.commons.io.output.StringBuilderWriter;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.util.Textifier;
+import org.objectweb.asm.util.TraceMethodVisitor;
+
+public class ValueHolderReplacementVisitor extends ClassVisitor {
+ static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ValueHolderReplacementVisitor.class);
+
+ public ValueHolderReplacementVisitor(ClassVisitor cw) {
+ super(Opcodes.ASM4, cw);
+ }
+
+
+
+ @Override
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+ MethodVisitor innerVisitor = super.visitMethod(access, name, desc, signature, exceptions);
+// innerVisitor = new Debugger(access, name, desc, signature, exceptions, innerVisitor);
+ return new ScalarReplacementNode(access, name, desc, signature, exceptions, innerVisitor);
+ }
+
+ private static class Debugger extends MethodNode {
+
+ MethodVisitor inner;
+
+ public Debugger(int access, String name, String desc, String signature, String[] exceptions, MethodVisitor inner) {
+ super(access, name, desc, signature, exceptions);
+ this.inner = inner;
+
+ }
+
+ @Override
+ public void visitEnd() {
+ try{
+ accept(inner);
+ }catch(Exception e){
+ Textifier t = new Textifier();
+ accept(new TraceMethodVisitor(t));
+ StringBuilderWriter sw = new StringBuilderWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ t.print(pw);
+ pw.flush();
+ String bytecode = sw.getBuilder().toString();
+ logger.error(String.format("Failure while rendering method %s, %s, %s. ByteCode:\n %s", name, desc, signature, bytecode), e);
+ throw new RuntimeException(String.format("Failure while rendering method %s, %s, %s. ByteCode:\n %s", name, desc, signature, bytecode), e);
+ }
+
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/CodeGeneratorMethod.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/CodeGeneratorMethod.java b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/CodeGeneratorMethod.java
index 9fe0cf3..a7b5680 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/CodeGeneratorMethod.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/CodeGeneratorMethod.java
@@ -28,13 +28,21 @@ import com.thoughtworks.paranamer.Paranamer;
public class CodeGeneratorMethod implements Iterable<CodeGeneratorArgument>{
static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CodeGeneratorMethod.class);
-
+
private final String methodName;
private final Class<?> returnType;
private final CodeGeneratorArgument[] arguments;
private final Class<?>[] exs;
private final Method underlyingMethod;
-
+
+ public CodeGeneratorMethod(String name, Class<?> returnType){
+ this.methodName = name;
+ this.returnType = returnType;
+ this.exs = new Class<?>[0];
+ this.underlyingMethod = null;
+ this.arguments = new CodeGeneratorArgument[0];
+ }
+
public CodeGeneratorMethod(Method m){
this.underlyingMethod = m;
this.methodName = m.getName();
@@ -51,7 +59,7 @@ public class CodeGeneratorMethod implements Iterable<CodeGeneratorArgument>{
}
exs = m.getExceptionTypes();
}
-
+
public String getMethodName() {
return methodName;
}
@@ -62,7 +70,7 @@ public class CodeGeneratorMethod implements Iterable<CodeGeneratorArgument>{
public Iterable<Class<?>> getThrowsIterable(){
return ImmutableList.copyOf(exs);
}
-
+
@Override
public Iterator<CodeGeneratorArgument> iterator() {
return Iterators.forArray(arguments);
@@ -73,5 +81,5 @@ public class CodeGeneratorMethod implements Iterable<CodeGeneratorArgument>{
return "CodeGeneratorMethod [" + underlyingMethod.toGenericString() + "]";
}
-
+
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/GeneratorMapping.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/GeneratorMapping.java b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/GeneratorMapping.java
index 70a3cda..57551ed 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/GeneratorMapping.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/GeneratorMapping.java
@@ -28,7 +28,7 @@ public class GeneratorMapping {
private String eval;
private String reset;
private String cleanup;
-
+
public GeneratorMapping(String setup, String eval, String reset, String cleanup) {
super();
@@ -49,15 +49,15 @@ public class GeneratorMapping {
public static GeneratorMapping GM(String setup, String eval){
return create(setup, eval, null, null);
}
-
+
public static GeneratorMapping GM(String setup, String eval, String reset, String cleanup){
return create(setup, eval, reset, cleanup);
}
- public static GeneratorMapping create(String setup, String eval, String reset, String cleanup){
+ public static GeneratorMapping create(String setup, String eval, String reset, String cleanup){
return new GeneratorMapping(setup, eval, reset, cleanup);
}
-
+
public String getMethodName(BlockType type){
switch(type){
case CLEANUP:
@@ -76,6 +76,6 @@ public class GeneratorMapping {
throw new IllegalStateException();
}
}
-
-
+
+
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/MappingSet.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/MappingSet.java b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/MappingSet.java
index ac0e413..80aaae8 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/MappingSet.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/MappingSet.java
@@ -42,6 +42,10 @@ public class MappingSet {
this("inIndex", "outIndex", new GeneratorMapping[] { mapping, mapping });
}
+ public boolean hasEmbeddedConstant(){
+ return constant == current;
+ }
+
public MappingSet(String readIndex, String writeIndex, String workspaceIndex, String incoming, String outgoing,
String workspace, GeneratorMapping... mappings) {
this(readIndex, writeIndex, incoming, outgoing, mappings);
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/SignatureHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/SignatureHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/SignatureHolder.java
index 536370b..d397acc 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/SignatureHolder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/SignatureHolder.java
@@ -31,13 +31,15 @@ import com.google.common.collect.Maps;
public class SignatureHolder implements Iterable<CodeGeneratorMethod>{
static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SignatureHolder.class);
-
+
private final Class<?> signature;
private final CodeGeneratorMethod[] methods;
private final Map<String, Integer> methodMap;
private final SignatureHolder[] childHolders;
-
-
+
+ public static final String DRILL_INIT_METHOD = "__DRILL_INIT__";
+ public static final CodeGeneratorMethod DRILL_INIT = new CodeGeneratorMethod(DRILL_INIT_METHOD, void.class);
+
public static SignatureHolder getHolder(Class<?> signature){
List<SignatureHolder> innerClasses = Lists.newArrayList();
for(Class<?> inner : signature.getClasses()){
@@ -46,36 +48,39 @@ public class SignatureHolder implements Iterable<CodeGeneratorMethod>{
}
return new SignatureHolder(signature, innerClasses.toArray(new SignatureHolder[innerClasses.size()]));
}
-
+
private SignatureHolder(Class<?> signature, SignatureHolder[] childHolders){
this.childHolders = childHolders;
this.signature = signature;
- Map<String, Integer> newMap = Maps.newHashMap();
-
+ Map<String, Integer> newMap = Maps.newHashMap();
+
List<CodeGeneratorMethod> methodHolders = Lists.newArrayList();
Method[] reflectMethods = signature.getDeclaredMethods();
-
+
for(Method m : reflectMethods){
if( (m.getModifiers() & Modifier.ABSTRACT) == 0 && m.getAnnotation(RuntimeOverridden.class) == null) continue;
methodHolders.add(new CodeGeneratorMethod(m));
}
-
- methods = new CodeGeneratorMethod[methodHolders.size()];
+
+ methods = new CodeGeneratorMethod[methodHolders.size()+1];
for(int i =0; i < methodHolders.size(); i++){
methods[i] = methodHolders.get(i);
Integer old = newMap.put(methods[i].getMethodName(), i);
if(old != null) throw new IllegalStateException(String.format("Attempting to add a method with name %s when there is already one method of that name in this class that is set to be runtime generated.", methods[i].getMethodName()));
-
+
}
+ methods[methodHolders.size()] = DRILL_INIT;
+ newMap.put(DRILL_INIT.getMethodName(), methodHolders.size());
+
methodMap = ImmutableMap.copyOf(newMap);
}
-
+
public Class<?> getSignatureClass(){
return signature;
}
-
+
public CodeGeneratorMethod get(int i){
return methods[i];
}
@@ -84,12 +89,12 @@ public class SignatureHolder implements Iterable<CodeGeneratorMethod>{
public Iterator<CodeGeneratorMethod> iterator() {
return Iterators.forArray(methods);
}
-
+
public int size(){
return methods.length;
}
-
-
+
+
public SignatureHolder[] getChildHolders() {
return childHolders;
}
@@ -109,6 +114,6 @@ public class SignatureHolder implements Iterable<CodeGeneratorMethod>{
return "SignatureHolder [methods="
+ (methods != null ? Arrays.asList(methods).subList(0, Math.min(methods.length, maxLen)) : null) + "]";
}
-
-
+
+
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ClassGenerator.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ClassGenerator.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ClassGenerator.java
index 4d4fc99..69d68bb 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ClassGenerator.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ClassGenerator.java
@@ -275,7 +275,7 @@ public class ClassGenerator<T>{
for(ClassGenerator<T> child : innerClasses.values()) {
child.flushCode();
- }
+ }
}
public JCodeModel getModel() {
@@ -405,6 +405,10 @@ public class ClassGenerator<T>{
return this;
}
+ public JFieldRef f(String name){
+ return holder.ref(name);
+ }
+
public boolean isConstant() {
return this.isConstant;
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/CodeGenerator.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/CodeGenerator.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/CodeGenerator.java
index 658c63c..73c5980 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/CodeGenerator.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/CodeGenerator.java
@@ -32,10 +32,10 @@ import com.sun.codemodel.JDefinedClass;
* A code generator is responsible for generating the Java source code required to complete the implementation of an
* abstract template. It is used with a class transformer to merge precompiled template code with runtime generated and
* compiled query specific code to create a runtime instance.
- *
+ *
* A code generator can contain one or more ClassGenerators that implement outer and inner classes associated with a
* particular runtime generated instance.
- *
+ *
* @param <T>
* The interface that results from compiling and merging the runtime code that is generated.
*/
@@ -46,8 +46,11 @@ public class CodeGenerator<T> {
private final TemplateClassDefinition<T> definition;
private final String className;
private final String fqcn;
+
private final JCodeModel model;
private final ClassGenerator<T> rootGenerator;
+ private String generatedCode;
+ private String generifiedCode;
CodeGenerator(TemplateClassDefinition<T> definition, FunctionImplementationRegistry funcRegistry) {
this(ClassGenerator.getDefaultMapping(), definition, funcRegistry);
@@ -74,12 +77,24 @@ public class CodeGenerator<T> {
return rootGenerator;
}
- public String generate() throws IOException {
+ public void generate() throws IOException {
rootGenerator.flushCode();
SingleClassStringWriter w = new SingleClassStringWriter();
model.build(w);
- return w.getCode().toString();
+
+ this.generatedCode = w.getCode().toString();
+ this.generifiedCode = generatedCode.replaceAll(this.className, "GenericGenerated");
+
+ }
+
+ public String generateAndGet() throws IOException {
+ generate();
+ return generatedCode;
+ }
+
+ public String getGeneratedCode(){
+ return generatedCode;
}
public TemplateClassDefinition<T> getDefinition() {
@@ -99,15 +114,49 @@ public class CodeGenerator<T> {
FunctionImplementationRegistry funcRegistry){
return get(definition, funcRegistry).getRoot();
}
-
+
public static <T> ClassGenerator<T> getRoot(MappingSet mappingSet, TemplateClassDefinition<T> definition,
FunctionImplementationRegistry funcRegistry){
return get(mappingSet, definition, funcRegistry).getRoot();
}
-
+
public static <T> CodeGenerator<T> get(MappingSet mappingSet, TemplateClassDefinition<T> definition,
FunctionImplementationRegistry funcRegistry) {
return new CodeGenerator<T>(mappingSet, definition, funcRegistry);
}
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((definition == null) ? 0 : definition.hashCode());
+ result = prime * result + ((generatedCode == null) ? 0 : generatedCode.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ CodeGenerator other = (CodeGenerator) obj;
+ if (definition == null) {
+ if (other.definition != null)
+ return false;
+ } else if (!definition.equals(other.definition))
+ return false;
+ if (generatedCode == null) {
+ if (other.generatedCode != null)
+ return false;
+ } else if (!generatedCode.equals(other.generatedCode))
+ return false;
+ return true;
+ }
+
+
+
+
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java
index caf9179..cf39246 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java
@@ -17,6 +17,7 @@
*/
package org.apache.drill.exec.expr;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -80,7 +81,13 @@ public class EvaluationVisitor {
}
public HoldingContainer addExpr(LogicalExpression e, ClassGenerator<?> generator) {
- Set<LogicalExpression> constantBoundaries = ConstantExpressionIdentifier.getConstantExpressionSet(e);
+
+ Set<LogicalExpression> constantBoundaries;
+ if(generator.getMappingSet().hasEmbeddedConstant()){
+ constantBoundaries = Collections.emptySet();
+ }else{
+ constantBoundaries = ConstantExpressionIdentifier.getConstantExpressionSet(e);
+ }
return e.accept(new ConstantFilter(constantBoundaries), generator);
}
@@ -93,17 +100,17 @@ public class EvaluationVisitor {
}
@Override
- public HoldingContainer visitBooleanOperator(BooleanOperator op,
+ public HoldingContainer visitBooleanOperator(BooleanOperator op,
ClassGenerator<?> generator) throws RuntimeException {
if (op.getName().equals("booleanAnd")) {
return visitBooleanAnd(op, generator);
}else if(op.getName().equals("booleanOr")) {
- return visitBooleanOr(op, generator);
+ return visitBooleanOr(op, generator);
} else {
throw new UnsupportedOperationException("BooleanOperator can only be booleanAnd, booleanOr. You are using " + op.getName());
}
}
-
+
@Override
public HoldingContainer visitFunctionHolderExpression(FunctionHolderExpression holderExpr,
ClassGenerator<?> generator) throws RuntimeException {
@@ -290,16 +297,9 @@ public class EvaluationVisitor {
return outputContainer;
}
} else {
- String setMethod = e.isSafe() ? "setSafe" : "set";
- String isSafeMethod = "isSafe";
-
- JInvocation setMeth;
- if (Types.usesHolderForGet(inputContainer.getMajorType())) {
- setMeth = vv.invoke("getMutator").invoke(setMethod).arg(outIndex).arg(inputContainer.getHolder());
- } else {
- setMeth = vv.invoke("getMutator").invoke(setMethod).arg(outIndex).arg(inputContainer.getValue());
- }
+ final JInvocation setMeth = GetSetVectorHelper.write(e.getChild().getMajorType(), vv, inputContainer, outIndex, e.isSafe() ? "setSafe" : "set");
+ final String isSafeMethod = "isSafe";
if (e.isSafe()) {
HoldingContainer outputContainer = generator.declare(Types.REQUIRED_BIT);
@@ -356,24 +356,9 @@ public class EvaluationVisitor {
}
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);
- }
+ GetSetVectorHelper.read(e.getMajorType(), vv1, eval, out, generator.getModel(), indexVariable);
+ generator.getEvalBlock().add(eval);
} else {
JExpression vector = e.isSuperReader() ? vv1.component(componentVariable) : vv1;
@@ -419,7 +404,7 @@ public class EvaluationVisitor {
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);
@@ -503,8 +488,9 @@ public class EvaluationVisitor {
JType holderType = generator.getHolderType(majorType);
JVar var = generator.declareClassField("string", holderType);
JExpression stringLiteral = JExpr.lit(e.value);
+ JExpression buffer = generator.getMappingSet().getIncoming().invoke("getContext").invoke("getManagedBuffer");
setup.assign(var,
- generator.getModel().ref(ValueHolderHelper.class).staticInvoke("getVarCharHolder").arg(stringLiteral));
+ generator.getModel().ref(ValueHolderHelper.class).staticInvoke("getVarCharHolder").arg(buffer).arg(stringLiteral));
return new HoldingContainer(majorType, var, null, null);
}
@@ -601,20 +587,20 @@ public class EvaluationVisitor {
FunctionCall fc = new FunctionCall(convertFunctionName, newArgs, e.getPosition());
return fc.accept(this, value);
}
-
+
private HoldingContainer visitBooleanAnd(BooleanOperator op,
ClassGenerator<?> generator) {
-
+
HoldingContainer out = generator.declare(op.getMajorType());
-
+
JLabel label = generator.getEvalBlockLabel("AndOP");
JBlock eval = generator.getEvalBlock().block(); // enter into nested block
generator.nestEvalBlock(eval);
HoldingContainer arg = null;
-
+
JExpression e = null;
-
+
// value of boolean "and" when one side is null
// p q p and q
// true null null
@@ -624,57 +610,57 @@ public class EvaluationVisitor {
// null null null
for (int i = 0; i < op.args.size(); i++) {
arg = op.args.get(i).accept(this, generator);
-
+
JBlock earlyExit = null;
if (arg.isOptional()) {
- earlyExit = eval._if(arg.getIsSet().eq(JExpr.lit(1)).cand(arg.getValue().ne(JExpr.lit(1))))._then();
+ earlyExit = eval._if(arg.getIsSet().eq(JExpr.lit(1)).cand(arg.getValue().ne(JExpr.lit(1))))._then();
if(e == null){
e = arg.getIsSet();
}else{
e = e.mul(arg.getIsSet());
- }
+ }
} else {
- earlyExit = eval._if(arg.getValue().ne(JExpr.lit(1)))._then();
+ earlyExit = eval._if(arg.getValue().ne(JExpr.lit(1)))._then();
}
-
+
if (out.isOptional()) {
earlyExit.assign(out.getIsSet(), JExpr.lit(1));
- }
-
- earlyExit.assign(out.getValue(), JExpr.lit(0));
- earlyExit._break(label);
+ }
+
+ earlyExit.assign(out.getValue(), JExpr.lit(0));
+ earlyExit._break(label);
}
-
+
if (out.isOptional()) {
assert (e != null);
-
+
JConditional notSetJC = eval._if(e.eq(JExpr.lit(0)));
notSetJC._then().assign(out.getIsSet(), JExpr.lit(0));
-
+
JBlock setBlock = notSetJC._else().block();
setBlock.assign(out.getIsSet(), JExpr.lit(1));
setBlock.assign(out.getValue(), JExpr.lit(1));
} else {
- assert (e == null);
+ assert (e == null);
eval.assign(out.getValue(), JExpr.lit(1)) ;
}
-
- generator.unNestEvalBlock(); // exit from nested block
-
+
+ generator.unNestEvalBlock(); // exit from nested block
+
return out;
}
-
+
private HoldingContainer visitBooleanOr(BooleanOperator op,
ClassGenerator<?> generator) {
-
+
HoldingContainer out = generator.declare(op.getMajorType());
-
+
JLabel label = generator.getEvalBlockLabel("OrOP");
JBlock eval = generator.getEvalBlock().block();
- generator.nestEvalBlock(eval); // enter into nested block.
+ generator.nestEvalBlock(eval); // enter into nested block.
HoldingContainer arg = null;
-
+
JExpression e = null;
// value of boolean "or" when one side is null
@@ -684,49 +670,49 @@ public class EvaluationVisitor {
// null true true
// null false null
// null null null
-
+
for (int i = 0; i < op.args.size(); i++) {
arg = op.args.get(i).accept(this, generator);
-
+
JBlock earlyExit = null;
if (arg.isOptional()) {
- earlyExit = eval._if(arg.getIsSet().eq(JExpr.lit(1)).cand(arg.getValue().eq(JExpr.lit(1))))._then();
+ earlyExit = eval._if(arg.getIsSet().eq(JExpr.lit(1)).cand(arg.getValue().eq(JExpr.lit(1))))._then();
if(e == null){
e = arg.getIsSet();
}else{
e = e.mul(arg.getIsSet());
- }
+ }
} else {
- earlyExit = eval._if(arg.getValue().eq(JExpr.lit(1)))._then();
+ earlyExit = eval._if(arg.getValue().eq(JExpr.lit(1)))._then();
}
-
+
if (out.isOptional()) {
earlyExit.assign(out.getIsSet(), JExpr.lit(1));
- }
-
- earlyExit.assign(out.getValue(), JExpr.lit(1));
- earlyExit._break(label);
+ }
+
+ earlyExit.assign(out.getValue(), JExpr.lit(1));
+ earlyExit._break(label);
}
-
+
if (out.isOptional()) {
assert (e != null);
-
+
JConditional notSetJC = eval._if(e.eq(JExpr.lit(0)));
notSetJC._then().assign(out.getIsSet(), JExpr.lit(0));
-
+
JBlock setBlock = notSetJC._else().block();
setBlock.assign(out.getIsSet(), JExpr.lit(1));
setBlock.assign(out.getValue(), JExpr.lit(0));
} else {
- assert (e == null);
+ assert (e == null);
eval.assign(out.getValue(), JExpr.lit(0)) ;
}
-
- generator.unNestEvalBlock(); // exit from nested block.
-
+
+ generator.unNestEvalBlock(); // exit from nested block.
+
return out;
}
-
+
}
private class ConstantFilter extends EvalVisitor {
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/GetSetVectorHelper.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/GetSetVectorHelper.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/GetSetVectorHelper.java
new file mode 100644
index 0000000..46bd7f0
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/GetSetVectorHelper.java
@@ -0,0 +1,175 @@
+/**
+ * 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.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 {
+ static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(GetSetVectorHelper.class);
+
+ // eval.add(getValueAccessor.arg(indexVariable).arg(out.getHolder()));
+
+ 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("getData"));
+ 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("getData"));
+ 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("getData").invoke("getInt").arg(start));
+ eval.assign(out.getHolder().ref("milliseconds"), vector.invoke("getData").invoke("getInt").arg(start.plus(JExpr.lit(4))));
+ return;
+ }
+ case VAR16CHAR:
+ case VARBINARY:
+ case VARCHAR:
+ eval.assign(out.getHolder().ref("buffer"), vector.invoke("getData"));
+ 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;
+
+ }
+ }
+
+ // 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);
+
+ switch(type.getMode()){
+ case OPTIONAL:
+ setMethod = setMethod.arg(in.f("isSet"));
+ 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:
+ return setMethod //
+ .arg(in.f("start")) //
+ .arg(in.f("end")) //
+ .arg(in.f("buffer"));
+ }
+ }
+
+
+ return setMethod.arg(in.getHolder());
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillAggFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillAggFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillAggFuncHolder.java
index 989e490..5281c37 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillAggFuncHolder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillAggFuncHolder.java
@@ -45,7 +45,7 @@ import com.sun.codemodel.JVar;
class DrillAggFuncHolder extends DrillFuncHolder{
static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillAggFuncHolder.class);
-
+
private final String setup;
private final String reset;
private final String add;
@@ -57,7 +57,7 @@ class DrillAggFuncHolder extends DrillFuncHolder{
Map<String, String> methods, List<String> imports) {
this(scope, nullHandling, isBinaryCommutative, isRandom, registeredNames, parameters, returnValue, workspaceVars, methods, imports, FunctionCostCategory.getDefault());
}
-
+
public DrillAggFuncHolder(FunctionScope scope, NullHandling nullHandling, boolean isBinaryCommutative, boolean isRandom,
String[] registeredNames, ValueReference[] parameters, ValueReference returnValue, WorkspaceReference[] workspaceVars,
Map<String, String> methods, List<String> imports, FunctionCostCategory costCategory) {
@@ -84,38 +84,38 @@ class DrillAggFuncHolder extends DrillFuncHolder{
@Override
public JVar[] renderStart(ClassGenerator<?> g, HoldingContainer[] inputVariables) {
- if (!g.getMappingSet().isHashAggMapping()) { //Declare workspace vars for non-hash-aggregation.
+ if (!g.getMappingSet().isHashAggMapping()) { //Declare workspace vars for non-hash-aggregation.
JVar[] workspaceJVars = declareWorkspaceVariables(g);
- generateBody(g, BlockType.SETUP, setup, null, workspaceJVars, false);
+ generateBody(g, BlockType.SETUP, setup, null, workspaceJVars, true);
return workspaceJVars;
} else { //Declare workspace vars and workspace vectors for hash aggregation.
-
+
JVar[] workspaceJVars = declareWorkspaceVectors(g);
-
+
JBlock setupBlock = g.getSetupBlock();
-
- //Loop through all workspace vectors, to get the minimum of size of all workspace vectors.
+
+ //Loop through all workspace vectors, to get the minimum of size of all workspace vectors.
JVar sizeVar = setupBlock.decl(g.getModel().INT, "vectorSize", JExpr.lit(Integer.MAX_VALUE));
JClass mathClass = g.getModel().ref(Math.class);
for (int id = 0; id<workspaceVars.length; id ++) {
setupBlock.assign(sizeVar,mathClass.staticInvoke("min").arg(sizeVar).arg(g.getWorkspaceVectors().get(workspaceVars[id]).invoke("getValueCapacity")));
}
-
- for(int i =0 ; i < workspaceVars.length; i++) {
+
+ for(int i =0 ; i < workspaceVars.length; i++) {
setupBlock.assign(workspaceJVars[i], JExpr._new(g.getHolderType(workspaceVars[i].majorType)));
}
-
- //Use for loop to initialize entries in the workspace vectors.
+
+ //Use for loop to initialize entries in the workspace vectors.
JForLoop forLoop = setupBlock._for();
JVar ivar = forLoop.init(g.getModel().INT, "drill_internal_i", JExpr.lit(0));
forLoop.test(ivar.lt(sizeVar));
forLoop.update(ivar.assignPlus(JExpr.lit(1)));
-
+
JBlock subBlock = generateInitWorkspaceBlockHA(g, BlockType.SETUP, setup, workspaceJVars, ivar);
forLoop.body().add(subBlock);
- return workspaceJVars;
+ return workspaceJVars;
}
-
+
}
@@ -134,7 +134,7 @@ class DrillAggFuncHolder extends DrillFuncHolder{
JVar internalOutput = sub.decl(JMod.FINAL, g.getHolderType(returnValue.type), returnValue.name, JExpr._new(g.getHolderType(returnValue.type)));
addProtectedBlock(g, sub, output, null, workspaceJVars, false);
sub.assign(out.getHolder(), internalOutput);
- //hash aggregate uses workspace vectors. Initialization is done in "setup" and does not require "reset" block.
+ //hash aggregate uses workspace vectors. Initialization is done in "setup" and does not require "reset" block.
if (!g.getMappingSet().isHashAggMapping()) {
generateBody(g, BlockType.RESET, reset, null, workspaceJVars, false);
}
@@ -146,27 +146,27 @@ class DrillAggFuncHolder extends DrillFuncHolder{
private JVar[] declareWorkspaceVectors(ClassGenerator<?> g) {
JVar[] workspaceJVars = new JVar[workspaceVars.length];
-
+
for(int i =0 ; i < workspaceVars.length; i++){
Preconditions.checkState(Types.isFixedWidthType(workspaceVars[i].majorType), String.format("Workspace variable '%s' in aggregation function '%s' is not allowed to have variable length type.", workspaceVars[i].name, registeredNames[0]));
Preconditions.checkState(workspaceVars[i].majorType.getMode()==DataMode.REQUIRED, String.format("Workspace variable '%s' in aggregation function '%s' is not allowed to have null or repeated type.", workspaceVars[i].name, registeredNames[0]));
//workspaceJVars[i] = g.declareClassField("work", g.getHolderType(workspaceVars[i].majorType), JExpr._new(g.getHolderType(workspaceVars[i].majorType)));
- workspaceJVars[i] = g.declareClassField("work", g.getHolderType(workspaceVars[i].majorType));
-
+ workspaceJVars[i] = g.declareClassField("work", g.getHolderType(workspaceVars[i].majorType));
+
//Declare a workspace vector for the workspace var.
TypedFieldId typedFieldId = new TypedFieldId(workspaceVars[i].majorType, g.getWorkspaceTypes().size());
JVar vv = g.declareVectorValueSetupAndMember(g.getMappingSet().getWorkspace(), typedFieldId);
-
+
g.getWorkspaceTypes().add(typedFieldId);
g.getWorkspaceVectors().put(workspaceVars[i], vv);
}
return workspaceJVars;
}
-
+
private JBlock generateInitWorkspaceBlockHA(ClassGenerator<?> g, BlockType bt, String body, JVar[] workspaceJVars, JExpression wsIndexVariable){
JBlock initBlock = new JBlock(true, true);
- if(!Strings.isNullOrEmpty(body) && !body.trim().isEmpty()){
+ if(!Strings.isNullOrEmpty(body) && !body.trim().isEmpty()){
JBlock sub = new JBlock(true, true);
addProtectedBlockHA(g, sub, body, null, workspaceJVars, wsIndexVariable);
initBlock.directStatement(String.format("/** start %s for function %s **/ ", bt.name(), registeredNames[0]));
@@ -175,51 +175,51 @@ class DrillAggFuncHolder extends DrillFuncHolder{
}
return initBlock;
}
-
+
@Override
protected void addProtectedBlock(ClassGenerator<?> g, JBlock sub, String body, HoldingContainer[] inputVariables, JVar[] workspaceJVars, boolean decConstantInputOnly){
if (!g.getMappingSet().isHashAggMapping()) {
super.addProtectedBlock(g, sub, body, inputVariables, workspaceJVars, decConstantInputOnly);
} else {
JExpression indexVariable = g.getMappingSet().getWorkspaceIndex();
- addProtectedBlockHA(g, sub, body, inputVariables, workspaceJVars, indexVariable);
+ addProtectedBlockHA(g, sub, body, inputVariables, workspaceJVars, indexVariable);
}
}
/*
- * This is customized version of "addProtectedBlock" for hash aggregation. It take one additional parameter "wsIndexVariable".
+ * 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 = parameters[i];
HoldingContainer inputVariable = inputVariables[i];
- sub.decl(inputVariable.getHolder().type(), parameter.name, inputVariable.getHolder());
+ sub.decl(inputVariable.getHolder().type(), parameter.name, inputVariable.getHolder());
}
}
- JVar[] internalVars = new JVar[workspaceJVars.length];
+ JVar[] internalVars = new JVar[workspaceJVars.length];
for(int i =0; i < workspaceJVars.length; i++){
//sub.assign(workspaceJVars[i], JExpr._new(g.getHolderType(workspaceVars[i].majorType)));
- //Access workspaceVar through workspace vector.
- JInvocation getValueAccessor = g.getWorkspaceVectors().get(workspaceVars[i]).invoke("getAccessor").invoke("get");
+ //Access workspaceVar through workspace vector.
+ JInvocation getValueAccessor = g.getWorkspaceVectors().get(workspaceVars[i]).invoke("getAccessor").invoke("get");
if (Types.usesHolderForGet(workspaceVars[i].majorType)) {
sub.add(getValueAccessor.arg(wsIndexVariable).arg(workspaceJVars[i]));
} else {
sub.assign(workspaceJVars[i].ref("value"), getValueAccessor.arg(wsIndexVariable));
}
- internalVars[i] = sub.decl(g.getHolderType(workspaceVars[i].majorType), workspaceVars[i].name, workspaceJVars[i]);
+ internalVars[i] = sub.decl(g.getHolderType(workspaceVars[i].majorType), workspaceVars[i].name, workspaceJVars[i]);
}
-
+
Preconditions.checkNotNull(body);
sub.directStatement(body);
JVar successVar = sub.decl(JType.parse(g.getModel(), "boolean"), "success", JExpr.lit(false));
-
+
// reassign workspace variables back.
for(int i =0; i < workspaceJVars.length; i++){
sub.assign(workspaceJVars[i], internalVars[i]);
-
- //Change workspaceVar through workspace vector.
+
+ //Change workspaceVar through workspace vector.
JInvocation setMeth;
if (Types.usesHolderForGet(workspaceVars[i].majorType)) {
setMeth = g.getWorkspaceVectors().get(workspaceVars[i]).invoke("getMutator").invoke("setSafe").arg(wsIndexVariable).arg(workspaceJVars[i]);
@@ -233,7 +233,7 @@ class DrillAggFuncHolder extends DrillFuncHolder{
sub._if(successVar.eq(JExpr.lit(false)))._then()._throw(JExpr._new(drillRunTimeException).arg(JExpr.lit("setsafe() failed; cannot set holder value into the vector")));
}
-
+
}
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalAddFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalAddFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalAddFuncHolder.java
index 98c1c85..61e04ca 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalAddFuncHolder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalAddFuncHolder.java
@@ -23,12 +23,11 @@ import java.util.Map;
import org.apache.drill.common.expression.LogicalExpression;
import org.apache.drill.common.types.TypeProtos;
import org.apache.drill.common.types.TypeProtos.MajorType;
-
import org.apache.drill.common.util.DecimalScalePrecisionAddFunction;
import org.apache.drill.common.util.DecimalScalePrecisionDivideFunction;
-import org.apache.drill.common.util.DecimalUtility;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+import org.apache.drill.exec.util.DecimalUtility;
public class DrillDecimalAddFuncHolder extends DrillSimpleFuncHolder{
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalDivScaleFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalDivScaleFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalDivScaleFuncHolder.java
index 941dc49..c3a23e7 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalDivScaleFuncHolder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalDivScaleFuncHolder.java
@@ -23,11 +23,10 @@ import java.util.Map;
import org.apache.drill.common.expression.LogicalExpression;
import org.apache.drill.common.types.TypeProtos;
import org.apache.drill.common.types.TypeProtos.MajorType;
-
import org.apache.drill.common.util.DecimalScalePrecisionDivideFunction;
-import org.apache.drill.common.util.DecimalUtility;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+import org.apache.drill.exec.util.DecimalUtility;
public class DrillDecimalDivScaleFuncHolder extends DrillSimpleFuncHolder{
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalModScaleFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalModScaleFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalModScaleFuncHolder.java
index 2cf1088..621e1dd 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalModScaleFuncHolder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalModScaleFuncHolder.java
@@ -23,12 +23,11 @@ import java.util.Map;
import org.apache.drill.common.expression.LogicalExpression;
import org.apache.drill.common.types.TypeProtos;
import org.apache.drill.common.types.TypeProtos.MajorType;
-
import org.apache.drill.common.util.DecimalScalePrecisionDivideFunction;
import org.apache.drill.common.util.DecimalScalePrecisionModFunction;
-import org.apache.drill.common.util.DecimalUtility;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+import org.apache.drill.exec.util.DecimalUtility;
public class DrillDecimalModScaleFuncHolder extends DrillSimpleFuncHolder{
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalSumScaleFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalSumScaleFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalSumScaleFuncHolder.java
index 6c04afc..cb8bfed 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalSumScaleFuncHolder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalSumScaleFuncHolder.java
@@ -23,11 +23,10 @@ import java.util.Map;
import org.apache.drill.common.expression.LogicalExpression;
import org.apache.drill.common.types.TypeProtos;
import org.apache.drill.common.types.TypeProtos.MajorType;
-
import org.apache.drill.common.util.DecimalScalePrecisionMulFunction;
-import org.apache.drill.common.util.DecimalUtility;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+import org.apache.drill.exec.util.DecimalUtility;
public class DrillDecimalSumScaleFuncHolder extends DrillSimpleFuncHolder{
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java
index 5ca48ce..fcc0b35 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java
@@ -28,6 +28,8 @@ import org.apache.drill.common.types.TypeProtos;
import org.apache.drill.common.types.TypeProtos.MajorType;
import org.apache.drill.common.types.TypeProtos.MinorType;
import org.apache.drill.common.types.Types;
+import org.apache.drill.exec.compile.bytecode.ScalarReplacementTypes;
+import org.apache.drill.exec.compile.sig.SignatureHolder;
import org.apache.drill.exec.expr.ClassGenerator;
import org.apache.drill.exec.expr.ClassGenerator.BlockType;
import org.apache.drill.exec.expr.ClassGenerator.HoldingContainer;
@@ -114,10 +116,26 @@ public abstract class DrillFuncHolder extends AbstractFuncHolder {
return isRandom;
}
+
protected JVar[] declareWorkspaceVariables(ClassGenerator<?> g) {
JVar[] workspaceJVars = new JVar[workspaceVars.length];
for (int i = 0; i < workspaceVars.length; i++) {
- workspaceJVars[i] = g.declareClassField("work", g.getModel()._ref(workspaceVars[i].type));
+ WorkspaceReference ref = workspaceVars[i];
+ JType jtype = g.getModel()._ref(ref.type);
+
+ if(ScalarReplacementTypes.CLASSES.contains(ref.type)){
+ workspaceJVars[i] = g.declareClassField("work", jtype);
+ JBlock b = g.getBlock(SignatureHolder.DRILL_INIT_METHOD);
+ b.assign(workspaceJVars[i], JExpr._new(jtype));
+ }else{
+ workspaceJVars[i] = g.declareClassField("work", jtype);
+ }
+
+ if(ref.isInject()){
+ g.getBlock(BlockType.SETUP).assign(workspaceJVars[i], g.getMappingSet().getIncoming().invoke("getContext").invoke("getManagedBuffer"));
+ }else{
+ //g.getBlock(BlockType.SETUP).assign(workspaceJVars[i], JExpr._new(jtype));
+ }
}
return workspaceJVars;
}
@@ -159,7 +177,13 @@ public abstract class DrillFuncHolder extends AbstractFuncHolder {
JVar[] internalVars = new JVar[workspaceJVars.length];
for (int i = 0; i < workspaceJVars.length; i++) {
- internalVars[i] = sub.decl(g.getModel()._ref(workspaceVars[i].type), workspaceVars[i].name, workspaceJVars[i]);
+ if(decConstInputOnly){
+ internalVars[i] = sub.decl(g.getModel()._ref(workspaceVars[i].type), workspaceVars[i].name, workspaceJVars[i]);
+ }else{
+
+ internalVars[i] = sub.decl(g.getModel()._ref(workspaceVars[i].type), workspaceVars[i].name, workspaceJVars[i]);
+ }
+
}
Preconditions.checkNotNull(body);
@@ -303,19 +327,24 @@ public abstract class DrillFuncHolder extends AbstractFuncHolder {
Class<?> type;
String name;
MajorType majorType;
+ boolean inject;
- public WorkspaceReference(Class<?> type, String name) {
+ public WorkspaceReference(Class<?> type, String name, boolean inject) {
super();
Preconditions.checkNotNull(type);
Preconditions.checkNotNull(name);
this.type = type;
this.name = name;
+ this.inject = inject;
}
void setMajorType(MajorType majorType) {
this.majorType = majorType;
}
+ public boolean isInject(){
+ return inject;
+ }
}
public boolean checkPrecisionRange() {
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java
index 64f45c7..63ddb11 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java
@@ -17,6 +17,8 @@
*/
package org.apache.drill.exec.expr.fn;
+import io.netty.buffer.DrillBuf;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
@@ -25,6 +27,8 @@ import java.net.URL;
import java.util.List;
import java.util.Map;
+import javax.inject.Inject;
+
import org.apache.drill.common.types.TypeProtos.MajorType;
import org.apache.drill.common.util.FileUtils;
import org.apache.drill.exec.expr.DrillFunc;
@@ -111,15 +115,17 @@ public class FunctionConverter {
Param param = field.getAnnotation(Param.class);
Output output = field.getAnnotation(Output.class);
Workspace workspace = field.getAnnotation(Workspace.class);
+ Inject inject = field.getAnnotation(Inject.class);
int i =0;
if(param != null) i++;
if(output != null) i++;
if(workspace != null) i++;
+ if(inject != null) i++;
if(i == 0){
- return failure("The field must be either a @Param, @Output or @Workspace field.", clazz, field);
+ return failure("The field must be either a @Param, @Output, @Inject or @Workspace field.", clazz, field);
}else if(i > 1){
- return failure("The field must be only one of @Param, @Output or @Workspace. It currently has more than one of these annotations.", clazz, field);
+ return failure("The field must be only one of @Param, @Output, @Inject or @Workspace. It currently has more than one of these annotations.", clazz, field);
}
if(param != null || output != null){
@@ -132,7 +138,7 @@ public class FunctionConverter {
// Special processing for @Output ComplexWriter
if (output != null && ComplexWriter.class.isAssignableFrom(field.getType())) {
-
+
if(outputField != null){
return failure("You've declared more than one @Output field. You must declare one and only @Output field per Function class.", clazz, field);
}else{
@@ -140,7 +146,7 @@ public class FunctionConverter {
}
continue;
}
-
+
// check that param and output are value holders.
if(!ValueHolder.class.isAssignableFrom(field.getType())){
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..", field.getType()), clazz, field);
@@ -168,12 +174,14 @@ public class FunctionConverter {
outputField = p;
}
}
-
+
}else{
// workspace work.
- WorkspaceReference wsReference = new WorkspaceReference(field.getType(), field.getName());
+ boolean isInject = inject != null;
+ if(isInject && !field.getType().equals(DrillBuf.class)) return failure(String.format("Only DrillBuf is allowed to be injected. You attempted to inject %s.", field.getType()), clazz, field);
+ WorkspaceReference wsReference = new WorkspaceReference(field.getType(), field.getName(), isInject);
- if (template.scope() == FunctionScope.POINT_AGGREGATE && !ValueHolder.class.isAssignableFrom(field.getType()) ) {
+ if (!isInject && template.scope() == FunctionScope.POINT_AGGREGATE && !ValueHolder.class.isAssignableFrom(field.getType()) ) {
return failure(String.format("Aggregate function '%s' workspace variable '%s' is of type '%s'. Please change it to Holder type.", template.name(), field.getName(), field.getType()), clazz, field);
}
@@ -229,21 +237,21 @@ public class FunctionConverter {
template.isRandom(), registeredNames, ps, outputField, works, methods, imports);
case SIMPLE:
if (outputField.isComplexWriter)
- return new DrillComplexWriterFuncHolder(template.scope(), template.nulls(),
+ return new DrillComplexWriterFuncHolder(template.scope(), template.nulls(),
template.isBinaryCommutative(),
- template.isRandom(), registeredNames,
+ template.isRandom(), registeredNames,
ps, outputField, works, methods, imports);
else
- return new DrillSimpleFuncHolder(template.scope(), template.nulls(),
+ return new DrillSimpleFuncHolder(template.scope(), template.nulls(),
template.isBinaryCommutative(),
- template.isRandom(), registeredNames,
+ template.isRandom(), registeredNames,
ps, outputField, works, methods, imports, template.costCategory());
case SC_BOOLEAN_OPERATOR:
- return new DrillBooleanOPHolder(template.scope(), template.nulls(),
+ return new DrillBooleanOPHolder(template.scope(), template.nulls(),
template.isBinaryCommutative(),
- template.isRandom(), registeredNames,
+ template.isRandom(), registeredNames,
ps, outputField, works, methods, imports);
-
+
case DECIMAL_MAX_SCALE:
return new DrillDecimalMaxScaleFuncHolder(template.scope(), template.nulls(), template.isBinaryCommutative(),
template.isRandom(), registeredNames, ps, outputField, works, methods, imports);
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/ByteFunctionHelpers.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/ByteFunctionHelpers.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/ByteFunctionHelpers.java
new file mode 100644
index 0000000..be1d9e6
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/ByteFunctionHelpers.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+
+ * 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.fn.impl;
+
+import com.google.common.primitives.UnsignedLongs;
+
+import io.netty.util.internal.PlatformDependent;
+
+public class ByteFunctionHelpers {
+ static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ByteFunctionHelpers.class);
+
+ public static final int equal(final long laddr, int lStart, int lEnd, final long raddr, int rStart,
+ final int rEnd) {
+
+ int n = lEnd - lStart;
+ if (n == rEnd - rStart) {
+ long lPos = laddr + lStart;
+ long rPos = raddr + rStart;
+
+ while (n > 7) {
+ long leftLong = PlatformDependent.getLong(lPos);
+ long rightLong = PlatformDependent.getLong(rPos);
+ if (leftLong != rightLong) {
+ return 0;
+ }
+ lPos += 8;
+ rPos += 8;
+ n -= 8;
+ }
+ while (n-- != 0) {
+ byte leftByte = PlatformDependent.getByte(lPos);
+ byte rightByte = PlatformDependent.getByte(rPos);
+ if (leftByte != rightByte) {
+ return 0;
+ }
+ lPos++;
+ rPos++;
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ public static final int compare(final long laddr, int lStart, int lEnd, final long raddr, int rStart, final int rEnd) {
+ int lLen = lEnd - lStart;
+ int rLen = rEnd - rStart;
+ int n = Math.min(rLen, lLen);
+ long lPos = laddr + lStart;
+ long rPos = raddr + rStart;
+
+ while (n > 7) {
+ long leftLong = PlatformDependent.getLong(lPos);
+ long rightLong = PlatformDependent.getLong(rPos);
+ if(leftLong != rightLong){
+ return UnsignedLongs.compare(Long.reverseBytes(leftLong), Long.reverseBytes(rightLong));
+ }
+ lPos += 8;
+ rPos += 8;
+ n -= 8;
+ }
+
+ while (n-- != 0) {
+ byte leftByte = PlatformDependent.getByte(lPos);
+ byte rightByte = PlatformDependent.getByte(rPos);
+ if (leftByte != rightByte) {
+ return ((leftByte & 0xFF) - (rightByte & 0xFF)) > 0 ? 1 : -1;
+ }
+ lPos++;
+ rPos++;
+ }
+
+ if (lLen == rLen) return 0;
+
+ return lLen > rLen ? 1 : 0;
+
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/CastVarBinaryToDate.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/CastVarBinaryToDate.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/CastVarBinaryToDate.java
new file mode 100644
index 0000000..2161bfd
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/CastVarBinaryToDate.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+
+ * 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.fn.impl;
+
+import org.apache.drill.exec.expr.DrillSimpleFunc;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionCostCategory;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+import org.apache.drill.exec.expr.annotations.Output;
+import org.apache.drill.exec.expr.annotations.Param;
+import org.apache.drill.exec.expr.holders.DateHolder;
+import org.apache.drill.exec.expr.holders.VarBinaryHolder;
+import org.apache.drill.exec.record.RecordBatch;
+
+@FunctionTemplate(names = {"castDATE", "datetype"}, scope = FunctionTemplate.FunctionScope.SIMPLE, nulls=NullHandling.NULL_IF_NULL, costCategory = FunctionCostCategory.COMPLEX)
+public class CastVarBinaryToDate implements DrillSimpleFunc {
+
+ @Param VarBinaryHolder in;
+ @Output DateHolder out;
+
+ public void setup(RecordBatch incoming) {
+ }
+
+ public void eval() {
+ out.value = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.getDate(in.buffer.memoryAddress(), in.start, in.end);
+ }
+ }
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/CastVarCharVar16Char.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/CastVarCharVar16Char.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/CastVarCharVar16Char.java
index 12656d4..5280717 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/CastVarCharVar16Char.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/CastVarCharVar16Char.java
@@ -17,7 +17,12 @@
*/
package org.apache.drill.exec.expr.fn.impl;
-import io.netty.buffer.ByteBuf;
+import io.netty.buffer.DrillBuf;
+
+import java.nio.charset.Charset;
+
+import javax.inject.Inject;
+
import org.apache.drill.exec.expr.DrillSimpleFunc;
import org.apache.drill.exec.expr.annotations.FunctionTemplate;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
@@ -29,8 +34,6 @@ import org.apache.drill.exec.expr.holders.Var16CharHolder;
import org.apache.drill.exec.expr.holders.VarCharHolder;
import org.apache.drill.exec.record.RecordBatch;
-import java.nio.charset.Charset;
-
@SuppressWarnings("unused")
@FunctionTemplate(names = {"castVAR16CHAR", "to_var16char", "to_string"}, scope = FunctionTemplate.FunctionScope.SIMPLE, nulls= NullHandling.NULL_IF_NULL)
public class CastVarCharVar16Char implements DrillSimpleFunc {
@@ -38,19 +41,18 @@ public class CastVarCharVar16Char implements DrillSimpleFunc {
@Param BigIntHolder length;
@Output Var16CharHolder out;
@Workspace Charset charset;
- @Workspace ByteBuf buffer;
+ @Inject DrillBuf buffer;
@Override
public void setup(RecordBatch incoming) {
charset = java.nio.charset.Charset.forName("UTF-16");
- buffer = io.netty.buffer.Unpooled.wrappedBuffer(new byte[65536]);
}
@Override
public void eval() {
//if input length <= target_type length, do nothing
//else truncate based on target_type length
- byte[] buf = in.toString().getBytes(charset);
+ byte[] buf = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(in.start, in.end, in.buffer).getBytes(charset);
buffer.setBytes(0, buf);
out.start = 0;
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/DateTypeFunctions.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/DateTypeFunctions.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/DateTypeFunctions.java
index 725566f..f063466 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/DateTypeFunctions.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/DateTypeFunctions.java
@@ -18,7 +18,9 @@
package org.apache.drill.exec.expr.fn.impl;
-import io.netty.buffer.ByteBuf;
+import io.netty.buffer.DrillBuf;
+
+import javax.inject.Inject;
import org.apache.drill.exec.expr.DrillSimpleFunc;
import org.apache.drill.exec.expr.annotations.FunctionTemplate;
@@ -59,7 +61,7 @@ public class DateTypeFunctions {
out.months = (int) ((inputYears.value * org.apache.drill.exec.expr.fn.impl.DateUtility.yearsToMonths) +
(inputMonths.value));
out.days = (int) inputDays.value;
- out.milliSeconds = (int) ((inputHours.value * org.apache.drill.exec.expr.fn.impl.DateUtility.hoursToMillis) +
+ out.milliseconds = (int) ((inputHours.value * org.apache.drill.exec.expr.fn.impl.DateUtility.hoursToMillis) +
(inputMinutes.value * org.apache.drill.exec.expr.fn.impl.DateUtility.minutesToMillis) +
(inputSeconds.value * org.apache.drill.exec.expr.fn.impl.DateUtility.secondsToMillis) +
(inputMilliSeconds.value));
@@ -99,7 +101,7 @@ public class DateTypeFunctions {
public void eval() {
out.days = (int) inputDays.value;
- out.milliSeconds = (int) ((inputHours.value * org.apache.drill.exec.expr.fn.impl.DateUtility.hoursToMillis) +
+ out.milliseconds = (int) ((inputHours.value * org.apache.drill.exec.expr.fn.impl.DateUtility.hoursToMillis) +
(inputMinutes.value * org.apache.drill.exec.expr.fn.impl.DateUtility.minutesToMillis) +
(inputSeconds.value * org.apache.drill.exec.expr.fn.impl.DateUtility.secondsToMillis) +
(inputMillis.value));
@@ -174,7 +176,7 @@ public class DateTypeFunctions {
public void eval() {
- String timeZone = (inputTimeZone.toString());
+ String timeZone = (org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputTimeZone.start, inputTimeZone.end, inputTimeZone.buffer));
out.value = ((new org.joda.time.MutableDateTime((int)inputYears.value,
(int)inputMonths.value,
(int)inputDays.value,
@@ -268,11 +270,10 @@ public class DateTypeFunctions {
@FunctionTemplate(name = "timeofday", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL, isRandom = true)
public static class TimeOfDay implements DrillSimpleFunc {
- @Workspace ByteBuf buffer;
+ @Inject DrillBuf buffer;
@Output VarCharHolder out;
public void setup(RecordBatch incoming) {
- buffer = io.netty.buffer.Unpooled.wrappedBuffer(new byte[100]);
}
public void eval() {
@@ -388,7 +389,7 @@ public class DateTypeFunctions {
long days = diff / org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis;
out.months = (int) (days / org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays);
out.days = (int) (days % org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays);
- out.milliSeconds = (int) (diff % org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis);
+ out.milliseconds = (int) (diff % org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis);
}
}
@@ -411,7 +412,7 @@ public class DateTypeFunctions {
long days = diff / org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis;
out.months = (int) (days / org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays);
out.days = (int) (days % org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays);
- out.milliSeconds = (int) (diff % org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis);
+ out.milliseconds = (int) (diff % org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis);
}
}
@@ -430,7 +431,7 @@ public class DateTypeFunctions {
long days = diff / org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis;
out.months = (int) (days / org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays);
out.days = (int) (days % org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays);
- out.milliSeconds = (int) (diff % org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis);
+ out.milliseconds = (int) (diff % org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis);
}
}
@@ -453,7 +454,7 @@ public class DateTypeFunctions {
long days = diff / org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis;
out.months = (int) (days / org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays);
out.days = (int) (days % org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays);
- out.milliSeconds = (int) (diff % org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis);
+ out.milliseconds = (int) (diff % org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/HashFunctions.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/HashFunctions.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/HashFunctions.java
index 7475420..7c847eb 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/HashFunctions.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/HashFunctions.java
@@ -460,7 +460,7 @@ public class HashFunctions {
int xor = 0;
for (int i = 0; i < in.nDecimalDigits; i++) {
- xor = xor ^ in.getInteger(i);
+ xor = xor ^ Decimal28SparseHolder.getInteger(i, in.start, in.buffer);
}
out.value = com.google.common.hash.Hashing.murmur3_128().hashInt(xor).asInt();
}
@@ -480,7 +480,7 @@ public class HashFunctions {
else {
int xor = 0;
for (int i = 0; i < in.nDecimalDigits; i++) {
- xor = xor ^ in.getInteger(i);
+ xor = xor ^ NullableDecimal28SparseHolder.getInteger(i, in.start, in.buffer);
}
out.value = com.google.common.hash.Hashing.murmur3_128().hashInt(xor).asInt();
}
@@ -499,7 +499,7 @@ public class HashFunctions {
int xor = 0;
for (int i = 0; i < in.nDecimalDigits; i++) {
- xor = xor ^ in.getInteger(i);
+ xor = xor ^ Decimal38SparseHolder.getInteger(i, in.start, in.buffer);
}
out.value = com.google.common.hash.Hashing.murmur3_128().hashInt(xor).asInt();
}
@@ -519,7 +519,7 @@ public class HashFunctions {
else {
int xor = 0;
for (int i = 0; i < in.nDecimalDigits; i++) {
- xor = xor ^ in.getInteger(i);
+ xor = xor ^ NullableDecimal38SparseHolder.getInteger(i, in.start, in.buffer);
}
out.value = com.google.common.hash.Hashing.murmur3_128().hashInt(xor).asInt();
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/SimpleCastFunctions.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/SimpleCastFunctions.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/SimpleCastFunctions.java
index 83c5540..8a09cff 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/SimpleCastFunctions.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/SimpleCastFunctions.java
@@ -17,7 +17,9 @@
*/
package org.apache.drill.exec.expr.fn.impl;
-import io.netty.buffer.ByteBuf;
+import io.netty.buffer.DrillBuf;
+
+import javax.inject.Inject;
import org.apache.drill.exec.expr.DrillSimpleFunc;
import org.apache.drill.exec.expr.annotations.FunctionTemplate;
@@ -30,8 +32,9 @@ import org.apache.drill.exec.expr.holders.VarCharHolder;
import org.apache.drill.exec.record.RecordBatch;
public class SimpleCastFunctions {
- public static final ByteBuf FALSE = org.apache.drill.exec.util.ByteBufUtil.createBuffer(new byte[] {'f', 'a', 'l', 's', 'e'});
- public static final ByteBuf TRUE = org.apache.drill.exec.util.ByteBufUtil.createBuffer(new byte[] {'t', 'r', 'u', 'e'});
+ public static final byte[] TRUE = {'t','r','u','e'};
+ public static final byte[] FALSE = {'f','a','l','s','e'};
+
@FunctionTemplate(names = {"castBIT", "castBOOLEAN"}, scope = FunctionTemplate.FunctionScope.SIMPLE, nulls=NullHandling.NULL_IF_NULL)
public static class CastVarCharBoolean implements DrillSimpleFunc {
@@ -39,7 +42,9 @@ public class SimpleCastFunctions {
@Param VarCharHolder in;
@Output BitHolder out;
- public void setup(RecordBatch b) {}
+ public void setup(RecordBatch b) {
+
+ }
public void eval() {
byte[] buf = new byte[in.end - in.start];
@@ -61,14 +66,16 @@ public class SimpleCastFunctions {
@Param BitHolder in;
@Param BigIntHolder len;
@Output VarCharHolder out;
+ @Inject DrillBuf buffer;
public void setup(RecordBatch b) {}
public void eval() {
- io.netty.buffer.ByteBuf buffer = in.value == 1 ? org.apache.drill.exec.expr.fn.impl.SimpleCastFunctions.TRUE : org.apache.drill.exec.expr.fn.impl.SimpleCastFunctions.FALSE;
+ byte[] outB = in.value == 1 ? org.apache.drill.exec.expr.fn.impl.SimpleCastFunctions.TRUE : org.apache.drill.exec.expr.fn.impl.SimpleCastFunctions.FALSE;
+ buffer.setBytes(0, outB);
out.buffer = buffer;
out.start = 0;
- out.end = Math.min((int)len.value, buffer.capacity()); // truncate if target type has length smaller than that of input's string
+ out.end = Math.min((int)len.value, outB.length); // truncate if target type has length smaller than that of input's string
}
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c5cef06/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctionHelpers.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctionHelpers.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctionHelpers.java
new file mode 100644
index 0000000..68f7ca4
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctionHelpers.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+
+ * 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.fn.impl;
+
+import io.netty.buffer.DrillBuf;
+import io.netty.util.internal.PlatformDependent;
+
+import org.joda.time.chrono.ISOChronology;
+
+import com.google.common.base.Charsets;
+
+public class StringFunctionHelpers {
+ static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(StringFunctionHelpers.class);
+
+ // Assumes Alpha as [A-Za-z0-9]
+ // white space is treated as everything else.
+ public static void initCap(int start, int end, DrillBuf inBuf, DrillBuf outBuf) {
+ boolean capNext = true;
+
+ for (int id = start; id < end; id++) {
+ byte currentByte = inBuf.getByte(id);
+
+ // 'A - Z' : 0x41 - 0x5A
+ // 'a - z' : 0x61 - 0x7A
+ // '0-9' : 0x30 - 0x39
+ if (capNext) { // curCh is whitespace or first character of word.
+ if (currentByte >= 0x30 && currentByte <= 0x39) { // 0-9
+ capNext = false;
+ } else if (currentByte >= 0x41 && currentByte <= 0x5A) { // A-Z
+ capNext = false;
+ } else if (currentByte >= 0x61 && currentByte <= 0x7A) { // a-z
+ capNext = false;
+ currentByte -= 0x20; // Uppercase this character
+ }
+ // else {} whitespace
+ } else { // Inside of a word or white space after end of word.
+ if (currentByte >= 0x30 && currentByte <= 0x39) { // 0-9
+ // noop
+ } else if (currentByte >= 0x41 && currentByte <= 0x5A) { // A-Z
+ currentByte -= 0x20; // Lowercase this character
+ } else if (currentByte >= 0x61 && currentByte <= 0x7A) { // a-z
+ // noop
+ } else { // whitespace
+ capNext = true;
+ }
+ }
+
+ outBuf.setByte(id, currentByte);
+ } // end of for_loop
+ }
+
+ public static String toStringFromUTF8(int start, int end, DrillBuf buffer) {
+ byte[] buf = new byte[end - start];
+ buffer.getBytes(start, buf, 0, end - start);
+ String s = new String(buf, Charsets.UTF_8);
+ return s;
+ }
+
+ public static String toStringFromUTF16(int start, int end, DrillBuf buffer) {
+ byte[] buf = new byte[end - start];
+ buffer.getBytes(start, buf, 0, end - start);
+ return new String(buf, Charsets.UTF_16);
+ }
+
+ private static final ISOChronology CHRONOLOGY = org.joda.time.chrono.ISOChronology.getInstanceUTC();
+
+ public static long getDate(long memoryAddress, int start, int end){
+ long index = memoryAddress + start;
+ final long endIndex = memoryAddress + end;
+ int digit = 0;
+ int radix = 10; // Base 10 digits
+
+ // Stores three fields (year, month, day)
+ int[] dateFields = new int[3];
+ int dateIndex = 0;
+ int value = 0;
+
+ while (dateIndex < 3 && index < endIndex) {
+ digit = Character.digit(PlatformDependent.getByte(index++), radix);
+
+ if (digit == -1) {
+ dateFields[dateIndex++] = value;
+ value = 0;
+ } else {
+ value = (value * 10) + digit;
+ }
+ }
+
+ if (dateIndex < 3) {
+ // If we reached the end of input, we would have not encountered a separator, store the last value
+ dateFields[dateIndex++] = value;
+ }
+
+ /* Handle two digit years
+ * Follow convention as done by Oracle, Postgres
+ * If range of two digits is between 70 - 99 then year = 1970 - 1999
+ * Else if two digits is between 00 - 69 = 2000 - 2069
+ */
+ if (dateFields[0] < 100) {
+ if (dateFields[0] < 70) {
+ dateFields[0] += 2000;
+ } else {
+ dateFields[0] += 1900;
+ }
+ }
+
+ return CHRONOLOGY.getDateTimeMillis(dateFields[0], dateFields[1], dateFields[2], 0);
+ }
+}