PHOENIX-1516 Add RAND() built-in function

Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/7a2944a0
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/7a2944a0
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/7a2944a0

Branch: refs/heads/master
Commit: 7a2944a0d2fa56431c06e63461afa6f1f63e65d0
Parents: f6f7109
Author: James Taylor <[email protected]>
Authored: Fri Jan 23 09:45:31 2015 -0800
Committer: James Taylor <[email protected]>
Committed: Fri Jan 23 09:45:31 2015 -0800

----------------------------------------------------------------------
 .../phoenix/compile/CreateTableCompiler.java    |   4 +-
 .../phoenix/compile/ExpressionCompiler.java     |  54 ++--
 .../phoenix/compile/ProjectionCompiler.java     |  11 +-
 .../apache/phoenix/compile/RowProjector.java    | 104 ++----
 .../apache/phoenix/compile/SequenceManager.java |  55 ----
 .../compile/SequenceValueExpression.java        |  83 +++++
 .../apache/phoenix/compile/WhereOptimizer.java  |  18 +-
 .../expression/ArithmeticExpression.java        |   2 +
 .../expression/ArrayConstructorExpression.java  |  17 +-
 .../expression/BaseCompoundExpression.java      |  11 -
 .../expression/BaseSingleExpression.java        |   6 +-
 .../expression/BaseTerminalExpression.java      |   8 -
 .../phoenix/expression/CaseExpression.java      |  22 +-
 .../phoenix/expression/CoerceExpression.java    |  15 +-
 .../expression/ComparisonExpression.java        |  22 +-
 .../phoenix/expression/DateAddExpression.java   |  12 +-
 .../expression/DateSubtractExpression.java      |  12 +-
 .../expression/DecimalAddExpression.java        |   9 +-
 .../expression/DecimalDivideExpression.java     |   9 +-
 .../expression/DecimalMultiplyExpression.java   |   9 +-
 .../expression/DecimalSubtractExpression.java   |  11 +-
 .../phoenix/expression/DoubleAddExpression.java |   8 +-
 .../expression/DoubleDivideExpression.java      |   8 +-
 .../expression/DoubleMultiplyExpression.java    |   8 +-
 .../expression/DoubleSubtractExpression.java    |   8 +-
 .../phoenix/expression/ExpressionType.java      |   4 +-
 .../phoenix/expression/InListExpression.java    |   6 +-
 .../phoenix/expression/IsNullExpression.java    |  13 +-
 .../phoenix/expression/LikeExpression.java      |  13 +-
 .../phoenix/expression/LongAddExpression.java   |   8 +-
 .../expression/LongDivideExpression.java        |   8 +-
 .../expression/LongMultiplyExpression.java      |  10 +-
 .../expression/LongSubtractExpression.java      |  10 +-
 .../phoenix/expression/ModulusExpression.java   |  22 +-
 .../phoenix/expression/NotExpression.java       |   8 +-
 .../phoenix/expression/RowKeyExpression.java    |  10 +-
 .../RowValueConstructorExpression.java          |   6 +-
 .../expression/TimestampAddExpression.java      |  12 +-
 .../expression/TimestampSubtractExpression.java |  12 +-
 .../expression/aggregator/BaseAggregator.java   |   7 +
 .../function/ArrayAnyComparisonExpression.java  |  15 +-
 .../function/ArrayElemRefExpression.java        |  83 +++++
 .../function/InlineArrayElemRefExpression.java  |  73 -----
 .../expression/function/RandomFunction.java     |   3 +-
 .../expression/function/ScalarFunction.java     |   9 +
 .../visitor/BaseExpressionVisitor.java          | 127 +-------
 .../visitor/CloneExpressionVisitor.java         | 195 +++++++++++
 .../expression/visitor/ExpressionVisitor.java   |  37 +--
 .../visitor/KeyValueExpressionVisitor.java      |   2 +-
 .../visitor/RowKeyExpressionVisitor.java        |   2 +-
 .../visitor/SingleAggregateFunctionVisitor.java |   2 +-
 .../StatelessTraverseAllExpressionVisitor.java  | 181 +++++++++++
 .../StatelessTraverseNoExpressionVisitor.java   | 181 +++++++++++
 .../visitor/TraverseAllExpressionVisitor.java   |   6 +-
 .../visitor/TraverseNoExpressionVisitor.java    |   4 +-
 .../filter/MultiKeyValueComparisonFilter.java   |   5 +-
 .../filter/SingleKeyValueComparisonFilter.java  |   3 +-
 .../arithmetic/ArithmeticOperationTest.java     | 320 -------------------
 .../expression/ArithmeticOperationTest.java     | 273 ++++++++++++++++
 .../phoenix/expression/ILikeExpressionTest.java |   2 +-
 .../phoenix/expression/LikeExpressionTest.java  |   2 +-
 .../expression/SortOrderExpressionTest.java     |   8 +-
 .../function/ExternalSqlTypeIdFunctionTest.java |  25 +-
 .../phoenix/parse/BuiltInFunctionInfoTest.java  |  22 +-
 .../java/org/apache/phoenix/util/TestUtil.java  |  12 +-
 65 files changed, 1420 insertions(+), 847 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/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 ade8345..a95cd86 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
@@ -38,7 +38,7 @@ import org.apache.phoenix.expression.IsNullExpression;
 import org.apache.phoenix.expression.KeyValueColumnExpression;
 import org.apache.phoenix.expression.LiteralExpression;
 import org.apache.phoenix.expression.RowKeyColumnExpression;
-import org.apache.phoenix.expression.visitor.TraverseNoExpressionVisitor;
+import 
org.apache.phoenix.expression.visitor.StatelessTraverseNoExpressionVisitor;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.parse.ColumnParseNode;
@@ -213,7 +213,7 @@ public class CreateTableCompiler {
         }
     }
     
-    private static class ViewWhereExpressionVisitor extends 
TraverseNoExpressionVisitor<Boolean> {
+    private static class ViewWhereExpressionVisitor extends 
StatelessTraverseNoExpressionVisitor<Boolean> {
         private boolean isUpdatable = true;
         private final PTable table;
         private int position;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/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 360243b..32216db 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
@@ -65,7 +65,7 @@ import org.apache.phoenix.expression.TimestampAddExpression;
 import org.apache.phoenix.expression.TimestampSubtractExpression;
 import org.apache.phoenix.expression.function.ArrayAllComparisonExpression;
 import org.apache.phoenix.expression.function.ArrayAnyComparisonExpression;
-import org.apache.phoenix.expression.function.InlineArrayElemRefExpression;
+import org.apache.phoenix.expression.function.ArrayElemRefExpression;
 import org.apache.phoenix.parse.AddParseNode;
 import org.apache.phoenix.parse.AndParseNode;
 import org.apache.phoenix.parse.ArithmeticParseNode;
@@ -101,29 +101,29 @@ import 
org.apache.phoenix.parse.UnsupportedAllParseNodeVisitor;
 import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
 import org.apache.phoenix.schema.ColumnNotFoundException;
 import org.apache.phoenix.schema.ColumnRef;
-import org.apache.phoenix.schema.types.PChar;
-import org.apache.phoenix.schema.types.PDate;
-import org.apache.phoenix.schema.types.PDecimal;
 import org.apache.phoenix.schema.DelegateDatum;
 import org.apache.phoenix.schema.LocalIndexDataColumnRef;
-import org.apache.phoenix.schema.types.PArrayDataType;
-import org.apache.phoenix.schema.types.PBoolean;
 import org.apache.phoenix.schema.PColumn;
-import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.PDatum;
-import org.apache.phoenix.schema.types.PDouble;
-import org.apache.phoenix.schema.types.PLong;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTable.IndexType;
 import org.apache.phoenix.schema.PTableType;
-import org.apache.phoenix.schema.types.PTimestamp;
-import org.apache.phoenix.schema.types.PUnsignedTimestamp;
-import org.apache.phoenix.schema.types.PVarbinary;
-import org.apache.phoenix.schema.types.PhoenixArray;
 import org.apache.phoenix.schema.RowKeyValueAccessor;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.TypeMismatchException;
+import org.apache.phoenix.schema.types.PArrayDataType;
+import org.apache.phoenix.schema.types.PBoolean;
+import org.apache.phoenix.schema.types.PChar;
+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.PLong;
+import org.apache.phoenix.schema.types.PTimestamp;
+import org.apache.phoenix.schema.types.PUnsignedTimestamp;
+import org.apache.phoenix.schema.types.PVarbinary;
+import org.apache.phoenix.schema.types.PhoenixArray;
 import org.apache.phoenix.util.ExpressionUtil;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.SchemaUtil;
@@ -428,32 +428,16 @@ public class ExpressionCompiler extends 
UnsupportedAllParseNodeVisitor<Expressio
         return true;
     }
 
-    private static Determinism getDeterminism(List<Expression> l) {
-       Determinism determinism = Determinism.ALWAYS;
-        for (Expression e : l) {
-               determinism.combine(e.getDeterminism());
-        }
-        return determinism;
-    }
-
     @Override
     public Expression visitLeave(CaseParseNode node, List<Expression> l) 
throws SQLException {
-        final CaseExpression caseExpression = new CaseExpression(l);
+        final Expression caseExpression = CaseExpression.create(l);
         for (int i = 0; i < node.getChildren().size(); i+=2) {
             ParseNode childNode = node.getChildren().get(i);
             if (childNode instanceof BindParseNode) {
                 
context.getBindManager().addParamMetaData((BindParseNode)childNode, new 
DelegateDatum(caseExpression));
             }
         }
-        if (ExpressionUtil.isConstant(caseExpression)) {
-            ImmutableBytesWritable ptr = context.getTempPtr();
-            int index = caseExpression.evaluateIndexOf(null, ptr);
-            if (index < 0) {
-                return LiteralExpression.newConstant(null, getDeterminism(l));
-            }
-            return caseExpression.getChildren().get(index);
-        }
-        return wrapGroupByExpression(caseExpression);
+         return wrapGroupByExpression(caseExpression);
     }
 
     @Override
@@ -500,15 +484,15 @@ public class ExpressionCompiler extends 
UnsupportedAllParseNodeVisitor<Expressio
                 if (node.getLikeType() == LikeType.CASE_SENSITIVE) {
                   CompareOp op = node.isNegate() ? CompareOp.NOT_EQUAL : 
CompareOp.EQUAL;
                   if (pattern.equals(rhsLiteral)) {
-                      return new ComparisonExpression(op, children);
+                      return new ComparisonExpression(children, op);
                   } else {
                       rhs = LiteralExpression.newConstant(rhsLiteral, 
PChar.INSTANCE, rhs.getDeterminism());
-                      return new ComparisonExpression(op, 
Arrays.asList(lhs,rhs));
+                      return new ComparisonExpression(Arrays.asList(lhs,rhs), 
op);
                   }
                 }
             }
         }
-        Expression expression = new LikeExpression(children, 
node.getLikeType());
+        Expression expression = LikeExpression.create(children, 
node.getLikeType());
         if (ExpressionUtil.isConstant(expression)) {
             ImmutableBytesWritable ptr = context.getTempPtr();
             if (!expression.evaluate(null, ptr)) {
@@ -1122,7 +1106,7 @@ public class ExpressionCompiler extends 
UnsupportedAllParseNodeVisitor<Expressio
     
     @Override
     public Expression visitLeave(ArrayElemRefNode node, List<Expression> l) 
throws SQLException {
-        return new InlineArrayElemRefExpression(l);
+        return new ArrayElemRefExpression(l);
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java 
b/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
index 04b086a..6b518b9 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
@@ -46,6 +46,7 @@ import 
org.apache.phoenix.expression.aggregator.ClientAggregators;
 import org.apache.phoenix.expression.aggregator.ServerAggregators;
 import org.apache.phoenix.expression.function.ArrayIndexFunction;
 import org.apache.phoenix.expression.function.SingleAggregateFunction;
+import org.apache.phoenix.expression.visitor.ExpressionVisitor;
 import org.apache.phoenix.expression.visitor.KeyValueExpressionVisitor;
 import org.apache.phoenix.expression.visitor.SingleAggregateFunctionVisitor;
 import org.apache.phoenix.jdbc.PhoenixConnection;
@@ -62,15 +63,14 @@ import org.apache.phoenix.parse.TableWildcardParseNode;
 import org.apache.phoenix.parse.WildcardParseNode;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.ArgumentTypeMismatchException;
+import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
 import org.apache.phoenix.schema.ColumnNotFoundException;
 import org.apache.phoenix.schema.ColumnRef;
 import org.apache.phoenix.schema.KeyValueSchema;
 import org.apache.phoenix.schema.KeyValueSchema.KeyValueSchemaBuilder;
-import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
 import org.apache.phoenix.schema.LocalIndexDataColumnRef;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PColumnFamily;
-import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.PDatum;
 import org.apache.phoenix.schema.PName;
 import org.apache.phoenix.schema.PTable;
@@ -82,6 +82,7 @@ import org.apache.phoenix.schema.RowKeySchema;
 import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.ValueBitSet;
 import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.SchemaUtil;
@@ -461,6 +462,12 @@ public class ProjectionCompiler {
         public PDataType getDataType() {
             return this.type;
         }
+
+        @Override
+        public <T> T accept(ExpressionVisitor<T> visitor) {
+            // TODO Auto-generated method stub
+            return null;
+        }
     }
     private static void 
serailizeArrayIndexInformationAndSetInScan(StatementContext context, 
List<Expression> arrayKVFuncs,
             List<KeyValueColumnExpression> arrayKVRefs) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/compile/RowProjector.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/compile/RowProjector.java 
b/phoenix-core/src/main/java/org/apache/phoenix/compile/RowProjector.java
index d828eae..2833962 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/RowProjector.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/RowProjector.java
@@ -17,26 +17,20 @@
  */
 package org.apache.phoenix.compile;
 
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import org.apache.hadoop.io.WritableUtils;
+import org.apache.phoenix.expression.Determinism;
 import org.apache.phoenix.expression.Expression;
-import org.apache.phoenix.expression.ExpressionType;
+import org.apache.phoenix.expression.visitor.CloneExpressionVisitor;
 import org.apache.phoenix.schema.AmbiguousColumnException;
 import org.apache.phoenix.schema.ColumnNotFoundException;
 import org.apache.phoenix.util.SchemaUtil;
-import org.apache.phoenix.util.TrustedByteArrayOutputStream;
 
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.ListMultimap;
-import com.google.common.collect.Lists;
 
 
 /**
@@ -57,8 +51,7 @@ public class RowProjector implements Cloneable {
     private final boolean someCaseSensitive;
     private final int estimatedSize;
     private final boolean isProjectEmptyKeyValue;
-    private volatile List<byte[]> rowExpressions;
-    private List<Expression> statelessExpressions;
+    private final boolean cloneRequired;
     
     public RowProjector(RowProjector projector, boolean 
isProjectEmptyKeyValue) {
         this(projector.getColumnProjectors(), 
projector.getEstimatedRowByteSize(), isProjectEmptyKeyValue);
@@ -89,77 +82,42 @@ public class RowProjector implements Cloneable {
         this.someCaseSensitive = someCaseSensitive;
         this.estimatedSize = estimatedRowSize;
         this.isProjectEmptyKeyValue = isProjectEmptyKeyValue;
+        boolean hasPerInvocationExpression = false;
+        for (int i = 0; i < this.columnProjectors.size(); i++) {
+            Expression expression = 
this.columnProjectors.get(i).getExpression();
+            if (expression.getDeterminism() == Determinism.PER_INVOCATION) {
+                hasPerInvocationExpression = true;
+                break;
+            }
+        }
+        this.cloneRequired = hasPerInvocationExpression;
     }
 
     @Override
     public RowProjector clone() {
-        return cloneRowProjector();
-    }
-
-    private RowProjector cloneRowProjector() {
-        if (rowExpressions == null) {
-            synchronized(this) {
-                if (rowExpressions == null) {
-                    List<byte[]> localRowExpressions = new 
ArrayList<byte[]>(this.getColumnCount());
-                    try {
-                        for (int i = 0; i < this.getColumnCount(); i++) {
-                             TrustedByteArrayOutputStream bytesOut = new 
TrustedByteArrayOutputStream(1024);
-                             DataOutputStream output = new 
DataOutputStream(bytesOut);
-                             Expression expression = 
this.getColumnProjector(i).getExpression();
-                             // Hack to clone expressions by serializing them. 
Not all expressions
-                             // are serializable. For example NEXT VALUE FOR 
is client-side only.
-                             // In this case, we keep the original exception 
and restore it when
-                             // we clone (as we don't need to clone it).
-                             // TODO: visitor that clones based on Determinism 
of PER_INVOCATION
-                             // instead, that way we'd only be cloning 
expression trees with RAND.
-                             ExpressionType expressionType = 
ExpressionType.valueOfOrNull(expression);
-                             if (expressionType == null) {
-                                 if (statelessExpressions == null) {
-                                     statelessExpressions = 
Lists.newArrayList();
-                                 }
-                                 statelessExpressions.add(expression);
-                                 WritableUtils.writeVInt(output, 
-statelessExpressions.size());
-                             } else {
-                                 WritableUtils.writeVInt(output, 
expressionType.ordinal());
-                                 expression.write(output);
-                             }
-                             output.flush();
-                             localRowExpressions.add(bytesOut.getBuffer());
-                        }
-                    } catch (IOException io) {
-                        throw new RuntimeException(io);
-                    }
-                    rowExpressions = localRowExpressions;
-                }
-            }
+        if (!cloneRequired) {
+            return this;
         }
-        List<ColumnProjector> colProjectors = new 
ArrayList<ColumnProjector>(rowExpressions.size());
-        try {
-            for (int i=0; i<rowExpressions.size(); i++) {
-                ByteArrayInputStream bytesIn = new 
ByteArrayInputStream(rowExpressions.get(i));
-                DataInputStream input = new DataInputStream(bytesIn);
-                int ordinal = WritableUtils.readVInt(input);
-                Expression expression;
-                if (ordinal < 0) {
-                    expression = statelessExpressions.get(ordinal+1);
-                } else {
-                    expression = 
ExpressionType.values()[ordinal].newInstance();
-                    expression.readFields(input);
-                }
-                ColumnProjector colProjector = this.getColumnProjector(i);
-                colProjectors.add(new 
ExpressionProjector(colProjector.getName(),
-                    colProjector.getTableName(), 
-                    expression,
-                    colProjector.isCaseSensitive()));
+        List<ColumnProjector> clonedColProjectors = new 
ArrayList<ColumnProjector>(columnProjectors.size());
+        for (int i = 0; i < this.columnProjectors.size(); i++) {
+            ColumnProjector colProjector = columnProjectors.get(i);
+            Expression expression = colProjector.getExpression();
+            if (expression.getDeterminism() == Determinism.PER_INVOCATION) {
+                CloneExpressionVisitor visitor = new CloneExpressionVisitor();
+                Expression clonedExpression = expression.accept(visitor);
+                clonedColProjectors.add(new 
ExpressionProjector(colProjector.getName(),
+                        colProjector.getTableName(), 
+                        clonedExpression,
+                        colProjector.isCaseSensitive()));
+            } else {
+                clonedColProjectors.add(colProjector);
             }
-            return new RowProjector(colProjectors, 
+        }
+        return new RowProjector(clonedColProjectors, 
                 this.getEstimatedRowByteSize(),
                 this.isProjectEmptyKeyValue());
-        } catch (IOException io) {
-            throw new RuntimeException(io);
-        }
-   }
-    
+    }
+
     public boolean isProjectEmptyKeyValue() {
         return isProjectEmptyKeyValue;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/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 e62f87d..ede6d9c 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
@@ -24,22 +24,16 @@ import java.util.List;
 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.SequenceValueParseNode.Op;
 import org.apache.phoenix.parse.TableName;
 import org.apache.phoenix.query.ConnectionQueryServices;
-import org.apache.phoenix.schema.types.PDataType;
-import org.apache.phoenix.schema.types.PLong;
 import org.apache.phoenix.schema.PName;
 import org.apache.phoenix.schema.Sequence;
 import org.apache.phoenix.schema.SequenceKey;
 import org.apache.phoenix.schema.tuple.DelegateTuple;
 import org.apache.phoenix.schema.tuple.Tuple;
-import org.apache.phoenix.util.SchemaUtil;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
@@ -174,53 +168,4 @@ public class SequenceManager {
         services.validateSequences(nextSequences, timestamp, 
srcSequenceValues, sqlExceptions, action);
         setSequenceValues(srcSequenceValues, dstSequenceValues, sqlExceptions);
     }
-    
-    private class SequenceValueExpression extends BaseTerminalExpression {
-        private final SequenceKey key;
-        private final Op op;
-        private final int index;
-
-        private SequenceValueExpression(SequenceKey key, Op op, int index) {
-            this.key = key;
-            this.op = op;
-            this.index = index;
-        }
-
-        public int getIndex() {
-            return index;
-        }
-        
-        @Override
-        public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
-                       byte[] valueBuffer = new 
byte[PLong.INSTANCE.getByteSize()];
-            
PLong.INSTANCE.getCodec().encodeLong(tuple.getSequenceValue(index), 
valueBuffer, 0);
-            ptr.set(valueBuffer);
-            return true;
-        }
-
-        @Override
-        public PDataType getDataType() {
-            return PLong.INSTANCE;
-        }
-        
-        @Override
-        public boolean isNullable() {
-            return false;
-        }
-        
-        @Override
-        public Determinism getDeterminism() {
-            return Determinism.PER_ROW;
-        }
-        
-        @Override
-        public boolean isStateless() {
-            return true;
-        }
-
-        @Override
-        public String toString() {
-            return op.getName() + " VALUE FOR " + 
SchemaUtil.getTableName(key.getSchemaName(),key.getSequenceName());
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/compile/SequenceValueExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/compile/SequenceValueExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/compile/SequenceValueExpression.java
new file mode 100644
index 0000000..cdaae68
--- /dev/null
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/compile/SequenceValueExpression.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.compile;
+
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.phoenix.expression.BaseTerminalExpression;
+import org.apache.phoenix.expression.Determinism;
+import org.apache.phoenix.expression.visitor.ExpressionVisitor;
+import org.apache.phoenix.parse.SequenceValueParseNode.Op;
+import org.apache.phoenix.schema.SequenceKey;
+import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PLong;
+import org.apache.phoenix.util.SchemaUtil;
+
+public class SequenceValueExpression extends BaseTerminalExpression {
+    private final SequenceKey key;
+    final Op op;
+    private final int index;
+
+    public SequenceValueExpression(SequenceKey key, Op op, int index) {
+        this.key = key;
+        this.op = op;
+        this.index = index;
+    }
+
+    public int getIndex() {
+        return index;
+    }
+    
+    @Override
+    public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
+               byte[] valueBuffer = new byte[PLong.INSTANCE.getByteSize()];
+        PLong.INSTANCE.getCodec().encodeLong(tuple.getSequenceValue(index), 
valueBuffer, 0);
+        ptr.set(valueBuffer);
+        return true;
+    }
+
+    @Override
+    public PDataType getDataType() {
+        return PLong.INSTANCE;
+    }
+    
+    @Override
+    public boolean isNullable() {
+        return false;
+    }
+    
+    @Override
+    public Determinism getDeterminism() {
+        return Determinism.PER_ROW;
+    }
+    
+    @Override
+    public boolean isStateless() {
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return op.getName() + " VALUE FOR " + 
SchemaUtil.getTableName(key.getSchemaName(),key.getSequenceName());
+    }
+
+    @Override
+    public <T> T accept(ExpressionVisitor<T> visitor) {
+        return visitor.visit(this);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/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 5edd38c..a1a349a 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
@@ -48,22 +48,23 @@ import org.apache.phoenix.expression.RowKeyColumnExpression;
 import org.apache.phoenix.expression.RowValueConstructorExpression;
 import 
org.apache.phoenix.expression.function.FunctionExpression.OrderPreserving;
 import org.apache.phoenix.expression.function.ScalarFunction;
-import org.apache.phoenix.expression.visitor.TraverseNoExpressionVisitor;
+import org.apache.phoenix.expression.visitor.ExpressionVisitor;
+import 
org.apache.phoenix.expression.visitor.StatelessTraverseNoExpressionVisitor;
 import org.apache.phoenix.parse.FilterableStatement;
 import org.apache.phoenix.parse.HintNode.Hint;
 import org.apache.phoenix.parse.LikeParseNode.LikeType;
 import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.query.QueryConstants;
-import org.apache.phoenix.schema.types.PChar;
 import org.apache.phoenix.schema.PColumn;
-import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.PName;
 import org.apache.phoenix.schema.PTable;
-import org.apache.phoenix.schema.types.PVarbinary;
 import org.apache.phoenix.schema.RowKeySchema;
 import org.apache.phoenix.schema.SaltingUtil;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PChar;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PVarbinary;
 import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.MetaDataUtil;
 import org.apache.phoenix.util.ScanUtil;
@@ -399,7 +400,7 @@ public class WhereOptimizer {
                 && (remaining == null || 
remaining.equals(LiteralExpression.newConstant(true, Determinism.ALWAYS)));
     }
 
-    private static class RemoveExtractedNodesVisitor extends 
TraverseNoExpressionVisitor<Expression> {
+    private static class RemoveExtractedNodesVisitor extends 
StatelessTraverseNoExpressionVisitor<Expression> {
         private final Set<Expression> nodesToRemove;
 
         private RemoveExtractedNodesVisitor(Set<Expression> nodesToRemove) {
@@ -446,7 +447,7 @@ public class WhereOptimizer {
      * Currently the first case would not be optimized. This includes other 
arithmetic
      * operators, CASE statements, and string concatenation.
      */
-    public static class KeyExpressionVisitor extends 
TraverseNoExpressionVisitor<KeyExpressionVisitor.KeySlots> {
+    public static class KeyExpressionVisitor extends 
StatelessTraverseNoExpressionVisitor<KeyExpressionVisitor.KeySlots> {
         private static final KeySlots EMPTY_KEY_SLOTS = new KeySlots() {
             @Override
             public Iterator<KeySlot> iterator() {
@@ -1369,6 +1370,11 @@ public class WhereOptimizer {
                                 public SortOrder getSortOrder() {
                                     return 
childPart.getColumn().getSortOrder();
                                 }
+
+                                @Override
+                                public <T> T accept(ExpressionVisitor<T> 
visitor) {
+                                    return null;
+                                }
                             };
                         }
                         

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/ArithmeticExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/ArithmeticExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/ArithmeticExpression.java
index 9212709..2500cbb 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/ArithmeticExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/ArithmeticExpression.java
@@ -30,6 +30,8 @@ public abstract class ArithmeticExpression extends 
BaseCompoundExpression {
         super(children);
     }
 
+    abstract public ArithmeticExpression clone(List<Expression> children);
+    
     @Override
     public String toString() {
         StringBuilder buf = new StringBuilder("(");

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/ArrayConstructorExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/ArrayConstructorExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/ArrayConstructorExpression.java
index 9faab96..9b0ee8f 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/ArrayConstructorExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/ArrayConstructorExpression.java
@@ -18,10 +18,11 @@ import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.io.WritableUtils;
+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.PArrayDataType;
 import org.apache.phoenix.schema.types.PDataType;
-import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.TrustedByteArrayOutputStream;
 
 /**
@@ -46,6 +47,10 @@ public class ArrayConstructorExpression extends 
BaseCompoundExpression {
         init(baseType);
     }
 
+    public ArrayConstructorExpression clone(List<Expression> children) {
+        return new ArrayConstructorExpression(children, this.baseType);
+    }
+    
     private void init(PDataType baseType) {
         this.baseType = baseType;
         elements = new Object[getChildren().size()];
@@ -151,4 +156,14 @@ public class ArrayConstructorExpression extends 
BaseCompoundExpression {
     public boolean requiresFinalEvaluation() {
         return true;
     }
+
+    @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/7a2944a0/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 bd6161c..5fc8361 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
@@ -25,7 +25,6 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.hadoop.io.WritableUtils;
-import org.apache.phoenix.expression.visitor.ExpressionVisitor;
 
 import com.google.common.collect.ImmutableList;
 
@@ -132,16 +131,6 @@ public abstract class BaseCompoundExpression extends 
BaseExpression {
     }
     
     @Override
-    public <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 String toString() {
         return this.getClass().getName() + " [children=" + children + "]";
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseSingleExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseSingleExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseSingleExpression.java
index 705841f..c0e2fea 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseSingleExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseSingleExpression.java
@@ -43,7 +43,11 @@ public abstract class BaseSingleExpression extends 
BaseExpression {
     }
 
     public BaseSingleExpression(Expression expression) {
-        this.children = ImmutableList.of(expression);
+        this(ImmutableList.of(expression));
+    }
+
+    public BaseSingleExpression(List<Expression> children) {
+        this.children = children;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseTerminalExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseTerminalExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseTerminalExpression.java
index 8d0d336..832c95c 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseTerminalExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseTerminalExpression.java
@@ -20,8 +20,6 @@ package org.apache.phoenix.expression;
 import java.util.Collections;
 import java.util.List;
 
-import org.apache.phoenix.expression.visitor.ExpressionVisitor;
-
 
 
 /**
@@ -36,10 +34,4 @@ public abstract class BaseTerminalExpression extends 
BaseExpression {
     public List<Expression> getChildren() {
         return Collections.emptyList();
     }
-    
-    @Override
-    public <T> T accept(ExpressionVisitor<T> visitor) {
-        return null;
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/CaseExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/CaseExpression.java 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/CaseExpression.java
index 96338cc..c426d83 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/CaseExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/CaseExpression.java
@@ -29,10 +29,11 @@ import org.apache.hadoop.io.WritableUtils;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.exception.SQLExceptionInfo;
 import org.apache.phoenix.expression.visitor.ExpressionVisitor;
-import org.apache.phoenix.schema.types.PDecimal;
+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.tuple.Tuple;
+import org.apache.phoenix.schema.types.PDecimal;
+import org.apache.phoenix.util.ExpressionUtil;
 
 
 /**
@@ -52,6 +53,19 @@ public class CaseExpression extends BaseCompoundExpression {
     public CaseExpression() {
     }
     
+    public static Expression create(List<Expression> children) throws 
SQLException {
+        CaseExpression caseExpression = new 
CaseExpression(coerceIfNecessary(children));
+        if (ExpressionUtil.isConstant(caseExpression)) {
+            ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+            int index = caseExpression.evaluateIndexOf(null, ptr);
+            if (index < 0) {
+                return LiteralExpression.newConstant(null, 
caseExpression.getDeterminism());
+            }
+            return caseExpression.getChildren().get(index);
+        }
+        return caseExpression;
+    }
+    
     private static List<Expression> coerceIfNecessary(List<Expression> 
children) throws SQLException {
         boolean isChildTypeUnknown = false;
         PDataType returnType = children.get(0).getDataType();
@@ -98,8 +112,8 @@ public class CaseExpression extends BaseCompoundExpression {
      * @throws SQLException if return type of case expressions do not match 
and cannot
      *  be coerced to a common type
      */
-    public CaseExpression(List<Expression> expressions) throws SQLException {
-        super(coerceIfNecessary(expressions));
+    public CaseExpression(List<Expression> children) {
+        super(children);
         returnType = children.get(0).getDataType();
     }
     

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/CoerceExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/CoerceExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/CoerceExpression.java
index 275ed23..811ed47 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/CoerceExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/CoerceExpression.java
@@ -26,11 +26,12 @@ import java.util.List;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.io.WritableUtils;
 import org.apache.phoenix.expression.visitor.ExpressionVisitor;
-import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PDataType;
 
 import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
 
 
 public class CoerceExpression extends BaseSingleExpression {
@@ -61,13 +62,21 @@ public class CoerceExpression extends BaseSingleExpression {
     }
     
     CoerceExpression(Expression expression, PDataType toType, SortOrder 
toSortOrder, Integer maxLength) {
-        super(expression);
+        this(ImmutableList.of(expression), toType, toSortOrder, maxLength);
+    }
+
+    public CoerceExpression(List<Expression> children, PDataType toType, 
SortOrder toSortOrder, Integer maxLength) {
+        super(children);
         Preconditions.checkNotNull(toSortOrder);
         this.toType = toType;
         this.toSortOrder = toSortOrder;
         this.maxLength = maxLength;
     }
-
+    
+    public CoerceExpression clone(List<Expression> children) {
+        return new CoerceExpression(children, this.getDataType(), 
this.getSortOrder(), this.getMaxLength());
+    }
+    
     @Override
     public Integer getMaxLength() {
         return maxLength;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/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 38b69b7..4bfa0e9 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
@@ -29,19 +29,19 @@ import java.util.List;
 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.expression.function.InlineArrayElemRefExpression;
+import org.apache.phoenix.expression.function.ArrayElemRefExpression;
 import org.apache.phoenix.expression.visitor.ExpressionVisitor;
-import org.apache.phoenix.schema.types.PDecimal;
+import org.apache.phoenix.schema.SortOrder;
+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.PChar;
-import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PDecimal;
+import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PLong;
 import org.apache.phoenix.schema.types.PUnsignedInt;
 import org.apache.phoenix.schema.types.PUnsignedLong;
-import org.apache.phoenix.schema.SortOrder;
-import org.apache.phoenix.schema.TypeMismatchException;
-import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.ExpressionUtil;
 import org.apache.phoenix.util.StringUtil;
@@ -120,7 +120,7 @@ public class ComparisonExpression extends 
BaseCompoundExpression {
         PDataType lhsExprDataType = lhsExpr.getDataType();
         PDataType rhsExprDataType = rhsExpr.getDataType();
         
-        if ((lhsExpr instanceof RowValueConstructorExpression || rhsExpr 
instanceof RowValueConstructorExpression) && !(lhsExpr instanceof 
InlineArrayElemRefExpression) && !(rhsExpr instanceof 
InlineArrayElemRefExpression)) {
+        if ((lhsExpr instanceof RowValueConstructorExpression || rhsExpr 
instanceof RowValueConstructorExpression) && !(lhsExpr instanceof 
ArrayElemRefExpression) && !(rhsExpr instanceof ArrayElemRefExpression)) {
             if (op == CompareOp.EQUAL || op == CompareOp.NOT_EQUAL) {
                 List<Expression> andNodes = 
Lists.<Expression>newArrayListWithExpectedSize(Math.max(lhsExpr.getChildren().size(),
 rhsExpr.getChildren().size()));
                 rewriteRVCAsEqualityExpression(lhsExpr, rhsExpr, andNodes, 
ptr);
@@ -262,13 +262,13 @@ public class ComparisonExpression extends 
BaseCompoundExpression {
                 }
             }
         }
-        return new ComparisonExpression(op, children);
+        return new ComparisonExpression(children, op);
     }
     
     public ComparisonExpression() {
     }
 
-    public ComparisonExpression(CompareOp op, List<Expression> children) {
+    public ComparisonExpression(List<Expression> children, CompareOp op) {
         super(children);
         if (op == null) {
             throw new NullPointerException();
@@ -276,6 +276,10 @@ public class ComparisonExpression extends 
BaseCompoundExpression {
         this.op = op;
     }
 
+    public ComparisonExpression clone(List<Expression> children) {
+        return new ComparisonExpression(children, this.getFilterOp());
+    }
+    
     @Override
     public int hashCode() {
         final int prime = 31;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/DateAddExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DateAddExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DateAddExpression.java
index bc79d15..1174086 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DateAddExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DateAddExpression.java
@@ -21,15 +21,14 @@ import java.math.BigDecimal;
 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.PDate;
 import org.apache.phoenix.schema.types.PDecimal;
 import org.apache.phoenix.schema.types.PDouble;
 import org.apache.phoenix.schema.types.PLong;
-import org.apache.phoenix.schema.SortOrder;
-import org.apache.phoenix.schema.types.PDataType;
-import org.apache.phoenix.schema.tuple.Tuple;
 
 
 public class DateAddExpression extends AddExpression {
@@ -79,4 +78,9 @@ public class DateAddExpression extends AddExpression {
         return PDate.INSTANCE;
     }
 
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new DateAddExpression(children);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/DateSubtractExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DateSubtractExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DateSubtractExpression.java
index 3f5897c..1d50c6a 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DateSubtractExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DateSubtractExpression.java
@@ -21,15 +21,14 @@ import java.math.BigDecimal;
 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.PDate;
 import org.apache.phoenix.schema.types.PDecimal;
 import org.apache.phoenix.schema.types.PDouble;
 import org.apache.phoenix.schema.types.PLong;
-import org.apache.phoenix.schema.SortOrder;
-import org.apache.phoenix.schema.types.PDataType;
-import org.apache.phoenix.schema.tuple.Tuple;
 
 
 public class DateSubtractExpression extends SubtractExpression {
@@ -79,4 +78,9 @@ public class DateSubtractExpression extends 
SubtractExpression {
         return PDate.INSTANCE;
     }
 
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new DateSubtractExpression(children);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalAddExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalAddExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalAddExpression.java
index df1ec4f..fac9ae6 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalAddExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalAddExpression.java
@@ -22,10 +22,10 @@ import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.exception.ValueTypeIncompatibleException;
-import org.apache.phoenix.schema.types.PDecimal;
-import org.apache.phoenix.schema.types.PDataType;
 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.util.NumberUtil;
 
 
@@ -94,4 +94,9 @@ public class DecimalAddExpression extends AddExpression {
     public Integer getMaxLength() {
         return maxLength;
     }
+
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new DecimalAddExpression(children);
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalDivideExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalDivideExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalDivideExpression.java
index 81ff3bc..a740f5a 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalDivideExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalDivideExpression.java
@@ -22,10 +22,10 @@ import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.exception.ValueTypeIncompatibleException;
-import org.apache.phoenix.schema.types.PDecimal;
-import org.apache.phoenix.schema.types.PDataType;
 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.util.NumberUtil;
 
 
@@ -74,4 +74,9 @@ public class DecimalDivideExpression extends DivideExpression 
{
     public PDataType getDataType() {
         return PDecimal.INSTANCE;
     }
+
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new DecimalDivideExpression(children);
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalMultiplyExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalMultiplyExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalMultiplyExpression.java
index 0a9e3de..fe224b3 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalMultiplyExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalMultiplyExpression.java
@@ -22,10 +22,10 @@ import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.exception.ValueTypeIncompatibleException;
-import org.apache.phoenix.schema.types.PDecimal;
-import org.apache.phoenix.schema.types.PDataType;
 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.util.NumberUtil;
 
 
@@ -74,4 +74,9 @@ public class DecimalMultiplyExpression extends 
MultiplyExpression {
     public PDataType getDataType() {
         return PDecimal.INSTANCE;
     }
+
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new DecimalMultiplyExpression(children);
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalSubtractExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalSubtractExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalSubtractExpression.java
index c46a70f..c6eb485 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalSubtractExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalSubtractExpression.java
@@ -22,11 +22,11 @@ import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.exception.ValueTypeIncompatibleException;
-import org.apache.phoenix.schema.types.PDate;
-import org.apache.phoenix.schema.types.PDecimal;
-import org.apache.phoenix.schema.types.PDataType;
 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.PDate;
+import org.apache.phoenix.schema.types.PDecimal;
 import org.apache.phoenix.util.NumberUtil;
 
 
@@ -112,4 +112,9 @@ public class DecimalSubtractExpression extends 
SubtractExpression {
     public Integer getMaxLength() {
         return maxLength;
     }
+
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new DecimalSubtractExpression(children);
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleAddExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleAddExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleAddExpression.java
index 8ca2f05..5a6d839 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleAddExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleAddExpression.java
@@ -20,10 +20,9 @@ package org.apache.phoenix.expression;
 import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
+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.tuple.Tuple;
 
 public class DoubleAddExpression extends AddExpression {
 
@@ -66,4 +65,9 @@ public class DoubleAddExpression extends AddExpression {
         return PDouble.INSTANCE;
     }
 
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new DoubleAddExpression(children);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleDivideExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleDivideExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleDivideExpression.java
index 161e060..f153fd9 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleDivideExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleDivideExpression.java
@@ -20,10 +20,9 @@ package org.apache.phoenix.expression;
 import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
+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.tuple.Tuple;
 
 public class DoubleDivideExpression extends DivideExpression {
 
@@ -70,4 +69,9 @@ public class DoubleDivideExpression extends DivideExpression {
         return PDouble.INSTANCE;
     }
 
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new DoubleDivideExpression(children);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleMultiplyExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleMultiplyExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleMultiplyExpression.java
index 28a381c..9daf3fb 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleMultiplyExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleMultiplyExpression.java
@@ -20,10 +20,9 @@ package org.apache.phoenix.expression;
 import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
+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.tuple.Tuple;
 
 public class DoubleMultiplyExpression extends MultiplyExpression {
 
@@ -66,4 +65,9 @@ public class DoubleMultiplyExpression extends 
MultiplyExpression {
         return PDouble.INSTANCE;
     }
 
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new DoubleMultiplyExpression(children);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleSubtractExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleSubtractExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleSubtractExpression.java
index 6d2ca3e..ae014e4 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleSubtractExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DoubleSubtractExpression.java
@@ -20,10 +20,9 @@ package org.apache.phoenix.expression;
 import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
+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.tuple.Tuple;
 
 public class DoubleSubtractExpression extends SubtractExpression {
 
@@ -70,4 +69,9 @@ public class DoubleSubtractExpression extends 
SubtractExpression {
         return PDouble.INSTANCE;
     }
 
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new DoubleSubtractExpression(children);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
index 5e3668c..706a751 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
@@ -40,7 +40,7 @@ import 
org.apache.phoenix.expression.function.FloorDateExpression;
 import org.apache.phoenix.expression.function.FloorDecimalExpression;
 import org.apache.phoenix.expression.function.FloorFunction;
 import org.apache.phoenix.expression.function.IndexStateNameFunction;
-import org.apache.phoenix.expression.function.InlineArrayElemRefExpression;
+import org.apache.phoenix.expression.function.ArrayElemRefExpression;
 import org.apache.phoenix.expression.function.InvertFunction;
 import org.apache.phoenix.expression.function.LTrimFunction;
 import org.apache.phoenix.expression.function.LastValueFunction;
@@ -182,7 +182,7 @@ public enum ExpressionType {
     LastValueFunction(LastValueFunction.class),
     ArrayAnyComparisonExpression(ArrayAnyComparisonExpression.class),
     ArrayAllComparisonExpression(ArrayAllComparisonExpression.class),
-    InlineArrayElemRefExpression(InlineArrayElemRefExpression.class),
+    InlineArrayElemRefExpression(ArrayElemRefExpression.class),
     SQLIndexTypeFunction(SQLIndexTypeFunction.class),
     ModulusExpression(ModulusExpression.class),
     DistinctValueAggregateFunction(DistinctValueAggregateFunction.class),

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/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 6a56e4f..772db97 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
@@ -33,10 +33,10 @@ import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.io.WritableUtils;
 import org.apache.phoenix.expression.visitor.ExpressionVisitor;
 import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
-import org.apache.phoenix.schema.types.PBoolean;
-import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.SortOrder;
 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.util.ByteUtil;
 import org.apache.phoenix.util.ExpressionUtil;
 
@@ -109,7 +109,7 @@ public class InListExpression extends BaseSingleExpression {
     public InListExpression() {
     }
 
-    private InListExpression(List<Expression> keyExpressions) throws 
SQLException {
+    public InListExpression(List<Expression> keyExpressions) {
         super(keyExpressions.get(0));
         this.keyExpressions = keyExpressions.subList(1, keyExpressions.size());
         Set<ImmutableBytesPtr> values = 
Sets.newHashSetWithExpectedSize(keyExpressions.size()-1);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/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 b4095e3..d8f6cbe 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
@@ -25,9 +25,9 @@ import java.util.List;
 
 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.PBoolean;
 import org.apache.phoenix.schema.types.PDataType;
-import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.ExpressionUtil;
 
 
@@ -35,8 +35,6 @@ import org.apache.phoenix.util.ExpressionUtil;
  * 
  * Implementation of IS NULL and IS NOT NULL expression
  *
- * 
- * @since 0.1
  */
 public class IsNullExpression extends BaseSingleExpression {
     private boolean isNegate;
@@ -60,6 +58,15 @@ public class IsNullExpression extends BaseSingleExpression {
         this.isNegate = negate;
     }
 
+    public IsNullExpression(List<Expression> children, boolean negate) {
+        super(children);
+        this.isNegate = negate;
+    }
+
+    public IsNullExpression clone(List<Expression> children) {
+        return new IsNullExpression(children, this.isNegate());
+    }
+    
     @Override
     public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
         boolean evaluated = getChild().evaluate(tuple, ptr);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/LikeExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/LikeExpression.java 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/LikeExpression.java
index 7f6323b..730cffb 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/LikeExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/LikeExpression.java
@@ -26,10 +26,10 @@ import java.util.regex.Pattern;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.expression.visitor.ExpressionVisitor;
 import org.apache.phoenix.parse.LikeParseNode.LikeType;
+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.PVarchar;
-import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.StringUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -195,6 +195,10 @@ public class LikeExpression extends BaseCompoundExpression 
{
 //        return sb.toString();
 //    }
 
+    public static LikeExpression create(List<Expression> children, LikeType 
likeType) {
+        return new LikeExpression(addLikeTypeChild(children,likeType));
+    }
+    
     private static final int LIKE_TYPE_INDEX = 2;
     private static final LiteralExpression[] LIKE_TYPE_LITERAL = new 
LiteralExpression[LikeType.values().length];
     static {
@@ -214,12 +218,11 @@ public class LikeExpression extends 
BaseCompoundExpression {
         return newChildren;
     }
     
-    public LikeExpression(List<Expression> children, LikeType likeType) {
-        super(addLikeTypeChild(children,likeType));
-        this.likeType = likeType;
+    public LikeExpression(List<Expression> children) {
+        super(children);
         init();
     }
-
+    
     public LikeType getLikeType () {
       return likeType;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/LongAddExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/LongAddExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/LongAddExpression.java
index 161758a..d498b82 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/LongAddExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/LongAddExpression.java
@@ -20,10 +20,9 @@ package org.apache.phoenix.expression;
 import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
+import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PLong;
-import org.apache.phoenix.schema.tuple.Tuple;
 
 
 public class LongAddExpression extends AddExpression {
@@ -58,4 +57,9 @@ public class LongAddExpression extends AddExpression {
         return PLong.INSTANCE;
     }
 
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new LongAddExpression(children);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/LongDivideExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/LongDivideExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/LongDivideExpression.java
index 599b38e..e59594e 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/LongDivideExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/LongDivideExpression.java
@@ -20,10 +20,9 @@ package org.apache.phoenix.expression;
 import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
+import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PLong;
-import org.apache.phoenix.schema.tuple.Tuple;
 
 
 public class LongDivideExpression extends DivideExpression {
@@ -62,4 +61,9 @@ public class LongDivideExpression extends DivideExpression {
         return PLong.INSTANCE;
     }
 
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new LongDivideExpression(children);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/LongMultiplyExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/LongMultiplyExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/LongMultiplyExpression.java
index 40d6622..fa30029 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/LongMultiplyExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/LongMultiplyExpression.java
@@ -20,10 +20,9 @@ package org.apache.phoenix.expression;
 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.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PLong;
 
 
 public class LongMultiplyExpression extends MultiplyExpression {
@@ -61,4 +60,9 @@ public class LongMultiplyExpression extends 
MultiplyExpression {
         return PLong.INSTANCE;
     }
 
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new LongMultiplyExpression(children);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/phoenix-core/src/main/java/org/apache/phoenix/expression/LongSubtractExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/LongSubtractExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/LongSubtractExpression.java
index c7e1ee0..95505a6 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/LongSubtractExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/LongSubtractExpression.java
@@ -20,12 +20,11 @@ package org.apache.phoenix.expression;
 import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
 import org.apache.phoenix.query.QueryConstants;
-import org.apache.phoenix.schema.types.PDate;
+import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PDate;
 import org.apache.phoenix.schema.types.PLong;
-import org.apache.phoenix.schema.tuple.Tuple;
 
 
 
@@ -79,5 +78,10 @@ public class LongSubtractExpression extends 
SubtractExpression {
        public final PDataType getDataType() {
                return PLong.INSTANCE;
        }
+
+    @Override
+    public ArithmeticExpression clone(List<Expression> children) {
+        return new LongSubtractExpression(children);
+    }
        
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7a2944a0/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/7a2944a0/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/7a2944a0/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/7a2944a0/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/7a2944a0/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/7a2944a0/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/7a2944a0/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/7a2944a0/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

Reply via email to