Hi,
I'm trying to implement the abs() function within drill.
Now the abs() function can work with int,bigint as well as other numeric
types.
so i have done this, but this is failing as we cannot register twice. How
do we handle this situation where the corresponding function implementation
is called based on the input parameter data type.
I'm bit lost here.
@FunctionTemplate(name = "absolute_int",
scope = FunctionTemplate.FunctionScope.SIMPLE,
nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
public static class AbsoluteInt implements DrillFunc {
@Param IntHolder input;
@Output IntHolder out;
public void setup(RecordBatch b){}
public void eval(){
out.value = Math.abs(input.value);
}
public static class Provider implements CallProvider {
@Override
public FunctionDefinition[] getFunctionDefintions() {
return new FunctionDefinition[] {
FunctionDefinition.simple("absolute_int",
new BasicArgumentValidator(new Arg(Types.required(
TypeProtos.MinorType.INT))),
new OutputTypeDeterminer.SameAsFirstInput(),
"abs")
};
}
}
}
@FunctionTemplate(name = "absolute_bigint",
scope = FunctionTemplate.FunctionScope.SIMPLE,
nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
public static class AbsoluteBigInt implements DrillFunc {
@Param BigIntHolder input;
@Output BigIntHolder out;
public void setup(RecordBatch b){}
public void eval(){
out.value = Math.abs(input.value);
}
public static class Provider implements CallProvider {
@Override
public FunctionDefinition[] getFunctionDefintions() {
return new FunctionDefinition[] {
FunctionDefinition.simple("absolute_bigint",
new BasicArgumentValidator(new
Arg(Types.required(TypeProtos.MinorType.BIGINT))),
new OutputTypeDeterminer.SameAsFirstInput(),
"abs")
};
}
}
}
Thanks and Regards,
Tanujit
diff --git
a/sandbox/prototype/exec/java-exec/src/main/codegen/ValueVectors/templates/FixedValueVectors.java
b/sandbox/prototype/exec/java-exec/src/main/codegen/ValueVectors/templates/FixedValueVectors.java
index 311e715..f01fd18 100644
---
a/sandbox/prototype/exec/java-exec/src/main/codegen/ValueVectors/templates/FixedValueVectors.java
+++
b/sandbox/prototype/exec/java-exec/src/main/codegen/ValueVectors/templates/FixedValueVectors.java
@@ -243,9 +243,11 @@ public final class ${minor.class}Vector extends
BaseDataValueVector implements F
boolean even = true;
for(int i =0; i < valueCount; i++, even = !even){
if(even){
- set(i, ${minor.boxedType!type.boxedType}.MIN_VALUE);
+ //set(i, ${minor.boxedType!type.boxedType}.MIN_VALUE);
+ set(i, i);
}else{
- set(i, ${minor.boxedType!type.boxedType}.MAX_VALUE);
+ //set(i, ${minor.boxedType!type.boxedType}.MAX_VALUE);
+ set(i, -1*i);
}
}
}
diff --git
a/sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/MathFunctions.java
b/sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/MathFunctions.java
index 78630ba..cca830c 100644
---
a/sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/MathFunctions.java
+++
b/sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/MathFunctions.java
@@ -1,5 +1,8 @@
package org.apache.drill.exec.expr.fn.impl;
+import org.apache.drill.common.expression.*;
+import org.apache.drill.common.types.TypeProtos;
+import org.apache.drill.common.types.Types;
import org.apache.drill.exec.expr.DrillFunc;
import org.apache.drill.exec.expr.annotations.FunctionTemplate;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
@@ -58,5 +61,61 @@ public class MathFunctions{
}
}
+
+ @FunctionTemplate(name = "absolute_int",
+ scope = FunctionTemplate.FunctionScope.SIMPLE,
+ nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
+ public static class AbsoluteInt implements DrillFunc {
+
+ @Param IntHolder input;
+ @Output IntHolder out;
+
+ public void setup(RecordBatch b){}
+
+ public void eval(){
+ out.value = Math.abs(input.value);
+ }
+
+ public static class Provider implements CallProvider {
+
+ @Override
+ public FunctionDefinition[] getFunctionDefintions() {
+ return new FunctionDefinition[] {
+ FunctionDefinition.simple("absolute_int",
+ new BasicArgumentValidator(new
Arg(Types.required(TypeProtos.MinorType.INT))),
+ new OutputTypeDeterminer.SameAsFirstInput(),
+ "abs")
+ };
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "absolute_bigint",
+ scope = FunctionTemplate.FunctionScope.SIMPLE,
+ nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
+ public static class AbsoluteBigInt implements DrillFunc {
+
+ @Param BigIntHolder input;
+ @Output BigIntHolder out;
+
+ public void setup(RecordBatch b){}
+
+ public void eval(){
+ out.value = Math.abs(input.value);
+ }
+
+ public static class Provider implements CallProvider {
+
+ @Override
+ public FunctionDefinition[] getFunctionDefintions() {
+ return new FunctionDefinition[] {
+ FunctionDefinition.simple("absolute_bigint",
+ new BasicArgumentValidator(new
Arg(Types.required(TypeProtos.MinorType.BIGINT))),
+ new OutputTypeDeterminer.SameAsFirstInput(),
+ "abs")
+ };
+ }
+ }
+ }
}
diff --git
a/sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/store/mock/MockRecordReader.java
b/sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/store/mock/MockRecordReader.java
index 024aa21..121297a 100644
---
a/sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/store/mock/MockRecordReader.java
+++
b/sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/store/mock/MockRecordReader.java
@@ -93,12 +93,12 @@ public class MockRecordReader implements RecordReader {
recordsRead += recordSetSize;
for(ValueVector v : valueVectors){
AllocationHelper.allocate(v, recordSetSize, 50, 5);
-
+
logger.debug("MockRecordReader: Generating random data for VV of type "
+ v.getClass().getName());
ValueVector.Mutator m = v.getMutator();
m.setValueCount(recordSetSize);
m.generateTestData();
-
+
}
return recordSetSize;
}
diff --git
a/sandbox/prototype/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestSimpleFunctions.java
b/sandbox/prototype/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestSimpleFunctions.java
index ce5dccd..e2a865c 100644
---
a/sandbox/prototype/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestSimpleFunctions.java
+++
b/sandbox/prototype/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestSimpleFunctions.java
@@ -20,6 +20,7 @@ package org.apache.drill.exec.physical.impl;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
+import com.google.common.io.Resources;
import com.yammer.metrics.MetricRegistry;
import mockit.Injectable;
import mockit.NonStrictExpectations;
@@ -37,10 +38,7 @@ import org.apache.drill.exec.proto.CoordinationProtos;
import org.apache.drill.exec.proto.ExecProtos;
import org.apache.drill.exec.rpc.user.UserServer;
import org.apache.drill.exec.server.DrillbitContext;
-import org.apache.drill.exec.vector.NullableVarBinaryHolder;
-import org.apache.drill.exec.vector.NullableVarBinaryVector;
-import org.apache.drill.exec.vector.NullableVarCharHolder;
-import org.apache.drill.exec.vector.NullableVarCharVector;
+import org.apache.drill.exec.vector.*;
import org.junit.After;
import org.junit.Test;
@@ -95,7 +93,7 @@ public class TestSimpleFunctions {
SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context,
(FragmentRoot) plan.getSortedOperators(false).iterator().next()));
while(exec.next()){
- assertEquals(50, exec.getSelectionVector2().getCount());
+ assertEquals(100, exec.getSelectionVector2().getCount());
}
if(context.getFailureCause() != null){
@@ -222,6 +220,56 @@ public class TestSimpleFunctions {
assertTrue(!context.isFailed());
}
+
+ public void testAbsolute(@Injectable final DrillbitContext bitContext,
+ @Injectable UserServer.UserClientConnection
connection,
+ String expression) throws Throwable{
+
+ new NonStrictExpectations(){{
+ bitContext.getMetrics(); result = new MetricRegistry("test");
+ bitContext.getAllocator(); result = BufferAllocator.getAllocator(c);
+ }};
+
+ String planString =
Resources.toString(Resources.getResource("functions/testMathFunctions.json"),
Charsets.UTF_8).replaceAll("EXPRESSION", expression);
+ PhysicalPlanReader reader = new PhysicalPlanReader(c, c.getMapper(),
CoordinationProtos.DrillbitEndpoint.getDefaultInstance());
+ PhysicalPlan plan = reader.readPhysicalPlan(planString);
+ FunctionImplementationRegistry registry = new
FunctionImplementationRegistry(c);
+ FragmentContext context = new FragmentContext(bitContext,
ExecProtos.FragmentHandle.getDefaultInstance(), connection, null, registry);
+ SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context,
(FragmentRoot) plan.getSortedOperators(false).iterator().next()));
+
+ while(exec.next()){
+ IntVector c1 = exec.getValueVectorById(new SchemaPath("col3",
ExpressionPosition.UNKNOWN), IntVector.class);
+ IntVector.Accessor a1;
+ a1 = c1.getAccessor();
+
+ int count = 0;
+ for(int i = 0; i < c1.getAccessor().getValueCount(); i++){
+ IntHolder holder = new IntHolder();
+ a1.get(i, holder);
+ System.out.println(i + "-->" + holder.value);
+ ++count;
+ }
+ assertEquals("Absolute Function -", 100, count);
+ }
+
+ if(context.getFailureCause() != null){
+ throw context.getFailureCause();
+ }
+ assertTrue(!context.isFailed());
+
+ }
+
+ @Test
+ public void testAbsoluteInt(@Injectable final DrillbitContext bitContext,
+ @Injectable UserServer.UserClientConnection
connection) throws Throwable{
+ testAbsolute(bitContext,connection, "abs(blue)");
+ }
+
+ @Test
+ public void testAbsoluteBigInt(@Injectable final DrillbitContext bitContext,
+ @Injectable UserServer.UserClientConnection
connection) throws Throwable{
+ testAbsolute(bitContext,connection, "abs(red)");
+ }
@After
public void tearDown() throws Exception{
diff --git a/sandbox/prototype/exec/java-exec/src/test/resources/logback.xml
b/sandbox/prototype/exec/java-exec/src/test/resources/logback.xml
index 206a469..2b9f7aa 100644
--- a/sandbox/prototype/exec/java-exec/src/test/resources/logback.xml
+++ b/sandbox/prototype/exec/java-exec/src/test/resources/logback.xml
@@ -21,7 +21,7 @@
</logger>
<root>
- <level value="error" />
+ <level value="debug" />
<appender-ref ref="STDOUT" />
</root>