You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ja...@apache.org on 2014/10/04 07:28:35 UTC
git commit: PHOENIX-1030 Change Expression.isDeterministic() to
return a enum of values ALWAYS, PER_STATEMENT, PER_ROW (Thomas D'Silva)
Repository: phoenix
Updated Branches:
refs/heads/master 340280b2e -> b1be0f8b8
PHOENIX-1030 Change Expression.isDeterministic() to return a enum of values ALWAYS, PER_STATEMENT, PER_ROW (Thomas D'Silva)
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/b1be0f8b
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/b1be0f8b
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/b1be0f8b
Branch: refs/heads/master
Commit: b1be0f8b8b5921bd6d0a91f549294eea7f27da95
Parents: 340280b
Author: James Taylor <jt...@salesforce.com>
Authored: Fri Oct 3 22:30:45 2014 -0700
Committer: James Taylor <jt...@salesforce.com>
Committed: Fri Oct 3 22:33:34 2014 -0700
----------------------------------------------------------------------
.../phoenix/compile/CreateTableCompiler.java | 4 +-
.../phoenix/compile/ExpressionCompiler.java | 64 ++++++-------
.../apache/phoenix/compile/SequenceManager.java | 5 +-
.../apache/phoenix/compile/UpsertCompiler.java | 7 +-
.../apache/phoenix/compile/WhereCompiler.java | 3 +-
.../apache/phoenix/compile/WhereOptimizer.java | 3 +-
.../apache/phoenix/execute/HashJoinPlan.java | 3 +-
.../phoenix/expression/AndExpression.java | 6 +-
.../expression/BaseCompoundExpression.java | 11 +--
.../phoenix/expression/BaseExpression.java | 6 +-
.../expression/ComparisonExpression.java | 34 +++----
.../expression/CurrentDateTimeFunction.java | 4 +-
.../apache/phoenix/expression/Determinism.java | 19 ++++
.../apache/phoenix/expression/Expression.java | 6 +-
.../phoenix/expression/InListExpression.java | 4 +-
.../phoenix/expression/IsNullExpression.java | 4 +-
.../phoenix/expression/LiteralExpression.java | 99 +++++++++++---------
.../phoenix/expression/NotExpression.java | 4 +-
.../expression/function/AggregateFunction.java | 5 +-
.../function/CeilDecimalExpression.java | 8 +-
.../expression/function/CoalesceFunction.java | 3 +-
.../function/CountAggregateFunction.java | 4 +-
.../function/FloorDecimalExpression.java | 8 +-
.../function/RoundDateExpression.java | 5 +-
.../function/RoundDecimalExpression.java | 6 +-
.../function/SingleAggregateFunction.java | 4 +-
.../apache/phoenix/parse/FunctionParseNode.java | 10 +-
.../org/apache/phoenix/util/ExpressionUtil.java | 28 +++---
.../phoenix/expression/DeterminismTest.java | 37 ++++++++
29 files changed, 248 insertions(+), 156 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java
index 7794416..7a8ebf4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java
@@ -32,6 +32,7 @@ import org.apache.phoenix.exception.SQLExceptionInfo;
import org.apache.phoenix.execute.MutationState;
import org.apache.phoenix.expression.AndExpression;
import org.apache.phoenix.expression.ComparisonExpression;
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.IsNullExpression;
import org.apache.phoenix.expression.KeyValueColumnExpression;
@@ -257,7 +258,8 @@ public class CreateTableCompiler {
@Override
public Iterator<Expression> visitEnter(ComparisonExpression node) {
- if (node.getFilterOp() == CompareOp.EQUAL && node.getChildren().get(1).isStateless() && node.getChildren().get(1).isDeterministic()) {
+ if (node.getFilterOp() == CompareOp.EQUAL && node.getChildren().get(1).isStateless()
+ && node.getChildren().get(1).getDeterminism() == Determinism.ALWAYS ) {
return Iterators.singletonIterator(node.getChildren().get(0));
}
return super.visitEnter(node);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
index 1511539..573cb55 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
@@ -41,6 +41,7 @@ import org.apache.phoenix.expression.DecimalAddExpression;
import org.apache.phoenix.expression.DecimalDivideExpression;
import org.apache.phoenix.expression.DecimalMultiplyExpression;
import org.apache.phoenix.expression.DecimalSubtractExpression;
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.DoubleAddExpression;
import org.apache.phoenix.expression.DoubleDivideExpression;
import org.apache.phoenix.expression.DoubleMultiplyExpression;
@@ -226,7 +227,7 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
private Expression orExpression(List<Expression> children) throws SQLException {
Iterator<Expression> iterator = children.iterator();
- boolean isDeterministic = true;
+ Determinism determinism = Determinism.ALWAYS;
while (iterator.hasNext()) {
Expression child = iterator.next();
if (child.getDataType() != PDataType.BOOLEAN) {
@@ -238,10 +239,10 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
if (LiteralExpression.isTrue(child)) {
return child;
}
- isDeterministic &= child.isDeterministic();
+ determinism = determinism.combine(child.getDeterminism());
}
if (children.size() == 0) {
- return LiteralExpression.newConstant(true, isDeterministic);
+ return LiteralExpression.newConstant(true, determinism);
}
if (children.size() == 1) {
return children.get(0);
@@ -395,12 +396,12 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
@Override
public Expression visit(BindParseNode node) throws SQLException {
Object value = context.getBindManager().getBindValue(node);
- return LiteralExpression.newConstant(value, true);
+ return LiteralExpression.newConstant(value, Determinism.ALWAYS);
}
@Override
public Expression visit(LiteralParseNode node) throws SQLException {
- return LiteralExpression.newConstant(node.getValue(), node.getType(), true);
+ return LiteralExpression.newConstant(node.getValue(), node.getType(), Determinism.ALWAYS);
}
@Override
@@ -420,13 +421,12 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
return true;
}
- private static boolean isDeterministic(List<Expression> l) {
+ private static Determinism getDeterminism(List<Expression> l) {
+ Determinism determinism = Determinism.ALWAYS;
for (Expression e : l) {
- if (!e.isDeterministic()) {
- return false;
- }
+ determinism.combine(e.getDeterminism());
}
- return true;
+ return determinism;
}
@Override
@@ -442,7 +442,7 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
ImmutableBytesWritable ptr = context.getTempPtr();
int index = caseExpression.evaluateIndexOf(null, ptr);
if (index < 0) {
- return LiteralExpression.newConstant(null, isDeterministic(l));
+ return LiteralExpression.newConstant(null, getDeterminism(l));
}
return caseExpression.getChildren().get(index);
}
@@ -474,7 +474,7 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
if (rhs instanceof LiteralExpression) {
String pattern = (String)((LiteralExpression)rhs).getValue();
if (pattern == null || pattern.length() == 0) {
- return LiteralExpression.newConstant(null, rhs.isDeterministic());
+ return LiteralExpression.newConstant(null, rhs.getDeterminism());
}
// TODO: for pattern of '%' optimize to strlength(lhs) > 0
// We can't use lhs IS NOT NULL b/c if lhs is NULL we need
@@ -483,19 +483,19 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
// Can't possibly be as long as the constant, then FALSE
Integer lhsMaxLength = lhs.getMaxLength();
if (lhsMaxLength != null && lhsMaxLength < index) {
- return LiteralExpression.newConstant(false, rhs.isDeterministic());
+ return LiteralExpression.newConstant(false, rhs.getDeterminism());
}
if (index == -1) {
String rhsLiteral = LikeExpression.unescapeLike(pattern);
if (lhsMaxLength != null && lhsMaxLength != rhsLiteral.length()) {
- return LiteralExpression.newConstant(false, rhs.isDeterministic());
+ return LiteralExpression.newConstant(false, rhs.getDeterminism());
}
if (node.getLikeType() == LikeType.CASE_SENSITIVE) {
CompareOp op = node.isNegate() ? CompareOp.NOT_EQUAL : CompareOp.EQUAL;
if (pattern.equals(rhsLiteral)) {
return new ComparisonExpression(op, children);
} else {
- rhs = LiteralExpression.newConstant(rhsLiteral, PDataType.CHAR, rhs.isDeterministic());
+ rhs = LiteralExpression.newConstant(rhsLiteral, PDataType.CHAR, rhs.getDeterminism());
return new ComparisonExpression(op, Arrays.asList(lhs,rhs));
}
}
@@ -505,9 +505,9 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
if (ExpressionUtil.isConstant(expression)) {
ImmutableBytesWritable ptr = context.getTempPtr();
if (!expression.evaluate(null, ptr)) {
- return LiteralExpression.newConstant(null, expression.isDeterministic());
+ return LiteralExpression.newConstant(null, expression.getDeterminism());
} else {
- return LiteralExpression.newConstant(Boolean.TRUE.equals(PDataType.BOOLEAN.toObject(ptr)) ^ node.isNegate(), expression.isDeterministic());
+ return LiteralExpression.newConstant(Boolean.TRUE.equals(PDataType.BOOLEAN.toObject(ptr)) ^ node.isNegate(), expression.getDeterminism());
}
}
if (node.isNegate()) {
@@ -691,7 +691,7 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
return ExpressionUtil.getConstantExpression(expression, ptr);
}
else if (isNull) {
- return LiteralExpression.newConstant(null, expression.getDataType(), expression.isDeterministic());
+ return LiteralExpression.newConstant(null, expression.getDataType(), expression.getDeterminism());
}
// Otherwise create and return the expression
return wrapGroupByExpression(expression);
@@ -740,11 +740,11 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
@Override
public Expression create(ArithmeticParseNode node, List<Expression> children) throws SQLException {
boolean foundDate = false;
- boolean isDeterministic = true;
+ Determinism determinism = Determinism.ALWAYS;
PDataType theType = null;
for(int i = 0; i < children.size(); i++) {
Expression e = children.get(i);
- isDeterministic &= e.isDeterministic();
+ determinism = determinism.combine(e.getDeterminism());
PDataType type = e.getDataType();
if (type == null) {
continue;
@@ -779,7 +779,7 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
} else if (theType == PDataType.DOUBLE) {
return new DoubleAddExpression(children);
} else if (theType == null) {
- return LiteralExpression.newConstant(null, theType, isDeterministic);
+ return LiteralExpression.newConstant(null, theType, determinism);
} else if (theType == PDataType.TIMESTAMP || theType == PDataType.UNSIGNED_TIMESTAMP) {
return new TimestampAddExpression(children);
} else if (theType.isCoercibleTo(PDataType.DATE)) {
@@ -867,7 +867,7 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
PDataType theType = null;
Expression e1 = children.get(0);
Expression e2 = children.get(1);
- boolean isDeterministic = e1.isDeterministic() && e2.isDeterministic();
+ Determinism determinism = e1.getDeterminism().combine(e2.getDeterminism());
PDataType type1 = e1.getDataType();
PDataType type2 = e2.getDataType();
// TODO: simplify this special case for DATE conversion
@@ -919,7 +919,7 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
// This logic finds the common type to which all child types are coercible
// without losing precision.
Expression e = children.get(i);
- isDeterministic &= e.isDeterministic();
+ determinism = determinism.combine(e.getDeterminism());
PDataType type = e.getDataType();
if (type == null) {
continue;
@@ -952,7 +952,7 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
} else if (theType == PDataType.DOUBLE) {
return new DoubleSubtractExpression(children);
} else if (theType == null) {
- return LiteralExpression.newConstant(null, theType, isDeterministic);
+ return LiteralExpression.newConstant(null, theType, determinism);
} else if (theType == PDataType.TIMESTAMP || theType == PDataType.UNSIGNED_TIMESTAMP) {
return new TimestampSubtractExpression(children);
} else if (theType.isCoercibleTo(PDataType.DATE)) {
@@ -975,10 +975,10 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
@Override
public Expression create(ArithmeticParseNode node, List<Expression> children) throws SQLException {
PDataType theType = null;
- boolean isDeterministic = true;
+ Determinism determinism = Determinism.ALWAYS;
for(int i = 0; i < children.size(); i++) {
Expression e = children.get(i);
- isDeterministic &= e.isDeterministic();
+ determinism = determinism.combine(e.getDeterminism());
PDataType type = e.getDataType();
if (type == null) {
continue;
@@ -1004,7 +1004,7 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
case DOUBLE:
return new DoubleMultiplyExpression( children);
default:
- return LiteralExpression.newConstant(null, theType, isDeterministic);
+ return LiteralExpression.newConstant(null, theType, determinism);
}
}
});
@@ -1036,10 +1036,10 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
@Override
public Expression create(ArithmeticParseNode node, List<Expression> children) throws SQLException {
PDataType theType = null;
- boolean isDeterministic = true;
+ Determinism determinism = Determinism.ALWAYS;
for(int i = 0; i < children.size(); i++) {
Expression e = children.get(i);
- isDeterministic &= e.isDeterministic();
+ determinism = determinism.combine(e.getDeterminism());
PDataType type = e.getDataType();
if (type == null) {
continue;
@@ -1065,7 +1065,7 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
case DOUBLE:
return new DoubleDivideExpression(children);
default:
- return LiteralExpression.newConstant(null, theType, isDeterministic);
+ return LiteralExpression.newConstant(null, theType, determinism);
}
}
});
@@ -1230,11 +1230,11 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
Expression child = children.get(i);
child.evaluate(null, ptr);
Object value = arrayElemDataType.toObject(ptr, child.getDataType(), child.getSortOrder());
- elements[i] = LiteralExpression.newConstant(value, child.getDataType(), child.isDeterministic()).getValue();
+ elements[i] = LiteralExpression.newConstant(value, child.getDataType(), child.getDeterminism()).getValue();
}
Object value = PArrayDataType.instantiatePhoenixArray(arrayElemDataType, elements);
return LiteralExpression.newConstant(value,
- PDataType.fromTypeId(arrayElemDataType.getSqlType() + PDataType.ARRAY_TYPE_BASE), true);
+ PDataType.fromTypeId(arrayElemDataType.getSqlType() + PDataType.ARRAY_TYPE_BASE), Determinism.ALWAYS);
}
return wrapGroupByExpression(arrayExpression);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/compile/SequenceManager.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/SequenceManager.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/SequenceManager.java
index de352b5..9be45a4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/SequenceManager.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/SequenceManager.java
@@ -26,6 +26,7 @@ import java.util.Map;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.phoenix.expression.BaseTerminalExpression;
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.parse.SequenceValueParseNode;
import org.apache.phoenix.parse.TableName;
@@ -202,8 +203,8 @@ public class SequenceManager {
}
@Override
- public boolean isDeterministic() {
- return false;
+ public Determinism getDeterminism() {
+ return Determinism.PER_ROW;
}
@Override
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
index 612f322..3a48a93 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
@@ -42,6 +42,7 @@ import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.exception.SQLExceptionInfo;
import org.apache.phoenix.execute.AggregatePlan;
import org.apache.phoenix.execute.MutationState;
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.LiteralExpression;
import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
@@ -511,7 +512,7 @@ public class UpsertCompiler {
}
// Add literal null for missing PK columns
pos = projectedExpressions.size();
- Expression literalNull = LiteralExpression.newConstant(null, column.getDataType(), true);
+ Expression literalNull = LiteralExpression.newConstant(null, column.getDataType(), Determinism.ALWAYS);
projectedExpressions.add(literalNull);
allColumnsIndexes[pos] = column.getPosition();
}
@@ -812,7 +813,7 @@ public class UpsertCompiler {
if (isTopLevel()) {
context.getBindManager().addParamMetaData(node, column);
Object value = context.getBindManager().getBindValue(node);
- return LiteralExpression.newConstant(value, column.getDataType(), column.getSortOrder(), true);
+ return LiteralExpression.newConstant(value, column.getDataType(), column.getSortOrder(), Determinism.ALWAYS);
}
return super.visit(node);
}
@@ -820,7 +821,7 @@ public class UpsertCompiler {
@Override
public Expression visit(LiteralParseNode node) throws SQLException {
if (isTopLevel()) {
- return LiteralExpression.newConstant(node.getValue(), column.getDataType(), column.getSortOrder(), true);
+ return LiteralExpression.newConstant(node.getValue(), column.getDataType(), column.getSortOrder(), Determinism.ALWAYS);
}
return super.visit(node);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
index 27a4490..51d0ffc 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
@@ -29,6 +29,7 @@ import org.apache.hadoop.hbase.filter.Filter;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.exception.SQLExceptionInfo;
import org.apache.phoenix.expression.AndExpression;
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.KeyValueColumnExpression;
import org.apache.phoenix.expression.LiteralExpression;
@@ -120,7 +121,7 @@ public class WhereCompiler {
Set<Expression> extractedNodes = Sets.<Expression>newHashSet();
WhereExpressionCompiler whereCompiler = new WhereExpressionCompiler(context);
- Expression expression = where == null ? LiteralExpression.newConstant(true,PDataType.BOOLEAN,true) : where.accept(whereCompiler);
+ Expression expression = where == null ? LiteralExpression.newConstant(true,PDataType.BOOLEAN,Determinism.ALWAYS) : where.accept(whereCompiler);
if (whereCompiler.isAggregate()) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.AGGREGATE_IN_WHERE).build().buildException();
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java
index a9908b9..5f652f1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java
@@ -37,6 +37,7 @@ import org.apache.phoenix.expression.BaseExpression.ExpressionComparabilityWrapp
import org.apache.phoenix.expression.BaseTerminalExpression;
import org.apache.phoenix.expression.CoerceExpression;
import org.apache.phoenix.expression.ComparisonExpression;
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.InListExpression;
import org.apache.phoenix.expression.IsNullExpression;
@@ -407,7 +408,7 @@ public class WhereOptimizer {
if (l.size() != node.getChildren().size()) {
if (l.isEmpty()) {
// Don't return null here, because then our defaultReturn will kick in
- return LiteralExpression.newConstant(true, true);
+ return LiteralExpression.newConstant(true, Determinism.ALWAYS);
}
if (l.size() == 1) {
return l.get(0);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
index 7ee242e..6e552d8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
@@ -49,6 +49,7 @@ import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.exception.SQLExceptionInfo;
import org.apache.phoenix.expression.AndExpression;
import org.apache.phoenix.expression.ComparisonExpression;
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.InListExpression;
import org.apache.phoenix.expression.LiteralExpression;
@@ -217,7 +218,7 @@ public class HashJoinPlan implements QueryPlan {
Expression rhsExpression, List<ImmutableBytesWritable> rhsValues,
ImmutableBytesWritable ptr, boolean hasFilters) throws SQLException {
if (rhsValues.isEmpty())
- return LiteralExpression.newConstant(null, PDataType.BOOLEAN, true);
+ return LiteralExpression.newConstant(null, PDataType.BOOLEAN, Determinism.ALWAYS);
PDataType type = rhsExpression.getDataType();
if (!useInClause(hasFilters)) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/AndExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/AndExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/AndExpression.java
index 2806394..e9c2740 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/AndExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/AndExpression.java
@@ -37,7 +37,7 @@ public class AndExpression extends AndOrExpression {
private static final String AND = "AND";
public static Expression create(List<Expression> children) throws SQLException {
- boolean isDeterministic = true;
+ Determinism determinism = Determinism.ALWAYS;
Iterator<Expression> iterator = children.iterator();
while (iterator.hasNext()) {
Expression child = iterator.next();
@@ -50,10 +50,10 @@ public class AndExpression extends AndOrExpression {
if (LiteralExpression.isTrue(child)) {
iterator.remove();
}
- isDeterministic &= child.isDeterministic();
+ determinism.combine(child.getDeterminism());
}
if (children.size() == 0) {
- return LiteralExpression.newConstant(true, isDeterministic);
+ return LiteralExpression.newConstant(true, determinism);
}
if (children.size() == 1) {
return children.get(0);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseCompoundExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseCompoundExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseCompoundExpression.java
index 03df653..bd6161c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseCompoundExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseCompoundExpression.java
@@ -34,7 +34,7 @@ public abstract class BaseCompoundExpression extends BaseExpression {
protected List<Expression> children;
private boolean isNullable;
private boolean isStateless;
- private boolean isDeterministic;
+ private Determinism determinism;
private boolean requiresFinalEvaluation;
public BaseCompoundExpression() {
@@ -48,18 +48,17 @@ public abstract class BaseCompoundExpression extends BaseExpression {
private void init(List<Expression> children) {
this.children = ImmutableList.copyOf(children);
boolean isStateless = true;
- boolean isDeterministic = true;
boolean isNullable = false;
boolean requiresFinalEvaluation = false;
+ this.determinism = Determinism.ALWAYS;
for (int i = 0; i < children.size(); i++) {
Expression child = children.get(i);
isNullable |= child.isNullable();
isStateless &= child.isStateless();
- isDeterministic &= child.isDeterministic();
+ this.determinism = this.determinism.combine(child.getDeterminism());
requiresFinalEvaluation |= child.requiresFinalEvaluation();
}
this.isStateless = isStateless;
- this.isDeterministic = isDeterministic;
this.isNullable = isNullable;
this.requiresFinalEvaluation = requiresFinalEvaluation;
}
@@ -71,8 +70,8 @@ public abstract class BaseCompoundExpression extends BaseExpression {
@Override
- public boolean isDeterministic() {
- return isDeterministic;
+ public Determinism getDeterminism() {
+ return determinism;
}
@Override
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseExpression.java
index fac82a8..8993e37 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseExpression.java
@@ -168,7 +168,7 @@ public abstract class BaseExpression implements Expression {
} else if (lhs == null) {
return rhs;
} else if (rhs == null) {
- return LiteralExpression.newConstant(null, lhs.getDataType(), lhs.isDeterministic());
+ return LiteralExpression.newConstant(null, lhs.getDataType(), lhs.getDeterminism());
} else {
if (rhs.getDataType() != null && lhs.getDataType() != null && !rhs.getDataType().isCastableTo(lhs.getDataType())) {
throw TypeMismatchException.newException(lhs.getDataType(), rhs.getDataType());
@@ -239,8 +239,8 @@ public abstract class BaseExpression implements Expression {
}
@Override
- public boolean isDeterministic() {
- return true;
+ public Determinism getDeterminism() {
+ return Determinism.ALWAYS;
}
@Override
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/ComparisonExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/ComparisonExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/ComparisonExpression.java
index 8e352e6..a1ed221 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/ComparisonExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/ComparisonExpression.java
@@ -133,7 +133,7 @@ public class ComparisonExpression extends BaseCompoundExpression {
} else if(lhsExprDataType != null && rhsExprDataType != null && !lhsExprDataType.isComparableTo(rhsExprDataType)) {
throw TypeMismatchException.newException(lhsExprDataType, rhsExprDataType, toString(op, children));
}
- boolean isDeterministic = lhsExpr.isDeterministic() || rhsExpr.isDeterministic();
+ Determinism determinism = lhsExpr.getDeterminism().combine(rhsExpr.getDeterminism());
Object lhsValue = null;
// Can't use lhsNode.isConstant(), because we have cases in which we don't know
@@ -142,7 +142,7 @@ public class ComparisonExpression extends BaseCompoundExpression {
if (lhsExpr instanceof LiteralExpression) {
lhsValue = ((LiteralExpression)lhsExpr).getValue();
if (lhsValue == null) {
- return LiteralExpression.newConstant(false, PDataType.BOOLEAN, lhsExpr.isDeterministic());
+ return LiteralExpression.newConstant(false, PDataType.BOOLEAN, lhsExpr.getDeterminism());
}
}
Object rhsValue = null;
@@ -150,11 +150,11 @@ public class ComparisonExpression extends BaseCompoundExpression {
if (rhsExpr instanceof LiteralExpression) {
rhsValue = ((LiteralExpression)rhsExpr).getValue();
if (rhsValue == null) {
- return LiteralExpression.newConstant(false, PDataType.BOOLEAN, rhsExpr.isDeterministic());
+ return LiteralExpression.newConstant(false, PDataType.BOOLEAN, rhsExpr.getDeterminism());
}
}
if (lhsValue != null && rhsValue != null) {
- return LiteralExpression.newConstant(ByteUtil.compare(op,lhsExprDataType.compareTo(lhsValue, rhsValue, rhsExprDataType)), isDeterministic);
+ return LiteralExpression.newConstant(ByteUtil.compare(op,lhsExprDataType.compareTo(lhsValue, rhsValue, rhsExprDataType)), determinism);
}
// Coerce constant to match type of lhs so that we don't need to
// convert at filter time. Since we normalize the select statement
@@ -168,11 +168,11 @@ public class ComparisonExpression extends BaseCompoundExpression {
// TODO: if lengths are unequal and fixed width?
if (rhsExprDataType.isCoercibleTo(lhsExprDataType, rhsValue)) { // will convert 2.0 -> 2
children = Arrays.asList(children.get(0), LiteralExpression.newConstant(rhsValue, lhsExprDataType,
- lhsExpr.getMaxLength(), null, lhsExpr.getSortOrder(), isDeterministic));
+ lhsExpr.getMaxLength(), null, lhsExpr.getSortOrder(), determinism));
} else if (op == CompareOp.EQUAL) {
- return LiteralExpression.newConstant(false, PDataType.BOOLEAN, true);
+ return LiteralExpression.newConstant(false, PDataType.BOOLEAN, Determinism.ALWAYS);
} else if (op == CompareOp.NOT_EQUAL) {
- return LiteralExpression.newConstant(true, PDataType.BOOLEAN, true);
+ return LiteralExpression.newConstant(true, PDataType.BOOLEAN, Determinism.ALWAYS);
} else { // TODO: generalize this with PDataType.getMinValue(), PDataTypeType.getMaxValue() methods
switch(rhsExprDataType) {
case DECIMAL:
@@ -190,7 +190,7 @@ public class ComparisonExpression extends BaseCompoundExpression {
default: // Else, we truncate the value
BigDecimal bd = (BigDecimal)rhsValue;
rhsValue = bd.longValue() + increment;
- children = Arrays.asList(lhsExpr, LiteralExpression.newConstant(rhsValue, lhsExprDataType, lhsExpr.getSortOrder(), rhsExpr.isDeterministic()));
+ children = Arrays.asList(lhsExpr, LiteralExpression.newConstant(rhsValue, lhsExprDataType, lhsExpr.getSortOrder(), rhsExpr.getDeterminism()));
break;
}
break;
@@ -212,16 +212,16 @@ public class ComparisonExpression extends BaseCompoundExpression {
case LESS:
case LESS_OR_EQUAL:
if ((Long)rhsValue > 0) {
- return LiteralExpression.newConstant(true, PDataType.BOOLEAN, isDeterministic);
+ return LiteralExpression.newConstant(true, PDataType.BOOLEAN, determinism);
} else {
- return LiteralExpression.newConstant(false, PDataType.BOOLEAN, isDeterministic);
+ return LiteralExpression.newConstant(false, PDataType.BOOLEAN, determinism);
}
case GREATER:
case GREATER_OR_EQUAL:
if ((Long)rhsValue > 0) {
- return LiteralExpression.newConstant(false, PDataType.BOOLEAN, isDeterministic);
+ return LiteralExpression.newConstant(false, PDataType.BOOLEAN, determinism);
} else {
- return LiteralExpression.newConstant(true, PDataType.BOOLEAN, isDeterministic);
+ return LiteralExpression.newConstant(true, PDataType.BOOLEAN, determinism);
}
default:
break;
@@ -230,15 +230,15 @@ public class ComparisonExpression extends BaseCompoundExpression {
switch (op) {
case LESS:
case LESS_OR_EQUAL:
- return LiteralExpression.newConstant(false, PDataType.BOOLEAN, isDeterministic);
+ return LiteralExpression.newConstant(false, PDataType.BOOLEAN, determinism);
case GREATER:
case GREATER_OR_EQUAL:
- return LiteralExpression.newConstant(true, PDataType.BOOLEAN, isDeterministic);
+ return LiteralExpression.newConstant(true, PDataType.BOOLEAN, determinism);
default:
break;
}
}
- children = Arrays.asList(lhsExpr, LiteralExpression.newConstant(rhsValue, rhsExprDataType, lhsExpr.getSortOrder(), isDeterministic));
+ children = Arrays.asList(lhsExpr, LiteralExpression.newConstant(rhsValue, rhsExprDataType, lhsExpr.getSortOrder(), determinism));
break;
}
}
@@ -249,9 +249,9 @@ public class ComparisonExpression extends BaseCompoundExpression {
if (children.get(1).getMaxLength() != null && lhsExpr.getMaxLength() != null && lhsExpr.getMaxLength() < children.get(1).getMaxLength()) {
switch (op) {
case EQUAL:
- return LiteralExpression.newConstant(false, PDataType.BOOLEAN, isDeterministic);
+ return LiteralExpression.newConstant(false, PDataType.BOOLEAN, determinism);
case NOT_EQUAL:
- return LiteralExpression.newConstant(true, PDataType.BOOLEAN, isDeterministic);
+ return LiteralExpression.newConstant(true, PDataType.BOOLEAN, determinism);
default:
break;
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/CurrentDateTimeFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/CurrentDateTimeFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/CurrentDateTimeFunction.java
index 63e6d23..0b5faa2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/CurrentDateTimeFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/CurrentDateTimeFunction.java
@@ -36,7 +36,7 @@ public abstract class CurrentDateTimeFunction extends ScalarFunction {
}
@Override
- public boolean isDeterministic() {
- return false;
+ public Determinism getDeterminism() {
+ return Determinism.PER_STATEMENT;
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/Determinism.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/Determinism.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/Determinism.java
new file mode 100644
index 0000000..b2f3524
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/Determinism.java
@@ -0,0 +1,19 @@
+/*
+ * 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.phoenix.expression;
+
+public enum Determinism {
+
+ ALWAYS, PER_STATEMENT, PER_ROW;
+
+ public Determinism combine (Determinism that) {
+ return Determinism.values()[Math.max(this.ordinal(), that.ordinal())];
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/Expression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/Expression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/Expression.java
index ccd4d7b..aeea0c8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/Expression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/Expression.java
@@ -34,6 +34,7 @@ import org.apache.phoenix.schema.tuple.Tuple;
* @since 0.1
*/
public interface Expression extends PDatum, Writable {
+
/**
* Access the value by setting a pointer to it (as opposed to making
* a copy of it which can be expensive)
@@ -75,10 +76,9 @@ public interface Expression extends PDatum, Writable {
boolean isStateless();
/**
- * @return true if the expression returns the same output every
- * time given the same input.
+ * @return Determinism enum
*/
- boolean isDeterministic();
+ Determinism getDeterminism();
/**
* Determines if an evaluate is required after partial evaluation
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/InListExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/InListExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/InListExpression.java
index c171153..fdb20ff 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/InListExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/InListExpression.java
@@ -60,7 +60,7 @@ public class InListExpression extends BaseSingleExpression {
Expression firstChild = children.get(0);
if (firstChild.isStateless() && (!firstChild.evaluate(null, ptr) || ptr.getLength() == 0)) {
- return LiteralExpression.newConstant(null, PDataType.BOOLEAN, firstChild.isDeterministic());
+ return LiteralExpression.newConstant(null, PDataType.BOOLEAN, firstChild.getDeterminism());
}
if (children.size() == 2) {
return ComparisonExpression.create(isNegate ? CompareOp.NOT_EQUAL : CompareOp.EQUAL, children, ptr);
@@ -86,7 +86,7 @@ public class InListExpression extends BaseSingleExpression {
throw sqlE;
}
if (coercedKeyExpressions.size() == 2 && addedNull) {
- return LiteralExpression.newConstant(null, PDataType.BOOLEAN, true);
+ return LiteralExpression.newConstant(null, PDataType.BOOLEAN, Determinism.ALWAYS);
}
Expression expression = new InListExpression(coercedKeyExpressions);
if (isNegate) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/IsNullExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/IsNullExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/IsNullExpression.java
index 4162dfc..3fb7a62 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/IsNullExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/IsNullExpression.java
@@ -42,11 +42,11 @@ public class IsNullExpression extends BaseSingleExpression {
public static Expression create(Expression child, boolean negate, ImmutableBytesWritable ptr) throws SQLException {
if (!child.isNullable()) {
- return LiteralExpression.newConstant(negate, PDataType.BOOLEAN, child.isDeterministic());
+ return LiteralExpression.newConstant(negate, PDataType.BOOLEAN, child.getDeterminism());
}
if (ExpressionUtil.isConstant(child)) {
boolean evaluated = child.evaluate(null, ptr);
- return LiteralExpression.newConstant(negate ^ (!evaluated || ptr.getLength() == 0), PDataType.BOOLEAN, child.isDeterministic());
+ return LiteralExpression.newConstant(negate ^ (!evaluated || ptr.getLength() == 0), PDataType.BOOLEAN, child.getDeterminism());
}
return new IsNullExpression(child, negate);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/LiteralExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/LiteralExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/LiteralExpression.java
index 91a3125..a84135c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/LiteralExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/LiteralExpression.java
@@ -48,25 +48,25 @@ import com.google.common.base.Preconditions;
* @since 0.1
*/
public class LiteralExpression extends BaseTerminalExpression {
- public static final LiteralExpression NULL_EXPRESSION = new LiteralExpression(null, true);
- private static final LiteralExpression ND_NULL_EXPRESSION = new LiteralExpression(null, false);
+ public static final LiteralExpression NULL_EXPRESSION = new LiteralExpression(null, Determinism.ALWAYS);
+ private static final LiteralExpression ND_NULL_EXPRESSION = new LiteralExpression(null, Determinism.PER_ROW);
private static final LiteralExpression[] TYPED_NULL_EXPRESSIONS = new LiteralExpression[PDataType.values().length * 2];
static {
for (int i = 0; i < PDataType.values().length; i++) {
- TYPED_NULL_EXPRESSIONS[i] = new LiteralExpression(PDataType.values()[i], true);
+ TYPED_NULL_EXPRESSIONS[i] = new LiteralExpression(PDataType.values()[i], Determinism.ALWAYS);
}
for (int i = 0; i < PDataType.values().length; i++) {
- TYPED_NULL_EXPRESSIONS[i+PDataType.values().length] = new LiteralExpression(PDataType.values()[i], false);
+ TYPED_NULL_EXPRESSIONS[i+PDataType.values().length] = new LiteralExpression(PDataType.values()[i], Determinism.PER_ROW);
}
}
- private static final LiteralExpression FALSE_EXPRESSION = new LiteralExpression(Boolean.FALSE, PDataType.BOOLEAN, PDataType.BOOLEAN.toBytes(Boolean.FALSE), true);
- private static final LiteralExpression TRUE_EXPRESSION = new LiteralExpression(Boolean.TRUE, PDataType.BOOLEAN, PDataType.BOOLEAN.toBytes(Boolean.TRUE), true);
- private static final LiteralExpression ND_FALSE_EXPRESSION = new LiteralExpression(Boolean.FALSE, PDataType.BOOLEAN, PDataType.BOOLEAN.toBytes(Boolean.FALSE), false);
- private static final LiteralExpression ND_TRUE_EXPRESSION = new LiteralExpression(Boolean.TRUE, PDataType.BOOLEAN, PDataType.BOOLEAN.toBytes(Boolean.TRUE), false);
+ private static final LiteralExpression FALSE_EXPRESSION = new LiteralExpression(Boolean.FALSE, PDataType.BOOLEAN, PDataType.BOOLEAN.toBytes(Boolean.FALSE), Determinism.ALWAYS);
+ private static final LiteralExpression TRUE_EXPRESSION = new LiteralExpression(Boolean.TRUE, PDataType.BOOLEAN, PDataType.BOOLEAN.toBytes(Boolean.TRUE), Determinism.ALWAYS);
+ private static final LiteralExpression ND_FALSE_EXPRESSION = new LiteralExpression(Boolean.FALSE, PDataType.BOOLEAN, PDataType.BOOLEAN.toBytes(Boolean.FALSE), Determinism.PER_ROW);
+ private static final LiteralExpression ND_TRUE_EXPRESSION = new LiteralExpression(Boolean.TRUE, PDataType.BOOLEAN, PDataType.BOOLEAN.toBytes(Boolean.TRUE), Determinism.PER_ROW);
private Object value;
private PDataType type;
- private boolean isDeterministic;
+ private Determinism determinism;
private byte[] byteValue;
private Integer maxLength;
private Integer scale;
@@ -82,24 +82,24 @@ public class LiteralExpression extends BaseTerminalExpression {
}
public static LiteralExpression newConstant(Object value) {
- return newConstant(value, true);
+ return newConstant(value, Determinism.ALWAYS);
}
// TODO: cache?
- public static LiteralExpression newConstant(Object value, boolean isDeterministic) {
+ public static LiteralExpression newConstant(Object value, Determinism determinism) {
if (Boolean.FALSE.equals(value)) {
- return isDeterministic ? FALSE_EXPRESSION : ND_FALSE_EXPRESSION;
+ return determinism == Determinism.ALWAYS ? FALSE_EXPRESSION : ND_FALSE_EXPRESSION;
}
if (Boolean.TRUE.equals(value)) {
- return isDeterministic ? TRUE_EXPRESSION : ND_TRUE_EXPRESSION;
+ return determinism == Determinism.ALWAYS ? TRUE_EXPRESSION : ND_TRUE_EXPRESSION;
}
if (value == null) {
- return isDeterministic ? NULL_EXPRESSION : ND_NULL_EXPRESSION;
+ return determinism == Determinism.ALWAYS ? NULL_EXPRESSION : ND_NULL_EXPRESSION;
}
PDataType type = PDataType.fromLiteral(value);
byte[] b = type.toBytes(value);
if (type.isNull(b)) {
- return TYPED_NULL_EXPRESSIONS[type.ordinal() + ( isDeterministic ? 0 : TYPED_NULL_EXPRESSIONS.length/2)];
+ return TYPED_NULL_EXPRESSIONS[type.ordinal() + ( determinism == Determinism.ALWAYS ? 0 : TYPED_NULL_EXPRESSIONS.length/2)];
}
if (type == PDataType.VARCHAR) {
String s = (String) value;
@@ -107,35 +107,35 @@ public class LiteralExpression extends BaseTerminalExpression {
type = PDataType.CHAR;
}
}
- return new LiteralExpression(value, type, b, isDeterministic);
+ return new LiteralExpression(value, type, b, determinism);
}
public static LiteralExpression newConstant(Object value, PDataType type) throws SQLException {
- return newConstant(value, type, true);
+ return newConstant(value, type, Determinism.ALWAYS);
}
- public static LiteralExpression newConstant(Object value, PDataType type, boolean isDeterministic) throws SQLException {
- return newConstant(value, type, SortOrder.getDefault(), isDeterministic);
+ public static LiteralExpression newConstant(Object value, PDataType type, Determinism determinism) throws SQLException {
+ return newConstant(value, type, SortOrder.getDefault(), determinism);
}
public static LiteralExpression newConstant(Object value, PDataType type, SortOrder sortOrder) throws SQLException {
- return newConstant(value, type, null, null, sortOrder, true);
+ return newConstant(value, type, null, null, sortOrder, Determinism.ALWAYS);
}
- public static LiteralExpression newConstant(Object value, PDataType type, SortOrder sortOrder, boolean isDeterministic) throws SQLException {
- return newConstant(value, type, null, null, sortOrder, isDeterministic);
+ public static LiteralExpression newConstant(Object value, PDataType type, SortOrder sortOrder, Determinism determinism) throws SQLException {
+ return newConstant(value, type, null, null, sortOrder, determinism);
}
public static LiteralExpression newConstant(Object value, PDataType type, Integer maxLength, Integer scale) throws SQLException {
- return newConstant(value, type, maxLength, scale, SortOrder.getDefault(), true);
+ return newConstant(value, type, maxLength, scale, SortOrder.getDefault(), Determinism.ALWAYS);
}
- public static LiteralExpression newConstant(Object value, PDataType type, Integer maxLength, Integer scale, boolean isDeterministic) throws SQLException { // remove?
- return newConstant(value, type, maxLength, scale, SortOrder.getDefault(), isDeterministic);
+ public static LiteralExpression newConstant(Object value, PDataType type, Integer maxLength, Integer scale, Determinism determinism) throws SQLException { // remove?
+ return newConstant(value, type, maxLength, scale, SortOrder.getDefault(), determinism);
}
// TODO: cache?
- public static LiteralExpression newConstant(Object value, PDataType type, Integer maxLength, Integer scale, SortOrder sortOrder, boolean isDeterministic)
+ public static LiteralExpression newConstant(Object value, PDataType type, Integer maxLength, Integer scale, SortOrder sortOrder, Determinism determinism)
throws SQLException {
if (value == null) {
if (type == null) {
@@ -144,10 +144,10 @@ public class LiteralExpression extends BaseTerminalExpression {
return TYPED_NULL_EXPRESSIONS[type.ordinal()];
}
if (Boolean.FALSE.equals(value)) {
- return isDeterministic ? FALSE_EXPRESSION : ND_FALSE_EXPRESSION;
+ return determinism == Determinism.ALWAYS ? FALSE_EXPRESSION : ND_FALSE_EXPRESSION;
}
if (Boolean.TRUE.equals(value)) {
- return isDeterministic ? TRUE_EXPRESSION : ND_TRUE_EXPRESSION;
+ return determinism == Determinism.ALWAYS ? TRUE_EXPRESSION : ND_TRUE_EXPRESSION;
}
PDataType actualType = PDataType.fromLiteral(value);
// For array we should check individual element in it?
@@ -173,7 +173,7 @@ public class LiteralExpression extends BaseTerminalExpression {
if (maxLength == null) {
maxLength = type == null || !type.isFixedWidth() ? null : type.getMaxLength(value);
}
- return new LiteralExpression(value, type, b, maxLength, scale, sortOrder, isDeterministic);
+ return new LiteralExpression(value, type, b, maxLength, scale, sortOrder, determinism);
} catch (IllegalDataException e) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.ILLEGAL_DATA).setRootCause(e).build().buildException();
}
@@ -182,16 +182,16 @@ public class LiteralExpression extends BaseTerminalExpression {
public LiteralExpression() {
}
- private LiteralExpression(PDataType type, boolean isDeterministic) {
- this(null, type, ByteUtil.EMPTY_BYTE_ARRAY, isDeterministic);
+ private LiteralExpression(PDataType type, Determinism determinism) {
+ this(null, type, ByteUtil.EMPTY_BYTE_ARRAY, determinism);
}
- private LiteralExpression(Object value, PDataType type, byte[] byteValue, boolean isDeterministic) {
- this(value, type, byteValue, type == null || !type.isFixedWidth() ? null : type.getMaxLength(value), null, SortOrder.getDefault(), isDeterministic);
+ private LiteralExpression(Object value, PDataType type, byte[] byteValue, Determinism determinism) {
+ this(value, type, byteValue, type == null || !type.isFixedWidth() ? null : type.getMaxLength(value), null, SortOrder.getDefault(), determinism);
}
private LiteralExpression(Object value, PDataType type, byte[] byteValue,
- Integer maxLength, Integer scale, SortOrder sortOrder, boolean isDeterministic) {
+ Integer maxLength, Integer scale, SortOrder sortOrder, Determinism deterministic) {
Preconditions.checkNotNull(sortOrder);
this.value = value;
this.type = type;
@@ -199,12 +199,12 @@ public class LiteralExpression extends BaseTerminalExpression {
this.maxLength = maxLength;
this.scale = scale != null ? scale : type == null ? null : type.getScale(value);
this.sortOrder = sortOrder;
- this.isDeterministic = isDeterministic;
+ this.determinism = deterministic;
}
@Override
- public boolean isDeterministic() {
- return isDeterministic;
+ public Determinism getDeterminism() {
+ return determinism;
}
@Override
@@ -234,12 +234,22 @@ public class LiteralExpression extends BaseTerminalExpression {
@Override
public void readFields(DataInput input) throws IOException {
- int encodedByteLengthAndBool = WritableUtils.readVInt(input);
- this.isDeterministic = encodedByteLengthAndBool > 0;
+ int encodedByteLengthAndBool = WritableUtils.readVInt(input);
int byteLength = Math.abs(encodedByteLengthAndBool)-1;
this.byteValue = new byte[byteLength];
input.readFully(byteValue, 0, byteLength);
- sortOrder = SortOrder.fromSystemValue(WritableUtils.readVInt(input));
+ int sortOrderAndDeterminism = WritableUtils.readVInt(input);
+ if (sortOrderAndDeterminism<=2) {
+ //client is on an older version
+ this.determinism = encodedByteLengthAndBool > 0 ? Determinism.ALWAYS : Determinism.PER_ROW;
+ this.sortOrder = SortOrder.fromSystemValue(sortOrderAndDeterminism);;
+ }
+ else {
+ int determinismOrdinal = (sortOrderAndDeterminism>>2)-1;
+ this.determinism = Determinism.values()[determinismOrdinal];
+ int sortOrderValue = sortOrderAndDeterminism & ((1 << 2) - 1); //get the least 2 significant bits
+ this.sortOrder = SortOrder.fromSystemValue(sortOrderValue);
+ }
int typeOrdinal = WritableUtils.readVInt(input);
if (typeOrdinal < 0) {
this.type = null;
@@ -255,10 +265,13 @@ public class LiteralExpression extends BaseTerminalExpression {
@Override
public void write(DataOutput output) throws IOException {
- WritableUtils.writeVInt(output, (byteValue.length + 1) * (this.isDeterministic ? 1 : -1));
+ WritableUtils.writeVInt(output, (byteValue.length + 1) * (this.determinism==Determinism.ALWAYS ? 1 : -1));
output.write(byteValue);
- WritableUtils.writeVInt(output, sortOrder.getSystemValue());
- WritableUtils.writeVInt(output, type == null ? -1 : this.type.ordinal());
+ // since we need to support clients of a lower version, serialize the determinism enum ordinal in the int used to
+ // serialize sort order system value (which is either 1 or 2)
+ int sortOrderAndDeterminism = ((this.determinism.ordinal()+1)<<2) + sortOrder.getSystemValue();
+ WritableUtils.writeVInt(output, sortOrderAndDeterminism);
+ WritableUtils.writeVInt(output, this.type == null ? -1 : this.type.ordinal());
}
@Override
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/NotExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/NotExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/NotExpression.java
index e25f1e2..0c17ab8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/NotExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/NotExpression.java
@@ -43,9 +43,9 @@ public class NotExpression extends BaseSingleExpression {
}
if (child.isStateless()) {
if (!child.evaluate(null, ptr) || ptr.getLength() == 0) {
- return LiteralExpression.newConstant(null, PDataType.BOOLEAN, child.isDeterministic());
+ return LiteralExpression.newConstant(null, PDataType.BOOLEAN, child.getDeterminism());
}
- return LiteralExpression.newConstant(!(Boolean)PDataType.BOOLEAN.toObject(ptr), PDataType.BOOLEAN, child.isDeterministic());
+ return LiteralExpression.newConstant(!(Boolean)PDataType.BOOLEAN.toObject(ptr), PDataType.BOOLEAN, child.getDeterminism());
}
return new NotExpression(child);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/AggregateFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/AggregateFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/AggregateFunction.java
index 257890c..32cae19 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/AggregateFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/AggregateFunction.java
@@ -19,6 +19,7 @@ package org.apache.phoenix.expression.function;
import java.util.List;
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
@@ -46,7 +47,7 @@ abstract public class AggregateFunction extends FunctionExpression {
}
@Override
- public boolean isDeterministic() {
- return false;
+ public Determinism getDeterminism() {
+ return Determinism.PER_ROW;
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDecimalExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDecimalExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDecimalExpression.java
index d6b4e45..bd36d0f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDecimalExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDecimalExpression.java
@@ -21,13 +21,17 @@ import java.math.RoundingMode;
import java.sql.SQLException;
import java.util.List;
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.LiteralExpression;
import org.apache.phoenix.schema.PDataType;
import com.google.common.collect.Lists;
+
import java.math.BigDecimal;
+
import org.apache.phoenix.query.KeyRange;
+
import static org.apache.phoenix.schema.PDataType.DECIMAL;
/**
@@ -53,7 +57,7 @@ public class CeilDecimalExpression extends RoundDecimalExpression {
if (expr.getDataType().isCoercibleTo(PDataType.LONG)) {
return expr;
}
- Expression scaleExpr = LiteralExpression.newConstant(scale, PDataType.INTEGER, true);
+ Expression scaleExpr = LiteralExpression.newConstant(scale, PDataType.INTEGER, Determinism.ALWAYS);
List<Expression> expressions = Lists.newArrayList(expr, scaleExpr);
return new CeilDecimalExpression(expressions);
}
@@ -64,7 +68,7 @@ public class CeilDecimalExpression extends RoundDecimalExpression {
return expr;
}
if (exprs.size() == 1) {
- Expression scaleExpr = LiteralExpression.newConstant(0, PDataType.INTEGER, true);
+ Expression scaleExpr = LiteralExpression.newConstant(0, PDataType.INTEGER, Determinism.ALWAYS);
exprs = Lists.newArrayList(expr, scaleExpr);
}
return new CeilDecimalExpression(exprs);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CoalesceFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CoalesceFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CoalesceFunction.java
index 87fc908..2eef8b3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CoalesceFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CoalesceFunction.java
@@ -30,6 +30,7 @@ import org.apache.phoenix.parse.FunctionParseNode.Argument;
import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
import org.apache.phoenix.schema.PDataType;
import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.util.ExpressionUtil;
/**
@@ -59,7 +60,7 @@ public class CoalesceFunction extends ScalarFunction {
Expression firstChild = children.get(0);
Expression secondChild = children.get(1);
- if (secondChild.isStateless() && secondChild.isDeterministic()) { // is literal
+ if (ExpressionUtil.isConstant(secondChild)) { // is literal
ImmutableBytesWritable ptr = new ImmutableBytesPtr();
secondChild.evaluate(null, ptr);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CountAggregateFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CountAggregateFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CountAggregateFunction.java
index b7a5861..f1e8ab5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CountAggregateFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CountAggregateFunction.java
@@ -22,7 +22,7 @@ import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.LiteralExpression;
import org.apache.phoenix.expression.aggregator.Aggregator;
@@ -45,7 +45,7 @@ import org.apache.phoenix.util.SchemaUtil;
@BuiltInFunction(name=CountAggregateFunction.NAME, args= {@Argument()} )
public class CountAggregateFunction extends SingleAggregateFunction {
public static final String NAME = "COUNT";
- public static final List<Expression> STAR = Arrays.<Expression>asList(LiteralExpression.newConstant(1, true));
+ public static final List<Expression> STAR = Arrays.<Expression>asList(LiteralExpression.newConstant(1, Determinism.ALWAYS));
public static final String NORMALIZED_NAME = SchemaUtil.normalizeIdentifier(NAME);
public CountAggregateFunction() {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDecimalExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDecimalExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDecimalExpression.java
index b5566ca..037fcc5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDecimalExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDecimalExpression.java
@@ -21,13 +21,17 @@ import java.math.RoundingMode;
import java.sql.SQLException;
import java.util.List;
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.LiteralExpression;
import org.apache.phoenix.schema.PDataType;
import com.google.common.collect.Lists;
+
import java.math.BigDecimal;
+
import org.apache.phoenix.query.KeyRange;
+
import static org.apache.phoenix.schema.PDataType.DECIMAL;
/**
@@ -54,7 +58,7 @@ public class FloorDecimalExpression extends RoundDecimalExpression {
if (expr.getDataType().isCoercibleTo(PDataType.LONG)) {
return expr;
}
- Expression scaleExpr = LiteralExpression.newConstant(scale, PDataType.INTEGER, true);
+ Expression scaleExpr = LiteralExpression.newConstant(scale, PDataType.INTEGER, Determinism.ALWAYS);
List<Expression> expressions = Lists.newArrayList(expr, scaleExpr);
return new FloorDecimalExpression(expressions);
}
@@ -65,7 +69,7 @@ public class FloorDecimalExpression extends RoundDecimalExpression {
return expr;
}
if (exprs.size() == 1) {
- Expression scaleExpr = LiteralExpression.newConstant(0, PDataType.INTEGER, true);
+ Expression scaleExpr = LiteralExpression.newConstant(0, PDataType.INTEGER, Determinism.ALWAYS);
exprs = Lists.newArrayList(expr, scaleExpr);
}
return new FloorDecimalExpression(exprs);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java
index f928218..58ff652 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java
@@ -29,6 +29,7 @@ import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.io.WritableUtils;
import org.apache.phoenix.compile.KeyPart;
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.LiteralExpression;
import org.apache.phoenix.query.KeyRange;
@@ -92,11 +93,11 @@ public class RoundDateExpression extends ScalarFunction {
}
static Expression getTimeUnitExpr(TimeUnit timeUnit) throws SQLException {
- return LiteralExpression.newConstant(timeUnit.name(), PDataType.VARCHAR, true);
+ return LiteralExpression.newConstant(timeUnit.name(), PDataType.VARCHAR, Determinism.ALWAYS);
}
static Expression getMultiplierExpr(int multiplier) throws SQLException {
- return LiteralExpression.newConstant(multiplier, PDataType.INTEGER, true);
+ return LiteralExpression.newConstant(multiplier, PDataType.INTEGER, Determinism.ALWAYS);
}
RoundDateExpression(List<Expression> children) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDecimalExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDecimalExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDecimalExpression.java
index 92756a5..e8d96a8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDecimalExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDecimalExpression.java
@@ -27,6 +27,7 @@ import java.util.List;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.io.WritableUtils;
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.LiteralExpression;
import org.apache.phoenix.schema.IllegalDataException;
@@ -37,7 +38,6 @@ import com.google.common.collect.Lists;
import java.util.Collections;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.phoenix.compile.KeyPart;
-import static org.apache.phoenix.expression.function.ScalarFunction.evaluateExpression;
import org.apache.phoenix.query.KeyRange;
import org.apache.phoenix.schema.PColumn;
import static org.apache.phoenix.schema.PDataType.DECIMAL;
@@ -62,7 +62,7 @@ public class RoundDecimalExpression extends ScalarFunction {
if (expr.getDataType().isCoercibleTo(PDataType.LONG)) {
return expr;
}
- Expression scaleExpr = LiteralExpression.newConstant(scale, PDataType.INTEGER, true);
+ Expression scaleExpr = LiteralExpression.newConstant(scale, PDataType.INTEGER, Determinism.ALWAYS);
List<Expression> expressions = Lists.newArrayList(expr, scaleExpr);
return new RoundDecimalExpression(expressions);
}
@@ -81,7 +81,7 @@ public class RoundDecimalExpression extends ScalarFunction {
return expr;
}
if (exprs.size() == 1) {
- Expression scaleExpr = LiteralExpression.newConstant(0, PDataType.INTEGER, true);
+ Expression scaleExpr = LiteralExpression.newConstant(0, PDataType.INTEGER, Determinism.ALWAYS);
exprs = Lists.newArrayList(expr, scaleExpr);
}
return new RoundDecimalExpression(exprs);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/SingleAggregateFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/SingleAggregateFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/SingleAggregateFunction.java
index 154bdf8..d33d555 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/SingleAggregateFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/SingleAggregateFunction.java
@@ -25,7 +25,7 @@ import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.LiteralExpression;
import org.apache.phoenix.expression.aggregator.Aggregator;
@@ -43,7 +43,7 @@ import org.apache.phoenix.schema.tuple.Tuple;
* @since 0.1
*/
abstract public class SingleAggregateFunction extends AggregateFunction {
- private static final List<Expression> DEFAULT_EXPRESSION_LIST = Arrays.<Expression>asList(LiteralExpression.newConstant(1, true));
+ private static final List<Expression> DEFAULT_EXPRESSION_LIST = Arrays.<Expression>asList(LiteralExpression.newConstant(1, Determinism.ALWAYS));
protected boolean isConstant;
private Aggregator aggregator;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
index 10c7208..ea8c1fb 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
@@ -33,7 +33,9 @@ import java.util.Set;
import org.apache.http.annotation.Immutable;
import com.google.common.collect.ImmutableSet;
+
import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.LiteralExpression;
import org.apache.phoenix.expression.function.AggregateFunction;
@@ -137,7 +139,7 @@ public class FunctionParseNode extends CompoundParseNode {
if (args.length > children.size()) {
List<Expression> moreChildren = new ArrayList<Expression>(children);
for (int i = children.size(); i < info.getArgs().length; i++) {
- moreChildren.add(LiteralExpression.newConstant(null, args[i].allowedTypes.length == 0 ? null : args[i].allowedTypes[0], true));
+ moreChildren.add(LiteralExpression.newConstant(null, args[i].allowedTypes.length == 0 ? null : args[i].allowedTypes[0], Determinism.ALWAYS));
}
children = moreChildren;
}
@@ -174,7 +176,7 @@ public class FunctionParseNode extends CompoundParseNode {
// based on the function argument annonation set the parameter meta data.
if (child.getDataType() == null) {
if (allowedTypes.length > 0) {
- context.getBindManager().addParamMetaData(bindNode, LiteralExpression.newConstant(null, allowedTypes[0], true));
+ context.getBindManager().addParamMetaData(bindNode, LiteralExpression.newConstant(null, allowedTypes[0], Determinism.ALWAYS));
}
} else { // Use expression as is, since we already have the data type set
context.getBindManager().addParamMetaData(bindNode, child);
@@ -376,11 +378,11 @@ public class FunctionParseNode extends CompoundParseNode {
SQLParser parser = new SQLParser(strValue);
try {
LiteralParseNode node = parser.parseLiteral();
- LiteralExpression defaultValue = LiteralExpression.newConstant(node.getValue(), this.allowedTypes[0], true);
+ LiteralExpression defaultValue = LiteralExpression.newConstant(node.getValue(), this.allowedTypes[0], Determinism.ALWAYS);
if (this.getAllowedTypes().length > 0) {
for (PDataType type : this.getAllowedTypes()) {
if (defaultValue.getDataType() == null || defaultValue.getDataType().isCoercibleTo(type, node.getValue())) {
- return LiteralExpression.newConstant(node.getValue(), type, true);
+ return LiteralExpression.newConstant(node.getValue(), type, Determinism.ALWAYS);
}
}
throw new IllegalStateException("Unable to coerce default value " + strValue + " to any of the allowed types of " + Arrays.toString(this.getAllowedTypes()));
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/main/java/org/apache/phoenix/util/ExpressionUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/ExpressionUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/ExpressionUtil.java
index 227a385..eac396b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/ExpressionUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/ExpressionUtil.java
@@ -13,6 +13,7 @@ import java.sql.SQLException;
import java.util.List;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.LiteralExpression;
import org.apache.phoenix.expression.function.CurrentDateFunction;
@@ -24,16 +25,20 @@ import com.google.common.collect.Lists;
public class ExpressionUtil {
- @SuppressWarnings("unchecked")
- private static final List<Class<? extends FunctionExpression>> OVERRIDE_LITERAL_FUNCTIONS = Lists
- .<Class<? extends FunctionExpression>> newArrayList(CurrentDateFunction.class, CurrentTimeFunction.class);
+ @SuppressWarnings("unchecked")
+ private static final List<Class<? extends FunctionExpression>> OVERRIDE_LITERAL_FUNCTIONS = Lists
+ .<Class<? extends FunctionExpression>> newArrayList(
+ CurrentDateFunction.class, CurrentTimeFunction.class);
- private ExpressionUtil() {}
+ private ExpressionUtil() {
+ }
- public static boolean isConstant(Expression expression) {
- return (expression.isStateless() && expression.isDeterministic() || OVERRIDE_LITERAL_FUNCTIONS
- .contains(expression.getClass()));
- }
+ public static boolean isConstant(Expression expression) {
+ return (expression.isStateless() && (expression.getDeterminism() == Determinism.ALWAYS
+ || expression.getDeterminism() == Determinism.PER_STATEMENT
+ // TODO remove this in 3.4/4.4 (need to support clients on 3.1/4.1)
+ || OVERRIDE_LITERAL_FUNCTIONS.contains(expression.getClass())));
+ }
public static LiteralExpression getConstantExpression(Expression expression, ImmutableBytesWritable ptr)
throws SQLException {
@@ -42,16 +47,15 @@ public class ExpressionUtil {
if (expression.evaluate(null, ptr) && ptr.getLength() != 0) {
value = type.toObject(ptr);
}
- return LiteralExpression.newConstant(value, type, expression.isDeterministic());
+ return LiteralExpression.newConstant(value, type, expression.getDeterminism());
}
public static boolean isNull(Expression expression, ImmutableBytesWritable ptr) {
- return expression.isStateless() && expression.isDeterministic()
- && (!expression.evaluate(null, ptr) || ptr.getLength() == 0);
+ return isConstant(expression) && (!expression.evaluate(null, ptr) || ptr.getLength() == 0);
}
public static LiteralExpression getNullExpression(Expression expression) throws SQLException {
- return LiteralExpression.newConstant(null, expression.getDataType(), expression.isDeterministic());
+ return LiteralExpression.newConstant(null, expression.getDataType(), expression.getDeterminism());
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/b1be0f8b/phoenix-core/src/test/java/org/apache/phoenix/expression/DeterminismTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/expression/DeterminismTest.java b/phoenix-core/src/test/java/org/apache/phoenix/expression/DeterminismTest.java
new file mode 100644
index 0000000..4e4a648
--- /dev/null
+++ b/phoenix-core/src/test/java/org/apache/phoenix/expression/DeterminismTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.phoenix.expression;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class DeterminismTest {
+ @Test
+ public void testCombine() {
+ // combining a determinism enum with ALWAYS should always return the
+ // other determinism
+ assertEquals("Unexpected result ", Determinism.PER_ROW,
+ Determinism.ALWAYS.combine(Determinism.PER_ROW));
+ assertEquals("Unexpected result ", Determinism.PER_STATEMENT,
+ Determinism.ALWAYS.combine(Determinism.PER_STATEMENT));
+ assertEquals("Unexpected result ", Determinism.PER_STATEMENT,
+ Determinism.PER_STATEMENT.combine(Determinism.ALWAYS));
+ assertEquals("Unexpected result ", Determinism.PER_ROW,
+ Determinism.PER_ROW.combine(Determinism.ALWAYS));
+
+ // combining PER_STATEMENT and PER_ROW should return PER_ROW
+ assertEquals("Unexpected result ", Determinism.PER_ROW,
+ Determinism.PER_STATEMENT.combine(Determinism.PER_ROW));
+ assertEquals("Unexpected result ", Determinism.PER_ROW,
+ Determinism.PER_ROW.combine(Determinism.PER_STATEMENT));
+
+ }
+}