phoenix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From maryann...@apache.org
Subject phoenix git commit: PHOENIX-2881 Support bind parameters in Calcite-Phoenix
Date Sat, 07 May 2016 19:08:30 GMT
Repository: phoenix
Updated Branches:
  refs/heads/calcite d561370b3 -> 91b923563


PHOENIX-2881 Support bind parameters in Calcite-Phoenix


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

Branch: refs/heads/calcite
Commit: 91b923563e541c0230afd21b2b4cc90de3568598
Parents: d561370
Author: maryannxue <maryann.xue@gmail.com>
Authored: Sat May 7 15:08:17 2016 -0400
Committer: maryannxue <maryann.xue@gmail.com>
Committed: Sat May 7 15:08:17 2016 -0400

----------------------------------------------------------------------
 .../calcite/jdbc/PhoenixCalciteFactory.java     | 29 +++++++++++++-
 .../apache/phoenix/calcite/CalciteUtils.java    | 11 ++++++
 .../calcite/rel/PhoenixRelImplementor.java      |  2 +
 .../calcite/rel/PhoenixRelImplementorImpl.java  |  7 ++++
 .../phoenix/calcite/rel/PhoenixTableScan.java   | 20 ++++++++--
 .../rel/PhoenixToEnumerableConverter.java       |  5 ++-
 .../apache/phoenix/execute/CorrelatePlan.java   |  4 +-
 .../apache/phoenix/execute/RuntimeContext.java  | 13 +++++++
 .../phoenix/execute/RuntimeContextImpl.java     | 16 ++++++++
 .../expression/BindParameterExpression.java     | 41 ++++++++++++++++++++
 .../CorrelateVariableFieldAccessExpression.java | 29 ++------------
 .../phoenix/expression/ExpressionType.java      |  4 +-
 .../phoenix/expression/VariableExpression.java  | 31 +++++++++++++++
 .../visitor/CloneExpressionVisitor.java         |  6 +++
 .../expression/visitor/ExpressionVisitor.java   |  2 +
 .../StatelessTraverseAllExpressionVisitor.java  |  7 +++-
 .../StatelessTraverseNoExpressionVisitor.java   |  7 +++-
 17 files changed, 198 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java
b/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java
index d153903..093316c 100644
--- a/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java
+++ b/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java
@@ -7,6 +7,8 @@ import java.sql.ResultSetMetaData;
 import java.sql.RowId;
 import java.sql.SQLException;
 import java.sql.SQLXML;
+import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 import java.util.TimeZone;
 
@@ -20,14 +22,20 @@ import org.apache.calcite.avatica.AvaticaStatement;
 import org.apache.calcite.avatica.Meta;
 import org.apache.calcite.avatica.Meta.Signature;
 import org.apache.calcite.avatica.Meta.StatementHandle;
+import org.apache.calcite.avatica.remote.TypedValue;
 import org.apache.calcite.avatica.QueryState;
 import org.apache.calcite.avatica.UnregisteredDriver;
 import org.apache.calcite.jdbc.CalciteConnectionImpl;
 import org.apache.calcite.jdbc.CalciteFactory;
 import org.apache.calcite.jdbc.Driver;
+import org.apache.calcite.linq4j.Enumerable;
+import org.apache.calcite.linq4j.Ord;
 import org.apache.phoenix.calcite.PhoenixSchema;
+import org.apache.phoenix.execute.RuntimeContext;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 
+import com.google.common.collect.Maps;
+
 public class PhoenixCalciteFactory extends CalciteFactory {
     
     public PhoenixCalciteFactory() {
@@ -97,7 +105,26 @@ public class PhoenixCalciteFactory extends CalciteFactory {
             super(driver, factory, url, info,
                     CalciteSchema.createRootSchema(true, false), typeFactory);
         }
-        
+
+        public <T> Enumerable<T> enumerable(Meta.StatementHandle handle,
+                CalcitePrepare.CalciteSignature<T> signature) throws SQLException {
+            Map<String, Object> map = Maps.newLinkedHashMap();
+            AvaticaStatement statement = lookupStatement(handle);
+            final List<TypedValue> parameterValues =
+                    TROJAN.getParameterValues(statement);
+            for (Ord<TypedValue> o : Ord.zip(parameterValues)) {
+                map.put("?" + o.i, o.e.toLocal());
+            }
+            try {
+                for (RuntimeContext runtimeContext : RuntimeContext.THREAD_LOCAL.get()) {
+                    runtimeContext.setBindParameterValues(map);
+                }
+                return super.enumerable(handle, signature);
+            } finally {
+                RuntimeContext.THREAD_LOCAL.get().clear();
+            }
+        }
+
         public void setAutoCommit(final boolean isAutoCommit) throws SQLException {
             call(new PhoenixConnectionCallable() {
                 @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java
index 8eec17f..87bfeab 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java
@@ -18,6 +18,7 @@ import org.apache.calcite.rel.core.JoinRelType;
 import org.apache.calcite.rel.core.Project;
 import org.apache.calcite.rex.RexCall;
 import org.apache.calcite.rex.RexCorrelVariable;
+import org.apache.calcite.rex.RexDynamicParam;
 import org.apache.calcite.rex.RexFieldAccess;
 import org.apache.calcite.rex.RexInputRef;
 import org.apache.calcite.rex.RexLiteral;
@@ -621,6 +622,16 @@ public class CalciteUtils {
                 return implementor.newFieldAccessExpression(varId, index, type);
             }		    
 		});
+        EXPRESSION_MAP.put(SqlKind.DYNAMIC_PARAM, new ExpressionFactory() {
+            @SuppressWarnings("rawtypes")
+            @Override
+            public Expression newExpression(RexNode node, PhoenixRelImplementor implementor)
{
+                RexDynamicParam param = (RexDynamicParam) node;
+                int index = param.getIndex();
+                PDataType type = sqlTypeNameToPDataType(node.getType().getSqlTypeName());
+                return implementor.newBindParameterExpression(index, type);
+            }            
+        });
 		EXPRESSION_MAP.put(SqlKind.CAST, new ExpressionFactory() {
 
             @SuppressWarnings("rawtypes")

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementor.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementor.java
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementor.java
index b2f275c..a086b40 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementor.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementor.java
@@ -21,6 +21,8 @@ public interface PhoenixRelImplementor {
     QueryPlan visitInput(int i, PhoenixQueryRel input);
     ColumnExpression newColumnExpression(int index);
     @SuppressWarnings("rawtypes")
+    Expression newBindParameterExpression(int index, PDataType type);
+    @SuppressWarnings("rawtypes")
     Expression newFieldAccessExpression(String variableId, int index, PDataType type);
     SequenceValueExpression newSequenceExpression(PhoenixSequence seq, SequenceValueParseNode.Op
op);
     RuntimeContext getRuntimeContext();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementorImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementorImpl.java
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementorImpl.java
index f76ab35..2706258 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementorImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementorImpl.java
@@ -13,6 +13,7 @@ import org.apache.phoenix.compile.SequenceValueExpression;
 import org.apache.phoenix.coprocessor.MetaDataProtocol;
 import org.apache.phoenix.execute.RuntimeContext;
 import org.apache.phoenix.execute.TupleProjector;
+import org.apache.phoenix.expression.BindParameterExpression;
 import org.apache.phoenix.expression.ColumnExpression;
 import org.apache.phoenix.expression.CorrelateVariableFieldAccessExpression;
 import org.apache.phoenix.expression.Expression;
@@ -53,6 +54,12 @@ public class PhoenixRelImplementorImpl implements PhoenixRelImplementor
{
     
     @SuppressWarnings("rawtypes")
     @Override
+    public Expression newBindParameterExpression(int index, PDataType type) {
+        return new BindParameterExpression(index, type, runtimeContext);
+    }
+    
+    @SuppressWarnings("rawtypes")
+    @Override
     public Expression newFieldAccessExpression(String variableId, int index, PDataType type)
{
         Expression fieldAccessExpr = runtimeContext.getCorrelateVariable(variableId).newExpression(index);
         return new CorrelateVariableFieldAccessExpression(runtimeContext, variableId, fieldAccessExpr);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
index 76e9a4d..7859e15 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
@@ -117,16 +117,28 @@ public class PhoenixTableScan extends TableScan implements PhoenixQueryRel
{
             } else {
                 this.extendedColumnRef = extendedColumnRef.union(
                         tableMapping.getExtendedColumnRef(ImmutableList.of(filter)));
-                // We use a implementor with a special implementation for field access
-                // here, which translates RexFieldAccess into a LiteralExpression
+                // We use a implementor with a special implementation for correlate variables
+                // or bind parameters here, which translates them into a LiteralExpression
                 // with a sample value. This will achieve 3 goals at a time:
-                // 1) avoid getting exception when translating RexFieldAccess at this 
-                //    time when the correlate variable has not been defined yet.
+                // 1) avoid getting exception when translating RexFieldAccess at this time
when
+                //    the correlate variable has not been defined yet.
                 // 2) get a guess of ScanRange even if the runtime value is absent.
+                //    TODO instead of getting a random sample value, we'd better get it from
+                //    existing guidepost bytes.
                 // 3) test whether this dynamic filter is worth a recompile at runtime.
                 PhoenixRelImplementor tmpImplementor = new PhoenixRelImplementorImpl(null)
{                    
                     @SuppressWarnings("rawtypes")
                     @Override
+                    public Expression newBindParameterExpression(int index, PDataType type)
{
+                        try {
+                            return LiteralExpression.newConstant(type.getSampleValue(), type);
+                        } catch (SQLException e) {
+                            throw new RuntimeException(e);
+                        }
+                    }
+                    
+                    @SuppressWarnings("rawtypes")
+                    @Override
                     public Expression newFieldAccessExpression(String variableId, int index,
PDataType type) {
                         try {
                             return LiteralExpression.newConstant(type.getSampleValue(), type);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java
index bffdf2f..a72793a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java
@@ -31,6 +31,7 @@ import org.apache.phoenix.compile.QueryPlan;
 import org.apache.phoenix.compile.RowProjector;
 import org.apache.phoenix.compile.StatementPlan;
 import org.apache.phoenix.execute.DelegateQueryPlan;
+import org.apache.phoenix.execute.RuntimeContext;
 import org.apache.phoenix.execute.RuntimeContextImpl;
 import org.apache.phoenix.iterate.DefaultParallelScanGrouper;
 import org.apache.phoenix.iterate.ParallelScanGrouper;
@@ -91,7 +92,9 @@ public class PhoenixToEnumerableConverter extends ConverterImpl implements
Enume
     }
     
     static StatementPlan makePlan(PhoenixRel rel) {
-        final PhoenixRelImplementor phoenixImplementor = new PhoenixRelImplementorImpl(new
RuntimeContextImpl());
+        RuntimeContext runtimeContext = new RuntimeContextImpl();
+        RuntimeContext.THREAD_LOCAL.get().add(runtimeContext);
+        final PhoenixRelImplementor phoenixImplementor = new PhoenixRelImplementorImpl(runtimeContext);
         phoenixImplementor.pushContext(new ImplementorContext(true, false, ImmutableIntList.identity(rel.getRowType().getFieldCount())));
         final StatementPlan plan = rel.implement(phoenixImplementor);
         if (!(plan instanceof QueryPlan)) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/phoenix-core/src/main/java/org/apache/phoenix/execute/CorrelatePlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/CorrelatePlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/CorrelatePlan.java
index e354e34..56930ba 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/CorrelatePlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/CorrelatePlan.java
@@ -27,6 +27,7 @@ import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
 import org.apache.phoenix.compile.QueryPlan;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.exception.SQLExceptionInfo;
+import org.apache.phoenix.execute.RuntimeContext.CorrelateVariable;
 import org.apache.phoenix.execute.TupleProjector.ProjectedValueTuple;
 import org.apache.phoenix.iterate.DefaultParallelScanGrouper;
 import org.apache.phoenix.iterate.ParallelScanGrouper;
@@ -107,6 +108,7 @@ public class CorrelatePlan extends DelegateQueryPlan {
     public ResultIterator iterator(ParallelScanGrouper scanGrouper)
             throws SQLException {
         return new ResultIterator() {
+            private final CorrelateVariable variable = runtimeContext.getCorrelateVariable(variableId);
             private final ValueBitSet destBitSet = ValueBitSet.newInstance(joinedSchema);
             private final ValueBitSet lhsBitSet = ValueBitSet.newInstance(lhsSchema);
             private final ValueBitSet rhsBitSet = 
@@ -150,7 +152,7 @@ public class CorrelatePlan extends DelegateQueryPlan {
                         close();
                         return null;
                     }
-                    runtimeContext.getCorrelateVariable(variableId).setValue(current);
+                    variable.setValue(current);
                     rhsIter = rhs.iterator();
                     rhsCurrent = rhsIter.next();
                     if ((rhsCurrent == null && (joinType == JoinType.Inner || joinType
== JoinType.Semi))

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/phoenix-core/src/main/java/org/apache/phoenix/execute/RuntimeContext.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/RuntimeContext.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/RuntimeContext.java
index ea2b74a..4063c0a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/RuntimeContext.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/RuntimeContext.java
@@ -17,10 +17,20 @@
  */
 package org.apache.phoenix.execute;
 
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.schema.tuple.Tuple;
 
 public interface RuntimeContext {
+    ThreadLocal<List<RuntimeContext>> THREAD_LOCAL =
+            new ThreadLocal<List<RuntimeContext>>() {
+        @Override protected List<RuntimeContext> initialValue() {
+            return new LinkedList<RuntimeContext>();
+        }
+    };
     
     public interface CorrelateVariable {
         public Expression newExpression(int index);        
@@ -30,4 +40,7 @@ public interface RuntimeContext {
 
     public void defineCorrelateVariable(String variableId, CorrelateVariable def);
     public CorrelateVariable getCorrelateVariable(String variableId);
+    
+    public void setBindParameterValues(Map<String, Object> values);
+    public Object getBindParameterValue(String name);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/phoenix-core/src/main/java/org/apache/phoenix/execute/RuntimeContextImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/RuntimeContextImpl.java
b/phoenix-core/src/main/java/org/apache/phoenix/execute/RuntimeContextImpl.java
index 86097bd..ab375ea 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/RuntimeContextImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/RuntimeContextImpl.java
@@ -19,12 +19,15 @@ package org.apache.phoenix.execute;
 
 import java.util.Map;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 
 public class RuntimeContextImpl implements RuntimeContext {
+    Map<String, Object> parameters;
     Map<String, CorrelateVariable> correlateVariables;
 
     public RuntimeContextImpl() {
+        this.parameters = null;
         this.correlateVariables = Maps.newHashMap();
     }
     
@@ -41,4 +44,17 @@ public class RuntimeContextImpl implements RuntimeContext {
         
         return entry;
     }
+
+    @Override
+    public void setBindParameterValues(Map<String, Object> values) {
+        this.parameters = ImmutableMap.copyOf(values);
+    }
+
+    @Override
+    public Object getBindParameterValue(String name) {
+        if (this.parameters == null)
+            throw new RuntimeException("Bind parameters not set.");
+        
+        return this.parameters.get(name);
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/phoenix-core/src/main/java/org/apache/phoenix/expression/BindParameterExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/BindParameterExpression.java
b/phoenix-core/src/main/java/org/apache/phoenix/expression/BindParameterExpression.java
new file mode 100644
index 0000000..d3fac67
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/BindParameterExpression.java
@@ -0,0 +1,41 @@
+package org.apache.phoenix.expression;
+
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.phoenix.execute.RuntimeContext;
+import org.apache.phoenix.expression.visitor.ExpressionVisitor;
+import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PDataType;
+
+public class BindParameterExpression extends VariableExpression {
+    @SuppressWarnings("rawtypes")
+    private final PDataType type;
+
+    public BindParameterExpression(int index,
+            @SuppressWarnings("rawtypes") PDataType type, RuntimeContext runtimeContext)
{
+        super("?" + index, runtimeContext);
+        this.type = type;
+    }
+
+    @Override
+    public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
+        Object value = runtimeContext.getBindParameterValue(name);
+        if (value == null) {
+            return false;
+        }
+        
+        ptr.set(type.toBytes(value));
+        return true;
+    }
+
+    @Override
+    public <T> T accept(ExpressionVisitor<T> visitor) {
+        return visitor.visit(this);
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public PDataType getDataType() {
+        return type;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/phoenix-core/src/main/java/org/apache/phoenix/expression/CorrelateVariableFieldAccessExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/CorrelateVariableFieldAccessExpression.java
b/phoenix-core/src/main/java/org/apache/phoenix/expression/CorrelateVariableFieldAccessExpression.java
index 185e0a1..d981e8a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/CorrelateVariableFieldAccessExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/CorrelateVariableFieldAccessExpression.java
@@ -17,33 +17,25 @@
  */
 package org.apache.phoenix.expression;
 
-import java.io.DataOutput;
-import java.io.IOException;
-import java.sql.SQLException;
-
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.execute.RuntimeContext;
 import org.apache.phoenix.expression.visitor.ExpressionVisitor;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PDataType;
 
-public class CorrelateVariableFieldAccessExpression extends BaseTerminalExpression {
-    private final RuntimeContext runtimeContext;
-    private final String variableId;
+public class CorrelateVariableFieldAccessExpression extends VariableExpression {
     private final Expression fieldAccessExpression;
     
     public CorrelateVariableFieldAccessExpression(RuntimeContext context, String variableId,
Expression fieldAccessExpression) {
-        super();
-        this.runtimeContext = context;
-        this.variableId = variableId;
+        super(variableId, context);
         this.fieldAccessExpression = fieldAccessExpression;
     }
 
     @Override
     public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
-        Tuple variable = runtimeContext.getCorrelateVariable(variableId).getValue();
+        Tuple variable = runtimeContext.getCorrelateVariable(name).getValue();
         if (variable == null)
-            throw new RuntimeException("Variable '" + variableId + "' not set.");
+            throw new RuntimeException("Variable '" + name + "' not set.");
         
         return fieldAccessExpression.evaluate(variable, ptr);
     }
@@ -52,19 +44,6 @@ public class CorrelateVariableFieldAccessExpression extends BaseTerminalExpressi
     public <T> T accept(ExpressionVisitor<T> visitor) {
         return visitor.visit(this);
     }
-
-    @Override
-    public void write(DataOutput output) throws IOException {
-        ImmutableBytesWritable ptr = new ImmutableBytesWritable();
-        boolean success = evaluate(null, ptr);
-        Object value = success ? getDataType().toObject(ptr) : null;
-        try {
-            LiteralExpression expr = LiteralExpression.newConstant(value, getDataType());
-            expr.write(output);
-        } catch (SQLException e) {
-            throw new IOException(e);
-        }
-    }
     
     @SuppressWarnings("rawtypes")
     @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/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 f13e265..53f71ec 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
@@ -318,10 +318,10 @@ public enum ExpressionType {
      */
     public static ExpressionType valueOfOrNull(Expression expression) {
         Class <? extends Expression> clazz = expression.getClass();
-        // We will not have CorrelateVariableFieldAccessExpression on the server side,
+        // We will not have instances of VariableExpression on the server side,
         // it will be evaluated at client side and will be serialized as 
         // LiteralExpression instead.
-        if (clazz == CorrelateVariableFieldAccessExpression.class) {
+        if (VariableExpression.class.isAssignableFrom(clazz)) {
             clazz = LiteralExpression.class;
         }
         return classToEnumMap.get(clazz);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/phoenix-core/src/main/java/org/apache/phoenix/expression/VariableExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/VariableExpression.java
b/phoenix-core/src/main/java/org/apache/phoenix/expression/VariableExpression.java
new file mode 100644
index 0000000..a1b1689
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/VariableExpression.java
@@ -0,0 +1,31 @@
+package org.apache.phoenix.expression;
+
+import java.io.DataOutput;
+import java.io.IOException;
+import java.sql.SQLException;
+
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.phoenix.execute.RuntimeContext;
+
+public abstract class VariableExpression extends BaseTerminalExpression {
+    protected final String name;
+    protected final RuntimeContext runtimeContext;
+    
+    VariableExpression(String name, RuntimeContext runtimeContext) {
+        this.name = name;
+        this.runtimeContext = runtimeContext;
+    }
+
+    @Override
+    public void write(DataOutput output) throws IOException {
+        ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+        boolean success = evaluate(null, ptr);
+        Object value = success ? getDataType().toObject(ptr) : null;
+        try {
+            LiteralExpression expr = LiteralExpression.newConstant(value, getDataType());
+            expr.write(output);
+        } catch (SQLException e) {
+            throw new IOException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/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
index 00ece40..31c71c0 100644
--- 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
@@ -23,6 +23,7 @@ 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.BindParameterExpression;
 import org.apache.phoenix.expression.CaseExpression;
 import org.apache.phoenix.expression.CoerceExpression;
 import org.apache.phoenix.expression.ComparisonExpression;
@@ -67,6 +68,11 @@ public abstract class CloneExpressionVisitor extends TraverseAllExpressionVisito
     }
 
     @Override
+    public Expression visit(BindParameterExpression node) {
+        return null;
+    }
+
+    @Override
     public Expression visit(LiteralExpression node) {
         return node;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/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 31f340d..1503698 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
@@ -24,6 +24,7 @@ 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.BindParameterExpression;
 import org.apache.phoenix.expression.CaseExpression;
 import org.apache.phoenix.expression.CoerceExpression;
 import org.apache.phoenix.expression.ComparisonExpression;
@@ -110,6 +111,7 @@ public interface ExpressionVisitor<E> {
     public E visitLeave(ArrayConstructorExpression node, List<E> l);
     
     public E visit(CorrelateVariableFieldAccessExpression node);
+    public E visit(BindParameterExpression node);
     public E visit(LiteralExpression node);
     public E visit(RowKeyColumnExpression node);
     public E visit(KeyValueColumnExpression node);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/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
index 3b7067a..534937c 100644
--- 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
@@ -23,12 +23,12 @@ 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.BindParameterExpression;
 import org.apache.phoenix.expression.CaseExpression;
 import org.apache.phoenix.expression.CoerceExpression;
 import org.apache.phoenix.expression.ComparisonExpression;
 import org.apache.phoenix.expression.CorrelateVariableFieldAccessExpression;
 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;
@@ -106,6 +106,11 @@ public class StatelessTraverseAllExpressionVisitor<E> extends TraverseAllExpress
     }
 
     @Override
+    public E visit(BindParameterExpression node) {
+        return null;
+    }
+
+    @Override
     public E visit(LiteralExpression node) {
         return null;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/91b92356/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
index 83b28bd..36e47f3 100644
--- 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
@@ -23,12 +23,12 @@ 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.BindParameterExpression;
 import org.apache.phoenix.expression.CaseExpression;
 import org.apache.phoenix.expression.CoerceExpression;
 import org.apache.phoenix.expression.ComparisonExpression;
 import org.apache.phoenix.expression.CorrelateVariableFieldAccessExpression;
 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;
@@ -106,6 +106,11 @@ public class StatelessTraverseNoExpressionVisitor<E> extends TraverseNoExpressio
     }
 
     @Override
+    public E visit(BindParameterExpression node) {
+        return null;
+    }
+
+    @Override
     public E visit(LiteralExpression node) {
         return null;
     }


Mime
View raw message