phoenix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jamestay...@apache.org
Subject [2/2] phoenix git commit: PHOENIX-2413 Implement BaseMutationPlan for common method implementation
Date Fri, 13 Nov 2015 05:49:57 GMT
PHOENIX-2413 Implement BaseMutationPlan for common method implementation


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

Branch: refs/heads/master
Commit: 461aaa239479abb8bb35df79324d2d2c3627e0d5
Parents: a95d701
Author: James Taylor <jtaylor@salesforce.com>
Authored: Thu Nov 12 21:49:32 2015 -0800
Committer: James Taylor <jtaylor@salesforce.com>
Committed: Thu Nov 12 21:49:32 2015 -0800

----------------------------------------------------------------------
 .../phoenix/compile/BaseMutationPlan.java       |  67 ++++++
 .../phoenix/compile/CreateFunctionCompiler.java |  17 +-
 .../phoenix/compile/CreateIndexCompiler.java    |  28 +--
 .../phoenix/compile/CreateSequenceCompiler.java |  32 +--
 .../phoenix/compile/CreateTableCompiler.java    |  25 +--
 .../apache/phoenix/compile/DeleteCompiler.java  | 130 ++++++++----
 .../phoenix/compile/DropSequenceCompiler.java   |  24 +--
 .../phoenix/compile/ListJarsQueryPlan.java      |  14 +-
 .../apache/phoenix/compile/MutationPlan.java    |   6 +-
 .../apache/phoenix/compile/PostDDLCompiler.java |  75 ++++---
 .../apache/phoenix/compile/StatementPlan.java   |   8 +-
 .../apache/phoenix/compile/TraceQueryPlan.java  |  27 ++-
 .../apache/phoenix/compile/UpsertCompiler.java  |  95 +++++----
 .../apache/phoenix/execute/BaseQueryPlan.java   |  51 +++--
 .../phoenix/execute/DelegateQueryPlan.java      |  14 +-
 .../phoenix/execute/SortMergeJoinPlan.java      |  18 +-
 .../org/apache/phoenix/execute/UnionPlan.java   |  20 +-
 .../apache/phoenix/jdbc/PhoenixStatement.java   | 209 +++++--------------
 .../query/ConnectionlessQueryServicesImpl.java  |   2 +-
 .../apache/phoenix/schema/MetaDataClient.java   |  27 +--
 .../query/ParallelIteratorsSplitTest.java       |  22 +-
 21 files changed, 492 insertions(+), 419 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/compile/BaseMutationPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/BaseMutationPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/BaseMutationPlan.java
new file mode 100644
index 0000000..d82aa1f
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/BaseMutationPlan.java
@@ -0,0 +1,67 @@
+/*
+ * 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 java.sql.ParameterMetaData;
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
+import org.apache.phoenix.schema.TableRef;
+
+public abstract class BaseMutationPlan implements MutationPlan {
+    private final StatementContext context;
+    private final Operation operation;
+    
+    public BaseMutationPlan(StatementContext context, Operation operation) {
+        this.context = context;
+        this.operation = operation;
+    }
+    
+    @Override
+    public Operation getOperation() {
+        return operation;
+    }
+    
+    @Override
+    public StatementContext getContext() {
+        return context;
+    }
+
+    @Override
+    public ParameterMetaData getParameterMetaData() {
+        return context.getBindManager().getParameterMetaData();
+    }
+
+    @Override
+    public ExplainPlan getExplainPlan() throws SQLException {
+        return ExplainPlan.EMPTY_PLAN;
+    }
+
+    @Override
+    public TableRef getTargetRef() {
+        return context.getCurrentTable();
+    }
+    
+    @Override
+    public Set<TableRef> getSourceRefs() {
+        return Collections.emptySet();
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateFunctionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateFunctionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateFunctionCompiler.java
index 138c75d..0e8036a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateFunctionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateFunctionCompiler.java
@@ -17,12 +17,9 @@
  */
 package org.apache.phoenix.compile;
 
-import java.sql.ParameterMetaData;
 import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
 import java.util.Collections;
 
-import org.apache.hadoop.hbase.client.Scan;
 import org.apache.phoenix.execute.MutationState;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixStatement;
@@ -43,12 +40,7 @@ public class CreateFunctionCompiler {
         final StatementContext context = new StatementContext(statement);
         final MetaDataClient client = new MetaDataClient(connectionToBe);
         
-        return new MutationPlan() {
-
-            @Override
-            public ParameterMetaData getParameterMetaData() {
-                return context.getBindManager().getParameterMetaData();
-            }
+        return new BaseMutationPlan(context, create.getOperation()) {
 
             @Override
             public MutationState execute() throws SQLException {
@@ -69,14 +61,9 @@ public class CreateFunctionCompiler {
             }
 
             @Override
-            public PhoenixConnection getConnection() {
-                return connection;
-            }
-            
-            @Override
             public StatementContext getContext() {
                 return context;
             }
         };
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateIndexCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateIndexCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateIndexCompiler.java
index f1937a5..1837b52 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateIndexCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateIndexCompiler.java
@@ -17,7 +17,6 @@
  */
 package org.apache.phoenix.compile;
 
-import java.sql.ParameterMetaData;
 import java.sql.SQLException;
 import java.util.Collections;
 import java.util.List;
@@ -31,17 +30,19 @@ import org.apache.phoenix.expression.LiteralExpression;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.parse.CreateIndexStatement;
 import org.apache.phoenix.parse.ParseNode;
-import org.apache.phoenix.parse.PropertyName;
 import org.apache.phoenix.schema.MetaDataClient;
 import org.apache.phoenix.schema.PTable.IndexType;
 
 public class CreateIndexCompiler {
     private final PhoenixStatement statement;
+    private final Operation operation;
 
-    public CreateIndexCompiler(PhoenixStatement statement) {
+    public CreateIndexCompiler(PhoenixStatement statement, Operation operation) {
         this.statement = statement;
+        this.operation = operation;
     }
 
     public MutationPlan compile(final CreateIndexStatement create) throws SQLException {
@@ -78,18 +79,7 @@ public class CreateIndexCompiler {
         }
         final MetaDataClient client = new MetaDataClient(connection);
         
-        return new MutationPlan() {
-
-            @Override
-            public ParameterMetaData getParameterMetaData() {
-                return context.getBindManager().getParameterMetaData();
-            }
-
-            @Override
-            public PhoenixConnection getConnection() {
-                return connection;
-            }
-
+        return new BaseMutationPlan(context, operation) {
             @Override
             public MutationState execute() throws SQLException {
                 return client.createIndex(create, splits);
@@ -99,11 +89,7 @@ public class CreateIndexCompiler {
             public ExplainPlan getExplainPlan() throws SQLException {
                 return new ExplainPlan(Collections.singletonList("CREATE INDEX"));
             }
-
-            @Override
-            public StatementContext getContext() {
-                return context;
-            }
+        	
         };
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateSequenceCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateSequenceCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateSequenceCompiler.java
index 65d2c04..3ff149a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateSequenceCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateSequenceCompiler.java
@@ -17,7 +17,6 @@
  */
 package org.apache.phoenix.compile;
 
-import java.sql.ParameterMetaData;
 import java.sql.SQLException;
 import java.util.Collections;
 
@@ -27,26 +26,28 @@ import org.apache.phoenix.execute.MutationState;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.parse.BindParseNode;
 import org.apache.phoenix.parse.CreateSequenceStatement;
 import org.apache.phoenix.parse.ParseNode;
-import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.parse.TableName;
+import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.query.QueryServicesOptions;
-import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.MetaDataClient;
-import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.PDatum;
-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.types.PInteger;
+import org.apache.phoenix.schema.types.PLong;
 import org.apache.phoenix.util.SequenceUtil;
 
 public class CreateSequenceCompiler {
     private final PhoenixStatement statement;
+    private final Operation operation;
 
-    public CreateSequenceCompiler(PhoenixStatement statement) {
+    public CreateSequenceCompiler(PhoenixStatement statement, Operation operation) {
         this.statement = statement;
+        this.operation = operation;
     }
     
     private static class LongDatum implements PDatum {
@@ -231,7 +232,7 @@ public class CreateSequenceCompiler {
         final long cacheSize = Math.max(1L, cacheSizeValue);
 
         final MetaDataClient client = new MetaDataClient(connection);
-        return new MutationPlan() {
+        return new BaseMutationPlan(context, operation) {
 
             @Override
             public MutationState execute() throws SQLException {
@@ -242,21 +243,6 @@ public class CreateSequenceCompiler {
             public ExplainPlan getExplainPlan() throws SQLException {
                 return new ExplainPlan(Collections.singletonList("CREATE SEQUENCE"));
             }
-
-            @Override
-            public PhoenixConnection getConnection() {
-                return connection;
-            }
-
-            @Override
-            public ParameterMetaData getParameterMetaData() {
-                return context.getBindManager().getParameterMetaData();
-            }
-
-            @Override
-            public StatementContext getContext() {
-                return context;
-            }
         };
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/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 a5adc49..f09b508 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
@@ -17,7 +17,6 @@
  */
 package org.apache.phoenix.compile;
 
-import java.sql.ParameterMetaData;
 import java.sql.SQLException;
 import java.util.BitSet;
 import java.util.Collections;
@@ -41,6 +40,7 @@ import org.apache.phoenix.expression.RowKeyColumnExpression;
 import org.apache.phoenix.expression.visitor.StatelessTraverseNoExpressionVisitor;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.parse.BindParseNode;
 import org.apache.phoenix.parse.ColumnParseNode;
 import org.apache.phoenix.parse.CreateTableStatement;
@@ -69,9 +69,11 @@ import com.google.common.collect.Iterators;
 public class CreateTableCompiler {
     private static final PDatum VARBINARY_DATUM = new VarbinaryDatum();
     private final PhoenixStatement statement;
+    private final Operation operation;
     
-    public CreateTableCompiler(PhoenixStatement statement) {
+    public CreateTableCompiler(PhoenixStatement statement, Operation operation) {
         this.statement = statement;
+        this.operation = operation;
     }
 
     public MutationPlan compile(final CreateTableStatement create) throws SQLException {
@@ -173,12 +175,7 @@ public class CreateTableCompiler {
         final MetaDataClient client = new MetaDataClient(connectionToBe);
         final PTable parent = parentToBe;
         
-        return new MutationPlan() {
-
-            @Override
-            public ParameterMetaData getParameterMetaData() {
-                return context.getBindManager().getParameterMetaData();
-            }
+        return new BaseMutationPlan(context, operation) {
 
             @Override
             public MutationState execute() throws SQLException {
@@ -195,16 +192,6 @@ public class CreateTableCompiler {
             public ExplainPlan getExplainPlan() throws SQLException {
                 return new ExplainPlan(Collections.singletonList("CREATE TABLE"));
             }
-
-            @Override
-            public PhoenixConnection getConnection() {
-                return connection;
-            }
-            
-            @Override
-            public StatementContext getContext() {
-                return context;
-            }
         };
     }
     
@@ -339,4 +326,4 @@ public class CreateTableCompiler {
         }
         
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java
index 2c90bdf..f0f693e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java
@@ -1,5 +1,4 @@
 /*
- * 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
@@ -50,6 +49,7 @@ import org.apache.phoenix.iterate.ResultIterator;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixResultSet;
 import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.optimize.QueryOptimizer;
 import org.apache.phoenix.parse.AliasedNode;
 import org.apache.phoenix.parse.DeleteStatement;
@@ -91,9 +91,11 @@ public class DeleteCompiler {
     private static ParseNodeFactory FACTORY = new ParseNodeFactory();
     
     private final PhoenixStatement statement;
+    private final Operation operation;
     
-    public DeleteCompiler(PhoenixStatement statement) {
+    public DeleteCompiler(PhoenixStatement statement, Operation operation) {
         this.statement = statement;
+        this.operation = operation;
     }
     
     private static MutationState deleteRows(StatementContext childContext, TableRef targetTableRef, TableRef indexTableRef, ResultIterator iterator, RowProjector projector, TableRef sourceTableRef) throws SQLException {
@@ -270,11 +272,6 @@ public class DeleteCompiler {
         }
 
         @Override
-        public PhoenixConnection getConnection() {
-            return firstPlan.getConnection();
-        }
-
-        @Override
         public MutationState execute() throws SQLException {
             MutationState state = firstPlan.execute();
             for (MutationPlan plan : plans.subList(1, plans.size())) {
@@ -282,6 +279,21 @@ public class DeleteCompiler {
             }
             return state;
         }
+
+        @Override
+        public TableRef getTargetRef() {
+            return firstPlan.getTargetRef();
+        }
+
+        @Override
+        public Set<TableRef> getSourceRefs() {
+            return firstPlan.getSourceRefs();
+        }
+
+		@Override
+		public Operation getOperation() {
+			return operation;
+		}
     }
     
     public MutationPlan compile(DeleteStatement delete) throws SQLException {
@@ -298,20 +310,28 @@ public class DeleteCompiler {
         boolean noQueryReqd = false;
         boolean runOnServer = false;
         SelectStatement select = null;
+        ColumnResolver resolverToBe = null;
         Set<PTable> immutableIndex = Collections.emptySet();
         DeletingParallelIteratorFactory parallelIteratorFactory = null;
+        QueryPlan dataPlanToBe = null;
         while (true) {
             try {
-                ColumnResolver resolver = FromCompiler.getResolverForMutation(delete, connection);
-                tableRefToBe = resolver.getTables().get(0);
+                resolverToBe = FromCompiler.getResolverForMutation(delete, connection);
+                tableRefToBe = resolverToBe.getTables().get(0);
                 PTable table = tableRefToBe.getTable();
-                if (table.getType() == PTableType.VIEW && table.getViewType().isReadOnly()) {
-                    throw new ReadOnlyTableException(table.getSchemaName().getString(),table.getTableName().getString());
+                // Cannot update:
+                // - read-only VIEW 
+                // - transactional table with a connection having an SCN
+                // TODO: SchemaUtil.isReadOnly(PTable, connection)?
+                if ( table.getType() == PTableType.VIEW && table.getViewType().isReadOnly() ) {
+                    throw new ReadOnlyTableException(schemaName,tableName);
                 }
                 
                 immutableIndex = getNonDisabledImmutableIndexes(tableRefToBe);
                 boolean mayHaveImmutableIndexes = !immutableIndex.isEmpty();
                 noQueryReqd = !hasLimit;
+                // Can't run on same server for transactional data, as we need the row keys for the data
+                // that is being upserted for conflict detection purposes.
                 runOnServer = isAutoCommit && noQueryReqd;
                 HintNode hint = delete.getHint();
                 if (runOnServer && !delete.getHint().hasHint(Hint.USE_INDEX_OVER_DATA_TABLE)) {
@@ -332,17 +352,19 @@ public class DeleteCompiler {
                         Collections.<ParseNode>emptyList(), null, 
                         delete.getOrderBy(), delete.getLimit(),
                         delete.getBindCount(), false, false, Collections.<SelectStatement>emptyList(), delete.getUdfParseNodes());
-                select = StatementNormalizer.normalize(select, resolver);
-                SelectStatement transformedSelect = SubqueryRewriter.transform(select, resolver, connection);
+                select = StatementNormalizer.normalize(select, resolverToBe);
+                SelectStatement transformedSelect = SubqueryRewriter.transform(select, resolverToBe, connection);
                 if (transformedSelect != select) {
-                    resolver = FromCompiler.getResolverForQuery(transformedSelect, connection);
-                    select = StatementNormalizer.normalize(transformedSelect, resolver);
+                    resolverToBe = FromCompiler.getResolverForQuery(transformedSelect, connection);
+                    select = StatementNormalizer.normalize(transformedSelect, resolverToBe);
                 }
                 parallelIteratorFactory = hasLimit ? null : new DeletingParallelIteratorFactory(connection);
                 QueryOptimizer optimizer = new QueryOptimizer(services);
+                QueryCompiler compiler = new QueryCompiler(statement, select, resolverToBe, Collections.<PColumn>emptyList(), parallelIteratorFactory, new SequenceManager(statement));
+                dataPlanToBe = compiler.compile();
                 queryPlans = Lists.newArrayList(mayHaveImmutableIndexes
-                        ? optimizer.getApplicablePlans(statement, select, resolver, Collections.<PColumn>emptyList(), parallelIteratorFactory)
-                        : optimizer.getBestPlan(statement, select, resolver, Collections.<PColumn>emptyList(), parallelIteratorFactory));
+                        ? optimizer.getApplicablePlans(statement, select, resolverToBe, Collections.<PColumn>emptyList(), parallelIteratorFactory)
+                        : optimizer.getBestPlan(statement, select, resolverToBe, Collections.<PColumn>emptyList(), parallelIteratorFactory));
                 if (mayHaveImmutableIndexes) { // FIXME: this is ugly
                     // Lookup the table being deleted from in the cache, as it's possible that the
                     // optimizer updated the cache if it found indexes that were out of date.
@@ -367,6 +389,8 @@ public class DeleteCompiler {
             }
             break;
         }
+        final QueryPlan dataPlan = dataPlanToBe;
+        final ColumnResolver resolver = resolverToBe;
         final boolean hasImmutableIndexes = !immutableIndex.isEmpty();
         // tableRefs is parallel with queryPlans
         TableRef[] tableRefs = new TableRef[hasImmutableIndexes ? immutableIndex.size() : 1];
@@ -401,7 +425,7 @@ public class DeleteCompiler {
         
         // Make sure the first plan is targeting deletion from the data table
         // In the case of an immutable index, we'll also delete from the index.
-        tableRefs[0] = tableRefToBe;
+        final TableRef dataTableRef = tableRefs[0] = tableRefToBe;
         /*
          * Create a mutationPlan for each queryPlan. One plan will be for the deletion of the rows
          * from the data table, while the others will be for deleting rows from immutable indexes.
@@ -433,7 +457,7 @@ public class DeleteCompiler {
                     }
     
                     @Override
-                    public MutationState execute() {
+                    public MutationState execute() throws SQLException {
                         // We have a point lookup, so we know we have a simple set of fully qualified
                         // keys for our ranges
                         ScanRanges ranges = context.getScanRanges();
@@ -451,14 +475,25 @@ public class DeleteCompiler {
                     }
     
                     @Override
-                    public PhoenixConnection getConnection() {
-                        return connection;
-                    }
-    
-                    @Override
                     public StatementContext getContext() {
                         return context;
                     }
+
+                    @Override
+                    public TableRef getTargetRef() {
+                        return dataTableRef;
+                    }
+
+                    @Override
+                    public Set<TableRef> getSourceRefs() {
+                        // Don't include the target
+                        return Collections.emptySet();
+                    }
+
+            		@Override
+            		public Operation getOperation() {
+            			return operation;
+            		}
                 });
             } else if (runOnServer) {
                 // TODO: better abstraction
@@ -472,12 +507,6 @@ public class DeleteCompiler {
                 final RowProjector projector = ProjectionCompiler.compile(context, aggSelect, GroupBy.EMPTY_GROUP_BY);
                 final QueryPlan aggPlan = new AggregatePlan(context, select, tableRef, projector, null, OrderBy.EMPTY_ORDER_BY, null, GroupBy.EMPTY_GROUP_BY, null);
                 mutationPlans.add(new MutationPlan() {
-    
-                    @Override
-                    public PhoenixConnection getConnection() {
-                        return connection;
-                    }
-    
                     @Override
                     public ParameterMetaData getParameterMetaData() {
                         return context.getBindManager().getParameterMetaData();
@@ -489,10 +518,26 @@ public class DeleteCompiler {
                     }
     
                     @Override
+                    public TableRef getTargetRef() {
+                        return dataTableRef;
+                    }
+
+                    @Override
+                    public Set<TableRef> getSourceRefs() {
+                        return dataPlan.getSourceRefs();
+                    }
+
+            		@Override
+            		public Operation getOperation() {
+            			return operation;
+            		}
+
+                    @Override
                     public MutationState execute() throws SQLException {
                         // TODO: share this block of code with UPSERT SELECT
                         ImmutableBytesWritable ptr = context.getTempPtr();
-                        tableRef.getTable().getIndexMaintainers(ptr, context.getConnection());
+                        PTable table = tableRef.getTable();
+                        table.getIndexMaintainers(ptr, context.getConnection());
                         ServerCache cache = null;
                         try {
                             if (ptr.getLength() > 0) {
@@ -539,12 +584,6 @@ public class DeleteCompiler {
                     parallelIteratorFactory.setIndexTargetTableRef(deleteFromImmutableIndexToo ? plan.getTableRef() : null);
                 }
                 mutationPlans.add( new MutationPlan() {
-    
-                    @Override
-                    public PhoenixConnection getConnection() {
-                        return connection;
-                    }
-    
                     @Override
                     public ParameterMetaData getParameterMetaData() {
                         return context.getBindManager().getParameterMetaData();
@@ -556,6 +595,21 @@ public class DeleteCompiler {
                     }
     
                     @Override
+                    public TableRef getTargetRef() {
+                        return dataTableRef;
+                    }
+
+                    @Override
+                    public Set<TableRef> getSourceRefs() {
+                        return dataPlan.getSourceRefs();
+                    }
+
+            		@Override
+            		public Operation getOperation() {
+            			return operation;
+            		}
+
+                    @Override
                     public MutationState execute() throws SQLException {
                         ResultIterator iterator = plan.iterator();
                         if (!hasLimit) {
@@ -591,4 +645,4 @@ public class DeleteCompiler {
         }
         return mutationPlans.size() == 1 ? mutationPlans.get(0) : new MultiDeleteMutationPlan(mutationPlans);
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/compile/DropSequenceCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/DropSequenceCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/DropSequenceCompiler.java
index 698d5ea..2785dc8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/DropSequenceCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/DropSequenceCompiler.java
@@ -17,23 +17,24 @@
  */
 package org.apache.phoenix.compile;
 
-import java.sql.ParameterMetaData;
 import java.sql.SQLException;
 import java.util.Collections;
 
 import org.apache.phoenix.execute.MutationState;
 import org.apache.phoenix.jdbc.PhoenixConnection;
-import org.apache.phoenix.jdbc.PhoenixParameterMetaData;
 import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.parse.DropSequenceStatement;
 import org.apache.phoenix.schema.MetaDataClient;
 
 
 public class DropSequenceCompiler {
     private final PhoenixStatement statement;
+    private final Operation operation;
 
-    public DropSequenceCompiler(PhoenixStatement statement) {
+    public DropSequenceCompiler(PhoenixStatement statement, Operation operation) {
         this.statement = statement;
+        this.operation = operation;
     }
     
 
@@ -41,7 +42,7 @@ public class DropSequenceCompiler {
         final PhoenixConnection connection = statement.getConnection();
         final MetaDataClient client = new MetaDataClient(connection);        
         final StatementContext context = new StatementContext(statement);
-        return new MutationPlan() {           
+        return new BaseMutationPlan(context, operation) {           
 
             @Override
             public MutationState execute() throws SQLException {
@@ -53,21 +54,6 @@ public class DropSequenceCompiler {
                 return new ExplainPlan(Collections.singletonList("DROP SEQUENCE"));
             }
 
-            @Override
-            public StatementContext getContext() {
-                return context;
-            }
-
-            @Override
-            public PhoenixConnection getConnection() {
-                return connection;
-            }
-
-            @Override
-            public ParameterMetaData getParameterMetaData() {                
-                return PhoenixParameterMetaData.EMPTY_PARAMETER_META_DATA;
-            }
-
         };
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
index f93ab03..dac691f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
@@ -23,6 +23,7 @@ import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
@@ -47,6 +48,7 @@ import org.apache.phoenix.iterate.ParallelScanGrouper;
 import org.apache.phoenix.iterate.ResultIterator;
 import org.apache.phoenix.jdbc.PhoenixParameterMetaData;
 import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.parse.FilterableStatement;
 import org.apache.phoenix.parse.LiteralParseNode;
 import org.apache.phoenix.parse.ParseNodeFactory;
@@ -230,4 +232,14 @@ public class ListJarsQueryPlan implements QueryPlan {
     public boolean useRoundRobinIterator() {
         return false;
     }
-}
+
+	@Override
+	public Set<TableRef> getSourceRefs() {
+		return Collections.<TableRef>emptySet();
+	}
+
+	@Override
+	public Operation getOperation() {
+		return stmt.getUpdateOperation();
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/compile/MutationPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/MutationPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/MutationPlan.java
index 277b5a2..ddc2004 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/MutationPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/MutationPlan.java
@@ -20,10 +20,10 @@ package org.apache.phoenix.compile;
 import java.sql.SQLException;
 
 import org.apache.phoenix.execute.MutationState;
-import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.schema.TableRef;
 
 
 public interface MutationPlan extends StatementPlan {
-    public PhoenixConnection getConnection();
     public MutationState execute() throws SQLException;
-}
+    public TableRef getTargetRef();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
index d75fe38..c6f6bf2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
@@ -17,7 +17,6 @@
  */
 package org.apache.phoenix.compile;
 
-import java.sql.ParameterMetaData;
 import java.sql.SQLException;
 import java.util.Collections;
 import java.util.List;
@@ -32,8 +31,8 @@ import org.apache.phoenix.execute.AggregatePlan;
 import org.apache.phoenix.execute.MutationState;
 import org.apache.phoenix.iterate.ResultIterator;
 import org.apache.phoenix.jdbc.PhoenixConnection;
-import org.apache.phoenix.jdbc.PhoenixParameterMetaData;
 import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.parse.PFunction;
 import org.apache.phoenix.parse.SelectStatement;
 import org.apache.phoenix.query.QueryConstants;
@@ -41,12 +40,13 @@ import org.apache.phoenix.schema.AmbiguousColumnException;
 import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
 import org.apache.phoenix.schema.ColumnNotFoundException;
 import org.apache.phoenix.schema.ColumnRef;
+import org.apache.phoenix.schema.FunctionNotFoundException;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PColumnFamily;
-import org.apache.phoenix.schema.types.PLong;
 import org.apache.phoenix.schema.TableNotFoundException;
 import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PLong;
 import org.apache.phoenix.util.ScanUtil;
 
 import com.google.common.collect.Lists;
@@ -66,7 +66,7 @@ import com.google.common.collect.Lists;
  */
 public class PostDDLCompiler {
     private final PhoenixConnection connection;
-    private final StatementContext context; // bogus context
+    private final Scan scan;
 
     public PostDDLCompiler(PhoenixConnection connection) {
         this(connection, new Scan());
@@ -74,29 +74,53 @@ public class PostDDLCompiler {
 
     public PostDDLCompiler(PhoenixConnection connection, Scan scan) {
         this.connection = connection;
-        this.context = new StatementContext(new PhoenixStatement(connection), scan);
+        this.scan = scan;
         scan.setAttribute(BaseScannerRegionObserver.UNGROUPED_AGG, QueryConstants.TRUE);
     }
 
     public MutationPlan compile(final List<TableRef> tableRefs, final byte[] emptyCF, final byte[] projectCF, final List<PColumn> deleteList,
             final long timestamp) throws SQLException {
-        
-        return new MutationPlan() {
-            
-            @Override
-            public PhoenixConnection getConnection() {
-                return connection;
-            }
-            
-            @Override
-            public ParameterMetaData getParameterMetaData() {
-                return PhoenixParameterMetaData.EMPTY_PARAMETER_META_DATA;
-            }
-            
-            @Override
-            public ExplainPlan getExplainPlan() throws SQLException {
-                return ExplainPlan.EMPTY_PLAN;
-            }
+        PhoenixStatement statement = new PhoenixStatement(connection);
+        final StatementContext context = new StatementContext(
+                statement, 
+                new ColumnResolver() {
+
+                    @Override
+                    public List<TableRef> getTables() {
+                        return tableRefs;
+                    }
+
+                    @Override
+                    public TableRef resolveTable(String schemaName, String tableName) throws SQLException {
+                        throw new UnsupportedOperationException();
+                    }
+
+                    @Override
+                    public ColumnRef resolveColumn(String schemaName, String tableName, String colName)
+                            throws SQLException {
+                        throw new UnsupportedOperationException();
+                    }
+
+					@Override
+					public List<PFunction> getFunctions() {
+						return Collections.<PFunction>emptyList();
+					}
+
+					@Override
+					public PFunction resolveFunction(String functionName)
+							throws SQLException {
+						throw new FunctionNotFoundException(functionName);
+					}
+
+					@Override
+					public boolean hasUDFs() {
+						return false;
+					}
+                    
+                },
+                scan,
+                new SequenceManager(statement));
+        return new BaseMutationPlan(context, Operation.UPSERT /* FIXME */) {
             
             @Override
             public MutationState execute() throws SQLException {
@@ -267,11 +291,6 @@ public class PostDDLCompiler {
                     if (!wasAutoCommit) connection.setAutoCommit(wasAutoCommit);
                 }
             }
-
-            @Override
-            public StatementContext getContext() {
-                return context;
-            }
         };
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementPlan.java
index ab6f68a..cfdb8e9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementPlan.java
@@ -19,6 +19,10 @@ package org.apache.phoenix.compile;
 
 import java.sql.ParameterMetaData;
 import java.sql.SQLException;
+import java.util.Set;
+
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
+import org.apache.phoenix.schema.TableRef;
 
 
 public interface StatementPlan {
@@ -29,4 +33,6 @@ public interface StatementPlan {
     ParameterMetaData getParameterMetaData();
     
     ExplainPlan getExplainPlan() throws SQLException;
-}
+    public Set<TableRef> getSourceRefs();
+    Operation getOperation();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
index 50ec919..a9754b3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
@@ -22,6 +22,7 @@ import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellUtil;
@@ -42,8 +43,8 @@ import org.apache.phoenix.iterate.DefaultParallelScanGrouper;
 import org.apache.phoenix.iterate.ParallelScanGrouper;
 import org.apache.phoenix.iterate.ResultIterator;
 import org.apache.phoenix.jdbc.PhoenixConnection;
-import org.apache.phoenix.jdbc.PhoenixParameterMetaData;
 import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.metrics.MetricInfo;
 import org.apache.phoenix.parse.FilterableStatement;
 import org.apache.phoenix.parse.LiteralParseNode;
@@ -87,12 +88,17 @@ public class TraceQueryPlan implements QueryPlan {
         TRACE_PROJECTOR = new RowProjector(projectedColumns, estimatedByteSize, false);
     }
 
-    public TraceQueryPlan(TraceStatement traceStatement, PhoenixStatement stmt) {
+    public TraceQueryPlan(TraceStatement traceStatement, PhoenixStatement stmt ) {
         this.traceStatement = traceStatement;
         this.stmt = stmt;
         this.context = new StatementContext(stmt);
     }
 
+	@Override
+	public Operation getOperation() {
+		return traceStatement.getOperation();
+	}
+	
     @Override
     public StatementContext getContext() {
         return this.context;
@@ -100,12 +106,7 @@ public class TraceQueryPlan implements QueryPlan {
 
     @Override
     public ParameterMetaData getParameterMetaData() {
-        return PhoenixParameterMetaData.EMPTY_PARAMETER_META_DATA;
-    }
-
-    @Override
-    public ExplainPlan getExplainPlan() throws SQLException {
-        return ExplainPlan.EMPTY_PLAN;
+        return context.getBindManager().getParameterMetaData();
     }
     
     @Override
@@ -185,6 +186,11 @@ public class TraceQueryPlan implements QueryPlan {
     }
 
     @Override
+    public Set<TableRef> getSourceRefs() {
+        return Collections.emptySet();
+    }
+
+    @Override
     public TableRef getTableRef() {
         return null;
     }
@@ -233,6 +239,11 @@ public class TraceQueryPlan implements QueryPlan {
     public boolean isRowKeyOrdered() {
         return false;
     }
+
+    @Override
+    public ExplainPlan getExplainPlan() throws SQLException {
+        return ExplainPlan.EMPTY_PLAN;
+    }
     
     @Override
     public boolean useRoundRobinIterator() {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
index 56087c0..953eb2f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
@@ -20,11 +20,9 @@ package org.apache.phoenix.compile;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.collect.Lists.newArrayListWithCapacity;
 
-import java.sql.Date;
 import java.sql.ParameterMetaData;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Arrays;
 import java.util.BitSet;
@@ -58,6 +56,7 @@ import org.apache.phoenix.iterate.ResultIterator;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixResultSet;
 import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.optimize.QueryOptimizer;
 import org.apache.phoenix.parse.AliasedNode;
 import org.apache.phoenix.parse.BindParseNode;
@@ -90,17 +89,10 @@ import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TableRef;
 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;
-import org.apache.phoenix.schema.types.PDate;
-import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PLong;
-import org.apache.phoenix.schema.types.PTime;
 import org.apache.phoenix.schema.types.PTimestamp;
-import org.apache.phoenix.schema.types.PUnsignedDate;
 import org.apache.phoenix.schema.types.PUnsignedLong;
-import org.apache.phoenix.schema.types.PUnsignedTime;
-import org.apache.phoenix.schema.types.PUnsignedTimestamp;
 import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.MetaDataUtil;
@@ -242,9 +234,11 @@ public class UpsertCompiler {
     }
     
     private final PhoenixStatement statement;
+    private final Operation operation;
     
-    public UpsertCompiler(PhoenixStatement statement) {
+    public UpsertCompiler(PhoenixStatement statement, Operation operation) {
         this.statement = statement;
+        this.operation = operation;
     }
     
     private static LiteralParseNode getNodeForRowTimestampColumn(PColumn col) {
@@ -295,10 +289,11 @@ public class UpsertCompiler {
                 resolver = FromCompiler.getResolverForMutation(upsert, connection);
                 tableRefToBe = resolver.getTables().get(0);
                 table = tableRefToBe.getTable();
-                if (table.getType() == PTableType.VIEW) {
-                    if (table.getViewType().isReadOnly()) {
-                        throw new ReadOnlyTableException(schemaName,tableName);
-                    }
+                // Cannot update:
+                // - read-only VIEW 
+                // - transactional table with a connection having an SCN 
+                if ( table.getType() == PTableType.VIEW && table.getViewType().isReadOnly() ) {
+                    throw new ReadOnlyTableException(schemaName,tableName);
                 }
                 boolean isSalted = table.getBucketNum() != null;
                 isTenantSpecific = table.isMultiTenant() && connection.getTenantId() != null;
@@ -456,7 +451,7 @@ public class UpsertCompiler {
                      *    puts for index tables.
                      * 5) no limit clause, as the limit clause requires client-side post processing
                      * 6) no sequences, as sequences imply that the order of upsert must match the order of
-                     *    selection.
+                     *    selection. TODO: change this and only force client side if there's a ORDER BY on the sequence value
                      * Otherwise, run the query to pull the data from the server
                      * and populate the MutationState (upto a limit).
                     */            
@@ -536,6 +531,7 @@ public class UpsertCompiler {
             break;
         }
         
+        final QueryPlan originalQueryPlan = queryPlanToBe;
         RowProjector projectorToBe = null;
         // Optimize only after all checks have been performed
         if (valueNodes == null) {
@@ -652,12 +648,6 @@ public class UpsertCompiler {
                     // Ignore order by - it has no impact
                     final QueryPlan aggPlan = new AggregatePlan(context, select, tableRef, aggProjector, null, OrderBy.EMPTY_ORDER_BY, null, GroupBy.EMPTY_GROUP_BY, null);
                     return new MutationPlan() {
-    
-                        @Override
-                        public PhoenixConnection getConnection() {
-                            return connection;
-                        }
-    
                         @Override
                         public ParameterMetaData getParameterMetaData() {
                             return queryPlan.getContext().getBindManager().getParameterMetaData();
@@ -669,9 +659,26 @@ public class UpsertCompiler {
                         }
 
                         @Override
+                        public TableRef getTargetRef() {
+                            return tableRef;
+                        }
+
+                        @Override
+                        public Set<TableRef> getSourceRefs() {
+                            return originalQueryPlan.getSourceRefs();
+                        }
+
+                		@Override
+                		public Operation getOperation() {
+                			return operation;
+                		}
+
+                        @Override
                         public MutationState execute() throws SQLException {
                             ImmutableBytesWritable ptr = context.getTempPtr();
-                            tableRef.getTable().getIndexMaintainers(ptr, context.getConnection());
+                            PTable table = tableRef.getTable();
+                            table.getIndexMaintainers(ptr, context.getConnection());
+
                             ServerCache cache = null;
                             try {
                                 if (ptr.getLength() > 0) {
@@ -715,12 +722,6 @@ public class UpsertCompiler {
             // UPSERT SELECT run client-side
             /////////////////////////////////////////////////////////////////////
             return new MutationPlan() {
-
-                @Override
-                public PhoenixConnection getConnection() {
-                    return connection;
-                }
-                
                 @Override
                 public ParameterMetaData getParameterMetaData() {
                     return queryPlan.getContext().getBindManager().getParameterMetaData();
@@ -732,6 +733,21 @@ public class UpsertCompiler {
                 }
 
                 @Override
+                public TableRef getTargetRef() {
+                    return tableRef;
+                }
+
+                @Override
+                public Set<TableRef> getSourceRefs() {
+                    return originalQueryPlan.getSourceRefs();
+                }
+
+        		@Override
+        		public Operation getOperation() {
+        			return operation;
+        		}
+
+                @Override
                 public MutationState execute() throws SQLException {
                     ResultIterator iterator = queryPlan.iterator();
                     if (parallelIteratorFactory == null) {
@@ -813,12 +829,6 @@ public class UpsertCompiler {
             nodeIndex++;
         }
         return new MutationPlan() {
-
-            @Override
-            public PhoenixConnection getConnection() {
-                return connection;
-            }
-
             @Override
             public ParameterMetaData getParameterMetaData() {
                 return context.getBindManager().getParameterMetaData();
@@ -830,6 +840,21 @@ public class UpsertCompiler {
             }
 
             @Override
+            public TableRef getTargetRef() {
+                return tableRef;
+            }
+
+            @Override
+            public Set<TableRef> getSourceRefs() {
+                return Collections.emptySet();
+            }
+
+    		@Override
+    		public Operation getOperation() {
+    			return operation;
+    		}
+
+            @Override
             public MutationState execute() throws SQLException {
                 ImmutableBytesWritable ptr = context.getTempPtr();
                 final SequenceManager sequenceManager = context.getSequenceManager();
@@ -1017,4 +1042,4 @@ public class UpsertCompiler {
             }
         }
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
index 1768621..e292dd8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
@@ -53,6 +53,7 @@ import org.apache.phoenix.iterate.ParallelIteratorFactory;
 import org.apache.phoenix.iterate.ParallelScanGrouper;
 import org.apache.phoenix.iterate.ResultIterator;
 import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.parse.FilterableStatement;
 import org.apache.phoenix.parse.HintNode.Hint;
 import org.apache.phoenix.parse.ParseNodeFactory;
@@ -73,6 +74,7 @@ import org.apache.phoenix.util.SQLCloseable;
 import org.apache.phoenix.util.SQLCloseables;
 import org.apache.phoenix.util.ScanUtil;
 
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 
 
@@ -89,6 +91,7 @@ public abstract class BaseQueryPlan implements QueryPlan {
     protected static final long DEFAULT_ESTIMATED_SIZE = 10 * 1024; // 10 K
     
     protected final TableRef tableRef;
+    protected final Set<TableRef> tableRefs;
     protected final StatementContext context;
     protected final FilterableStatement statement;
     protected final RowProjector projection;
@@ -112,6 +115,7 @@ public abstract class BaseQueryPlan implements QueryPlan {
         this.context = context;
         this.statement = statement;
         this.tableRef = table;
+        this.tableRefs = ImmutableSet.of(table);
         this.projection = projection;
         this.paramMetaData = paramMetaData;
         this.limit = limit;
@@ -121,6 +125,12 @@ public abstract class BaseQueryPlan implements QueryPlan {
         this.dynamicFilter = dynamicFilter;
     }
 
+
+	@Override
+	public Operation getOperation() {
+		return Operation.QUERY;
+	}
+	
     @Override
     public boolean isDegenerate() {
         return context.getScanRanges() == ScanRanges.NOTHING;
@@ -144,6 +154,11 @@ public abstract class BaseQueryPlan implements QueryPlan {
     }
 
     @Override
+    public Set<TableRef> getSourceRefs() {
+        return tableRefs;
+    }
+
+    @Override
     public Integer getLimit() {
         return limit;
     }
@@ -208,7 +223,7 @@ public abstract class BaseQueryPlan implements QueryPlan {
         if (table.getType() != PTableType.SYSTEM) {
             scan.setConsistency(connection.getConsistency());
         }
-                // Get the time range of row_timestamp column
+        // Get the time range of row_timestamp column
         TimeRange rowTimestampRange = context.getScanRanges().getRowTimestampRange();
         // Get the already existing time range on the scan.
         TimeRange scanTimeRange = scan.getTimeRange();
@@ -225,13 +240,17 @@ public abstract class BaseQueryPlan implements QueryPlan {
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
-        byte[] tenantIdBytes = connection.getTenantId() == null ?
-                  null
-                : ScanUtil.getTenantIdBytes(
-                        table.getRowKeySchema(),
-                        table.getBucketNum()!=null,
-                        connection.getTenantId(),
-                        table.isMultiTenant());
+        byte[] tenantIdBytes;
+        if( table.isMultiTenant() == true ) {
+            tenantIdBytes = connection.getTenantId() == null ? null :
+                    ScanUtil.getTenantIdBytes(
+                            table.getRowKeySchema(),
+                            table.getBucketNum()!=null,
+                            connection.getTenantId());
+        } else {
+            tenantIdBytes = connection.getTenantId() == null ? null : connection.getTenantId().getBytes();
+        }
+
         ScanUtil.setTenantId(scan, tenantIdBytes);
         String customAnnotations = LogUtil.customAnnotationsToString(connection);
         ScanUtil.setCustomAnnotations(scan, customAnnotations == null ? null : customAnnotations.getBytes());
@@ -250,13 +269,15 @@ public abstract class BaseQueryPlan implements QueryPlan {
                 KeyValueSchema schema = ProjectedColumnExpression.buildSchema(dataColumns);
                 // Set key value schema of the data columns.
                 serializeSchemaIntoScan(scan, schema);
-                String parentSchema = table.getParentSchemaName().getString();
-                String parentTable = table.getParentTableName().getString();
+                PTable parentTable = context.getCurrentTable().getTable();
+                String parentSchemaName = parentTable.getParentSchemaName().getString();
+                String parentTableName = parentTable.getParentTableName().getString();
                 final ParseNodeFactory FACTORY = new ParseNodeFactory();
+                // TODO: is it necessary to re-resolve the table?
                 TableRef dataTableRef =
                         FromCompiler.getResolver(
-                            FACTORY.namedTable(null, TableName.create(parentSchema, parentTable)),
-                            context.getConnection()).resolveTable(parentSchema, parentTable);
+                            FACTORY.namedTable(null, TableName.create(parentSchemaName, parentTableName)),
+                            context.getConnection()).resolveTable(parentSchemaName, parentTableName);
                 PTable dataTable = dataTableRef.getTable();
                 // Set index maintainer of the local index.
                 serializeIndexMaintainerIntoScan(scan, dataTable);
@@ -293,7 +314,7 @@ public abstract class BaseQueryPlan implements QueryPlan {
         return (scope.getSpan() != null) ? new TracingIterator(scope, iterator) : iterator;
     }
 
-    private void serializeIndexMaintainerIntoScan(Scan scan, PTable dataTable) {
+    private void serializeIndexMaintainerIntoScan(Scan scan, PTable dataTable) throws SQLException {
         PName name = context.getCurrentTable().getTable().getName();
         List<PTable> indexes = Lists.newArrayListWithExpectedSize(1);
         for (PTable index : dataTable.getIndexes()) {
@@ -420,7 +441,7 @@ public abstract class BaseQueryPlan implements QueryPlan {
     @Override
     public ExplainPlan getExplainPlan() throws SQLException {
         if (context.getScanRanges() == ScanRanges.NOTHING) {
-            return new ExplainPlan(Collections.singletonList("DEGENERATE SCAN OVER " + tableRef.getTable().getName().getString()));
+            return new ExplainPlan(Collections.singletonList("DEGENERATE SCAN OVER " + getTableRef().getTable().getName().getString()));
         }
         
         // Optimize here when getting explain plan, as queries don't get optimized until after compilation
@@ -439,4 +460,4 @@ public abstract class BaseQueryPlan implements QueryPlan {
         return groupBy.isEmpty() ? orderBy.getOrderByExpressions().isEmpty() : groupBy.isOrderPreserving();
     }
     
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java
index 7026433..56e0ccd 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java
@@ -20,6 +20,7 @@ package org.apache.phoenix.execute;
 import java.sql.ParameterMetaData;
 import java.sql.SQLException;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.hadoop.hbase.client.Scan;
 import org.apache.phoenix.compile.GroupByCompiler.GroupBy;
@@ -27,6 +28,7 @@ import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
 import org.apache.phoenix.compile.QueryPlan;
 import org.apache.phoenix.compile.RowProjector;
 import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.parse.FilterableStatement;
 import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.schema.TableRef;
@@ -59,6 +61,11 @@ public abstract class DelegateQueryPlan implements QueryPlan {
     }
 
     @Override
+    public Set<TableRef> getSourceRefs() {
+        return delegate.getSourceRefs();
+    }
+
+    @Override
     public RowProjector getProjector() {
         return delegate.getProjector();
     }
@@ -108,4 +115,9 @@ public abstract class DelegateQueryPlan implements QueryPlan {
         return delegate.useRoundRobinIterator();
     }
 
-}
+	@Override
+	public Operation getOperation() {
+		return delegate.getOperation();
+	}
+	
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java
index 297b6cc..41cae79 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java
@@ -27,6 +27,7 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Queue;
+import java.util.Set;
 
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.KeyValueUtil;
@@ -49,6 +50,7 @@ import org.apache.phoenix.iterate.MappedByteBufferQueue;
 import org.apache.phoenix.iterate.ParallelScanGrouper;
 import org.apache.phoenix.iterate.ResultIterator;
 import org.apache.phoenix.jdbc.PhoenixParameterMetaData;
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.parse.FilterableStatement;
 import org.apache.phoenix.parse.JoinTableNode.JoinType;
 import org.apache.phoenix.query.KeyRange;
@@ -66,6 +68,7 @@ import org.apache.phoenix.util.ResultUtil;
 import org.apache.phoenix.util.SchemaUtil;
 
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 
 public class SortMergeJoinPlan implements QueryPlan {
     private static final byte[] EMPTY_PTR = new byte[0];
@@ -83,6 +86,7 @@ public class SortMergeJoinPlan implements QueryPlan {
     private final KeyValueSchema rhsSchema;
     private final int rhsFieldPosition;
     private final boolean isSingleValueOnly;
+    private final Set<TableRef> tableRefs;
     private final int thresholdBytes;
 
     public SortMergeJoinPlan(StatementContext context, FilterableStatement statement, TableRef table, 
@@ -102,10 +106,18 @@ public class SortMergeJoinPlan implements QueryPlan {
         this.rhsSchema = buildSchema(rhsTable);
         this.rhsFieldPosition = rhsFieldPosition;
         this.isSingleValueOnly = isSingleValueOnly;
+        this.tableRefs = Sets.newHashSetWithExpectedSize(lhsPlan.getSourceRefs().size() + rhsPlan.getSourceRefs().size());
+        this.tableRefs.addAll(lhsPlan.getSourceRefs());
+        this.tableRefs.addAll(rhsPlan.getSourceRefs());
         this.thresholdBytes = context.getConnection().getQueryServices().getProps().getInt(
                 QueryServices.SPOOL_THRESHOLD_BYTES_ATTRIB, QueryServicesOptions.DEFAULT_SPOOL_THRESHOLD_BYTES);
     }
 
+    @Override
+    public Operation getOperation() {
+        return statement.getOperation();
+    }
+
     private static KeyValueSchema buildSchema(PTable table) {
         KeyValueSchemaBuilder builder = new KeyValueSchemaBuilder(0);
         if (table != null) {
@@ -645,5 +657,9 @@ public class SortMergeJoinPlan implements QueryPlan {
         return false;
     }
 
-}
+    @Override
+    public Set<TableRef> getSourceRefs() {
+        return tableRefs;
+    }
 
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/461aaa23/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java
index 53745fe..3208913 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java
@@ -22,6 +22,7 @@ import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.hadoop.hbase.client.Scan;
 import org.apache.phoenix.compile.ExplainPlan;
@@ -37,11 +38,14 @@ import org.apache.phoenix.iterate.MergeSortTopNResultIterator;
 import org.apache.phoenix.iterate.ParallelScanGrouper;
 import org.apache.phoenix.iterate.ResultIterator;
 import org.apache.phoenix.iterate.UnionResultIterators;
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.parse.FilterableStatement;
 import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.util.SQLCloseable;
 
+import com.google.common.collect.Sets;
+
 
 public class UnionPlan implements QueryPlan {
     private static final long DEFAULT_ESTIMATED_SIZE = 10 * 1024; // 10 K
@@ -197,5 +201,19 @@ public class UnionPlan implements QueryPlan {
     public boolean useRoundRobinIterator() throws SQLException {
         return false;
     }
-}
 
+	@Override
+	public Operation getOperation() {
+		return statement.getOperation();
+	}
+
+	@Override
+	public Set<TableRef> getSourceRefs() {
+		// TODO is this correct?
+		Set<TableRef> sources = Sets.newHashSetWithExpectedSize(plans.size());
+		for (QueryPlan plan : plans) {
+			sources.addAll(plan.getSourceRefs());
+		}
+		return sources;
+	}
+}


Mime
View raw message