http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/ModulusExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/ModulusExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/ModulusExpression.java
index bac52fc..b6b669f 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/ModulusExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/ModulusExpression.java
@@ -17,13 +17,13 @@
  */
 package org.apache.phoenix.expression;
 
-import java.sql.SQLException;
 import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-import org.apache.phoenix.schema.types.PLong;
-import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.expression.visitor.ExpressionVisitor;
 import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PLong;
 
 
 /**
@@ -39,7 +39,7 @@ public class ModulusExpression extends ArithmeticExpression {
 
     public ModulusExpression() { }
 
-    public ModulusExpression(List<Expression> children) throws SQLException {
+    public ModulusExpression(List<Expression> children) {
         super(children);
     }
 
@@ -93,4 +93,18 @@ public class ModulusExpression extends ArithmeticExpression {
         return " % ";
     }
 
+    @Override
+    public final <T> T accept(ExpressionVisitor<T> visitor) {
+        List<T> l = acceptChildren(visitor, visitor.visitEnter(this));
+        T t = visitor.visitLeave(this, l);
+        if (t == null) {
+            t = visitor.defaultReturn(this, l);
+        }
+        return t;
+    }
+
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new ModulusExpression(children);
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/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 c2f214e..4bbdcc4 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
@@ -22,10 +22,10 @@ import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.expression.visitor.ExpressionVisitor;
-import org.apache.phoenix.schema.types.PBoolean;
-import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.TypeMismatchException;
 import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PBoolean;
+import org.apache.phoenix.schema.types.PDataType;
 
 
 /**
@@ -58,6 +58,10 @@ public class NotExpression extends BaseSingleExpression {
         super(expression);
     }
 
+    public NotExpression(List<Expression> l) {
+        super(l);
+    }
+
     @Override
     public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
         if (!getChild().evaluate(tuple, ptr)) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/RowKeyExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/RowKeyExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/RowKeyExpression.java
index d9f6b90..97001e8 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/RowKeyExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/RowKeyExpression.java
@@ -19,10 +19,10 @@
 package org.apache.phoenix.expression;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
+import org.apache.phoenix.expression.visitor.ExpressionVisitor;
+import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PVarbinary;
-import org.apache.phoenix.schema.tuple.Tuple;
 
 public class RowKeyExpression extends BaseTerminalExpression {
     public static final RowKeyExpression INSTANCE = new RowKeyExpression();
@@ -41,4 +41,10 @@ public class RowKeyExpression extends BaseTerminalExpression 
{
         return PVarbinary.INSTANCE;
     }
 
+    @Override
+    public <T> T accept(ExpressionVisitor<T> visitor) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/RowValueConstructorExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/RowValueConstructorExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/RowValueConstructorExpression.java
index 546962e..940f909 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/RowValueConstructorExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/RowValueConstructorExpression.java
@@ -33,9 +33,9 @@ import java.util.List;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.expression.visitor.ExpressionVisitor;
 import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PVarbinary;
-import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.TrustedByteArrayOutputStream;
@@ -57,6 +57,10 @@ public class RowValueConstructorExpression extends 
BaseCompoundExpression {
         init(isConstant);
     }
 
+    public RowValueConstructorExpression clone(List<Expression> children) {
+        return new RowValueConstructorExpression(children, literalExprPtr != 
null);
+    }
+    
     public int getEstimatedSize() {
         return estimatedByteSize;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/TimestampAddExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/TimestampAddExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/TimestampAddExpression.java
index 892a38c..f4c629b 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/TimestampAddExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/TimestampAddExpression.java
@@ -23,15 +23,14 @@ import java.sql.Timestamp;
 import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
 import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PDecimal;
 import org.apache.phoenix.schema.types.PDouble;
 import org.apache.phoenix.schema.types.PTimestamp;
 import org.apache.phoenix.schema.types.PUnsignedTimestamp;
-import org.apache.phoenix.schema.SortOrder;
-import org.apache.phoenix.schema.types.PDataType;
-import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.DateUtil;
 
 /**
@@ -88,4 +87,9 @@ public class TimestampAddExpression extends AddExpression {
         return PTimestamp.INSTANCE;
     }
 
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new TimestampAddExpression(children);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/TimestampSubtractExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/TimestampSubtractExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/TimestampSubtractExpression.java
index 5718c94..87d634c 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/TimestampSubtractExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/TimestampSubtractExpression.java
@@ -23,14 +23,13 @@ import java.sql.Timestamp;
 import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
+import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PDecimal;
 import org.apache.phoenix.schema.types.PDouble;
 import org.apache.phoenix.schema.types.PTimestamp;
 import org.apache.phoenix.schema.types.PUnsignedTimestamp;
-import org.apache.phoenix.schema.SortOrder;
-import org.apache.phoenix.schema.types.PDataType;
-import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.DateUtil;
 /**
  * 
@@ -88,4 +87,9 @@ public class TimestampSubtractExpression extends 
SubtractExpression {
     public final PDataType getDataType() {
         return PTimestamp.INSTANCE;
     }
+
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new TimestampSubtractExpression(children);
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/aggregator/BaseAggregator.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/aggregator/BaseAggregator.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/aggregator/BaseAggregator.java
index 1a8aad6..9b673bf 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/aggregator/BaseAggregator.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/aggregator/BaseAggregator.java
@@ -20,6 +20,7 @@ package org.apache.phoenix.expression.aggregator;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.expression.BaseTerminalExpression;
+import org.apache.phoenix.expression.visitor.ExpressionVisitor;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.util.SizedUtil;
 
@@ -56,4 +57,10 @@ public abstract class BaseAggregator extends 
BaseTerminalExpression implements A
         ca.evaluate(null, ptr);
         return ptr;
     }
+    
+    @Override
+    public <T> T accept(ExpressionVisitor<T> visitor) {
+        return null;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayAnyComparisonExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayAnyComparisonExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayAnyComparisonExpression.java
index b57901b..e6702d0 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayAnyComparisonExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayAnyComparisonExpression.java
@@ -24,10 +24,11 @@ import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.expression.BaseCompoundExpression;
 import org.apache.phoenix.expression.ComparisonExpression;
 import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.visitor.ExpressionVisitor;
+import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PArrayDataType;
 import org.apache.phoenix.schema.types.PBoolean;
 import org.apache.phoenix.schema.types.PDataType;
-import org.apache.phoenix.schema.tuple.Tuple;
 
 public class ArrayAnyComparisonExpression extends BaseCompoundExpression {
     public ArrayAnyComparisonExpression () {
@@ -49,7 +50,7 @@ public class ArrayAnyComparisonExpression extends 
BaseCompoundExpression {
         for (int i = 0; i < length; i++) {
             Expression comparisonExpr = children.get(1);
             Expression arrayElemRef = 
((ComparisonExpression)comparisonExpr).getChildren().get(1);
-            ((InlineArrayElemRefExpression)arrayElemRef).setIndex(i + 1);
+            ((ArrayElemRefExpression)arrayElemRef).setIndex(i + 1);
             comparisonExpr.evaluate(tuple, ptr);
             if (expectedReturnResult(resultFound(ptr))) { return result(); }
             elementAvailable = true;
@@ -76,4 +77,14 @@ public class ArrayAnyComparisonExpression extends 
BaseCompoundExpression {
     public PDataType getDataType() {
         return PBoolean.INSTANCE;
     }
+
+    @Override
+    public final <T> T accept(ExpressionVisitor<T> visitor) {
+        List<T> l = acceptChildren(visitor, visitor.visitEnter(this));
+        T t = visitor.visitLeave(this, l);
+        if (t == null) {
+            t = visitor.defaultReturn(this, l);
+        }
+        return t;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayElemRefExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayElemRefExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayElemRefExpression.java
new file mode 100644
index 0000000..6631e70
--- /dev/null
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayElemRefExpression.java
@@ -0,0 +1,83 @@
+/*
+ * 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.function;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.phoenix.expression.BaseCompoundExpression;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.visitor.ExpressionVisitor;
+import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PArrayDataType;
+import org.apache.phoenix.schema.types.PDataType;
+
+public class ArrayElemRefExpression extends BaseCompoundExpression {
+
+    private int index;
+
+    public ArrayElemRefExpression() {
+    }
+    
+    public ArrayElemRefExpression(List<Expression> children) {
+        super(children);
+    }
+
+    public void setIndex(int index) {
+        this.index = index;
+    }
+
+    @Override
+    public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
+        Expression arrayExpr = children.get(0);
+        return PArrayDataType.positionAtArrayElement(tuple, ptr, index, 
arrayExpr, getDataType(), getMaxLength());
+    }
+
+    @Override
+    public Integer getMaxLength() {
+        return this.children.get(0).getMaxLength();
+    }
+
+    @Override
+    public PDataType getDataType() {
+        return PDataType.fromTypeId(children.get(0).getDataType().getSqlType() 
- PDataType.ARRAY_TYPE_BASE);
+    }
+    
+    @Override
+    public void write(DataOutput output) throws IOException {
+        super.write(output);
+    }
+    
+    @Override
+    public void readFields(DataInput input) throws IOException {
+        super.readFields(input);
+    }
+
+    @Override
+    public final <T> T accept(ExpressionVisitor<T> visitor) {
+        List<T> l = acceptChildren(visitor, visitor.visitEnter(this));
+        T t = visitor.visitLeave(this, l);
+        if (t == null) {
+            t = visitor.defaultReturn(this, l);
+        }
+        return t;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FunctionExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FunctionExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FunctionExpression.java
index 45c3e15..b45706a 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FunctionExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FunctionExpression.java
@@ -57,7 +57,7 @@ public abstract class FunctionExpression extends 
BaseCompoundExpression {
     abstract public String getName();
     
     @Override
-    public final String toString() {
+    public String toString() {
         StringBuilder buf = new StringBuilder(getName() + "(");
         if (children.size()==0)
             return buf.append(")").toString();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/function/InlineArrayElemRefExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/InlineArrayElemRefExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/InlineArrayElemRefExpression.java
deleted file mode 100644
index c5c1eea..0000000
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/InlineArrayElemRefExpression.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.function;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.util.List;
-
-import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-import org.apache.phoenix.expression.BaseCompoundExpression;
-import org.apache.phoenix.expression.Expression;
-import org.apache.phoenix.schema.types.PArrayDataType;
-import org.apache.phoenix.schema.types.PDataType;
-import org.apache.phoenix.schema.tuple.Tuple;
-
-public class InlineArrayElemRefExpression extends BaseCompoundExpression {
-
-    private int index;
-
-    public InlineArrayElemRefExpression() {
-    }
-    
-    public InlineArrayElemRefExpression(List<Expression> children) {
-        super(children);
-    }
-
-    public void setIndex(int index) {
-        this.index = index;
-    }
-
-    @Override
-    public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
-        Expression arrayExpr = children.get(0);
-        return PArrayDataType.positionAtArrayElement(tuple, ptr, index, 
arrayExpr, getDataType(), getMaxLength());
-    }
-
-    @Override
-    public Integer getMaxLength() {
-        return this.children.get(0).getMaxLength();
-    }
-
-    @Override
-    public PDataType getDataType() {
-        return PDataType.fromTypeId(children.get(0).getDataType().getSqlType() 
- PDataType.ARRAY_TYPE_BASE);
-    }
-    
-    @Override
-    public void write(DataOutput output) throws IOException {
-        super.write(output);
-    }
-    
-    @Override
-    public void readFields(DataInput input) throws IOException {
-        super.readFields(input);
-    }
-    
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RandomFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RandomFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RandomFunction.java
new file mode 100644
index 0000000..535a127
--- /dev/null
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RandomFunction.java
@@ -0,0 +1,133 @@
+package org.apache.phoenix.expression.function;
+
+import java.io.DataInput;
+import java.io.IOException;
+import java.util.List;
+import java.util.Random;
+
+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.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PDouble;
+import org.apache.phoenix.schema.types.PLong;
+
+/**
+ * Random function that produces a unique value upon each invocation unless a 
seed is provided.
+ * If a seed is provided the returned value is identical across each 
invocation for a single row, but different across multiple rows.
+ * The seed must be a constant.
+ * <p>
+ * Example:
+ * <pre>
+ * 0: jdbc:phoenix:localhost> select rand(), rand(), rand(1), rand(2), rand(1) 
from t;
+ * 
+----------------------------+----------------------------+----------------------------+----------------------------+-----------------------+
+ * |           RAND()           |           RAND()           |          
RAND(1)           |          RAND(2)           |          RAND(1)      |
+ * 
+----------------------------+----------------------------+----------------------------+----------------------------+-----------------------+
+ * | 0.18927325291276054        | 0.19335253869230284        | 
0.7308781907032909         | 0.7311469360199058         | 0.7308781907032909    
|
+ * | 0.08156917775368278        | 0.10178318739559034        | 
0.41008081149220166        | 0.9014476240300544         | 0.41008081149220166   
|
+ * 
+----------------------------+----------------------------+----------------------------+----------------------------+-----------------------+
+ * 2 rows selected (0.096 seconds)
+ * 0: jdbc:phoenix:localhost> select rand(), rand(), rand(1), rand(2), rand(1) 
from t;
+ * 
+----------------------------+----------------------------+----------------------------+----------------------------+-----------------------+
+ * |           RAND()           |           RAND()           |          
RAND(1)           |          RAND(2)           |          RAND(1)      |
+ * 
+----------------------------+----------------------------+----------------------------+----------------------------+-----------------------+
+ * | 0.6452639556507597         | 0.8167638693890659         | 
0.7308781907032909         | 0.7311469360199058         | 0.7308781907032909    
|
+ * | 0.8084646053276106         | 0.6969504742211767         | 
0.41008081149220166        | 0.9014476240300544         | 0.41008081149220166   
|
+ * 
+----------------------------+----------------------------+----------------------------+----------------------------+-----------------------+
+ * 2 rows selected (0.098 seconds)
+ * </pre>
+ */
+@BuiltInFunction(name = RandomFunction.NAME, args = 
{@Argument(allowedTypes={PLong.class},defaultValue="null",isConstant=true)})
+public class RandomFunction extends ScalarFunction {
+    public static final String NAME = "RAND";
+    private Random random;
+    private boolean hasSeed;
+    private Double current;
+
+    public RandomFunction() {
+    }
+
+    public RandomFunction(List<Expression> children) {
+        super(children);
+        init();
+    }
+
+    private void init() {
+        Number seed = (Number)((LiteralExpression)children.get(0)).getValue();
+        random = seed == null ? new Random() : new Random(seed.longValue());
+        hasSeed = seed != null;
+        current = null;
+    }
+
+    @Override
+    public void readFields(DataInput input) throws IOException {
+        super.readFields(input);
+        init();
+    }
+
+    @Override
+    public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
+        if (current == null) {
+            current = random.nextDouble();
+        }
+        ptr.set(PDouble.INSTANCE.toBytes(current));
+        return true;
+    }
+
+    // produce a new random value for each row
+    @Override
+    public void reset() {
+        super.reset();
+        current = null;
+    }
+
+    @Override
+    public PDataType<?> getDataType() {
+        return PDouble.INSTANCE;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+    @Override
+    public Determinism getDeterminism() {
+        return hasSeed ? Determinism.PER_ROW : Determinism.PER_INVOCATION;
+    }
+
+    @Override
+    public boolean isStateless() {
+        return true;
+    }
+
+    // take the random object onto account
+    @Override
+    public int hashCode() {
+        int hashCode = super.hashCode();
+        return hasSeed ? hashCode : (hashCode + random.hashCode());
+    }
+
+    // take the random object onto account, as otherwise we'll potentially 
collapse two
+    // RAND() calls into a single one.
+    @Override
+    public boolean equals(Object obj) {
+        return super.equals(obj) && (hasSeed || 
random.equals(((RandomFunction)obj).random));
+    }
+
+    // make sure we do not show the default 'null' parameter
+    @Override
+    public final String toString() {
+        StringBuilder buf = new StringBuilder(getName() + "(");
+        if (!hasSeed) return buf.append(")").toString();
+        for (int i = 0; i < children.size() - 1; i++) {
+            buf.append(children.get(i) + ", ");
+        }
+        buf.append(children.get(children.size()-1) + ")");
+        return buf.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ScalarFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ScalarFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ScalarFunction.java
index 37b8816..e694680 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ScalarFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ScalarFunction.java
@@ -36,6 +36,15 @@ public abstract class ScalarFunction extends 
FunctionExpression {
         super(children);
     }
     
+    public ScalarFunction clone(List<Expression> children) {
+        try {
+            // FIXME: we could potentially implement this on each subclass and 
not use reflection
+            return getClass().getConstructor(List.class).newInstance(children);
+        } catch (Exception e) {
+            throw new RuntimeException(e); // Impossible, since it was 
originally constructed this way
+        }
+    }
+    
     protected static byte[] evaluateExpression(Expression rhs) {
         ImmutableBytesWritable ptr = new ImmutableBytesWritable();
         rhs.evaluate(null, ptr);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/BaseExpressionVisitor.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/BaseExpressionVisitor.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/BaseExpressionVisitor.java
index 22bf195..8e8b32d 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/BaseExpressionVisitor.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/BaseExpressionVisitor.java
@@ -30,36 +30,21 @@ import org.apache.phoenix.expression.DivideExpression;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.InListExpression;
 import org.apache.phoenix.expression.IsNullExpression;
-import org.apache.phoenix.expression.KeyValueColumnExpression;
 import org.apache.phoenix.expression.LikeExpression;
-import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.ModulusExpression;
 import org.apache.phoenix.expression.MultiplyExpression;
 import org.apache.phoenix.expression.NotExpression;
 import org.apache.phoenix.expression.OrExpression;
-import org.apache.phoenix.expression.ProjectedColumnExpression;
-import org.apache.phoenix.expression.RowKeyColumnExpression;
 import org.apache.phoenix.expression.RowValueConstructorExpression;
 import org.apache.phoenix.expression.StringConcatExpression;
 import org.apache.phoenix.expression.SubtractExpression;
+import org.apache.phoenix.expression.function.ArrayAnyComparisonExpression;
+import org.apache.phoenix.expression.function.ArrayElemRefExpression;
 import org.apache.phoenix.expression.function.ScalarFunction;
 import org.apache.phoenix.expression.function.SingleAggregateFunction;
 
 
 public abstract class BaseExpressionVisitor<E> implements ExpressionVisitor<E> 
{
-    @Override
-    public E visit(Expression node) {
-        return null;
-    }
-
-    @Override
-    public Iterator<Expression> visitEnter(Expression node) {
-        return null;
-    }
-
-    @Override
-    public E visitLeave(Expression node, List<E> l) {
-        return null;
-    }
 
     @Override
     public E defaultReturn(Expression node, List<E> l) {
@@ -72,117 +57,52 @@ public abstract class BaseExpressionVisitor<E> implements 
ExpressionVisitor<E> {
     }
 
     @Override
-    public E visitLeave(AndExpression node, List<E> l) {
-        return null;
-    }
-
-    @Override
     public Iterator<Expression> visitEnter(OrExpression node) {
         return null;
     }
 
     @Override
-    public E visitLeave(OrExpression node, List<E> l) {
-        return null;
-    }
-
-    @Override
     public Iterator<Expression> visitEnter(ScalarFunction node) {
         return null;
     }
 
     @Override
-    public E visitLeave(ScalarFunction node, List<E> l) {
-        return null;
-    }
-
-    @Override
     public Iterator<Expression> visitEnter(ComparisonExpression node) {
         return null;
     }
 
     @Override
-    public E visitLeave(ComparisonExpression node, List<E> l) {
-        return null;
-    }
-
-    @Override
     public Iterator<Expression> visitEnter(LikeExpression node) {
         return null;
     }
 
     @Override
-    public E visitLeave(LikeExpression node, List<E> l) {
-        return null;
-    }
-
-    @Override
     public Iterator<Expression> visitEnter(SingleAggregateFunction node) {
         return null;
     }
 
     @Override
-    public E visitLeave(SingleAggregateFunction node, List<E> l) {
-        return null;
-    }
-
-    @Override
     public Iterator<Expression> visitEnter(CaseExpression node) {
         return null;
     }
 
     @Override
-    public E visitLeave(CaseExpression node, List<E> l) {
-        return null;
-    }
-
-    @Override
     public Iterator<Expression> visitEnter(NotExpression node) {
         return null;
     }
 
     @Override
-    public E visitLeave(NotExpression node, List<E> l) {
-        return null;
-    }
-
-    @Override
     public Iterator<Expression> visitEnter(IsNullExpression node) {
         return null;
     }
 
     @Override
-    public E visitLeave(IsNullExpression node, List<E> l) {
-        return null;
-    }
-
-    @Override
     public Iterator<Expression> visitEnter(InListExpression node) {
         return null;
     }
 
     @Override
-    public E visitLeave(InListExpression node, List<E> l) {
-        return null;
-    }
-
-    @Override
-    public E visit(LiteralExpression node) {
-        return null;
-    }
-
-    @Override
-    public E visit(RowKeyColumnExpression node) {
-        return null;
-    }
-
-    @Override
-    public E visit(KeyValueColumnExpression node) {
-        return null;
-    }
-    
-    @Override
-    public E visit(ProjectedColumnExpression node) {
+    public Iterator<Expression> visitEnter(AddExpression node) {
         return null;
     }
 
@@ -192,71 +112,48 @@ public abstract class BaseExpressionVisitor<E> implements 
ExpressionVisitor<E> {
     }
 
     @Override
-    public E visitLeave(SubtractExpression node, List<E> l) {
-        return null;
-    }
-
-    @Override
-    public Iterator<Expression> visitEnter(AddExpression node) {
-        return null;
-    }
-    @Override
-    public E visitLeave(AddExpression node, List<E> l) {
-        return null;
-    }
-
-    @Override
     public Iterator<Expression> visitEnter(MultiplyExpression node) {
         return null;
     }
-    @Override
-    public E visitLeave(MultiplyExpression node, List<E> l) {
-        return null;
-    }
 
     @Override
     public Iterator<Expression> visitEnter(DivideExpression node) {
         return null;
     }
-    @Override
-    public E visitLeave(DivideExpression node, List<E> l) {
-        return null;
-    }
     
     @Override
     public Iterator<Expression> visitEnter(StringConcatExpression node) {
         return null;
     }
-    @Override
-    public E visitLeave(StringConcatExpression node, List<E> l) {
-        return null;
-    }
     
     @Override
     public Iterator<Expression> visitEnter(RowValueConstructorExpression node) 
{
         return null;
     }
+    
     @Override
-    public E visitLeave(RowValueConstructorExpression node, List<E> l) {
+    public Iterator<Expression> visitEnter(CoerceExpression node) {
         return null;
     }
     
     @Override
-    public Iterator<Expression> visitEnter(CoerceExpression node) {
+    public Iterator<Expression> visitEnter(ArrayConstructorExpression node) {
         return null;
     }
     
     @Override
-    public E visitLeave(CoerceExpression node, List<E> l) {
+    public Iterator<Expression> visitEnter(ModulusExpression 
modulusExpression) {
         return null;
     }
 
     @Override
-    public Iterator<Expression> visitEnter(ArrayConstructorExpression node) {
+    public Iterator<Expression> visitEnter(ArrayAnyComparisonExpression 
arrayAnyComparisonExpression) {
         return null;
     }
+
     @Override
-    public E visitLeave(ArrayConstructorExpression node, List<E> l) {
+    public Iterator<Expression> visitEnter(ArrayElemRefExpression 
arrayElemRefExpression) {
         return null;
     }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/CloneExpressionVisitor.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/CloneExpressionVisitor.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/CloneExpressionVisitor.java
new file mode 100644
index 0000000..f415b01
--- /dev/null
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/CloneExpressionVisitor.java
@@ -0,0 +1,195 @@
+/*
+ * 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.visitor;
+
+import java.util.List;
+
+import org.apache.phoenix.compile.SequenceValueExpression;
+import org.apache.phoenix.expression.AddExpression;
+import org.apache.phoenix.expression.AndExpression;
+import org.apache.phoenix.expression.ArrayConstructorExpression;
+import org.apache.phoenix.expression.CaseExpression;
+import org.apache.phoenix.expression.CoerceExpression;
+import org.apache.phoenix.expression.ComparisonExpression;
+import org.apache.phoenix.expression.Determinism;
+import org.apache.phoenix.expression.DivideExpression;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.InListExpression;
+import org.apache.phoenix.expression.IsNullExpression;
+import org.apache.phoenix.expression.KeyValueColumnExpression;
+import org.apache.phoenix.expression.LikeExpression;
+import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.ModulusExpression;
+import org.apache.phoenix.expression.MultiplyExpression;
+import org.apache.phoenix.expression.NotExpression;
+import org.apache.phoenix.expression.OrExpression;
+import org.apache.phoenix.expression.ProjectedColumnExpression;
+import org.apache.phoenix.expression.RowKeyColumnExpression;
+import org.apache.phoenix.expression.RowValueConstructorExpression;
+import org.apache.phoenix.expression.StringConcatExpression;
+import org.apache.phoenix.expression.SubtractExpression;
+import org.apache.phoenix.expression.function.ArrayAnyComparisonExpression;
+import org.apache.phoenix.expression.function.ArrayElemRefExpression;
+import org.apache.phoenix.expression.function.ScalarFunction;
+import org.apache.phoenix.expression.function.SingleAggregateFunction;
+
+public class CloneExpressionVisitor extends 
TraverseAllExpressionVisitor<Expression> {
+
+    public CloneExpressionVisitor() {
+    }
+
+    @Override
+    public Expression defaultReturn(Expression node, List<Expression> l) {
+        // Needed for Expressions derived from BaseTerminalExpression which 
don't
+        // have accept methods. TODO: get rid of those
+        return node;
+    }
+
+    @Override
+    public Expression visit(LiteralExpression node) {
+        return node;
+    }
+
+    @Override
+    public Expression visit(RowKeyColumnExpression node) {
+        return node;
+    }
+
+    @Override
+    public Expression visit(KeyValueColumnExpression node) {
+        return node;
+    }
+
+    @Override
+    public Expression visit(ProjectedColumnExpression node) {
+        return node;
+    }
+
+    @Override
+    public Expression visit(SequenceValueExpression node) {
+        return node;
+    }
+
+    @Override
+    public Expression visitLeave(AndExpression node, List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node : new AndExpression(l);
+    }
+
+    @Override
+    public Expression visitLeave(OrExpression node, List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  new OrExpression(l);
+    }
+
+    @Override
+    public Expression visitLeave(ScalarFunction node, List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  node.clone(l);
+    }
+
+    @Override
+    public Expression visitLeave(ComparisonExpression node, List<Expression> 
l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  node.clone(l);
+    }
+
+    @Override
+    public Expression visitLeave(LikeExpression node, List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  new LikeExpression(l);
+    }
+
+    @Override
+    public Expression visitLeave(SingleAggregateFunction node, 
List<Expression> l) {
+        // Do not clone aggregate functions, as they're executed on the server 
side,
+        // so any state for evaluation will live there.
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  node;
+    }
+
+    @Override
+    public Expression visitLeave(CaseExpression node, List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  new CaseExpression(l);
+    }
+
+    @Override
+    public Expression visitLeave(NotExpression node, List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  new NotExpression(l);
+    }
+
+    @Override
+    public Expression visitLeave(InListExpression node, List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  new InListExpression(l);
+    }
+
+    @Override
+    public Expression visitLeave(IsNullExpression node, List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  node.clone(l);
+    }
+
+    @Override
+    public Expression visitLeave(SubtractExpression node, List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  node.clone(l);
+    }
+
+    @Override
+    public Expression visitLeave(MultiplyExpression node, List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  node.clone(l);
+    }
+
+    @Override
+    public Expression visitLeave(AddExpression node, List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node : node.clone(l);
+    }
+
+    @Override
+    public Expression visitLeave(DivideExpression node, List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  node.clone(l);
+    }
+
+    @Override
+    public Expression visitLeave(ModulusExpression node, List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  node.clone(l);
+    }
+
+    @Override
+    public Expression visitLeave(CoerceExpression node, List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  node.clone(l);
+    }
+
+    @Override
+    public Expression visitLeave(ArrayConstructorExpression node, 
List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  node.clone(l);
+    }
+
+    @Override
+    public Expression visitLeave(StringConcatExpression node, List<Expression> 
l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  new StringConcatExpression(l);
+    }
+
+    @Override
+    public Expression visitLeave(RowValueConstructorExpression node, 
List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  node.clone(l);
+    }
+
+    @Override
+    public Expression visitLeave(ArrayAnyComparisonExpression node, 
List<Expression> l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  new ArrayAnyComparisonExpression(l);
+    }
+
+    @Override
+    public Expression visitLeave(ArrayElemRefExpression node, List<Expression> 
l) {
+        return Determinism.PER_INVOCATION.compareTo(node.getDeterminism()) > 0 
? node :  new ArrayElemRefExpression(l);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/ExpressionVisitor.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/ExpressionVisitor.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/ExpressionVisitor.java
index 794c348..0a8d3ad 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/ExpressionVisitor.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/ExpressionVisitor.java
@@ -20,6 +20,7 @@ package org.apache.phoenix.expression.visitor;
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.phoenix.compile.SequenceValueExpression;
 import org.apache.phoenix.expression.AddExpression;
 import org.apache.phoenix.expression.AndExpression;
 import org.apache.phoenix.expression.ArrayConstructorExpression;
@@ -33,6 +34,7 @@ import org.apache.phoenix.expression.IsNullExpression;
 import org.apache.phoenix.expression.KeyValueColumnExpression;
 import org.apache.phoenix.expression.LikeExpression;
 import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.ModulusExpression;
 import org.apache.phoenix.expression.MultiplyExpression;
 import org.apache.phoenix.expression.NotExpression;
 import org.apache.phoenix.expression.OrExpression;
@@ -41,6 +43,8 @@ import org.apache.phoenix.expression.RowKeyColumnExpression;
 import org.apache.phoenix.expression.RowValueConstructorExpression;
 import org.apache.phoenix.expression.StringConcatExpression;
 import org.apache.phoenix.expression.SubtractExpression;
+import org.apache.phoenix.expression.function.ArrayAnyComparisonExpression;
+import org.apache.phoenix.expression.function.ArrayElemRefExpression;
 import org.apache.phoenix.expression.function.ScalarFunction;
 import org.apache.phoenix.expression.function.SingleAggregateFunction;
 
@@ -53,28 +57,6 @@ import 
org.apache.phoenix.expression.function.SingleAggregateFunction;
  * @since 0.1
  */
 public interface ExpressionVisitor<E> {
-    /**
-     * Default visit method when an expression subclass doesn't
-     * define an accept method of its own. This will end up calling
-     * the {@link #defaultIterator(Expression)} to iterate over the
-     * children calling accept on them
-     */
-    public E visit(Expression node);
-    /**
-     * Default visitEnter method when an expression subclass doesn't
-     * define an accept method of its own. This will end up calling
-     * the {@link #defaultIterator(Expression)} to iterate over the
-     * children calling accept on them
-     */
-    public Iterator<Expression> visitEnter(Expression node);
-    /**
-     * Default visitLeave method when an expression subclass doesn't
-     * define an accept method of its own.  This will end up calling
-     * the {@link #defaultReturn(Expression, List)} with the list from
-     * the iteration over the children.
-     */
-    public E visitLeave(Expression node, List<E> l);
-
     public E defaultReturn(Expression node, List<E> l);
     public Iterator<Expression> defaultIterator(Expression node);
     
@@ -130,11 +112,22 @@ public interface ExpressionVisitor<E> {
     public E visit(RowKeyColumnExpression node);
     public E visit(KeyValueColumnExpression node);
     public E visit(ProjectedColumnExpression node);
+    public E visit(SequenceValueExpression node);
     
        public Iterator<Expression> visitEnter(StringConcatExpression node);
        public E visitLeave(StringConcatExpression node, List<E> l);
        
        public Iterator<Expression> visitEnter(RowValueConstructorExpression 
node);
     public E visitLeave(RowValueConstructorExpression node, List<E> l);
+
+    public Iterator<Expression> visitEnter(ModulusExpression 
modulusExpression);
+    public E visitLeave(ModulusExpression node, List<E> l);
+    
+    public Iterator<Expression> visitEnter(ArrayAnyComparisonExpression 
arrayAnyComparisonExpression);
+    public E visitLeave(ArrayAnyComparisonExpression node, List<E> l);
+    
+    public Iterator<Expression> visitEnter(ArrayElemRefExpression 
arrayElemRefExpression);
+    public E visitLeave(ArrayElemRefExpression node, List<E> l);
+    
     
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/KeyValueExpressionVisitor.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/KeyValueExpressionVisitor.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/KeyValueExpressionVisitor.java
index 93ce7c5..df6a30c 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/KeyValueExpressionVisitor.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/KeyValueExpressionVisitor.java
@@ -30,7 +30,7 @@ import org.apache.phoenix.expression.KeyValueColumnExpression;
  * 
  * @since 0.1
  */
-public abstract class KeyValueExpressionVisitor extends 
TraverseAllExpressionVisitor<Void> {
+public abstract class KeyValueExpressionVisitor extends 
StatelessTraverseAllExpressionVisitor<Void> {
     @Override
     abstract public Void visit(KeyValueColumnExpression node);
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/RowKeyExpressionVisitor.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/RowKeyExpressionVisitor.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/RowKeyExpressionVisitor.java
index a3e8fb0..4b78550 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/RowKeyExpressionVisitor.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/RowKeyExpressionVisitor.java
@@ -30,7 +30,7 @@ import org.apache.phoenix.expression.RowKeyColumnExpression;
  * 
  * @since 0.1
  */
-public abstract class RowKeyExpressionVisitor extends 
TraverseAllExpressionVisitor<Void> {
+public abstract class RowKeyExpressionVisitor extends 
StatelessTraverseAllExpressionVisitor<Void> {
     @Override
     abstract public Void visit(RowKeyColumnExpression node);
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/SingleAggregateFunctionVisitor.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/SingleAggregateFunctionVisitor.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/SingleAggregateFunctionVisitor.java
index 8e3644a..7981a98 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/SingleAggregateFunctionVisitor.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/SingleAggregateFunctionVisitor.java
@@ -32,7 +32,7 @@ import 
org.apache.phoenix.expression.function.SingleAggregateFunction;
  * 
  * @since 0.1
  */
-public abstract class SingleAggregateFunctionVisitor extends 
TraverseAllExpressionVisitor<Void> {
+public abstract class SingleAggregateFunctionVisitor extends 
StatelessTraverseAllExpressionVisitor<Void> {
     @Override
     abstract public Iterator<Expression> visitEnter(SingleAggregateFunction 
node);
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/StatelessTraverseAllExpressionVisitor.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/StatelessTraverseAllExpressionVisitor.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/StatelessTraverseAllExpressionVisitor.java
new file mode 100644
index 0000000..e7e7c67
--- /dev/null
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/StatelessTraverseAllExpressionVisitor.java
@@ -0,0 +1,181 @@
+/*
+ * 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.visitor;
+
+import java.util.List;
+
+import org.apache.phoenix.compile.SequenceValueExpression;
+import org.apache.phoenix.expression.AddExpression;
+import org.apache.phoenix.expression.AndExpression;
+import org.apache.phoenix.expression.ArrayConstructorExpression;
+import org.apache.phoenix.expression.CaseExpression;
+import org.apache.phoenix.expression.CoerceExpression;
+import org.apache.phoenix.expression.ComparisonExpression;
+import org.apache.phoenix.expression.DivideExpression;
+import org.apache.phoenix.expression.InListExpression;
+import org.apache.phoenix.expression.IsNullExpression;
+import org.apache.phoenix.expression.KeyValueColumnExpression;
+import org.apache.phoenix.expression.LikeExpression;
+import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.ModulusExpression;
+import org.apache.phoenix.expression.MultiplyExpression;
+import org.apache.phoenix.expression.NotExpression;
+import org.apache.phoenix.expression.OrExpression;
+import org.apache.phoenix.expression.ProjectedColumnExpression;
+import org.apache.phoenix.expression.RowKeyColumnExpression;
+import org.apache.phoenix.expression.RowValueConstructorExpression;
+import org.apache.phoenix.expression.StringConcatExpression;
+import org.apache.phoenix.expression.SubtractExpression;
+import org.apache.phoenix.expression.function.ArrayAnyComparisonExpression;
+import org.apache.phoenix.expression.function.ArrayElemRefExpression;
+import org.apache.phoenix.expression.function.ScalarFunction;
+import org.apache.phoenix.expression.function.SingleAggregateFunction;
+
+public class StatelessTraverseAllExpressionVisitor<E> extends 
TraverseAllExpressionVisitor<E> {
+
+    @Override
+    public E visitLeave(AndExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(OrExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(ScalarFunction node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(ComparisonExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(LikeExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(SingleAggregateFunction node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(CaseExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(NotExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(IsNullExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(InListExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visit(LiteralExpression node) {
+        return null;
+    }
+
+    @Override
+    public E visit(RowKeyColumnExpression node) {
+        return null;
+    }
+
+    @Override
+    public E visit(KeyValueColumnExpression node) {
+        return null;
+    }
+    
+    @Override
+    public E visit(ProjectedColumnExpression node) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(AddExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(SubtractExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(MultiplyExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(DivideExpression node, List<E> l) {
+        return null;
+    }
+    
+    @Override
+    public E visitLeave(StringConcatExpression node, List<E> l) {
+        return null;
+    }
+    
+    @Override
+    public E visitLeave(RowValueConstructorExpression node, List<E> l) {
+        return null;
+    }
+    
+    @Override
+    public E visitLeave(CoerceExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(ArrayConstructorExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(ModulusExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(ArrayAnyComparisonExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(ArrayElemRefExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visit(SequenceValueExpression node) {
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/StatelessTraverseNoExpressionVisitor.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/StatelessTraverseNoExpressionVisitor.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/StatelessTraverseNoExpressionVisitor.java
new file mode 100644
index 0000000..019754f
--- /dev/null
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/StatelessTraverseNoExpressionVisitor.java
@@ -0,0 +1,181 @@
+/*
+ * 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.visitor;
+
+import java.util.List;
+
+import org.apache.phoenix.compile.SequenceValueExpression;
+import org.apache.phoenix.expression.AddExpression;
+import org.apache.phoenix.expression.AndExpression;
+import org.apache.phoenix.expression.ArrayConstructorExpression;
+import org.apache.phoenix.expression.CaseExpression;
+import org.apache.phoenix.expression.CoerceExpression;
+import org.apache.phoenix.expression.ComparisonExpression;
+import org.apache.phoenix.expression.DivideExpression;
+import org.apache.phoenix.expression.InListExpression;
+import org.apache.phoenix.expression.IsNullExpression;
+import org.apache.phoenix.expression.KeyValueColumnExpression;
+import org.apache.phoenix.expression.LikeExpression;
+import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.ModulusExpression;
+import org.apache.phoenix.expression.MultiplyExpression;
+import org.apache.phoenix.expression.NotExpression;
+import org.apache.phoenix.expression.OrExpression;
+import org.apache.phoenix.expression.ProjectedColumnExpression;
+import org.apache.phoenix.expression.RowKeyColumnExpression;
+import org.apache.phoenix.expression.RowValueConstructorExpression;
+import org.apache.phoenix.expression.StringConcatExpression;
+import org.apache.phoenix.expression.SubtractExpression;
+import org.apache.phoenix.expression.function.ArrayAnyComparisonExpression;
+import org.apache.phoenix.expression.function.ArrayElemRefExpression;
+import org.apache.phoenix.expression.function.ScalarFunction;
+import org.apache.phoenix.expression.function.SingleAggregateFunction;
+
+public class StatelessTraverseNoExpressionVisitor<E> extends 
TraverseNoExpressionVisitor<E> {
+
+    @Override
+    public E visitLeave(AndExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(OrExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(ScalarFunction node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(ComparisonExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(LikeExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(SingleAggregateFunction node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(CaseExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(NotExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(IsNullExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(InListExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visit(LiteralExpression node) {
+        return null;
+    }
+
+    @Override
+    public E visit(RowKeyColumnExpression node) {
+        return null;
+    }
+
+    @Override
+    public E visit(KeyValueColumnExpression node) {
+        return null;
+    }
+    
+    @Override
+    public E visit(ProjectedColumnExpression node) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(AddExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(SubtractExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(MultiplyExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(DivideExpression node, List<E> l) {
+        return null;
+    }
+    
+    @Override
+    public E visitLeave(StringConcatExpression node, List<E> l) {
+        return null;
+    }
+    
+    @Override
+    public E visitLeave(RowValueConstructorExpression node, List<E> l) {
+        return null;
+    }
+    
+    @Override
+    public E visitLeave(CoerceExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(ArrayConstructorExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(ModulusExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(ArrayAnyComparisonExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visitLeave(ArrayElemRefExpression node, List<E> l) {
+        return null;
+    }
+
+    @Override
+    public E visit(SequenceValueExpression node) {
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/TraverseAllExpressionVisitor.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/TraverseAllExpressionVisitor.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/TraverseAllExpressionVisitor.java
index c770b80..126be8d 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/TraverseAllExpressionVisitor.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/TraverseAllExpressionVisitor.java
@@ -17,14 +17,16 @@
  */
 package org.apache.phoenix.expression.visitor;
 
-import java.util.*;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
 
 import org.apache.phoenix.expression.Expression;
 
 
 
 
-public class TraverseAllExpressionVisitor<E> extends BaseExpressionVisitor<E> {
+public abstract class TraverseAllExpressionVisitor<E> extends 
BaseExpressionVisitor<E> {
 
     @Override
     public Iterator<Expression> defaultIterator(Expression node) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/TraverseNoExpressionVisitor.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/TraverseNoExpressionVisitor.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/TraverseNoExpressionVisitor.java
index 193d98d..4d488ef 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/TraverseNoExpressionVisitor.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/visitor/TraverseNoExpressionVisitor.java
@@ -19,11 +19,11 @@ package org.apache.phoenix.expression.visitor;
 
 import java.util.Iterator;
 
+import org.apache.phoenix.expression.Expression;
 
 import com.google.common.collect.Iterators;
-import org.apache.phoenix.expression.Expression;
 
-public class TraverseNoExpressionVisitor<E> extends BaseExpressionVisitor<E> {
+public abstract class TraverseNoExpressionVisitor<E> extends 
BaseExpressionVisitor<E> {
 
     @Override
     public Iterator<Expression> defaultIterator(Expression node) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/filter/MultiKeyValueComparisonFilter.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/filter/MultiKeyValueComparisonFilter.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/filter/MultiKeyValueComparisonFilter.java
index 7df3b27..1cb2255 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/filter/MultiKeyValueComparisonFilter.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/filter/MultiKeyValueComparisonFilter.java
@@ -30,7 +30,8 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.KeyValueColumnExpression;
-import org.apache.phoenix.expression.visitor.TraverseAllExpressionVisitor;
+import org.apache.phoenix.expression.visitor.ExpressionVisitor;
+import 
org.apache.phoenix.expression.visitor.StatelessTraverseAllExpressionVisitor;
 import org.apache.phoenix.schema.tuple.BaseTuple;
 
 
@@ -184,7 +185,7 @@ public abstract class MultiKeyValueComparisonFilter extends 
BooleanExpressionFil
     
     protected void init() {
         cfSet = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
-        TraverseAllExpressionVisitor<Void> visitor = new 
TraverseAllExpressionVisitor<Void>() {
+        ExpressionVisitor<Void> visitor = new 
StatelessTraverseAllExpressionVisitor<Void>() {
             @Override
             public Void visit(KeyValueColumnExpression expression) {
                 inputTuple.addColumn(expression.getColumnFamily(), 
expression.getColumnName());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/filter/SingleKeyValueComparisonFilter.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/filter/SingleKeyValueComparisonFilter.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/filter/SingleKeyValueComparisonFilter.java
index 16c87ce..c7ead67 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/filter/SingleKeyValueComparisonFilter.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/filter/SingleKeyValueComparisonFilter.java
@@ -25,6 +25,7 @@ import org.apache.hadoop.hbase.KeyValueUtil;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.KeyValueColumnExpression;
+import 
org.apache.phoenix.expression.visitor.StatelessTraverseAllExpressionVisitor;
 import org.apache.phoenix.expression.visitor.TraverseAllExpressionVisitor;
 import org.apache.phoenix.schema.tuple.SingleKeyValueTuple;
 
@@ -56,7 +57,7 @@ public abstract class SingleKeyValueComparisonFilter extends 
BooleanExpressionFi
     protected abstract int compare(byte[] cfBuf, int cfOffset, int cfLength, 
byte[] cqBuf, int cqOffset, int cqLength);
 
     private void init() {
-        TraverseAllExpressionVisitor<Void> visitor = new 
TraverseAllExpressionVisitor<Void>() {
+        TraverseAllExpressionVisitor<Void> visitor = new 
StatelessTraverseAllExpressionVisitor<Void>() {
             @Override
             public Void visit(KeyValueColumnExpression expression) {
                 cf = expression.getColumnFamily();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixResultSet.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixResultSet.java 
b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixResultSet.java
index 1630dbd..7d91dbb 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixResultSet.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixResultSet.java
@@ -49,13 +49,15 @@ import org.apache.phoenix.compile.RowProjector;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.exception.SQLExceptionInfo;
 import org.apache.phoenix.iterate.ResultIterator;
-import org.apache.phoenix.schema.types.PDecimal;
+import org.apache.phoenix.schema.tuple.ResultTuple;
+import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PBoolean;
+import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PDate;
+import org.apache.phoenix.schema.types.PDecimal;
 import org.apache.phoenix.schema.types.PDouble;
 import org.apache.phoenix.schema.types.PFloat;
 import org.apache.phoenix.schema.types.PInteger;
-import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PLong;
 import org.apache.phoenix.schema.types.PSmallint;
 import org.apache.phoenix.schema.types.PTime;
@@ -63,8 +65,6 @@ import org.apache.phoenix.schema.types.PTimestamp;
 import org.apache.phoenix.schema.types.PTinyint;
 import org.apache.phoenix.schema.types.PVarbinary;
 import org.apache.phoenix.schema.types.PVarchar;
-import org.apache.phoenix.schema.tuple.ResultTuple;
-import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.DateUtil;
 import org.apache.phoenix.util.SQLCloseable;
 
@@ -762,6 +762,7 @@ public class PhoenixResultSet implements ResultSet, 
SQLCloseable, org.apache.pho
         checkOpen();
         try {
             currentRow = scanner.next();
+            rowProjector.reset();
         } catch (RuntimeException e) {
             // FIXME: Expression.evaluate does not throw SQLException
             // so this will unwrap throws from that.

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/PhoenixRecordReader.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/PhoenixRecordReader.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/PhoenixRecordReader.java
index 2c206ab..b8eb116 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/PhoenixRecordReader.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/PhoenixRecordReader.java
@@ -109,7 +109,9 @@ public class PhoenixRecordReader<T extends DBWritable> 
extends RecordReader<Null
                 iterator = new SequenceResultIterator(iterator, 
queryPlan.getContext().getSequenceManager());
             }
             this.resultIterator = iterator;
-            this.resultSet = new PhoenixResultSet(this.resultIterator, 
queryPlan.getProjector(),queryPlan.getContext().getStatement());
+            // Clone the row projector as it's not thread safe and would be 
used simultaneously by
+            // multiple threads otherwise.
+            this.resultSet = new PhoenixResultSet(this.resultIterator, 
queryPlan.getProjector().clone(),queryPlan.getContext().getStatement());
         } catch (SQLException e) {
             LOG.error(String.format(" Error [%s] initializing 
PhoenixRecordReader. ",e.getMessage()));
             Throwables.propagate(e);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/5a988cb8/phoenix-core/src/test/java/org/apache/phoenix/arithmetic/ArithmeticOperationTest.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/test/java/org/apache/phoenix/arithmetic/ArithmeticOperationTest.java
 
b/phoenix-core/src/test/java/org/apache/phoenix/arithmetic/ArithmeticOperationTest.java
deleted file mode 100644
index c0b0c20..0000000
--- 
a/phoenix-core/src/test/java/org/apache/phoenix/arithmetic/ArithmeticOperationTest.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * 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.arithmetic;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.math.BigDecimal;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-import org.apache.phoenix.exception.ValueTypeIncompatibleException;
-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.Expression;
-import org.apache.phoenix.expression.LiteralExpression;
-import org.apache.phoenix.schema.types.PDecimal;
-import org.apache.phoenix.schema.types.PInteger;
-import org.apache.phoenix.schema.types.PDataType;
-import org.junit.Test;
-
-
-public class ArithmeticOperationTest {
-
-    // Addition
-    // result scale should be: max(ls, rs)
-    // result precision should be: max(lp - ls, rp - rs) + 1 + max(ls, rs)
-    @Test
-    public void testDecimalAddition() throws Exception {
-        LiteralExpression op1, op2, op3;
-        List<Expression> children;
-        ImmutableBytesWritable ptr;
-        DecimalAddExpression e;
-        boolean evaluated;
-
-        op1 = LiteralExpression.newConstant(new 
BigDecimal("1234567890123456789012345678901"), PDecimal.INSTANCE, 31, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("12345"), 
PDecimal.INSTANCE, 5, 0);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalAddExpression(children);
-        ptr = new ImmutableBytesWritable();
-        evaluated = e.evaluate(null, ptr);
-        assertTrue(evaluated);
-        assertEqualValue(PDecimal.INSTANCE, new 
BigDecimal("1234567890123456789012345691246"), ptr);
-
-        op1 = LiteralExpression.newConstant(new BigDecimal("12345"), 
PDecimal.INSTANCE, 5, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("123.45"), 
PDecimal.INSTANCE, 5, 2);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalAddExpression(children);
-        ptr = new ImmutableBytesWritable();
-        evaluated = e.evaluate(null, ptr);
-        assertTrue(evaluated);
-        assertEqualValue(PDecimal.INSTANCE, new BigDecimal("12468.45"), ptr);
-
-        // Exceeds precision.
-        op1 = LiteralExpression.newConstant(new 
BigDecimal("99999999999999999999999999999999999999"), PDecimal.INSTANCE, 38, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("123"), 
PDecimal.INSTANCE, 3, 0);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalAddExpression(children);
-        ptr = new ImmutableBytesWritable();
-        try {
-            evaluated = e.evaluate(null, ptr);
-            fail("Evaluation should have failed");
-        } catch (ValueTypeIncompatibleException ex) {
-        }
-
-        // Pass since we roll out imposing precisioin and scale.
-        op1 = LiteralExpression.newConstant(new 
BigDecimal("99999999999999999999999999999999999999"), PDecimal.INSTANCE, 38, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("123"), 
PDecimal.INSTANCE, 3, 0);
-        op3 = LiteralExpression.newConstant(new BigDecimal("-123"), 
PDecimal.INSTANCE, 3, 0);
-        children = Arrays.<Expression>asList(op1, op2, op3);
-        e = new DecimalAddExpression(children);
-        ptr = new ImmutableBytesWritable();
-        evaluated = e.evaluate(null, ptr);
-        assertTrue(evaluated);
-        assertEqualValue(PDecimal.INSTANCE, new 
BigDecimal("99999999999999999999999999999999999999"), ptr);
-
-        // Exceeds scale.
-        op1 = LiteralExpression.newConstant(new 
BigDecimal("12345678901234567890123456789012345678"), PDecimal.INSTANCE, 38, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("123.45"), 
PDecimal.INSTANCE, 5, 2);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalAddExpression(children);
-        ptr = new ImmutableBytesWritable();
-        try {
-            evaluated = e.evaluate(null, ptr);
-            fail("Evaluation should have failed");
-        } catch (ValueTypeIncompatibleException ex) {
-        }
-        
-        // Decimal with no precision and scale.
-        op1 = LiteralExpression.newConstant(new BigDecimal("9999.1"), 
PDecimal.INSTANCE);
-        op2 = LiteralExpression.newConstant(new BigDecimal("1.1111"), 
PDecimal.INSTANCE, 5, 4);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalAddExpression(children);
-        ptr = new ImmutableBytesWritable();
-        evaluated = e.evaluate(null, ptr);
-        assertTrue(evaluated);
-        assertEqualValue(PDecimal.INSTANCE, new BigDecimal("10000.2111"), ptr);
-    }
-
-    @Test
-    public void testIntPlusDecimal() throws Exception {
-        LiteralExpression op1, op2;
-        List<Expression> children;
-        ImmutableBytesWritable ptr;
-        DecimalAddExpression e;
-        boolean evaluated;
-
-        op1 = LiteralExpression.newConstant(new BigDecimal("1234.111"), 
PDecimal.INSTANCE);
-        assertNull(op1.getScale());
-        op2 = LiteralExpression.newConstant(1, PInteger.INSTANCE);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalAddExpression(children);
-        ptr = new ImmutableBytesWritable();
-        evaluated = e.evaluate(null, ptr);
-        assertTrue(evaluated);
-        assertEqualValue(PDecimal.INSTANCE, new BigDecimal("1235.111"), ptr);
-    }
-
-    // Subtraction
-    // result scale should be: max(ls, rs)
-    // result precision should be: max(lp - ls, rp - rs) + 1 + max(ls, rs)
-    @Test
-    public void testDecimalSubtraction() throws Exception {
-        LiteralExpression op1, op2, op3;
-        List<Expression> children;
-        ImmutableBytesWritable ptr;
-        DecimalSubtractExpression e;
-        boolean evaluated;
-
-        op1 = LiteralExpression.newConstant(new 
BigDecimal("1234567890123456789012345678901"), PDecimal.INSTANCE, 31, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("12345"), 
PDecimal.INSTANCE, 5, 0);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalSubtractExpression(children);
-        ptr = new ImmutableBytesWritable();
-        evaluated = e.evaluate(null, ptr);
-        assertTrue(evaluated);
-        assertEqualValue(PDecimal.INSTANCE, new 
BigDecimal("1234567890123456789012345666556"), ptr);
-
-        op1 = LiteralExpression.newConstant(new BigDecimal("12345"), 
PDecimal.INSTANCE, 5, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("123.45"), 
PDecimal.INSTANCE, 5, 2);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalSubtractExpression(children);
-        ptr = new ImmutableBytesWritable();
-        evaluated = e.evaluate(null, ptr);
-        assertTrue(evaluated);
-        assertEqualValue(PDecimal.INSTANCE, new BigDecimal("12221.55"), ptr);
-
-        // Excceds precision
-        op1 = LiteralExpression.newConstant(new 
BigDecimal("99999999999999999999999999999999999999"), PDecimal.INSTANCE, 38, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("-123"), 
PDecimal.INSTANCE, 3, 0);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalSubtractExpression(children);
-        ptr = new ImmutableBytesWritable();
-        try {
-            evaluated = e.evaluate(null, ptr);
-            fail("Evaluation should have failed");
-        } catch (ValueTypeIncompatibleException ex) {
-        }
-
-        // Pass since we roll up precision and scale imposing.
-        op1 = LiteralExpression.newConstant(new 
BigDecimal("99999999999999999999999999999999999999"), PDecimal.INSTANCE, 38, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("-123"), 
PDecimal.INSTANCE, 3, 0);
-        op3 = LiteralExpression.newConstant(new BigDecimal("123"), 
PDecimal.INSTANCE, 3, 0);
-        children = Arrays.<Expression>asList(op1, op2, op3);
-        e = new DecimalSubtractExpression(children);
-        ptr = new ImmutableBytesWritable();
-        evaluated = e.evaluate(null, ptr);
-        assertTrue(evaluated);
-        assertEqualValue(PDecimal.INSTANCE, new 
BigDecimal("99999999999999999999999999999999999999"), ptr);
-
-        // Exceeds scale.
-        op1 = LiteralExpression.newConstant(new 
BigDecimal("12345678901234567890123456789012345678"), PDecimal.INSTANCE, 38, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("123.45"), 
PDecimal.INSTANCE, 5, 2);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalSubtractExpression(children);
-        ptr = new ImmutableBytesWritable();
-        try {
-            evaluated = e.evaluate(null, ptr);
-            fail("Evaluation should have failed");
-        } catch (ValueTypeIncompatibleException ex) {
-        }
-        
-        // Decimal with no precision and scale.
-        op1 = LiteralExpression.newConstant(new BigDecimal("1111.1"), 
PDecimal.INSTANCE);
-        op2 = LiteralExpression.newConstant(new BigDecimal("1.1111"), 
PDecimal.INSTANCE, 5, 4);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalSubtractExpression(children);
-        ptr = new ImmutableBytesWritable();
-        evaluated = e.evaluate(null, ptr);
-        assertTrue(evaluated);
-        assertEqualValue(PDecimal.INSTANCE, new BigDecimal("1109.9889"), ptr);
-    }
-
-    // Multiplication
-    // result scale should be: ls + rs
-    // result precision should be: lp + rp
-    @Test
-    public void testDecimalMultiplication() throws Exception {
-        LiteralExpression op1, op2;
-        List<Expression> children;
-        ImmutableBytesWritable ptr;
-        DecimalMultiplyExpression e;
-        boolean evaluated;
-
-        op1 = LiteralExpression.newConstant(new BigDecimal("12345"), 
PDecimal.INSTANCE, 5, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("123.45"), 
PDecimal.INSTANCE, 5, 2);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalMultiplyExpression(children);
-        ptr = new ImmutableBytesWritable();
-        evaluated = e.evaluate(null, ptr);
-        assertTrue(evaluated);
-        assertEqualValue(PDecimal.INSTANCE, new BigDecimal("1523990.25"), ptr);
-
-        // Value too big, exceeds precision.
-        op1 = LiteralExpression.newConstant(new 
BigDecimal("12345678901234567890123456789012345678"), PDecimal.INSTANCE, 38, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("12345"), 
PDecimal.INSTANCE, 5, 0);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalMultiplyExpression(children);
-        ptr = new ImmutableBytesWritable();
-        try {
-            evaluated = e.evaluate(null, ptr);
-            fail("Evaluation should have failed");
-        } catch (ValueTypeIncompatibleException ex) {
-        }
-
-        // Values exceeds scale.
-        op1 = LiteralExpression.newConstant(new 
BigDecimal("12345678901234567890123456789012345678"), PDecimal.INSTANCE, 38, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("1.45"), 
PDecimal.INSTANCE, 3, 2);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalMultiplyExpression(children);
-        ptr = new ImmutableBytesWritable();
-        try {
-            evaluated = e.evaluate(null, ptr);
-            fail("Evaluation should have failed");
-        } catch (ValueTypeIncompatibleException ex) {
-        }
-        
-        // Decimal with no precision and scale.
-        op1 = LiteralExpression.newConstant(new BigDecimal("1111.1"), 
PDecimal.INSTANCE);
-        assertNull(op1.getScale());
-        op2 = LiteralExpression.newConstant(new BigDecimal("1.1111"), 
PDecimal.INSTANCE, 5, 4);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalMultiplyExpression(children);
-        ptr = new ImmutableBytesWritable();
-        evaluated = e.evaluate(null, ptr);
-        assertTrue(evaluated);
-        assertEqualValue(PDecimal.INSTANCE, new BigDecimal("1234.54321"), ptr);
-    }
-
-    // Division
-    // result scale should be: 31 - lp + ls - rs
-    // result precision should be: lp - ls + rp + scale
-    @Test
-    public void testDecimalDivision() throws Exception {
-        LiteralExpression op1, op2;
-        List<Expression> children;
-        ImmutableBytesWritable ptr;
-        DecimalDivideExpression e;
-        boolean evaluated;
-
-        // The value should be 1234500.0000...00 because we set to scale to be 
24. However, in
-        // PhoenixResultSet.getBigDecimal, the case to (BigDecimal) actually 
cause the scale to be eradicated. As
-        // a result, the resulting value does not have the right form.
-        op1 = LiteralExpression.newConstant(new BigDecimal("12345"), 
PDecimal.INSTANCE, 5, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("0.01"), 
PDecimal.INSTANCE, 2, 2);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalDivideExpression(children);
-        ptr = new ImmutableBytesWritable();
-        evaluated = e.evaluate(null, ptr);
-        assertTrue(evaluated);
-        assertEqualValue(PDecimal.INSTANCE, new BigDecimal("1.2345E+6"), ptr);
-
-        // Exceeds precision.
-        op1 = LiteralExpression.newConstant(new 
BigDecimal("12345678901234567890123456789012345678"), PDecimal.INSTANCE, 38, 0);
-        op2 = LiteralExpression.newConstant(new BigDecimal("0.01"), 
PDecimal.INSTANCE, 2, 2);
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalDivideExpression(children);
-        ptr = new ImmutableBytesWritable();
-        try {
-            evaluated = e.evaluate(null, ptr);
-            fail("Evaluation should have failed");
-        } catch (ValueTypeIncompatibleException ex) {
-        }
-        
-        // Decimal with no precision and scale.
-        op1 = LiteralExpression.newConstant(new BigDecimal("10"), 
PDecimal.INSTANCE);
-        op2 = LiteralExpression.newConstant(new BigDecimal("3"), 
PDecimal.INSTANCE, 5, 4);
-        assertEquals(Integer.valueOf(4),op2.getScale());
-        children = Arrays.<Expression>asList(op1, op2);
-        e = new DecimalDivideExpression(children);
-        ptr = new ImmutableBytesWritable();
-        evaluated = e.evaluate(null, ptr);
-        assertTrue(evaluated);
-        assertEqualValue(PDecimal.INSTANCE, new 
BigDecimal("3.3333333333333333333333333333333333333"), ptr);
-    }
-
-    private static void assertEqualValue(PDataType type, Object value, 
ImmutableBytesWritable ptr) {
-        assertEquals(value, type.toObject(ptr.get()));
-    }
-}

Reply via email to