You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ja...@apache.org on 2014/03/16 07:22:07 UTC
[1/2] PHOENIX-850 Optimize ORDER BY and GROUP BY for tenant specific
indexes (JamesTaylor)
Repository: incubator-phoenix
Updated Branches:
refs/heads/4.0 50f8fb206 -> 816e1358f
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/test/java/org/apache/phoenix/compile/TenantSpecificViewIndexCompileTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/TenantSpecificViewIndexCompileTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/TenantSpecificViewIndexCompileTest.java
new file mode 100644
index 0000000..df9bf06
--- /dev/null
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/TenantSpecificViewIndexCompileTest.java
@@ -0,0 +1,84 @@
+package org.apache.phoenix.compile;
+
+import static org.junit.Assert.assertEquals;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.util.Properties;
+
+import org.apache.phoenix.query.BaseConnectionlessQueryTest;
+import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.QueryUtil;
+import org.junit.Test;
+
+public class TenantSpecificViewIndexCompileTest extends BaseConnectionlessQueryTest {
+
+ @Test
+ public void testOrderByOptimizedOut() throws Exception {
+ Properties props = new Properties();
+ Connection conn = DriverManager.getConnection(getUrl());
+ conn.createStatement().execute("CREATE TABLE t(t_id VARCHAR NOT NULL, k1 VARCHAR, k2 VARCHAR, v1 VARCHAR," +
+ " CONSTRAINT pk PRIMARY KEY(t_id, k1, k2)) multi_tenant=true");
+
+ String tenantId = "me";
+ props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId); // connection is tenant-specific
+ conn = DriverManager.getConnection(getUrl(), props);
+ conn.createStatement().execute("CREATE VIEW v(v2 VARCHAR) AS SELECT * FROM t WHERE k1 = 'a'");
+ conn.createStatement().execute("CREATE INDEX i1 ON v(v2) INCLUDE(v1)");
+
+ ResultSet rs = conn.createStatement().executeQuery("EXPLAIN SELECT v1,v2 FROM v WHERE v2 > 'a' ORDER BY v2");
+ assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER _IDX_T ['me',-32768,'a'] - ['me',-32768,*]",
+ QueryUtil.getExplainPlan(rs));
+ }
+
+ @Test
+ public void testViewConstantsOptimizedOut() throws Exception {
+ Properties props = new Properties();
+ Connection conn = DriverManager.getConnection(getUrl());
+ conn.createStatement().execute("CREATE TABLE t(t_id VARCHAR NOT NULL, k1 VARCHAR, k2 VARCHAR, v1 VARCHAR," +
+ " CONSTRAINT pk PRIMARY KEY(t_id, k1, k2)) multi_tenant=true");
+
+ String tenantId = "me";
+ props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId); // connection is tenant-specific
+ conn = DriverManager.getConnection(getUrl(), props);
+ conn.createStatement().execute("CREATE VIEW v(v2 VARCHAR) AS SELECT * FROM t WHERE k2 = 'a'");
+ conn.createStatement().execute("CREATE INDEX i1 ON v(v2)");
+
+ ResultSet rs = conn.createStatement().executeQuery("EXPLAIN SELECT v2 FROM v WHERE v2 > 'a' and k2 = 'a' ORDER BY v2,k2");
+ assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER _IDX_T ['me',-32768,'a'] - ['me',-32768,*]",
+ QueryUtil.getExplainPlan(rs));
+
+ // Won't use index b/c v1 is not in index, but should optimize out k2 still from the order by
+ // K2 will still be referenced in the filter, as these are automatically tacked on to the where clause.
+ rs = conn.createStatement().executeQuery("EXPLAIN SELECT v1 FROM v WHERE v2 > 'a' ORDER BY k2");
+ assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER T ['me']\n" +
+ " SERVER FILTER BY (V2 > 'a' AND K2 = 'a')",
+ QueryUtil.getExplainPlan(rs));
+
+ // If we match K2 against a constant not equal to it's view constant, we should get a degenerate plan
+ rs = conn.createStatement().executeQuery("EXPLAIN SELECT v1 FROM v WHERE v2 > 'a' and k2='b' ORDER BY k2");
+ assertEquals("DEGENERATE SCAN OVER V",
+ QueryUtil.getExplainPlan(rs));
+ }
+
+ @Test
+ public void testViewConstantsOptimizedOutOnReadOnlyView() throws Exception {
+ Properties props = new Properties();
+ Connection conn = DriverManager.getConnection(getUrl());
+ conn.createStatement().execute("CREATE TABLE t(t_id VARCHAR NOT NULL, k1 VARCHAR, k2 VARCHAR, v1 VARCHAR," +
+ " CONSTRAINT pk PRIMARY KEY(t_id, k1, k2)) multi_tenant=true");
+
+ String tenantId = "me";
+ props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId); // connection is tenant-specific
+ conn = DriverManager.getConnection(getUrl(), props);
+ conn.createStatement().execute("CREATE VIEW v(v2 VARCHAR) AS SELECT * FROM t WHERE k2 = 'a'");
+ conn.createStatement().execute("CREATE VIEW v2(v3 VARCHAR) AS SELECT * FROM v WHERE k1 > 'a'");
+ conn.createStatement().execute("CREATE INDEX i2 ON v2(v3) include(v2)");
+
+ // Confirm that a read-only view on an updatable view still optimizes out the read-olnly parts of the updatable view
+ ResultSet rs = conn.createStatement().executeQuery("EXPLAIN SELECT v2 FROM v2 WHERE v3 > 'a' and k2 = 'a' ORDER BY v3,k2");
+ assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER _IDX_T ['me',-32768,'a'] - ['me',-32768,*]",
+ QueryUtil.getExplainPlan(rs));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java b/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
index 8e20a28..d63fc0e 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
@@ -39,7 +39,7 @@ public class ColumnExpressionTest {
int maxLen = 30;
int scale = 5;
PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PDataType.DECIMAL, maxLen, scale,
- true, 20, SortOrder.getDefault(), 0, null);
+ true, 20, SortOrder.getDefault(), 0, null, false);
ColumnExpression colExp = new KeyValueColumnExpression(column);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dOut = new DataOutputStream(baos);
@@ -59,7 +59,7 @@ public class ColumnExpressionTest {
public void testSerializationWithNullScale() throws Exception {
int maxLen = 30;
PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PDataType.BINARY, maxLen, null,
- true, 20, SortOrder.getDefault(), 0, null);
+ true, 20, SortOrder.getDefault(), 0, null, false);
ColumnExpression colExp = new KeyValueColumnExpression(column);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dOut = new DataOutputStream(baos);
@@ -79,7 +79,7 @@ public class ColumnExpressionTest {
public void testSerializationWithNullMaxLength() throws Exception {
int scale = 5;
PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PDataType.VARCHAR, null, scale,
- true, 20, SortOrder.getDefault(), 0, null);
+ true, 20, SortOrder.getDefault(), 0, null, false);
ColumnExpression colExp = new KeyValueColumnExpression(column);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dOut = new DataOutputStream(baos);
@@ -98,7 +98,7 @@ public class ColumnExpressionTest {
@Test
public void testSerializationWithNullScaleAndMaxLength() throws Exception {
PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PDataType.DECIMAL, null, null, true,
- 20, SortOrder.getDefault(), 0, null);
+ 20, SortOrder.getDefault(), 0, null, false);
ColumnExpression colExp = new KeyValueColumnExpression(column);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dOut = new DataOutputStream(baos);
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
index fb032ae..39c092b 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
@@ -115,6 +115,11 @@ public class AggregateResultScannerTest extends BaseConnectionlessQueryTest {
public byte[] getViewConstant() {
return null;
}
+
+ @Override
+ public boolean isViewReferenced() {
+ return false;
+ }
})), null);
aggregationManager.setAggregators(new ClientAggregators(Collections.<SingleAggregateFunction>singletonList(func), 1));
ResultIterators iterators = new ResultIterators() {
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-protocol/src/main/PTable.proto
----------------------------------------------------------------------
diff --git a/phoenix-protocol/src/main/PTable.proto b/phoenix-protocol/src/main/PTable.proto
index d5c3322..96bb52e 100644
--- a/phoenix-protocol/src/main/PTable.proto
+++ b/phoenix-protocol/src/main/PTable.proto
@@ -43,6 +43,7 @@ message PColumn {
required int32 sortOrder = 8;
optional int32 arraySize = 9;
optional bytes viewConstant = 10;
+ optional bool viewReferenced = 11;
}
message PTableStats {
[2/2] git commit: PHOENIX-850 Optimize ORDER BY and GROUP BY for
tenant specific indexes (JamesTaylor)
Posted by ja...@apache.org.
PHOENIX-850 Optimize ORDER BY and GROUP BY for tenant specific indexes (JamesTaylor)
Project: http://git-wip-us.apache.org/repos/asf/incubator-phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-phoenix/commit/816e1358
Tree: http://git-wip-us.apache.org/repos/asf/incubator-phoenix/tree/816e1358
Diff: http://git-wip-us.apache.org/repos/asf/incubator-phoenix/diff/816e1358
Branch: refs/heads/4.0
Commit: 816e1358fee2a994b34ae64598fd7408e6a2baa4
Parents: 50f8fb2
Author: James Taylor <ja...@apache.org>
Authored: Sat Mar 15 22:24:40 2014 -0700
Committer: James Taylor <ja...@apache.org>
Committed: Sat Mar 15 23:21:53 2014 -0700
----------------------------------------------------------------------
.../end2end/BaseTenantSpecificViewIndexIT.java | 10 +-
.../org/apache/phoenix/end2end/BaseViewIT.java | 8 +-
.../phoenix/compile/CreateTableCompiler.java | 35 +++--
.../phoenix/compile/ExpressionCompiler.java | 28 +++-
.../apache/phoenix/compile/FromCompiler.java | 2 +-
.../phoenix/compile/IndexStatementRewriter.java | 10 +-
.../apache/phoenix/compile/JoinCompiler.java | 6 +-
.../apache/phoenix/compile/PostDDLCompiler.java | 2 +
.../apache/phoenix/compile/QueryCompiler.java | 7 +-
.../TrackOrderPreservingExpressionCompiler.java | 8 +-
.../apache/phoenix/compile/WhereCompiler.java | 47 ++++++-
.../coprocessor/MetaDataEndpointImpl.java | 14 +-
.../phoenix/coprocessor/MetaDataProtocol.java | 7 +-
.../coprocessor/generated/PTableProtos.java | 131 ++++++++++++++---
.../apache/phoenix/index/IndexMaintainer.java | 5 +-
.../apache/phoenix/iterate/ExplainTable.java | 2 +-
.../phoenix/jdbc/PhoenixDatabaseMetaData.java | 2 +
.../apache/phoenix/optimize/QueryOptimizer.java | 3 +-
.../query/ConnectionlessQueryServicesImpl.java | 2 +-
.../apache/phoenix/query/QueryConstants.java | 2 +
.../apache/phoenix/schema/DelegateColumn.java | 5 +
.../apache/phoenix/schema/MetaDataClient.java | 60 +++++---
.../java/org/apache/phoenix/schema/PColumn.java | 2 +
.../org/apache/phoenix/schema/PColumnImpl.java | 139 ++++++++++---------
.../apache/phoenix/schema/PMetaDataImpl.java | 2 +-
.../org/apache/phoenix/schema/SaltingUtil.java | 2 +-
.../java/org/apache/phoenix/util/IndexUtil.java | 9 ++
.../TenantSpecificViewIndexCompileTest.java | 84 +++++++++++
.../expression/ColumnExpressionTest.java | 8 +-
.../iterate/AggregateResultScannerTest.java | 5 +
phoenix-protocol/src/main/PTable.proto | 1 +
31 files changed, 473 insertions(+), 175 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java
index 071c270..040aad2 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java
@@ -54,7 +54,7 @@ public class BaseTenantSpecificViewIndexIT extends BaseHBaseManagedTimeIT {
}
protected void testUpdatableViewsWithSameNameDifferentTenants(Integer saltBuckets) throws Exception {
- createBaseTable("t2", saltBuckets);
+ createBaseTable("t", saltBuckets);
Connection conn1 = createTenantConnection(TENANT1_ID);
Connection conn2 = createTenantConnection(TENANT2_ID);
try {
@@ -62,8 +62,8 @@ public class BaseTenantSpecificViewIndexIT extends BaseHBaseManagedTimeIT {
String prefixForTenant2Data = "TII";
// tenant views with same name for two different tables
- createAndPopulateTenantView(conn1, TENANT1_ID, "t2", prefixForTenant1Data);
- createAndPopulateTenantView(conn2, TENANT2_ID, "t2", prefixForTenant2Data);
+ createAndPopulateTenantView(conn1, TENANT1_ID, "t", prefixForTenant1Data);
+ createAndPopulateTenantView(conn2, TENANT2_ID, "t", prefixForTenant2Data);
createAndVerifyIndex(conn1, saltBuckets, TENANT1_ID, prefixForTenant1Data);
createAndVerifyIndex(conn2, saltBuckets, TENANT2_ID, prefixForTenant2Data);
@@ -104,8 +104,8 @@ public class BaseTenantSpecificViewIndexIT extends BaseHBaseManagedTimeIT {
conn.commit();
ResultSet rs = conn.createStatement().executeQuery("EXPLAIN SELECT k1, k2, v2 FROM v WHERE v2='" + valuePrefix + "v2-1'");
assertEquals(saltBuckets == null ?
- "CLIENT PARALLEL 1-WAY RANGE SCAN OVER I ['" + tenantId + "',-32768,'" + valuePrefix + "v2-1']" :
- "CLIENT PARALLEL 4-WAY SKIP SCAN ON 3 KEYS OVER I [0,'" + tenantId + "',-32768,'" + valuePrefix + "v2-1'] - [2,'" + tenantId + "',-32768,'" + valuePrefix + "v2-1']\n" +
+ "CLIENT PARALLEL 1-WAY RANGE SCAN OVER _IDX_T ['" + tenantId + "',-32768,'" + valuePrefix + "v2-1']" :
+ "CLIENT PARALLEL 4-WAY SKIP SCAN ON 3 KEYS OVER _IDX_T [0,'" + tenantId + "',-32768,'" + valuePrefix + "v2-1'] - [2,'" + tenantId + "',-32768,'" + valuePrefix + "v2-1']\n" +
"CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseViewIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseViewIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseViewIT.java
index 6c80ac6..03e8a43 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseViewIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseViewIT.java
@@ -110,8 +110,8 @@ public class BaseViewIT extends BaseHBaseManagedTimeIT {
assertFalse(rs.next());
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
assertEquals(saltBuckets == null
- ? "CLIENT PARALLEL 1-WAY RANGE SCAN OVER I1 [" + Short.MIN_VALUE + ",51]"
- : "CLIENT PARALLEL " + saltBuckets + "-WAY SKIP SCAN ON 3 KEYS OVER I1 [0," + Short.MIN_VALUE + ",51] - [2," + Short.MIN_VALUE + ",51]\nCLIENT MERGE SORT",
+ ? "CLIENT PARALLEL 1-WAY RANGE SCAN OVER _IDX_T [" + Short.MIN_VALUE + ",51]"
+ : "CLIENT PARALLEL " + saltBuckets + "-WAY SKIP SCAN ON 3 KEYS OVER _IDX_T [0," + Short.MIN_VALUE + ",51] - [2," + Short.MIN_VALUE + ",51]\nCLIENT MERGE SORT",
QueryUtil.getExplainPlan(rs));
conn.createStatement().execute("CREATE INDEX i2 on v(s)");
@@ -124,8 +124,8 @@ public class BaseViewIT extends BaseHBaseManagedTimeIT {
assertFalse(rs.next());
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
assertEquals(saltBuckets == null
- ? "CLIENT PARALLEL 1-WAY RANGE SCAN OVER I2 [" + (Short.MIN_VALUE+1) + ",'foo']"
- : "CLIENT PARALLEL " + saltBuckets + "-WAY SKIP SCAN ON 3 KEYS OVER I2 [0," + (Short.MIN_VALUE+1) + ",'foo'] - [2," + (Short.MIN_VALUE+1) + ",'foo']\nCLIENT MERGE SORT",
+ ? "CLIENT PARALLEL 1-WAY RANGE SCAN OVER _IDX_T [" + (Short.MIN_VALUE+1) + ",'foo']"
+ : "CLIENT PARALLEL " + saltBuckets + "-WAY SKIP SCAN ON 3 KEYS OVER _IDX_T [0," + (Short.MIN_VALUE+1) + ",'foo'] - [2," + (Short.MIN_VALUE+1) + ",'foo']\nCLIENT MERGE SORT",
QueryUtil.getExplainPlan(rs));
}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/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 51af286..693d3d6 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
@@ -19,6 +19,7 @@ package org.apache.phoenix.compile;
import java.sql.ParameterMetaData;
import java.sql.SQLException;
+import java.util.BitSet;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -47,7 +48,6 @@ import org.apache.phoenix.parse.SelectStatement;
import org.apache.phoenix.parse.TableName;
import org.apache.phoenix.parse.WildcardParseNode;
import org.apache.phoenix.query.DelegateConnectionQueryServices;
-import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.schema.ColumnRef;
import org.apache.phoenix.schema.MetaDataClient;
import org.apache.phoenix.schema.PMetaData;
@@ -83,12 +83,14 @@ public class CreateTableCompiler {
// TODO: support any statement for a VIEW instead of just a WHERE clause
ParseNode whereNode = create.getWhereClause();
String viewStatementToBe = null;
- byte[][] viewColumnConstantsToBe = MetaDataClient.EMPTY_VIEW_CONSTANTS;
+ byte[][] viewColumnConstantsToBe = null;
+ BitSet isViewColumnReferencedToBe = null;
if (type == PTableType.VIEW) {
TableRef tableRef = resolver.getTables().get(0);
- viewColumnConstantsToBe = new byte[tableRef.getTable().getColumns().size()][];
- // Used to track column references and their
- ExpressionCompiler expressionCompiler = new ColumnTrackingExpressionCompiler(context, viewColumnConstantsToBe);
+ int nColumns = tableRef.getTable().getColumns().size();
+ isViewColumnReferencedToBe = new BitSet(nColumns);
+ // Used to track column references in a view
+ ExpressionCompiler expressionCompiler = new ColumnTrackingExpressionCompiler(context, isViewColumnReferencedToBe);
parentToBe = tableRef.getTable();
viewTypeToBe = parentToBe.getViewType() == ViewType.MAPPED ? ViewType.MAPPED : ViewType.UPDATABLE;
if (whereNode == null) {
@@ -133,15 +135,22 @@ public class CreateTableCompiler {
}
},
connection, tableRef.getTimeStamp());
+ viewColumnConstantsToBe = new byte[nColumns][];
ViewWhereExpressionVisitor visitor = new ViewWhereExpressionVisitor(parentToBe, viewColumnConstantsToBe);
where.accept(visitor);
+ // If view is not updatable, viewColumnConstants should be empty. We will still
+ // inherit our parent viewConstants, but we have no additional ones.
viewTypeToBe = visitor.isUpdatable() ? ViewType.UPDATABLE : ViewType.READ_ONLY;
+ if (viewTypeToBe != ViewType.UPDATABLE) {
+ viewColumnConstantsToBe = null;
+ }
}
}
}
final ViewType viewType = viewTypeToBe;
final String viewStatement = viewStatementToBe;
final byte[][] viewColumnConstants = viewColumnConstantsToBe;
+ final BitSet isViewColumnReferenced = isViewColumnReferencedToBe;
List<ParseNode> splitNodes = create.getSplitNodes();
final byte[][] splits = new byte[splitNodes.size()][];
ImmutableBytesWritable ptr = context.getTempPtr();
@@ -171,7 +180,7 @@ public class CreateTableCompiler {
@Override
public MutationState execute() throws SQLException {
try {
- return client.createTable(create, splits, parent, viewStatement, viewType, viewColumnConstants);
+ return client.createTable(create, splits, parent, viewStatement, viewType, viewColumnConstants, isViewColumnReferenced);
} finally {
if (client.getConnection() != connection) {
client.getConnection().close();
@@ -197,21 +206,17 @@ public class CreateTableCompiler {
}
private static class ColumnTrackingExpressionCompiler extends ExpressionCompiler {
- private final byte[][] columnValues;
+ private final BitSet isColumnReferenced;
- public ColumnTrackingExpressionCompiler(StatementContext context, byte[][] columnValues) {
- super(context);
- this.columnValues = columnValues;
+ public ColumnTrackingExpressionCompiler(StatementContext context, BitSet isColumnReferenced) {
+ super(context, true);
+ this.isColumnReferenced = isColumnReferenced;
}
@Override
protected ColumnRef resolveColumn(ColumnParseNode node) throws SQLException {
ColumnRef ref = super.resolveColumn(node);
- // Set columnValue at position to any non null value.
- // We always strip the last byte so that we can recognize null
- // as a value with a single byte.
- // Will be overridden during ViewWhereExpressionVisitor
- columnValues[ref.getColumn().getPosition()] = QueryConstants.SEPARATOR_BYTE_ARRAY;
+ isColumnReferenced.set(ref.getColumn().getPosition());
return ref;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
index 5506eb5..4a05c0f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
@@ -90,6 +90,7 @@ import org.apache.phoenix.schema.ColumnNotFoundException;
import org.apache.phoenix.schema.ColumnRef;
import org.apache.phoenix.schema.DelegateDatum;
import org.apache.phoenix.schema.PArrayDataType;
+import org.apache.phoenix.schema.PColumn;
import org.apache.phoenix.schema.PDataType;
import org.apache.phoenix.schema.PDatum;
import org.apache.phoenix.schema.PTable;
@@ -98,6 +99,7 @@ import org.apache.phoenix.schema.RowKeyValueAccessor;
import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.schema.TableRef;
import org.apache.phoenix.schema.TypeMismatchException;
+import org.apache.phoenix.util.IndexUtil;
import org.apache.phoenix.util.SchemaUtil;
@@ -107,14 +109,24 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
protected final StatementContext context;
protected final GroupBy groupBy;
private int nodeCount;
+ private final boolean resolveViewConstants;
ExpressionCompiler(StatementContext context) {
- this(context,GroupBy.EMPTY_GROUP_BY);
+ this(context,GroupBy.EMPTY_GROUP_BY, false);
+ }
+
+ ExpressionCompiler(StatementContext context, boolean resolveViewConstants) {
+ this(context,GroupBy.EMPTY_GROUP_BY, resolveViewConstants);
}
ExpressionCompiler(StatementContext context, GroupBy groupBy) {
+ this(context, groupBy, false);
+ }
+
+ ExpressionCompiler(StatementContext context, GroupBy groupBy, boolean resolveViewConstants) {
this.context = context;
this.groupBy = groupBy;
+ this.resolveViewConstants = resolveViewConstants;
}
public boolean isAggregate() {
@@ -328,9 +340,17 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
public Expression visit(ColumnParseNode node) throws SQLException {
ColumnRef ref = resolveColumn(node);
TableRef tableRef = ref.getTableRef();
- if (tableRef.equals(context.getCurrentTable())
- && !SchemaUtil.isPKColumn(ref.getColumn())) { // project only kv columns
- context.getScan().addColumn(ref.getColumn().getFamilyName().getBytes(), ref.getColumn().getName().getBytes());
+ ImmutableBytesWritable ptr = context.getTempPtr();
+ PColumn column = ref.getColumn();
+ // If we have an UPDATABLE view, then we compile those view constants (i.e. columns in equality constraints
+ // in the view) to constants. This allows the optimize to optimize out reference to them in various scenarios.
+ // If the column is matched in a WHERE clause against a constant not equal to it's constant, then the entire
+ // query would become degenerate.
+ if (!resolveViewConstants && IndexUtil.getViewConstantValue(column, ptr)) {
+ return LiteralExpression.newConstant(column.getDataType().toObject(ptr), column.getDataType());
+ }
+ if (tableRef.equals(context.getCurrentTable()) && !SchemaUtil.isPKColumn(column)) { // project only kv columns
+ context.getScan().addColumn(column.getFamilyName().getBytes(), column.getName().getBytes());
}
Expression expression = ref.newColumnExpression();
Expression wrappedExpression = wrapGroupByExpression(expression);
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
index a987798..f43ff4f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
@@ -327,7 +327,7 @@ public class FromCompiler {
familyName = PNameFactory.newName(family);
}
allcolumns.add(new PColumnImpl(name, familyName, dynColumn.getDataType(), dynColumn.getMaxLength(),
- dynColumn.getScale(), dynColumn.isNull(), position, dynColumn.getSortOrder(), dynColumn.getArraySize(), null));
+ dynColumn.getScale(), dynColumn.isNull(), position, dynColumn.getSortOrder(), dynColumn.getArraySize(), null, false));
position++;
}
theTable = PTableImpl.makePTable(theTable, allcolumns);
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/compile/IndexStatementRewriter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/IndexStatementRewriter.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/IndexStatementRewriter.java
index 8d4b7db..7a5ebe1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/IndexStatementRewriter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/IndexStatementRewriter.java
@@ -35,8 +35,6 @@ import org.apache.phoenix.parse.WildcardParseNode;
import org.apache.phoenix.schema.ColumnRef;
import org.apache.phoenix.schema.PColumn;
import org.apache.phoenix.schema.PDataType;
-import org.apache.phoenix.schema.PTable;
-import org.apache.phoenix.schema.PTable.ViewType;
import org.apache.phoenix.schema.TableRef;
import org.apache.phoenix.util.IndexUtil;
@@ -81,10 +79,10 @@ public class IndexStatementRewriter extends ParseNodeRewriter {
ColumnRef dataColRef = getResolver().resolveColumn(node.getSchemaName(), node.getTableName(), node.getName());
PColumn dataCol = dataColRef.getColumn();
TableRef dataTableRef = dataColRef.getTableRef();
- PTable dataTable = dataTableRef.getTable();
- // Rewrite view constants in updatable views as literals, as they won't be in the schema for
- // an index on the view.
- if (dataTable.getViewType() == ViewType.UPDATABLE && dataCol.getViewConstant() != null) {
+ // Rewrite view constants as literals, as they won't be in the schema for
+ // an index on the view. Our view may be READ_ONLY yet still have inherited
+ // view constants if based on an UPDATABLE view
+ if (dataCol.getViewConstant() != null) {
byte[] viewConstant = dataCol.getViewConstant();
// Ignore last byte, as it's only there so we can have a way to differentiate null
// from the absence of a value.
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
index bc57ac7..fd5174b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
@@ -47,6 +47,7 @@ import org.apache.phoenix.parse.BetweenParseNode;
import org.apache.phoenix.parse.BindTableNode;
import org.apache.phoenix.parse.CaseParseNode;
import org.apache.phoenix.parse.CastParseNode;
+import org.apache.phoenix.parse.ColumnDef;
import org.apache.phoenix.parse.ColumnParseNode;
import org.apache.phoenix.parse.ComparisonParseNode;
import org.apache.phoenix.parse.ConcreteTableNode;
@@ -59,7 +60,6 @@ import org.apache.phoenix.parse.InListParseNode;
import org.apache.phoenix.parse.IsNullParseNode;
import org.apache.phoenix.parse.JoinTableNode;
import org.apache.phoenix.parse.JoinTableNode.JoinType;
-import org.apache.phoenix.parse.ColumnDef;
import org.apache.phoenix.parse.LikeParseNode;
import org.apache.phoenix.parse.NamedTableNode;
import org.apache.phoenix.parse.NotParseNode;
@@ -403,7 +403,7 @@ public class JoinCompiler {
PName name = PNameFactory.newName(aliasedName);
PColumnImpl column = new PColumnImpl(name, familyName, sourceColumn.getDataType(),
sourceColumn.getMaxLength(), sourceColumn.getScale(), sourceColumn.isNullable(),
- position, sourceColumn.getSortOrder(), sourceColumn.getArraySize(), sourceColumn.getViewConstant());
+ position, sourceColumn.getSortOrder(), sourceColumn.getArraySize(), sourceColumn.getViewConstant(), sourceColumn.isViewReferenced());
Expression sourceExpression = new ColumnRef(sourceTable, sourceColumn.getPosition()).newColumnExpression();
projectedColumns.add(column);
sourceExpressions.add(sourceExpression);
@@ -1163,7 +1163,7 @@ public class JoinCompiler {
PColumnImpl column = new PColumnImpl(c.getName(),
PNameFactory.newName(ScanProjector.VALUE_COLUMN_FAMILY), c.getDataType(),
c.getMaxLength(), c.getScale(), innerJoin ? c.isNullable() : true, position++,
- c.getSortOrder(), c.getArraySize(), c.getViewConstant());
+ c.getSortOrder(), c.getArraySize(), c.getViewConstant(), c.isViewReferenced());
merged.add(column);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/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 ab9b889..ccf805f 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
@@ -191,6 +191,8 @@ public class PostDDLCompiler {
// as this just means the view is invalid. Continue on and try to perform
// any other Post DDL operations.
try {
+ // Since dropping a VIEW does not affect the underlying data, we do
+ // not need to pass through the view statement here.
WhereCompiler.compile(context, select); // Push where clause into scan
} catch (ColumnFamilyNotFoundException e) {
continue;
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
index 111d532..a354ed1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
@@ -243,10 +243,9 @@ public class QueryCompiler {
ColumnResolver resolver = context.getResolver();
TableRef tableRef = context.getCurrentTable();
PTable table = tableRef.getTable();
+ ParseNode viewWhere = null;
if (table.getViewStatement() != null) {
- ParseNode viewNode = new SQLParser(table.getViewStatement()).parseQuery().getWhere();
- // Push VIEW expression into select
- select = select.combine(viewNode);
+ viewWhere = new SQLParser(table.getViewStatement()).parseQuery().getWhere();
}
Integer limit = LimitCompiler.compile(context, select);
@@ -258,7 +257,7 @@ public class QueryCompiler {
// Don't pass groupBy when building where clause expression, because we do not want to wrap these
// expressions as group by key expressions since they're pre, not post filtered.
context.setResolver(FromCompiler.getResolverForQuery(select, connection));
- WhereCompiler.compile(context, select);
+ WhereCompiler.compile(context, select, viewWhere);
context.setResolver(resolver); // recover resolver
OrderBy orderBy = OrderByCompiler.compile(context, select, groupBy, limit);
RowProjector projector = ProjectionCompiler.compile(context, select, groupBy, targetColumns);
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/compile/TrackOrderPreservingExpressionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TrackOrderPreservingExpressionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TrackOrderPreservingExpressionCompiler.java
index 0572cd0..ebf117d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/TrackOrderPreservingExpressionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/TrackOrderPreservingExpressionCompiler.java
@@ -34,6 +34,7 @@ import org.apache.phoenix.parse.DivideParseNode;
import org.apache.phoenix.parse.MultiplyParseNode;
import org.apache.phoenix.parse.SubtractParseNode;
import org.apache.phoenix.schema.ColumnRef;
+import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.util.SchemaUtil;
@@ -62,7 +63,12 @@ public class TrackOrderPreservingExpressionCompiler extends ExpressionCompiler {
TrackOrderPreservingExpressionCompiler(StatementContext context, GroupBy groupBy, int expectedEntrySize, Ordering ordering) {
super(context, groupBy);
- positionOffset = context.getResolver().getTables().get(0).getTable().getBucketNum() == null ? 0 : 1;
+ PTable table = context.getResolver().getTables().get(0).getTable();
+ boolean isSalted = table.getBucketNum() != null;
+ boolean isMultiTenant = context.getConnection().getTenantId() != null && table.isMultiTenant();
+ boolean isSharedViewIndex = table.getViewIndexId() != null;
+ // TODO: util for this offset, as it's computed in numerous places
+ positionOffset = (isSalted ? 1 : 0) + (isMultiTenant ? 1 : 0) + (isSharedViewIndex ? 1 : 0);
entries = Lists.newArrayListWithExpectedSize(expectedEntrySize);
this.ordering = ordering;
}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
index 126f402..98e4517 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
@@ -26,15 +26,35 @@ import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.exception.SQLExceptionInfo;
-import org.apache.phoenix.expression.*;
+import org.apache.phoenix.expression.AndExpression;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.KeyValueColumnExpression;
+import org.apache.phoenix.expression.LiteralExpression;
import org.apache.phoenix.expression.visitor.KeyValueExpressionVisitor;
-import org.apache.phoenix.filter.*;
-import org.apache.phoenix.parse.*;
+import org.apache.phoenix.filter.MultiCFCQKeyValueComparisonFilter;
+import org.apache.phoenix.filter.MultiCQKeyValueComparisonFilter;
+import org.apache.phoenix.filter.RowKeyComparisonFilter;
+import org.apache.phoenix.filter.SingleCFCQKeyValueComparisonFilter;
+import org.apache.phoenix.filter.SingleCQKeyValueComparisonFilter;
+import org.apache.phoenix.parse.ColumnParseNode;
+import org.apache.phoenix.parse.FilterableStatement;
import org.apache.phoenix.parse.HintNode.Hint;
-import org.apache.phoenix.schema.*;
-import org.apache.phoenix.util.*;
+import org.apache.phoenix.parse.ParseNode;
+import org.apache.phoenix.parse.ParseNodeFactory;
+import org.apache.phoenix.schema.AmbiguousColumnException;
+import org.apache.phoenix.schema.ColumnNotFoundException;
+import org.apache.phoenix.schema.ColumnRef;
+import org.apache.phoenix.schema.PDataType;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTableType;
+import org.apache.phoenix.schema.TableRef;
+import org.apache.phoenix.schema.TypeMismatchException;
+import org.apache.phoenix.util.ByteUtil;
+import org.apache.phoenix.util.ScanUtil;
+import org.apache.phoenix.util.SchemaUtil;
import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
@@ -51,6 +71,10 @@ public class WhereCompiler {
private WhereCompiler() {
}
+ public static Expression compile(StatementContext context, FilterableStatement statement) throws SQLException {
+ return compile(context, statement, null);
+ }
+
/**
* Pushes where clause filter expressions into scan by building and setting a filter.
* @param context the shared context during query compilation
@@ -61,7 +85,7 @@ public class WhereCompiler {
* @throws ColumnNotFoundException if column name could not be resolved
* @throws AmbiguousColumnException if an unaliased column name is ambiguous across multiple tables
*/
- public static Expression compile(StatementContext context, FilterableStatement statement) throws SQLException {
+ public static Expression compile(StatementContext context, FilterableStatement statement, ParseNode viewWhere) throws SQLException {
Set<Expression> extractedNodes = Sets.<Expression>newHashSet();
WhereExpressionCompiler whereCompiler = new WhereExpressionCompiler(context);
ParseNode where = statement.getWhere();
@@ -72,6 +96,11 @@ public class WhereCompiler {
if (expression.getDataType() != PDataType.BOOLEAN) {
throw TypeMismatchException.newException(PDataType.BOOLEAN, expression.getDataType(), expression.toString());
}
+ if (viewWhere != null) {
+ WhereExpressionCompiler viewWhereCompiler = new WhereExpressionCompiler(context, true);
+ Expression viewExpression = viewWhere.accept(viewWhereCompiler);
+ expression = AndExpression.create(Lists.newArrayList(expression, viewExpression));
+ }
expression = WhereOptimizer.pushKeyExpressionsToScan(context, statement, expression, extractedNodes);
setScanFilter(context, statement, expression, whereCompiler.disambiguateWithFamily);
@@ -83,7 +112,11 @@ public class WhereCompiler {
private boolean disambiguateWithFamily;
WhereExpressionCompiler(StatementContext context) {
- super(context);
+ super(context, true);
+ }
+
+ WhereExpressionCompiler(StatementContext context, boolean resolveViewConstants) {
+ super(context, resolveViewConstants);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index 62ced4b..09df3fb 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -31,6 +31,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DISABLE_WAL_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.FAMILY_NAME_INDEX;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IMMUTABLE_ROWS_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_STATE_BYTES;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_VIEW_REFERENCED_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.LINK_TYPE_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.MULTI_TENANT_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.NULLABLE_BYTES;
@@ -211,6 +212,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
private static final KeyValue SORT_ORDER_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, SORT_ORDER_BYTES);
private static final KeyValue ARRAY_SIZE_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, ARRAY_SIZE_BYTES);
private static final KeyValue VIEW_CONSTANT_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, VIEW_CONSTANT_BYTES);
+ private static final KeyValue IS_VIEW_REFERENCED_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, IS_VIEW_REFERENCED_BYTES);
private static final List<KeyValue> COLUMN_KV_COLUMNS = Arrays.<KeyValue>asList(
DECIMAL_DIGITS_KV,
COLUMN_SIZE_KV,
@@ -220,7 +222,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
SORT_ORDER_KV,
DATA_TABLE_NAME_KV, // included in both column and table row for metadata APIs
ARRAY_SIZE_KV,
- VIEW_CONSTANT_KV
+ VIEW_CONSTANT_KV,
+ IS_VIEW_REFERENCED_KV
);
static {
Collections.sort(COLUMN_KV_COLUMNS, KeyValue.COMPARATOR);
@@ -233,6 +236,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
private static final int SORT_ORDER_INDEX = COLUMN_KV_COLUMNS.indexOf(SORT_ORDER_KV);
private static final int ARRAY_SIZE_INDEX = COLUMN_KV_COLUMNS.indexOf(ARRAY_SIZE_KV);
private static final int VIEW_CONSTANT_INDEX = COLUMN_KV_COLUMNS.indexOf(VIEW_CONSTANT_KV);
+ private static final int IS_VIEW_REFERENCED_INDEX = COLUMN_KV_COLUMNS.indexOf(IS_VIEW_REFERENCED_KV);
private static final int LINK_TYPE_INDEX = 0;
@@ -501,8 +505,9 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
Cell viewConstantKv = colKeyValues[VIEW_CONSTANT_INDEX];
byte[] viewConstant = viewConstantKv == null ? null : viewConstantKv.getValue();
- PColumn column = new PColumnImpl(colName, famName, dataType, maxLength, scale, isNullable,
- position - 1, sortOrder, arraySize, viewConstant);
+ Cell isViewReferencedKv = colKeyValues[IS_VIEW_REFERENCED_INDEX];
+ boolean isViewReferenced = isViewReferencedKv != null && Boolean.TRUE.equals(PDataType.BOOLEAN.toObject(isViewReferencedKv.getValueArray(), isViewReferencedKv.getValueOffset(), isViewReferencedKv.getValueLength()));
+ PColumn column = new PColumnImpl(colName, famName, dataType, maxLength, scale, isNullable, position-1, sortOrder, arraySize, viewConstant, isViewReferenced);
columns.add(column);
}
@@ -1219,7 +1224,6 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
} else {
continue;
}
-
return new MetaDataMutationResult(
MutationCode.COLUMN_ALREADY_EXISTS, EnvironmentEdgeManager
.currentTimeMillis(), table);
@@ -1299,7 +1303,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
} else {
continue;
}
- if (columnToDelete.getViewConstant() != null) { // Disallow deletion of column referenced in WHERE clause of view
+ if (columnToDelete.isViewReferenced()) { // Disallow deletion of column referenced in WHERE clause of view
return new MetaDataMutationResult(MutationCode.UNALLOWED_TABLE_MUTATION, EnvironmentEdgeManager.currentTimeMillis(), table, columnToDelete);
}
// Look for columnToDelete in any indexes. If found as PK
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
index de6cf5b..4acf299 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
@@ -97,13 +97,18 @@ public abstract class MetaDataProtocol extends MetaDataService {
this.columnName = column.getName().getBytes();
this.familyName = column.getFamilyName().getBytes();
}
-
}
public MetaDataMutationResult(MutationCode returnCode, long currentTime, PTable table) {
this(returnCode, currentTime, table, Collections.<byte[]> emptyList());
}
+ // For testing, so that connectionless can set wasUpdated so ColumnResolver doesn't complain
+ public MetaDataMutationResult(MutationCode returnCode, long currentTime, PTable table, boolean wasUpdated) {
+ this(returnCode, currentTime, table, Collections.<byte[]> emptyList());
+ this.wasUpdated = wasUpdated;
+ }
+
public MetaDataMutationResult(MutationCode returnCode, long currentTime, PTable table, List<byte[]> tableNamesToDelete) {
this.returnCode = returnCode;
this.mutationTime = currentTime;
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
index ff946f3..ea4d135 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
@@ -224,6 +224,16 @@ public final class PTableProtos {
* <code>optional bytes viewConstant = 10;</code>
*/
com.google.protobuf.ByteString getViewConstant();
+
+ // optional bool viewReferenced = 11;
+ /**
+ * <code>optional bool viewReferenced = 11;</code>
+ */
+ boolean hasViewReferenced();
+ /**
+ * <code>optional bool viewReferenced = 11;</code>
+ */
+ boolean getViewReferenced();
}
/**
* Protobuf type {@code PColumn}
@@ -326,6 +336,11 @@ public final class PTableProtos {
viewConstant_ = input.readBytes();
break;
}
+ case 88: {
+ bitField0_ |= 0x00000400;
+ viewReferenced_ = input.readBool();
+ break;
+ }
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -553,6 +568,22 @@ public final class PTableProtos {
return viewConstant_;
}
+ // optional bool viewReferenced = 11;
+ public static final int VIEWREFERENCED_FIELD_NUMBER = 11;
+ private boolean viewReferenced_;
+ /**
+ * <code>optional bool viewReferenced = 11;</code>
+ */
+ public boolean hasViewReferenced() {
+ return ((bitField0_ & 0x00000400) == 0x00000400);
+ }
+ /**
+ * <code>optional bool viewReferenced = 11;</code>
+ */
+ public boolean getViewReferenced() {
+ return viewReferenced_;
+ }
+
private void initFields() {
columnNameBytes_ = com.google.protobuf.ByteString.EMPTY;
familyNameBytes_ = com.google.protobuf.ByteString.EMPTY;
@@ -564,6 +595,7 @@ public final class PTableProtos {
sortOrder_ = 0;
arraySize_ = 0;
viewConstant_ = com.google.protobuf.ByteString.EMPTY;
+ viewReferenced_ = false;
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
@@ -627,6 +659,9 @@ public final class PTableProtos {
if (((bitField0_ & 0x00000200) == 0x00000200)) {
output.writeBytes(10, viewConstant_);
}
+ if (((bitField0_ & 0x00000400) == 0x00000400)) {
+ output.writeBool(11, viewReferenced_);
+ }
getUnknownFields().writeTo(output);
}
@@ -676,6 +711,10 @@ public final class PTableProtos {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(10, viewConstant_);
}
+ if (((bitField0_ & 0x00000400) == 0x00000400)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBoolSize(11, viewReferenced_);
+ }
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
@@ -749,6 +788,11 @@ public final class PTableProtos {
result = result && getViewConstant()
.equals(other.getViewConstant());
}
+ result = result && (hasViewReferenced() == other.hasViewReferenced());
+ if (hasViewReferenced()) {
+ result = result && (getViewReferenced()
+ == other.getViewReferenced());
+ }
result = result &&
getUnknownFields().equals(other.getUnknownFields());
return result;
@@ -802,6 +846,10 @@ public final class PTableProtos {
hash = (37 * hash) + VIEWCONSTANT_FIELD_NUMBER;
hash = (53 * hash) + getViewConstant().hashCode();
}
+ if (hasViewReferenced()) {
+ hash = (37 * hash) + VIEWREFERENCED_FIELD_NUMBER;
+ hash = (53 * hash) + hashBoolean(getViewReferenced());
+ }
hash = (29 * hash) + getUnknownFields().hashCode();
memoizedHashCode = hash;
return hash;
@@ -931,6 +979,8 @@ public final class PTableProtos {
bitField0_ = (bitField0_ & ~0x00000100);
viewConstant_ = com.google.protobuf.ByteString.EMPTY;
bitField0_ = (bitField0_ & ~0x00000200);
+ viewReferenced_ = false;
+ bitField0_ = (bitField0_ & ~0x00000400);
return this;
}
@@ -999,6 +1049,10 @@ public final class PTableProtos {
to_bitField0_ |= 0x00000200;
}
result.viewConstant_ = viewConstant_;
+ if (((from_bitField0_ & 0x00000400) == 0x00000400)) {
+ to_bitField0_ |= 0x00000400;
+ }
+ result.viewReferenced_ = viewReferenced_;
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
@@ -1047,6 +1101,9 @@ public final class PTableProtos {
if (other.hasViewConstant()) {
setViewConstant(other.getViewConstant());
}
+ if (other.hasViewReferenced()) {
+ setViewReferenced(other.getViewReferenced());
+ }
this.mergeUnknownFields(other.getUnknownFields());
return this;
}
@@ -1474,6 +1531,39 @@ public final class PTableProtos {
return this;
}
+ // optional bool viewReferenced = 11;
+ private boolean viewReferenced_ ;
+ /**
+ * <code>optional bool viewReferenced = 11;</code>
+ */
+ public boolean hasViewReferenced() {
+ return ((bitField0_ & 0x00000400) == 0x00000400);
+ }
+ /**
+ * <code>optional bool viewReferenced = 11;</code>
+ */
+ public boolean getViewReferenced() {
+ return viewReferenced_;
+ }
+ /**
+ * <code>optional bool viewReferenced = 11;</code>
+ */
+ public Builder setViewReferenced(boolean value) {
+ bitField0_ |= 0x00000400;
+ viewReferenced_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bool viewReferenced = 11;</code>
+ */
+ public Builder clearViewReferenced() {
+ bitField0_ = (bitField0_ & ~0x00000400);
+ viewReferenced_ = false;
+ onChanged();
+ return this;
+ }
+
// @@protoc_insertion_point(builder_scope:PColumn)
}
@@ -5532,29 +5622,30 @@ public final class PTableProtos {
descriptor;
static {
java.lang.String[] descriptorData = {
- "\n\014PTable.proto\"\317\001\n\007PColumn\022\027\n\017columnName" +
+ "\n\014PTable.proto\"\347\001\n\007PColumn\022\027\n\017columnName" +
"Bytes\030\001 \002(\014\022\027\n\017familyNameBytes\030\002 \001(\014\022\020\n\010" +
"dataType\030\003 \002(\t\022\021\n\tmaxLength\030\004 \001(\005\022\r\n\005sca" +
"le\030\005 \001(\005\022\020\n\010nullable\030\006 \002(\010\022\020\n\010position\030\007" +
" \002(\005\022\021\n\tsortOrder\030\010 \002(\005\022\021\n\tarraySize\030\t \001" +
- "(\005\022\024\n\014viewConstant\030\n \001(\014\"*\n\013PTableStats\022" +
- "\013\n\003key\030\001 \002(\t\022\016\n\006values\030\002 \003(\014\"\367\003\n\006PTable\022" +
- "\027\n\017schemaNameBytes\030\001 \002(\014\022\026\n\016tableNameByt" +
- "es\030\002 \002(\014\022\036\n\ttableType\030\003 \002(\0162\013.PTableType" +
- "\022\022\n\nindexState\030\004 \001(\t\022\026\n\016sequenceNumber\030\005",
- " \002(\003\022\021\n\ttimeStamp\030\006 \002(\003\022\023\n\013pkNameBytes\030\007" +
- " \001(\014\022\021\n\tbucketNum\030\010 \002(\005\022\031\n\007columns\030\t \003(\013" +
- "2\010.PColumn\022\030\n\007indexes\030\n \003(\0132\007.PTable\022\027\n\017" +
- "isImmutableRows\030\013 \002(\010\022 \n\nguidePosts\030\014 \003(" +
- "\0132\014.PTableStats\022\032\n\022dataTableNameBytes\030\r " +
- "\001(\014\022\031\n\021defaultFamilyName\030\016 \001(\014\022\022\n\ndisabl" +
- "eWAL\030\017 \002(\010\022\023\n\013multiTenant\030\020 \002(\010\022\020\n\010viewT" +
- "ype\030\021 \001(\014\022\025\n\rviewStatement\030\022 \001(\014\022\025\n\rphys" +
- "icalNames\030\023 \003(\014\022\020\n\010tenantId\030\024 \001(\014\022\023\n\013vie" +
- "wIndexId\030\025 \001(\005*A\n\nPTableType\022\n\n\006SYSTEM\020\000",
- "\022\010\n\004USER\020\001\022\010\n\004VIEW\020\002\022\t\n\005INDEX\020\003\022\010\n\004JOIN\020" +
- "\004B@\n(org.apache.phoenix.coprocessor.gene" +
- "ratedB\014PTableProtosH\001\210\001\001\240\001\001"
+ "(\005\022\024\n\014viewConstant\030\n \001(\014\022\026\n\016viewReferenc" +
+ "ed\030\013 \001(\010\"*\n\013PTableStats\022\013\n\003key\030\001 \002(\t\022\016\n\006" +
+ "values\030\002 \003(\014\"\367\003\n\006PTable\022\027\n\017schemaNameByt" +
+ "es\030\001 \002(\014\022\026\n\016tableNameBytes\030\002 \002(\014\022\036\n\ttabl" +
+ "eType\030\003 \002(\0162\013.PTableType\022\022\n\nindexState\030\004",
+ " \001(\t\022\026\n\016sequenceNumber\030\005 \002(\003\022\021\n\ttimeStam" +
+ "p\030\006 \002(\003\022\023\n\013pkNameBytes\030\007 \001(\014\022\021\n\tbucketNu" +
+ "m\030\010 \002(\005\022\031\n\007columns\030\t \003(\0132\010.PColumn\022\030\n\007in" +
+ "dexes\030\n \003(\0132\007.PTable\022\027\n\017isImmutableRows\030" +
+ "\013 \002(\010\022 \n\nguidePosts\030\014 \003(\0132\014.PTableStats\022" +
+ "\032\n\022dataTableNameBytes\030\r \001(\014\022\031\n\021defaultFa" +
+ "milyName\030\016 \001(\014\022\022\n\ndisableWAL\030\017 \002(\010\022\023\n\013mu" +
+ "ltiTenant\030\020 \002(\010\022\020\n\010viewType\030\021 \001(\014\022\025\n\rvie" +
+ "wStatement\030\022 \001(\014\022\025\n\rphysicalNames\030\023 \003(\014\022" +
+ "\020\n\010tenantId\030\024 \001(\014\022\023\n\013viewIndexId\030\025 \001(\005*A",
+ "\n\nPTableType\022\n\n\006SYSTEM\020\000\022\010\n\004USER\020\001\022\010\n\004VI" +
+ "EW\020\002\022\t\n\005INDEX\020\003\022\010\n\004JOIN\020\004B@\n(org.apache." +
+ "phoenix.coprocessor.generatedB\014PTablePro" +
+ "tosH\001\210\001\001\240\001\001"
};
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -5566,7 +5657,7 @@ public final class PTableProtos {
internal_static_PColumn_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_PColumn_descriptor,
- new java.lang.String[] { "ColumnNameBytes", "FamilyNameBytes", "DataType", "MaxLength", "Scale", "Nullable", "Position", "SortOrder", "ArraySize", "ViewConstant", });
+ new java.lang.String[] { "ColumnNameBytes", "FamilyNameBytes", "DataType", "MaxLength", "Scale", "Nullable", "Position", "SortOrder", "ArraySize", "ViewConstant", "ViewReferenced", });
internal_static_PTableStats_descriptor =
getDescriptor().getMessageTypes().get(1);
internal_static_PTableStats_fieldAccessorTable = new
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java b/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
index b569a3c..c1d6c25 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
@@ -51,7 +51,6 @@ import org.apache.phoenix.schema.PColumnFamily;
import org.apache.phoenix.schema.PDataType;
import org.apache.phoenix.schema.PIndexState;
import org.apache.phoenix.schema.PTable;
-import org.apache.phoenix.schema.PTable.ViewType;
import org.apache.phoenix.schema.PTableType;
import org.apache.phoenix.schema.RowKeySchema;
import org.apache.phoenix.schema.SaltingUtil;
@@ -245,10 +244,10 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
int dataPosOffset = (isDataTableSalted ? 1 : 0) + (this.isMultiTenant ? 1 : 0);
int nDataPKColumns = dataRowKeySchema.getFieldCount() - dataPosOffset;
- // For indexes on updatable views, we need to remember which data columns are "constants"
+ // For indexes on views, we need to remember which data columns are "constants"
// These are the values in a VIEW where clause. For these, we don't put them in the
// index, as they're the same for every row in the index.
- if (dataTable.getViewType() == ViewType.UPDATABLE) {
+ if (dataTable.getType() == PTableType.VIEW) {
List<PColumn>dataPKColumns = dataTable.getPKColumns();
for (int i = dataPosOffset; i < dataPKColumns.size(); i++) {
PColumn dataPKColumn = dataPKColumns.get(i);
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
index a0376b6..af13df4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
@@ -94,7 +94,7 @@ public abstract class ExplainTable {
} else {
hasSkipScanFilter = explainSkipScan(buf);
}
- buf.append("OVER " + tableRef.getTable().getName().getString());
+ buf.append("OVER " + tableRef.getTable().getPhysicalName().getString());
if (!scanRanges.isPointLookup()) {
appendKeyRanges(buf);
}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
index fce65e7..7b2f6da 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
@@ -180,6 +180,8 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData, org.apache.pho
public static final byte[] ARRAY_SIZE_BYTES = Bytes.toBytes(ARRAY_SIZE);
public static final String VIEW_CONSTANT = "VIEW_CONSTANT";
public static final byte[] VIEW_CONSTANT_BYTES = Bytes.toBytes(VIEW_CONSTANT);
+ public static final String IS_VIEW_REFERENCED = "IS_VIEW_REFERENCED";
+ public static final byte[] IS_VIEW_REFERENCED_BYTES = Bytes.toBytes(IS_VIEW_REFERENCED);
public static final String VIEW_INDEX_ID = "VIEW_INDEX_ID";
public static final byte[] VIEW_INDEX_ID_BYTES = Bytes.toBytes(VIEW_INDEX_ID);
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java b/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
index ff87278..220ef89 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
@@ -43,7 +43,6 @@ import org.apache.phoenix.schema.PColumn;
import org.apache.phoenix.schema.PDatum;
import org.apache.phoenix.schema.PIndexState;
import org.apache.phoenix.schema.PTable;
-import org.apache.phoenix.schema.PTable.ViewType;
import org.apache.phoenix.schema.PTableType;
import com.google.common.collect.Lists;
@@ -266,7 +265,7 @@ public class QueryOptimizer {
int nViewConstants = 0;
PTable dataTable = dataPlan.getTableRef().getTable();
- if (dataTable.getViewType() == ViewType.UPDATABLE) {
+ if (dataTable.getType() == PTableType.VIEW) {
for (PColumn column : dataTable.getColumns()) {
if (column.getViewConstant() != null) {
nViewConstants++;
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
index 8b95ff1..7a190e1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
@@ -177,7 +177,7 @@ public class ConnectionlessQueryServicesImpl extends DelegateQueryServices imple
try {
String fullTableName = SchemaUtil.getTableName(schemaBytes, tableBytes);
PTable table = metaData.getTable(new PTableKey(tenantId, fullTableName));
- return new MetaDataMutationResult(MutationCode.TABLE_ALREADY_EXISTS, 0, table);
+ return new MetaDataMutationResult(MutationCode.TABLE_ALREADY_EXISTS, 0, table, true);
} catch (TableNotFoundException e) {
return new MetaDataMutationResult(MutationCode.TABLE_NOT_FOUND, 0, null);
}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
index 6224fb0..06bccce 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
@@ -70,6 +70,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TYPE_NAME;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TYPE_SEQUENCE;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_CONSTANT;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_INDEX_ID;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_VIEW_REFERENCED;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_STATEMENT;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_TYPE;
@@ -184,6 +185,7 @@ public interface QueryConstants {
SORT_ORDER + " INTEGER," +
ARRAY_SIZE + " INTEGER,\n" +
VIEW_CONSTANT + " VARBINARY,\n" +
+ IS_VIEW_REFERENCED + " BOOLEAN,\n" +
KEY_SEQ + " SMALLINT,\n" +
// Link metadata (only set on rows linking table to index or view)
LINK_TYPE + " UNSIGNED_TINYINT,\n" +
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
index 2356b2a..a4901cf 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
@@ -64,4 +64,9 @@ public class DelegateColumn extends DelegateDatum implements PColumn {
public int getEstimatedSize() {
return SizedUtil.OBJECT_SIZE + getDelegate().getEstimatedSize();
}
+
+ @Override
+ public boolean isViewReferenced() {
+ return getDelegate().isViewReferenced();
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index 32c979a..cb891eb 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -33,6 +33,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAM
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DISABLE_WAL;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IMMUTABLE_ROWS;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_STATE;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_VIEW_REFERENCED;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.KEY_SEQ;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.LINK_TYPE;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.MULTI_TENANT;
@@ -62,6 +63,7 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Types;
+import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -129,7 +131,6 @@ import com.google.common.primitives.Ints;
public class MetaDataClient {
private static final Logger logger = LoggerFactory.getLogger(MetaDataClient.class);
- public static final byte[][] EMPTY_VIEW_CONSTANTS = new byte[0][];
private static final ParseNodeFactory FACTORY = new ParseNodeFactory();
private static final String CREATE_TABLE =
@@ -220,9 +221,10 @@ public class MetaDataClient {
DATA_TABLE_NAME + "," + // write this both in the column and table rows for access by metadata APIs
ARRAY_SIZE + "," +
VIEW_CONSTANT + "," +
+ IS_VIEW_REFERENCED + "," +
PK_NAME + "," + // write this both in the column and table rows for access by metadata APIs
KEY_SEQ +
- ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+ ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static final String UPDATE_COLUMN_POSITION =
"UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\" ( " +
TENANT_ID + "," +
@@ -356,11 +358,12 @@ public class MetaDataClient {
colUpsert.setInt(13, column.getArraySize());
}
colUpsert.setBytes(14, column.getViewConstant());
- colUpsert.setString(15, pkName);
+ colUpsert.setBoolean(15, column.isViewReferenced());
+ colUpsert.setString(16, pkName);
if (keySeq == null) {
- colUpsert.setNull(16, Types.SMALLINT);
+ colUpsert.setNull(17, Types.SMALLINT);
} else {
- colUpsert.setShort(16, keySeq);
+ colUpsert.setShort(17, keySeq);
}
colUpsert.execute();
}
@@ -399,15 +402,15 @@ public class MetaDataClient {
}
PColumn column = new PColumnImpl(PNameFactory.newName(columnName), familyName, def.getDataType(),
- def.getMaxLength(), def.getScale(), def.isNull(), position, sortOrder, def.getArraySize(), null);
+ def.getMaxLength(), def.getScale(), def.isNull(), position, sortOrder, def.getArraySize(), null, false);
return column;
} catch (IllegalArgumentException e) { // Based on precondition check in constructor
throw new SQLException(e);
}
}
- public MutationState createTable(CreateTableStatement statement, byte[][] splits, PTable parent, String viewStatement, ViewType viewType, byte[][] viewColumnConstants) throws SQLException {
- PTable table = createTableInternal(statement, splits, parent, viewStatement, viewType, viewColumnConstants, null);
+ public MutationState createTable(CreateTableStatement statement, byte[][] splits, PTable parent, String viewStatement, ViewType viewType, byte[][] viewColumnConstants, BitSet isViewColumnReferenced) throws SQLException {
+ PTable table = createTableInternal(statement, splits, parent, viewStatement, viewType, viewColumnConstants, isViewColumnReferenced, null);
if (table == null || table.getType() == PTableType.VIEW) {
return new MutationState(0,connection);
}
@@ -564,14 +567,13 @@ public class MetaDataClient {
allPkColumns.add(new Pair<ColumnName, SortOrder>(colName, SortOrder.getDefault()));
columnDefs.add(FACTORY.columnDef(colName, dataType.getSqlTypeName(), false, null, null, false, SortOrder.getDefault()));
}
- boolean isUpdatableView = dataTable.getViewType() == ViewType.UPDATABLE;
// First columns are the indexed ones
for (Pair<ColumnName, SortOrder> pair : indexedPkColumns) {
ColumnName colName = pair.getFirst();
PColumn col = resolver.resolveColumn(null, colName.getFamilyName(), colName.getColumnName()).getColumn();
unusedPkColumns.remove(col);
// Ignore view constants for updatable views as we don't need these in the index
- if (!isUpdatableView || col.getViewConstant() == null) {
+ if (col.getViewConstant() == null) {
PDataType dataType = IndexUtil.getIndexColumnDataType(col);
colName = ColumnName.caseSensitiveColumnName(IndexUtil.getIndexColumnName(col));
allPkColumns.add(new Pair<ColumnName, SortOrder>(colName, pair.getSecond()));
@@ -584,7 +586,7 @@ public class MetaDataClient {
for (PColumn col : unusedPkColumns) {
// Don't add columns with constant values from updatable views, as
// we don't need these in the index
- if (!isUpdatableView || col.getViewConstant() == null) {
+ if (col.getViewConstant() == null) {
ColumnName colName = ColumnName.caseSensitiveColumnName(IndexUtil.getIndexColumnName(col));
allPkColumns.add(new Pair<ColumnName, SortOrder>(colName, col.getSortOrder()));
PDataType dataType = IndexUtil.getIndexColumnDataType(col);
@@ -607,7 +609,7 @@ public class MetaDataClient {
if (pk.contains(colName)) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.COLUMN_EXIST_IN_DEF).build().buildException();
}
- if (!SchemaUtil.isPKColumn(col) && (!isUpdatableView || col.getViewConstant() == null)) {
+ if (!SchemaUtil.isPKColumn(col) && col.getViewConstant() == null) {
// Need to re-create ColumnName, since the above one won't have the column family name
colName = ColumnName.caseSensitiveColumnName(col.getFamilyName().getString(), IndexUtil.getIndexColumnName(col));
columnDefs.add(FACTORY.columnDef(colName, col.getDataType().getSqlTypeName(), col.isNullable(), col.getMaxLength(), col.getScale(), false, col.getSortOrder()));
@@ -646,7 +648,7 @@ public class MetaDataClient {
statement.getProps().put("", new Pair<String,Object>(DEFAULT_COLUMN_FAMILY_NAME,dataTable.getDefaultFamilyName().getString()));
}
CreateTableStatement tableStatement = FACTORY.createTable(indexTableName, statement.getProps(), columnDefs, pk, statement.getSplitNodes(), PTableType.INDEX, statement.ifNotExists(), null, null, statement.getBindCount());
- table = createTableInternal(tableStatement, splits, dataTable, null, null, EMPTY_VIEW_CONSTANTS, viewIndexId);
+ table = createTableInternal(tableStatement, splits, dataTable, null, null, null, null, viewIndexId);
break;
} catch (ConcurrentTableMutationException e) { // Can happen if parent data table changes while above is in progress
if (retry) {
@@ -714,7 +716,7 @@ public class MetaDataClient {
return null;
}
- private PTable createTableInternal(CreateTableStatement statement, byte[][] splits, final PTable parent, String viewStatement, ViewType viewType, byte[][] viewColumnConstants, Short viewIndexId) throws SQLException {
+ private PTable createTableInternal(CreateTableStatement statement, byte[][] splits, final PTable parent, String viewStatement, ViewType viewType, final byte[][] viewColumnConstants, final BitSet isViewColumnReferenced, Short viewIndexId) throws SQLException {
final PTableType tableType = statement.getTableType();
boolean wasAutoCommit = connection.getAutoCommit();
connection.rollback();
@@ -1065,16 +1067,28 @@ public class MetaDataClient {
short nextKeySeq = 0;
for (int i = 0; i < columns.size(); i++) {
PColumn column = columns.get(i);
- int columnPosition = column.getPosition();
- final byte[] viewConstant = columnPosition < viewColumnConstants.length ? viewColumnConstants[columnPosition] : null;
+ final int columnPosition = column.getPosition();
// For client-side cache, we need to update the column
- if (viewConstant != null) {
- columns.set(i, column = new DelegateColumn(column) {
- @Override
- public byte[] getViewConstant() {
- return viewConstant;
- }
- });
+ if (isViewColumnReferenced != null) {
+ if (viewColumnConstants != null && columnPosition < viewColumnConstants.length) {
+ columns.set(i, column = new DelegateColumn(column) {
+ @Override
+ public byte[] getViewConstant() {
+ return viewColumnConstants[columnPosition];
+ }
+ @Override
+ public boolean isViewReferenced() {
+ return isViewColumnReferenced.get(columnPosition);
+ }
+ });
+ } else {
+ columns.set(i, column = new DelegateColumn(column) {
+ @Override
+ public boolean isViewReferenced() {
+ return isViewColumnReferenced.get(columnPosition);
+ }
+ });
+ }
}
Short keySeq = SchemaUtil.isPKColumn(column) ? ++nextKeySeq : null;
addColumnMutation(schemaName, tableName, column, colUpsert, parentTableName, pkName, keySeq);
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
index 9270d55..54eeaf0 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
@@ -47,5 +47,7 @@ public interface PColumn extends PDatum {
byte[] getViewConstant();
+ boolean isViewReferenced();
+
int getEstimatedSize();
}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
index 5999be6..c2e2ed2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
@@ -35,6 +35,7 @@ public class PColumnImpl implements PColumn {
private SortOrder sortOrder;
private Integer arraySize;
private byte[] viewConstant;
+ private boolean isViewReferenced;
public PColumnImpl() {
}
@@ -46,13 +47,13 @@ public class PColumnImpl implements PColumn {
Integer scale,
boolean nullable,
int position,
- SortOrder sortOrder, Integer arrSize, byte[] viewConstant) {
- init(name, familyName, dataType, maxLength, scale, nullable, position, sortOrder, arrSize, viewConstant);
+ SortOrder sortOrder, Integer arrSize, byte[] viewConstant, boolean isViewReferenced) {
+ init(name, familyName, dataType, maxLength, scale, nullable, position, sortOrder, arrSize, viewConstant, isViewReferenced);
}
public PColumnImpl(PColumn column, int position) {
this(column.getName(), column.getFamilyName(), column.getDataType(), column.getMaxLength(),
- column.getScale(), column.isNullable(), position, column.getSortOrder(), column.getArraySize(), column.getViewConstant());
+ column.getScale(), column.isNullable(), position, column.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced());
}
private void init(PName name,
@@ -64,7 +65,7 @@ public class PColumnImpl implements PColumn {
int position,
SortOrder sortOrder,
Integer arrSize,
- byte[] viewConstant) {
+ byte[] viewConstant, boolean isViewReferenced) {
Preconditions.checkNotNull(sortOrder);
this.dataType = dataType;
if (familyName == null) {
@@ -85,6 +86,7 @@ public class PColumnImpl implements PColumn {
this.sortOrder = sortOrder;
this.arraySize = arrSize;
this.viewConstant = viewConstant;
+ this.isViewReferenced = isViewReferenced;
}
@Override
@@ -173,63 +175,74 @@ public class PColumnImpl implements PColumn {
return viewConstant;
}
- /**
- * Create a PColumn instance from PBed PColumn instance
- * @param column
- */
- public static PColumn createFromProto(PTableProtos.PColumn column) {
- byte[] columnNameBytes = column.getColumnNameBytes().toByteArray();
- PName columnName = PNameFactory.newName(columnNameBytes);
- PName familyName = null;
- if (column.hasFamilyNameBytes()) {
- familyName = PNameFactory.newName(column.getFamilyNameBytes().toByteArray());
- }
- PDataType dataType = PDataType.fromSqlTypeName(column.getDataType());
- Integer maxLength = null;
- if (column.hasMaxLength()) {
- maxLength = column.getMaxLength();
- }
- Integer scale = null;
- if (column.hasScale()) {
- scale = column.getScale();
- }
- boolean nullable = column.getNullable();
- int position = column.getPosition();
- SortOrder sortOrder = SortOrder.fromSystemValue(column.getSortOrder());
- Integer arraySize = null;
- if(column.hasArraySize()){
- arraySize = column.getArraySize();
- }
- byte[] viewConstant = null;
- if (column.hasViewConstant()) {
- viewConstant = column.getViewConstant().toByteArray();
- }
- return new PColumnImpl(columnName, familyName, dataType, maxLength, scale, nullable, position,
- sortOrder, arraySize, viewConstant);
- }
-
- public static PTableProtos.PColumn toProto(PColumn column) {
- PTableProtos.PColumn.Builder builder = PTableProtos.PColumn.newBuilder();
- builder.setColumnNameBytes(HBaseZeroCopyByteString.wrap(column.getName().getBytes()));
- if (column.getFamilyName() != null) {
- builder.setFamilyNameBytes(HBaseZeroCopyByteString.wrap(column.getFamilyName().getBytes()));
- }
- builder.setDataType(column.getDataType().getSqlTypeName());
- if (column.getMaxLength() != null) {
- builder.setMaxLength(column.getMaxLength());
- }
- if (column.getScale() != null) {
- builder.setScale(column.getScale());
- }
- builder.setNullable(column.isNullable());
- builder.setPosition(column.getPosition());
- builder.setSortOrder(column.getSortOrder().getSystemValue());
- if(column.getArraySize() != null){
- builder.setArraySize(column.getArraySize());
- }
- if(column.getViewConstant() != null){
- builder.setViewConstant(HBaseZeroCopyByteString.wrap(column.getViewConstant()));
- }
- return builder.build();
- }
+ @Override
+ public boolean isViewReferenced() {
+ return isViewReferenced;
+ }
+
+ /**
+ * Create a PColumn instance from PBed PColumn instance
+ *
+ * @param column
+ */
+ public static PColumn createFromProto(PTableProtos.PColumn column) {
+ byte[] columnNameBytes = column.getColumnNameBytes().toByteArray();
+ PName columnName = PNameFactory.newName(columnNameBytes);
+ PName familyName = null;
+ if (column.hasFamilyNameBytes()) {
+ familyName = PNameFactory.newName(column.getFamilyNameBytes().toByteArray());
+ }
+ PDataType dataType = PDataType.fromSqlTypeName(column.getDataType());
+ Integer maxLength = null;
+ if (column.hasMaxLength()) {
+ maxLength = column.getMaxLength();
+ }
+ Integer scale = null;
+ if (column.hasScale()) {
+ scale = column.getScale();
+ }
+ boolean nullable = column.getNullable();
+ int position = column.getPosition();
+ SortOrder sortOrder = SortOrder.fromSystemValue(column.getSortOrder());
+ Integer arraySize = null;
+ if (column.hasArraySize()) {
+ arraySize = column.getArraySize();
+ }
+ byte[] viewConstant = null;
+ if (column.hasViewConstant()) {
+ viewConstant = column.getViewConstant().toByteArray();
+ }
+ boolean isViewReferenced = false;
+ if (column.hasViewReferenced()) {
+ isViewReferenced = column.getViewReferenced();
+ }
+
+ return new PColumnImpl(columnName, familyName, dataType, maxLength, scale, nullable, position, sortOrder,
+ arraySize, viewConstant, isViewReferenced);
+ }
+
+ public static PTableProtos.PColumn toProto(PColumn column) {
+ PTableProtos.PColumn.Builder builder = PTableProtos.PColumn.newBuilder();
+ builder.setColumnNameBytes(HBaseZeroCopyByteString.wrap(column.getName().getBytes()));
+ if (column.getFamilyName() != null) {
+ builder.setFamilyNameBytes(HBaseZeroCopyByteString.wrap(column.getFamilyName().getBytes()));
+ }
+ builder.setDataType(column.getDataType().getSqlTypeName());
+ if (column.getMaxLength() != null) {
+ builder.setMaxLength(column.getMaxLength());
+ }
+ if (column.getScale() != null) {
+ builder.setScale(column.getScale());
+ }
+ builder.setNullable(column.isNullable());
+ builder.setPosition(column.getPosition());
+ builder.setSortOrder(column.getSortOrder().getSystemValue());
+ if (column.getArraySize() != null) {
+ builder.setArraySize(column.getArraySize());
+ }
+ if (column.getViewConstant() != null) {
+ builder.setViewConstant(HBaseZeroCopyByteString.wrap(column.getViewConstant()));
+ }
+ return builder.build();
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
index ef48bbd..a1f7431 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
@@ -220,7 +220,7 @@ public class PMetaDataImpl implements PMetaData {
// Update position of columns that follow removed column
for (int i = position+1; i < oldColumns.size(); i++) {
PColumn oldColumn = oldColumns.get(i);
- PColumn newColumn = new PColumnImpl(oldColumn.getName(), oldColumn.getFamilyName(), oldColumn.getDataType(), oldColumn.getMaxLength(), oldColumn.getScale(), oldColumn.isNullable(), i-1+positionOffset, oldColumn.getSortOrder(), oldColumn.getArraySize(), oldColumn.getViewConstant());
+ PColumn newColumn = new PColumnImpl(oldColumn.getName(), oldColumn.getFamilyName(), oldColumn.getDataType(), oldColumn.getMaxLength(), oldColumn.getScale(), oldColumn.isNullable(), i-1+positionOffset, oldColumn.getSortOrder(), oldColumn.getArraySize(), oldColumn.getViewConstant(), oldColumn.isViewReferenced());
columns.add(newColumn);
}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
index 4cf9ff1..8ae43e3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
@@ -36,7 +36,7 @@ public class SaltingUtil {
public static final String SALTING_COLUMN_NAME = "_SALT";
public static final String SALTED_ROW_KEY_NAME = "_SALTED_KEY";
public static final PColumnImpl SALTING_COLUMN = new PColumnImpl(
- PNameFactory.newName(SALTING_COLUMN_NAME), null, PDataType.BINARY, 1, 0, false, 0, SortOrder.getDefault(), 0, null);
+ PNameFactory.newName(SALTING_COLUMN_NAME), null, PDataType.BINARY, 1, 0, false, 0, SortOrder.getDefault(), 0, null, false);
public static final RowKeySchema VAR_BINARY_SALTED_SCHEMA = new RowKeySchemaBuilder(1)
.addField(SALTING_COLUMN, false, SortOrder.getDefault())
.addField(SchemaUtil.VAR_BINARY_DATUM, false, SortOrder.getDefault()).build();
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/816e1358/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
index 41fb6e5..2057752 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
@@ -200,4 +200,13 @@ public class IndexUtil {
public static boolean isDataPKColumn(PColumn column) {
return column.getName().getString().startsWith(INDEX_COLUMN_NAME_SEP);
}
+
+ public static boolean getViewConstantValue(PColumn column, ImmutableBytesWritable ptr) {
+ byte[] value = column.getViewConstant();
+ if (value != null) {
+ ptr.set(value, 0, value.length-1);
+ return true;
+ }
+ return false;
+ }
}