aboutsummaryrefslogtreecommitdiff
path: root/exec/java-exec/src/main
diff options
context:
space:
mode:
authorJinfeng Ni <jni@maprtech.com>2014-06-18 07:11:54 -0700
committerJacques Nadeau <jacques@apache.org>2014-06-20 10:54:50 -0700
commit43bb57e758495d6c3e47e29b27e1f97b9f81f268 (patch)
tree8b61dcd5db9b4f7340348478271617487a628083 /exec/java-exec/src/main
parenta314c824ba99edf0c29b004c121904847bab2c15 (diff)
DRILL-1044: Optimize boolean and/or operators by short-circuit and fast-success / fast-fail approach.
Diffstat (limited to 'exec/java-exec/src/main')
-rw-r--r--exec/java-exec/src/main/codegen/templates/CastDateDate.java3
-rw-r--r--exec/java-exec/src/main/codegen/templates/CastDateVarChar.java4
-rw-r--r--exec/java-exec/src/main/codegen/templates/CastIntervalVarChar.java8
-rw-r--r--exec/java-exec/src/main/codegen/templates/CastVarCharDate.java4
-rw-r--r--exec/java-exec/src/main/codegen/templates/DateIntervalFunctions.java25
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java8
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/expr/DrillFuncHolderExpr.java23
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java51
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java20
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/expr/HiveFuncHolderExpr.java6
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/expr/HoldingContainerExpression.java12
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/expr/ValueVectorReadExpression.java13
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/expr/ValueVectorWriteExpression.java10
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java21
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillAggFuncHolder.java11
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillBooleanOPHolder.java (renamed from exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillSCBooleanOPHolder.java)7
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java9
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillSimpleFuncHolder.java10
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java6
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/filter/ReturnValueExpression.java7
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java18
21 files changed, 227 insertions, 49 deletions
diff --git a/exec/java-exec/src/main/codegen/templates/CastDateDate.java b/exec/java-exec/src/main/codegen/templates/CastDateDate.java
index 821323b30..93edd5ad5 100644
--- a/exec/java-exec/src/main/codegen/templates/CastDateDate.java
+++ b/exec/java-exec/src/main/codegen/templates/CastDateDate.java
@@ -30,6 +30,7 @@ import io.netty.buffer.ByteBuf;
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;
@@ -41,7 +42,7 @@ import org.joda.time.DateMidnight;
import org.apache.drill.exec.expr.fn.impl.DateUtility;
@SuppressWarnings("unused")
-@FunctionTemplate(name = "cast${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls=NullHandling.NULL_IF_NULL)
+@FunctionTemplate(name = "cast${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls=NullHandling.NULL_IF_NULL, costCategory=FunctionCostCategory.COMPLEX)
public class Cast${type.from}To${type.to} implements DrillSimpleFunc {
@Param ${type.from}Holder in;
diff --git a/exec/java-exec/src/main/codegen/templates/CastDateVarChar.java b/exec/java-exec/src/main/codegen/templates/CastDateVarChar.java
index 5b7ed6d72..e2fd9d59f 100644
--- a/exec/java-exec/src/main/codegen/templates/CastDateVarChar.java
+++ b/exec/java-exec/src/main/codegen/templates/CastDateVarChar.java
@@ -32,6 +32,7 @@ import io.netty.buffer.ByteBuf;
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;
@@ -44,7 +45,8 @@ import org.joda.time.DateMidnight;
import org.apache.drill.exec.expr.fn.impl.DateUtility;
@SuppressWarnings("unused")
-@FunctionTemplate(name = "cast${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls=NullHandling.NULL_IF_NULL)
+@FunctionTemplate(name = "cast${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls=NullHandling.NULL_IF_NULL,
+ costCategory = FunctionCostCategory.COMPLEX)
public class Cast${type.from}To${type.to} implements DrillSimpleFunc {
@Param ${type.from}Holder in;
diff --git a/exec/java-exec/src/main/codegen/templates/CastIntervalVarChar.java b/exec/java-exec/src/main/codegen/templates/CastIntervalVarChar.java
index 19adb27bf..4c88fccfd 100644
--- a/exec/java-exec/src/main/codegen/templates/CastIntervalVarChar.java
+++ b/exec/java-exec/src/main/codegen/templates/CastIntervalVarChar.java
@@ -31,6 +31,7 @@ import io.netty.buffer.ByteBuf;
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;
@@ -98,10 +99,12 @@ public class Cast${type.from}To${type.to} implements DrillSimpleFunc {
package org.apache.drill.exec.expr.fn.impl.gcast;
+
import io.netty.buffer.ByteBuf;
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;
@@ -150,10 +153,12 @@ public class Cast${type.from}To${type.to} implements DrillSimpleFunc {
package org.apache.drill.exec.expr.fn.impl.gcast;
+
import io.netty.buffer.ByteBuf;
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;
@@ -166,7 +171,8 @@ import org.joda.time.DateMidnight;
import org.apache.drill.exec.expr.fn.impl.DateUtility;
@SuppressWarnings("unused")
-@FunctionTemplate(name = "cast${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls=NullHandling.NULL_IF_NULL)
+@FunctionTemplate(name = "cast${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls=NullHandling.NULL_IF_NULL,
+ costCategory = FunctionCostCategory.COMPLEX)
public class Cast${type.from}To${type.to} implements DrillSimpleFunc {
@Param ${type.from}Holder in;
diff --git a/exec/java-exec/src/main/codegen/templates/CastVarCharDate.java b/exec/java-exec/src/main/codegen/templates/CastVarCharDate.java
index 5a3127a4c..e2e11434b 100644
--- a/exec/java-exec/src/main/codegen/templates/CastVarCharDate.java
+++ b/exec/java-exec/src/main/codegen/templates/CastVarCharDate.java
@@ -30,6 +30,7 @@ import io.netty.buffer.ByteBuf;
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;
@@ -41,7 +42,8 @@ import org.joda.time.DateMidnight;
import org.apache.drill.exec.expr.fn.impl.DateUtility;
@SuppressWarnings("unused")
-@FunctionTemplate(names = {"cast${type.to?upper_case}", "${type.alias}"}, scope = FunctionTemplate.FunctionScope.SIMPLE, nulls=NullHandling.NULL_IF_NULL)
+@FunctionTemplate(names = {"cast${type.to?upper_case}", "${type.alias}"}, scope = FunctionTemplate.FunctionScope.SIMPLE, nulls=NullHandling.NULL_IF_NULL,
+ costCategory = FunctionCostCategory.COMPLEX)
public class Cast${type.from}To${type.to} implements DrillSimpleFunc {
@Param ${type.from}Holder in;
diff --git a/exec/java-exec/src/main/codegen/templates/DateIntervalFunctions.java b/exec/java-exec/src/main/codegen/templates/DateIntervalFunctions.java
index a4bea61ac..b518c4432 100644
--- a/exec/java-exec/src/main/codegen/templates/DateIntervalFunctions.java
+++ b/exec/java-exec/src/main/codegen/templates/DateIntervalFunctions.java
@@ -27,10 +27,9 @@
package org.apache.drill.exec.expr.fn.impl;
-import javax.xml.ws.Holder;
-
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;
@@ -191,6 +190,7 @@ 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;
@@ -200,7 +200,8 @@ import org.apache.drill.exec.record.RecordBatch;
@SuppressWarnings("unused")
public class GCompare${type.name}Functions {
- @FunctionTemplate(name = "compare_to", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL)
+ @FunctionTemplate(name = "compare_to", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL,
+ costCategory = FunctionCostCategory.COMPLEX)
public static class GCCompare${type.name} implements DrillSimpleFunc {
@Param ${type.name}Holder left;
@@ -220,7 +221,8 @@ public class GCompare${type.name}Functions {
}
}
- @FunctionTemplate(name = "less_than", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL)
+ @FunctionTemplate(name = "less_than", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL,
+ costCategory = FunctionCostCategory.COMPLEX)
public static class LessThan${type.name} implements DrillSimpleFunc {
@Param ${type.name}Holder left;
@@ -241,7 +243,8 @@ public class GCompare${type.name}Functions {
}
}
- @FunctionTemplate(name = "less_than_or_equal_to", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL)
+ @FunctionTemplate(name = "less_than_or_equal_to", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL,
+ costCategory = FunctionCostCategory.COMPLEX)
public static class LessThanE${type.name} implements DrillSimpleFunc {
@Param ${type.name}Holder left;
@@ -262,7 +265,8 @@ public class GCompare${type.name}Functions {
}
}
- @FunctionTemplate(name = "greater_than", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL)
+ @FunctionTemplate(name = "greater_than", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL,
+ costCategory = FunctionCostCategory.COMPLEX)
public static class GreaterThan${type.name} implements DrillSimpleFunc {
@Param ${type.name}Holder left;
@@ -283,7 +287,8 @@ public class GCompare${type.name}Functions {
}
}
- @FunctionTemplate(name = "greater_than_or_equal_to", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL)
+ @FunctionTemplate(name = "greater_than_or_equal_to", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL,
+ costCategory = FunctionCostCategory.COMPLEX)
public static class GreaterThanE${type.name} implements DrillSimpleFunc {
@Param ${type.name}Holder left;
@@ -304,7 +309,8 @@ public class GCompare${type.name}Functions {
}
}
- @FunctionTemplate(name = "equal", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL)
+ @FunctionTemplate(name = "equal", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL,
+ costCategory = FunctionCostCategory.COMPLEX)
public static class Equals${type.name} implements DrillSimpleFunc {
@Param ${type.name}Holder left;
@@ -324,7 +330,8 @@ public class GCompare${type.name}Functions {
}
}
- @FunctionTemplate(name = "not_equal", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL)
+ @FunctionTemplate(name = "not_equal", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL,
+ costCategory = FunctionCostCategory.COMPLEX)
public static class NotEquals${type.name} implements DrillSimpleFunc {
@Param ${type.name}Holder left;
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java
index 489f62310..c65951de5 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java
@@ -22,6 +22,7 @@ import java.util.IdentityHashMap;
import java.util.List;
import java.util.Set;
+import org.apache.drill.common.expression.BooleanOperator;
import org.apache.drill.common.expression.CastExpression;
import org.apache.drill.common.expression.ConvertExpression;
import org.apache.drill.common.expression.FunctionCall;
@@ -108,7 +109,12 @@ public class ConstantExpressionIdentifier implements ExprVisitor<Boolean, Identi
public Boolean visitFunctionHolderExpression(FunctionHolderExpression holder, IdentityHashMap<LogicalExpression, Object> value) throws RuntimeException {
return checkChildren(holder, value, !holder.isAggregating() && !holder.isRandom());
}
-
+
+ @Override
+ public Boolean visitBooleanOperator(BooleanOperator op, IdentityHashMap<LogicalExpression, Object> value) throws RuntimeException {
+ return checkChildren(op, value, true);
+ }
+
@Override
public Boolean visitIfExpression(IfExpression ifExpr, IdentityHashMap<LogicalExpression, Object> value){
return checkChildren(ifExpr, value, true);
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/DrillFuncHolderExpr.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/DrillFuncHolderExpr.java
index f164bd84a..0341c457e 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/DrillFuncHolderExpr.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/DrillFuncHolderExpr.java
@@ -71,4 +71,27 @@ public class DrillFuncHolderExpr extends FunctionHolderExpression implements Ite
public boolean isComplexWriterFuncHolder() {
return holder instanceof DrillComplexWriterFuncHolder;
}
+
+ @Override
+ public int getSelfCost() {
+ return holder.getCostCategory();
+ }
+
+ @Override
+ public int getCumulativeCost() {
+ int cost = this.getSelfCost();
+
+ for (LogicalExpression arg : this.args) {
+ cost += arg.getCumulativeCost();
+ }
+
+ return cost;
+ }
+
+ @Override
+ public DrillFuncHolderExpr copy(List<LogicalExpression> args) {
+ return new DrillFuncHolderExpr(this.nameUsed, this.holder, args, this.getPosition());
+ }
+
}
+
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 d65e61891..f2019b837 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
@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Set;
import org.apache.commons.io.input.NullReader;
+import org.apache.drill.common.expression.BooleanOperator;
import org.apache.drill.common.expression.CastExpression;
import org.apache.drill.common.expression.ConvertExpression;
import org.apache.drill.common.expression.FunctionCall;
@@ -55,7 +56,7 @@ import org.apache.drill.exec.compile.sig.ConstantExpressionIdentifier;
import org.apache.drill.exec.expr.ClassGenerator.BlockType;
import org.apache.drill.exec.expr.ClassGenerator.HoldingContainer;
import org.apache.drill.exec.expr.fn.DrillFuncHolder;
-import org.apache.drill.exec.expr.fn.DrillSCBooleanOPHolder;
+import org.apache.drill.exec.expr.fn.DrillBooleanOPHolder;
import org.apache.drill.exec.expr.fn.FunctionImplementationRegistry;
import org.apache.drill.exec.expr.fn.HiveFuncHolder;
import org.apache.drill.exec.physical.impl.filter.ReturnValueExpression;
@@ -97,6 +98,18 @@ public class EvaluationVisitor {
}
@Override
+ 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);
+ } 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 {
// TODO: hack: (Drill/Hive)FuncHolderExpr reference classes in exec so
@@ -106,13 +119,6 @@ public class EvaluationVisitor {
if (holderExpr instanceof DrillFuncHolderExpr) {
DrillFuncHolder holder = ((DrillFuncHolderExpr) holderExpr).getHolder();
- if (holder instanceof DrillSCBooleanOPHolder && holderExpr.getName().equals("booleanAnd")) {
- return visitBooleanAnd(holderExpr, generator);
- }
-
- if (holder instanceof DrillSCBooleanOPHolder && holderExpr.getName().equals("booleanOr")) {
- return visitBooleanOr(holderExpr, generator);
- }
JVar[] workspaceVars = holder.renderStart(generator, null);
@@ -603,10 +609,10 @@ public class EvaluationVisitor {
return fc.accept(this, value);
}
- private HoldingContainer visitBooleanAnd(FunctionHolderExpression holderExpr,
+ private HoldingContainer visitBooleanAnd(BooleanOperator op,
ClassGenerator<?> generator) {
- HoldingContainer out = generator.declare(holderExpr.getMajorType());
+ HoldingContainer out = generator.declare(op.getMajorType());
JLabel label = generator.getEvalBlockLabel("AndOP");
JBlock eval = generator.getEvalBlock().block(); // enter into nested block
@@ -623,8 +629,8 @@ public class EvaluationVisitor {
// null true null
// null false false
// null null null
- for (int i = 0; i < holderExpr.args.size(); i++) {
- arg = holderExpr.args.get(i).accept(this, generator);
+ for (int i = 0; i < op.args.size(); i++) {
+ arg = op.args.get(i).accept(this, generator);
JBlock earlyExit = null;
if (arg.isOptional()) {
@@ -665,10 +671,10 @@ public class EvaluationVisitor {
return out;
}
- private HoldingContainer visitBooleanOr(FunctionHolderExpression holderExpr,
+ private HoldingContainer visitBooleanOr(BooleanOperator op,
ClassGenerator<?> generator) {
- HoldingContainer out = generator.declare(holderExpr.getMajorType());
+ HoldingContainer out = generator.declare(op.getMajorType());
JLabel label = generator.getEvalBlockLabel("OrOP");
JBlock eval = generator.getEvalBlock().block();
@@ -686,8 +692,8 @@ public class EvaluationVisitor {
// null false null
// null null null
- for (int i = 0; i < holderExpr.args.size(); i++) {
- arg = holderExpr.args.get(i).accept(this, generator);
+ for (int i = 0; i < op.args.size(); i++) {
+ arg = op.args.get(i).accept(this, generator);
JBlock earlyExit = null;
if (arg.isOptional()) {
@@ -762,6 +768,19 @@ public class EvaluationVisitor {
}
@Override
+ public HoldingContainer visitBooleanOperator(BooleanOperator e, ClassGenerator<?> generator)
+ throws RuntimeException {
+ if (constantBoundaries.contains(e)) {
+ generator.getMappingSet().enterConstant();
+ HoldingContainer c = super.visitBooleanOperator(e, generator);
+ return renderConstantExpression(generator, c);
+ } else if (generator.getMappingSet().isWithinConstant()) {
+ return super.visitBooleanOperator(e, generator).setConstant(true);
+ } else {
+ return super.visitBooleanOperator(e, generator);
+ }
+ }
+ @Override
public HoldingContainer visitIfExpression(IfExpression e, ClassGenerator<?> generator) throws RuntimeException {
if (constantBoundaries.contains(e)) {
generator.getMappingSet().enterConstant();
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
index 18609f864..4e10d2011 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
@@ -26,6 +26,7 @@ import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
+import org.apache.drill.common.expression.BooleanOperator;
import org.apache.drill.common.expression.CastExpression;
import org.apache.drill.common.expression.ConvertExpression;
import org.apache.drill.common.expression.ErrorCollector;
@@ -57,6 +58,7 @@ import org.apache.drill.common.expression.ValueExpressions.IntExpression;
import org.apache.drill.common.expression.ValueExpressions.QuotedString;
import org.apache.drill.common.expression.fn.CastFunctions;
import org.apache.drill.common.expression.visitors.AbstractExprVisitor;
+import org.apache.drill.common.expression.visitors.ConditionalExprOptimizer;
import org.apache.drill.common.expression.visitors.ExpressionValidator;
import org.apache.drill.common.types.TypeProtos;
import org.apache.drill.common.types.TypeProtos.DataMode;
@@ -89,6 +91,11 @@ public class ExpressionTreeMaterializer {
public static LogicalExpression materialize(LogicalExpression expr, VectorAccessible batch, ErrorCollector errorCollector, FunctionImplementationRegistry registry,
boolean allowComplexWriterExpr) {
LogicalExpression out = expr.accept(new MaterializeVisitor(batch, errorCollector, allowComplexWriterExpr), registry);
+
+ if (!errorCollector.hasErrors()) {
+ out = out.accept(ConditionalExprOptimizer.INSTANCE, null);
+ }
+
if(out instanceof NullExpression){
return new TypedNullConstant(Types.optional(MinorType.INT));
}else{
@@ -126,6 +133,19 @@ public class ExpressionTreeMaterializer {
}
@Override
+ public LogicalExpression visitBooleanOperator(BooleanOperator op, FunctionImplementationRegistry registry) {
+ List<LogicalExpression> args = Lists.newArrayList();
+ for (int i = 0; i < op.args.size(); ++i) {
+ LogicalExpression newExpr = op.args.get(i).accept(this, registry);
+ assert newExpr != null : String.format("Materialization of %s return a null expression.", op.args.get(i));
+ args.add(newExpr);
+ }
+
+ //replace with a new function call, since its argument could be changed.
+ return new BooleanOperator(op.getName(), args, op.getPosition());
+ }
+
+ @Override
public LogicalExpression visitFunctionCall(FunctionCall call, FunctionImplementationRegistry registry) {
List<LogicalExpression> args = Lists.newArrayList();
for (int i = 0; i < call.args.size(); ++i) {
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/HiveFuncHolderExpr.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/HiveFuncHolderExpr.java
index afcd9cd04..c765d3977 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/HiveFuncHolderExpr.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/HiveFuncHolderExpr.java
@@ -66,4 +66,10 @@ public class HiveFuncHolderExpr extends FunctionHolderExpression implements Iter
public boolean isRandom() {
return holder.isRandom();
}
+
+ @Override
+ public HiveFuncHolderExpr copy(List<LogicalExpression> args) {
+ return new HiveFuncHolderExpr(this.nameUsed, this.holder, args, this.getPosition());
+ }
+
}
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/HoldingContainerExpression.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/HoldingContainerExpression.java
index fd26e860d..45051b976 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/HoldingContainerExpression.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/HoldingContainerExpression.java
@@ -25,6 +25,7 @@ import org.apache.drill.common.expression.visitors.ExprVisitor;
import org.apache.drill.common.types.TypeProtos.MajorType;
import org.apache.drill.exec.expr.ClassGenerator.HoldingContainer;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Iterators;
public class HoldingContainerExpression implements LogicalExpression{
@@ -60,4 +61,15 @@ public class HoldingContainerExpression implements LogicalExpression{
public ExpressionPosition getPosition() {
return ExpressionPosition.UNKNOWN;
}
+
+ @Override
+ public int getSelfCost() {
+ return 0; // TODO
+ }
+
+ @Override
+ public int getCumulativeCost() {
+ return 0; // TODO
+ }
+
}
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ValueVectorReadExpression.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ValueVectorReadExpression.java
index 6e2809aa8..f8236d9a8 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ValueVectorReadExpression.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ValueVectorReadExpression.java
@@ -78,6 +78,15 @@ public class ValueVectorReadExpression implements LogicalExpression{
public Iterator<LogicalExpression> iterator() {
return Iterators.emptyIterator();
}
-
-
+
+ @Override
+ public int getSelfCost() {
+ return 0; // TODO
+ }
+
+ @Override
+ public int getCumulativeCost() {
+ return 0; // TODO
+ }
+
}
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ValueVectorWriteExpression.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ValueVectorWriteExpression.java
index 02277afe5..d2770578b 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ValueVectorWriteExpression.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ValueVectorWriteExpression.java
@@ -78,5 +78,15 @@ public class ValueVectorWriteExpression implements LogicalExpression {
return Iterators.singletonIterator(child);
}
+ @Override
+ public int getSelfCost() {
+ return 0; // TODO
+ }
+
+ @Override
+ public int getCumulativeCost() {
+ return 0; // TODO
+ }
+
}
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
index b364a4a75..be43d38e7 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
@@ -46,6 +46,8 @@ public @interface FunctionTemplate {
boolean isBinaryCommutative() default false;
boolean isRandom() default false;
+ FunctionCostCategory costCategory() default FunctionCostCategory.SIMPLE;
+
public static enum NullHandling {
INTERNAL, NULL_IF_NULL;
}
@@ -64,4 +66,23 @@ public @interface FunctionTemplate {
DECIMAL_ZERO_SCALE,
SC_BOOLEAN_OPERATOR
}
+
+ public static enum FunctionCostCategory {
+ SIMPLE(1), MEDIUM(3), COMPLEX(5);
+
+ private final int value;
+
+ private FunctionCostCategory(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return this.value;
+ }
+
+ public static FunctionCostCategory getDefault() {
+ return SIMPLE;
+ }
+
+ }
}
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 48c35f2e4..efe3ee318 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
@@ -25,6 +25,7 @@ import org.apache.drill.common.types.Types;
import org.apache.drill.exec.expr.ClassGenerator;
import org.apache.drill.exec.expr.ClassGenerator.BlockType;
import org.apache.drill.exec.expr.ClassGenerator.HoldingContainer;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionCostCategory;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
import org.apache.drill.exec.record.TypedFieldId;
@@ -48,12 +49,18 @@ class DrillAggFuncHolder extends DrillFuncHolder{
private final String add;
private final String output;
private final String cleanup;
-
+
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) {
+ 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) {
super(scope, nullHandling, isBinaryCommutative, isRandom,
- registeredNames, parameters, returnValue, workspaceVars, methods, imports);
+ registeredNames, parameters, returnValue, workspaceVars, methods, imports, costCategory);
Preconditions.checkArgument(nullHandling == NullHandling.INTERNAL, "An aggregation function is required to do its own null handling.");
setup = methods.get("setup");
reset = methods.get("reset");
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillSCBooleanOPHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillBooleanOPHolder.java
index d6d7037d5..9032d37b6 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillSCBooleanOPHolder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillBooleanOPHolder.java
@@ -21,15 +21,16 @@ package org.apache.drill.exec.expr.fn;
import java.util.List;
import java.util.Map;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionCostCategory;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
-public class DrillSCBooleanOPHolder extends DrillSimpleFuncHolder{
+public class DrillBooleanOPHolder extends DrillSimpleFuncHolder{
- public DrillSCBooleanOPHolder(FunctionScope scope, NullHandling nullHandling, boolean isBinaryCommutative, boolean isRandom,
+ public DrillBooleanOPHolder(FunctionScope scope, NullHandling nullHandling, boolean isBinaryCommutative, boolean isRandom,
String[] registeredNames, ValueReference[] parameters, ValueReference returnValue, WorkspaceReference[] workspaceVars,
Map<String, String> methods, List<String> imports) {
- super(scope, nullHandling, isBinaryCommutative, isRandom, registeredNames, parameters, returnValue, workspaceVars, methods, imports);
+ super(scope, nullHandling, isBinaryCommutative, isRandom, registeredNames, parameters, returnValue, workspaceVars, methods, imports, FunctionCostCategory.getDefault());
}
}
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 fc8dc0041..f3c1e130e 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
@@ -31,6 +31,7 @@ import org.apache.drill.exec.expr.ClassGenerator.BlockType;
import org.apache.drill.exec.expr.ClassGenerator.HoldingContainer;
import org.apache.drill.exec.expr.TypeHelper;
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.FunctionScope;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
import org.apache.drill.exec.vector.complex.impl.NullableBigIntSingularReaderImpl;
@@ -51,6 +52,7 @@ public abstract class DrillFuncHolder {
protected final FunctionTemplate.FunctionScope scope;
protected final FunctionTemplate.NullHandling nullHandling;
+ protected final FunctionTemplate.FunctionCostCategory costCategory;
protected final boolean isBinaryCommutative;
protected final boolean isRandom;
protected final String[] registeredNames;
@@ -62,7 +64,7 @@ public abstract class DrillFuncHolder {
public DrillFuncHolder(FunctionScope scope, NullHandling nullHandling, boolean isBinaryCommutative, boolean isRandom,
String[] registeredNames, ValueReference[] parameters, ValueReference returnValue,
- WorkspaceReference[] workspaceVars, Map<String, String> methods, List<String> imports) {
+ WorkspaceReference[] workspaceVars, Map<String, String> methods, List<String> imports, FunctionCostCategory costCategory) {
super();
this.scope = scope;
this.nullHandling = nullHandling;
@@ -74,6 +76,7 @@ public abstract class DrillFuncHolder {
this.parameters = parameters;
this.returnValue = returnValue;
this.imports = ImmutableList.copyOf(imports);
+ this.costCategory = costCategory;
}
public List<String> getImports() {
@@ -223,6 +226,10 @@ public abstract class DrillFuncHolder {
return registeredNames;
}
+ public int getCostCategory() {
+ return this.costCategory.getValue();
+ }
+
@Override
public String toString() {
final int maxLen = 10;
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillSimpleFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillSimpleFuncHolder.java
index 01fc514d2..53df02ded 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillSimpleFuncHolder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillSimpleFuncHolder.java
@@ -27,6 +27,7 @@ import org.apache.drill.common.types.TypeProtos.MajorType;
import org.apache.drill.exec.expr.ClassGenerator;
import org.apache.drill.exec.expr.ClassGenerator.BlockType;
import org.apache.drill.exec.expr.ClassGenerator.HoldingContainer;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionCostCategory;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
@@ -46,11 +47,16 @@ class DrillSimpleFuncHolder extends DrillFuncHolder{
private final String resetBody;
private final String cleanupBody;
-
public DrillSimpleFuncHolder(FunctionScope scope, NullHandling nullHandling, boolean isBinaryCommutative, boolean isRandom,
String[] registeredNames, ValueReference[] parameters, ValueReference returnValue, WorkspaceReference[] workspaceVars,
Map<String, String> methods, List<String> imports) {
- super(scope, nullHandling, isBinaryCommutative, isRandom, registeredNames, parameters, returnValue, workspaceVars, methods, imports);
+ this(scope, nullHandling, isBinaryCommutative, isRandom, registeredNames, parameters, returnValue, workspaceVars, methods, imports, FunctionCostCategory.getDefault());
+ }
+
+ public DrillSimpleFuncHolder(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) {
+ super(scope, nullHandling, isBinaryCommutative, isRandom, registeredNames, parameters, returnValue, workspaceVars, methods, imports, costCategory);
setupBody = methods.get("setup");
evalBody = methods.get("eval");
resetBody = methods.get("reset");
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 2107421e5..8328549f3 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
@@ -220,7 +220,7 @@ public class FunctionConverter {
switch(template.scope()){
case POINT_AGGREGATE:
return new DrillAggFuncHolder(template.scope(), template.nulls(), template.isBinaryCommutative(),
- template.isRandom(), registeredNames, ps, outputField, works, methods, imports);
+ template.isRandom(), registeredNames, ps, outputField, works, methods, imports, template.costCategory());
case DECIMAL_AGGREGATE:
return new DrillDecimalAggFuncHolder(template.scope(), template.nulls(), template.isBinaryCommutative(),
template.isRandom(), registeredNames, ps, outputField, works, methods, imports);
@@ -234,9 +234,9 @@ public class FunctionConverter {
return new DrillSimpleFuncHolder(template.scope(), template.nulls(),
template.isBinaryCommutative(),
template.isRandom(), registeredNames,
- ps, outputField, works, methods, imports);
+ ps, outputField, works, methods, imports, template.costCategory());
case SC_BOOLEAN_OPERATOR:
- return new DrillSCBooleanOPHolder(template.scope(), template.nulls(),
+ return new DrillBooleanOPHolder(template.scope(), template.nulls(),
template.isBinaryCommutative(),
template.isRandom(), registeredNames,
ps, outputField, works, methods, imports);
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/filter/ReturnValueExpression.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/filter/ReturnValueExpression.java
index 4ec4b096e..1aa300635 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/filter/ReturnValueExpression.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/filter/ReturnValueExpression.java
@@ -70,5 +70,12 @@ public class ReturnValueExpression implements LogicalExpression{
return returnTrueOnOne;
}
+ public int getSelfCost() {
+ throw new UnsupportedOperationException(String.format("The type of %s doesn't currently support LogicalExpression.getSelfCost().", this.getClass().getCanonicalName()));
+ }
+
+ public int getCumulativeCost() {
+ throw new UnsupportedOperationException(String.format("The type of %s doesn't currently support LogicalExpression.getCumulativeCost().", this.getClass().getCanonicalName()));
+ }
}
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
index dd3037887..21ff421a5 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
@@ -98,13 +98,19 @@ public class DrillOptiq {
for(RexNode r : call.getOperands()){
args.add(r.accept(this));
}
- args = Lists.reverse(args);
- LogicalExpression lastArg = args.get(0);
- for(int i = 1; i < args.size(); i++){
- lastArg = FunctionCallFactory.createExpression(funcName, Lists.newArrayList(args.get(i), lastArg));
- }
- return lastArg;
+ if (FunctionCallFactory.isBooleanOperator(funcName)) {
+ LogicalExpression func = FunctionCallFactory.createBooleanOperator(funcName, args);
+ return func;
+ } else {
+ args = Lists.reverse(args);
+ LogicalExpression lastArg = args.get(0);
+ for(int i = 1; i < args.size(); i++){
+ lastArg = FunctionCallFactory.createExpression(funcName, Lists.newArrayList(args.get(i), lastArg));
+ }
+
+ return lastArg;
+ }
case FUNCTION:
case FUNCTION_ID:
logger.debug("Function");