You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by td...@apache.org on 2018/10/05 00:33:52 UTC
[1/2] phoenix git commit: PHOENIX-4855 Continue to write base table
column metadata when creating a view in order to support rollback
Repository: phoenix
Updated Branches:
refs/heads/4.x-HBase-1.2 4ced25530 -> f3467445d
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3467445/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 a267629..361edf2 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
@@ -90,7 +90,8 @@ public class PColumnImpl implements PColumn {
}
}
- // a derived column has null type
+ // a excluded column (a column that was derived from a parent but that has been deleted) is
+ // denoted by a column that has a null type
public static PColumnImpl createExcludedColumn(PName familyName, PName columnName, Long timestamp) {
return new PColumnImpl(familyName, columnName, timestamp);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3467445/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
index 1623175..8cbf757 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
@@ -549,6 +549,12 @@ public interface PTable extends PMetaDataEntity {
* @return a list of all columns
*/
List<PColumn> getColumns();
+
+ /**
+ * Get all excluded columns
+ * @return a list of excluded columns
+ */
+ List<PColumn> getExcludedColumns();
/**
* @return A list of the column families of this table
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3467445/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index 8d57945..9f06e04 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@ -115,6 +115,8 @@ public class PTableImpl implements PTable {
// Have MultiMap for String->PColumn (may need family qualifier)
private List<PColumn> pkColumns;
private List<PColumn> allColumns;
+ // columns that were inherited from a parent table but that were dropped in the view
+ private List<PColumn> excludedColumns;
private List<PColumnFamily> families;
private Map<byte[], PColumnFamily> familyByBytes;
private Map<String, PColumnFamily> familyByString;
@@ -217,8 +219,8 @@ public class PTableImpl implements PTable {
// For indexes stored in shared physical tables
public PTableImpl(PName tenantId, PName schemaName, PName tableName, long timestamp, List<PColumnFamily> families,
- List<PColumn> columns, List<PName> physicalNames,PDataType viewIndexType, Long viewIndexId, boolean multiTenant, boolean isNamespaceMpped, ImmutableStorageScheme storageScheme, QualifierEncodingScheme qualifierEncodingScheme,
- EncodedCQCounter encodedCQCounter, Boolean useStatsForParallelization) throws SQLException {
+ List<PColumn> columns, List<PName> physicalNames, PDataType viewIndexType, Long viewIndexId, boolean multiTenant, boolean isNamespaceMpped, ImmutableStorageScheme storageScheme, QualifierEncodingScheme qualifierEncodingScheme,
+ EncodedCQCounter encodedCQCounter, Boolean useStatsForParallelization, Integer bucketNum) throws SQLException {
this.pkColumns = this.allColumns = Collections.emptyList();
this.rowKeySchema = RowKeySchema.EMPTY_SCHEMA;
this.indexes = Collections.emptyList();
@@ -229,10 +231,14 @@ public class PTableImpl implements PTable {
familyByString.put(family.getName().getString(), family);
}
this.families = families;
+ if (bucketNum!=null) {
+ columns = columns.subList(1, columns.size());
+ }
init(tenantId, this.schemaName, this.tableName, PTableType.INDEX, state, timeStamp, sequenceNumber, pkName, bucketNum, columns,
this.schemaName, parentTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
null, disableWAL, multiTenant, storeNulls, viewType, viewIndexType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
- transactionProvider, updateCacheFrequency, indexDisableTimestamp, isNamespaceMpped, null, false, storageScheme, qualifierEncodingScheme, encodedCQCounter, useStatsForParallelization);
+ transactionProvider, updateCacheFrequency, indexDisableTimestamp, isNamespaceMpped, null,
+ false, storageScheme, qualifierEncodingScheme, encodedCQCounter, useStatsForParallelization, null);
}
public PTableImpl(long timeStamp) { // For delete marker
@@ -288,7 +294,7 @@ public class PTableImpl implements PTable {
/**
* Used to create a PTable for views or view indexes, the basePTable is for attributes we inherit from the physical table
*/
- public static PTableImpl makePTable(PTable view, PTable baseTable, Collection<PColumn> columns, long timestamp, int baseTableColumnCount) throws SQLException {
+ public static PTableImpl makePTable(PTable view, PTable baseTable, Collection<PColumn> columns, long timestamp, int baseTableColumnCount, Collection<PColumn> excludedColumns) throws SQLException {
// if a TableProperty is not valid on a view we set it to the base table value
// if a TableProperty is valid on a view and is not mutable on a view we set it to the base table value
// if a TableProperty is valid on a view and is mutable on a view we use the value set on the view
@@ -300,7 +306,7 @@ public class PTableImpl implements PTable {
view.getViewIndexType(), view.getViewIndexId(), view.getIndexType(),
baseTableColumnCount, view.rowKeyOrderOptimizable(), baseTable.getTransactionProvider(), view.getUpdateCacheFrequency(),
view.getIndexDisableTimestamp(), view.isNamespaceMapped(), baseTable.getAutoPartitionSeqName(), baseTable.isAppendOnlySchema(),
- baseTable.getImmutableStorageScheme(), baseTable.getEncodingScheme(), view.getEncodedCQCounter(), view.useStatsForParallelization());
+ baseTable.getImmutableStorageScheme(), baseTable.getEncodingScheme(), view.getEncodedCQCounter(), view.useStatsForParallelization(), excludedColumns);
}
public static PTableImpl makePTable(PTable table, PTableType type, Collection<PColumn> columns) throws SQLException {
@@ -356,7 +362,7 @@ public class PTableImpl implements PTable {
indexType, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, rowKeyOrderOptimizable, transactionProvider,
updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, autoPartitionSeqName,
isAppendOnlySchema, storageScheme, qualifierEncodingScheme, encodedCQCounter,
- useStatsForParallelization);
+ useStatsForParallelization, null);
}
public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type,
@@ -374,7 +380,7 @@ public class PTableImpl implements PTable {
defaultFamilyName, viewExpression, disableWAL, multiTenant, storeNulls, viewType,viewIndexType, viewIndexId,
indexType, baseColumnCount, rowKeyOrderOptimizable, transactionProvider, updateCacheFrequency,
indexDisableTimestamp, isNamespaceMapped, autoPartitionSeqName, isAppendOnlySchema, storageScheme,
- qualifierEncodingScheme, encodedCQCounter, useStatsForParallelization);
+ qualifierEncodingScheme, encodedCQCounter, useStatsForParallelization, null);
}
private PTableImpl(PTable table, boolean rowKeyOrderOptimizable, PIndexState state, long timeStamp,
@@ -388,7 +394,7 @@ public class PTableImpl implements PTable {
table.getIndexType(), baseTableColumnCount, rowKeyOrderOptimizable, table.getTransactionProvider(),
updateCacheFrequency, table.getIndexDisableTimestamp(), table.isNamespaceMapped(),
table.getAutoPartitionSeqName(), table.isAppendOnlySchema(), table.getImmutableStorageScheme(),
- table.getEncodingScheme(), table.getEncodedCQCounter(), table.useStatsForParallelization());
+ table.getEncodingScheme(), table.getEncodedCQCounter(), table.useStatsForParallelization(), null);
}
private PTableImpl(PName tenantId, PName schemaName, PName tableName, PTableType type, PIndexState state,
@@ -398,12 +404,14 @@ public class PTableImpl implements PTable {
boolean storeNulls, ViewType viewType, PDataType viewIndexType, Long viewIndexId, IndexType indexType,
int baseColumnCount, boolean rowKeyOrderOptimizable, TransactionFactory.Provider transactionProvider, long updateCacheFrequency,
long indexDisableTimestamp, boolean isNamespaceMapped, String autoPartitionSeqName, boolean isAppendOnlySchema, ImmutableStorageScheme storageScheme,
- QualifierEncodingScheme qualifierEncodingScheme, EncodedCQCounter encodedCQCounter, Boolean useStatsForParallelization) throws SQLException {
+ QualifierEncodingScheme qualifierEncodingScheme, EncodedCQCounter encodedCQCounter,
+ Boolean useStatsForParallelization, Collection<PColumn> excludedColumns)
+ throws SQLException {
init(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName, bucketNum, columns,
parentSchemaName, parentTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
transactionProvider, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, autoPartitionSeqName, isAppendOnlySchema, storageScheme,
- qualifierEncodingScheme, encodedCQCounter, useStatsForParallelization);
+ qualifierEncodingScheme, encodedCQCounter, useStatsForParallelization, excludedColumns);
}
@Override
@@ -438,7 +446,7 @@ public class PTableImpl implements PTable {
boolean multiTenant, boolean storeNulls, ViewType viewType,PDataType viewIndexType, Long viewIndexId,
IndexType indexType , int baseColumnCount, boolean rowKeyOrderOptimizable, TransactionFactory.Provider transactionProvider, long updateCacheFrequency, long indexDisableTimestamp,
boolean isNamespaceMapped, String autoPartitionSeqName, boolean isAppendOnlySchema, ImmutableStorageScheme storageScheme, QualifierEncodingScheme qualifierEncodingScheme,
- EncodedCQCounter encodedCQCounter, Boolean useStatsForParallelization) throws SQLException {
+ EncodedCQCounter encodedCQCounter, Boolean useStatsForParallelization, Collection<PColumn> excludedColumns) throws SQLException {
Preconditions.checkNotNull(schemaName);
Preconditions.checkArgument(tenantId==null || tenantId.getBytes().length > 0); // tenantId should be null or not empty
int estimatedSize = SizedUtil.OBJECT_SIZE * 2 + 23 * SizedUtil.POINTER_SIZE + 4 * SizedUtil.INT_SIZE + 2 * SizedUtil.LONG_SIZE + 2 * SizedUtil.INT_OBJECT_SIZE +
@@ -627,6 +635,7 @@ public class PTableImpl implements PTable {
this.baseColumnCount = baseColumnCount;
this.encodedCQCounter = encodedCQCounter;
this.useStatsForParallelization = useStatsForParallelization;
+ this.excludedColumns = excludedColumns == null ? ImmutableList.<PColumn>of() : ImmutableList.copyOf(excludedColumns);
}
@Override
@@ -1079,6 +1088,11 @@ public class PTableImpl implements PTable {
public List<PColumn> getColumns() {
return allColumns;
}
+
+ @Override
+ public List<PColumn> getExcludedColumns() {
+ return excludedColumns;
+ }
@Override
public long getSequenceNumber() {
@@ -1367,7 +1381,7 @@ public class PTableImpl implements PTable {
isImmutableRows, physicalNames, defaultFamilyName, viewStatement, disableWAL,
multiTenant, storeNulls, viewType, viewIndexType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
transactionProvider, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, autoParititonSeqName,
- isAppendOnlySchema, storageScheme, qualifierEncodingScheme, encodedColumnQualifierCounter, useStatsForParallelization);
+ isAppendOnlySchema, storageScheme, qualifierEncodingScheme, encodedColumnQualifierCounter, useStatsForParallelization, null);
return result;
} catch (SQLException e) {
throw new RuntimeException(e); // Impossible
[2/2] phoenix git commit: PHOENIX-4855 Continue to write base table
column metadata when creating a view in order to support rollback
Posted by td...@apache.org.
PHOENIX-4855 Continue to write base table column metadata when creating a view in order to support rollback
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/f3467445
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/f3467445
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/f3467445
Branch: refs/heads/4.x-HBase-1.2
Commit: f3467445d3783efaaf3c24aea464d5cd14e69137
Parents: 4ced255
Author: Thomas D'Silva <td...@apache.org>
Authored: Mon Aug 20 10:42:56 2018 -0700
Committer: Thomas D'Silva <td...@apache.org>
Committed: Thu Oct 4 17:33:36 2018 -0700
----------------------------------------------------------------------
.../AlterMultiTenantTableWithViewsIT.java | 25 ++-
.../phoenix/end2end/AlterTableWithViewsIT.java | 196 ++++++++++-------
.../java/org/apache/phoenix/end2end/ViewIT.java | 14 +-
.../coprocessor/MetaDataEndpointImpl.java | 208 +++++++++++--------
.../phoenix/jdbc/PhoenixDatabaseMetaData.java | 158 +++++++++++---
.../apache/phoenix/schema/DelegateTable.java | 5 +
.../apache/phoenix/schema/MetaDataClient.java | 38 ++--
.../org/apache/phoenix/schema/PColumnImpl.java | 3 +-
.../java/org/apache/phoenix/schema/PTable.java | 6 +
.../org/apache/phoenix/schema/PTableImpl.java | 38 ++--
10 files changed, 461 insertions(+), 230 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3467445/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterMultiTenantTableWithViewsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterMultiTenantTableWithViewsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterMultiTenantTableWithViewsIT.java
index 669b6f6..d5e1af2 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterMultiTenantTableWithViewsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterMultiTenantTableWithViewsIT.java
@@ -498,20 +498,24 @@ public class AlterMultiTenantTableWithViewsIT extends SplitSystemCatalogIT {
String tenant = TENANT1;
try (Connection conn = DriverManager.getConnection(getUrl());
Connection tenant1Conn = getTenantConnection(tenant)) {
- String baseTableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR, V3 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
+ String baseTableDDL =
+ "CREATE TABLE " + baseTable
+ + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, "
+ + "V2 VARCHAR, V3 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1))"
+ + " MULTI_TENANT = true, SALT_BUCKETS = 4";
conn.createStatement().execute(baseTableDDL);
String view1DDL = "CREATE VIEW " + view1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 CHAR(256)) AS SELECT * FROM " + baseTable;
tenant1Conn.createStatement().execute(view1DDL);
- assertTableDefinition(conn, baseTable, PTableType.TABLE, null, 1, 5, BASE_TABLE_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V2", "V3");
- assertTableDefinition(tenant1Conn, view1, PTableType.VIEW, baseTable, 0, 7, 5, "PK1", "V1", "V2", "V3", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(conn, baseTable, PTableType.TABLE, null, 1, 6, BASE_TABLE_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V2", "V3");
+ assertTableDefinition(tenant1Conn, view1, PTableType.VIEW, baseTable, 0, 8, 6, "PK1", "V1", "V2", "V3", "VIEW_COL1", "VIEW_COL2");
String alterBaseTable = "ALTER TABLE " + baseTable + " ADD KV VARCHAR, PK2 VARCHAR PRIMARY KEY";
conn.createStatement().execute(alterBaseTable);
assertTableDefinition(conn, baseTable, PTableType.TABLE, null, 2, 7, BASE_TABLE_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V2", "V3", "KV", "PK2");
- assertTableDefinition(tenant1Conn, view1, PTableType.VIEW, baseTable, 0, 7, 5, "PK1", "V1", "V2", "V3", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(tenant1Conn, view1, PTableType.VIEW, baseTable, 0, 8, 6, "PK1", "V1", "V2", "V3", "KV", "PK2", "VIEW_COL1", "VIEW_COL2");
// verify that the both columns were added to view1
tenant1Conn.createStatement().execute("SELECT KV from " + view1);
@@ -526,21 +530,24 @@ public class AlterMultiTenantTableWithViewsIT extends SplitSystemCatalogIT {
String tenant = TENANT1;
try (Connection conn = DriverManager.getConnection(getUrl());
Connection tenant1Conn = getTenantConnection(tenant)) {
- String baseTableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR, V3 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
+ String baseTableDDL =
+ "CREATE TABLE " + baseTable
+ + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR,"
+ + " V3 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) "
+ + "MULTI_TENANT = true , SALT_BUCKETS = 4";
conn.createStatement().execute(baseTableDDL);
String view1DDL = "CREATE VIEW " + view1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 CHAR(256)) AS SELECT * FROM " + baseTable;
tenant1Conn.createStatement().execute(view1DDL);
- assertTableDefinition(conn, baseTable, PTableType.TABLE, null, 1, 5, BASE_TABLE_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V2", "V3");
- assertTableDefinition(tenant1Conn, view1, PTableType.VIEW, baseTable, 0, 7, 5, "PK1", "V1", "V2", "V3", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(conn, baseTable, PTableType.TABLE, null, 1, 6, BASE_TABLE_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V2", "V3");
+ assertTableDefinition(tenant1Conn, view1, PTableType.VIEW, baseTable, 0, 8, 6, "PK1", "V1", "V2", "V3", "VIEW_COL1", "VIEW_COL2");
String alterBaseTable = "ALTER TABLE " + baseTable + " DROP COLUMN V2";
conn.createStatement().execute(alterBaseTable);
assertTableDefinition(conn, baseTable, PTableType.TABLE, null, 2, 4, BASE_TABLE_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V3");
- // column adds and drops are no longer propagated to child views, when the parent view is resolved the dropped column is excluded
- assertTableDefinition(tenant1Conn, view1, PTableType.VIEW, baseTable, 0, 7, 5, "PK1", "V1", "V2", "V3", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(tenant1Conn, view1, PTableType.VIEW, baseTable, 0, 8, 6, "PK1", "V1", "V3", "VIEW_COL1", "VIEW_COL2");
// verify that the dropped columns aren't visible
try {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3467445/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
index e97a40d..b1f0fce 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
@@ -73,19 +73,22 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
private final boolean isMultiTenant;
private final boolean columnEncoded;
+ private final boolean salted;
private final String TENANT_SPECIFIC_URL1 = getUrl() + ';' + TENANT_ID_ATTRIB + "=" + TENANT1;
private final String TENANT_SPECIFIC_URL2 = getUrl() + ';' + TENANT_ID_ATTRIB + "=" + TENANT2;
- public AlterTableWithViewsIT(boolean isMultiTenant, boolean columnEncoded) {
- this.isMultiTenant = isMultiTenant;
+ public AlterTableWithViewsIT(boolean columnEncoded, boolean isMultiTenant, boolean salted) {
this.columnEncoded = columnEncoded;
+ this.isMultiTenant = isMultiTenant;
+ this.salted = salted;
}
- @Parameters(name="AlterTableWithViewsIT_multiTenant={0}, columnEncoded={1}") // name is used by failsafe as file name in reports
+ // name is used by failsafe as file name in reports
+ @Parameters(name = "AlterTableWithViewsIT_columnEncoded={0}, multiTenant={1}, salted={2}")
public static Collection<Boolean[]> data() {
- return Arrays.asList(new Boolean[][] {
- { false, false }, { false, true },
- { true, false }, { true, true } });
+ return Arrays.asList(new Boolean[][] { { false, false, false }, { false, false, true },
+ { false, true, false }, { false, true, true }, { true, false, false },
+ { true, false, true }, { true, true, false }, { true, true, true } });
}
// transform PColumn to String
@@ -112,6 +115,11 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
optionsBuilder.append(",");
optionsBuilder.append("MULTI_TENANT=true");
}
+ if (salted) {
+ if (optionsBuilder.length()!=0)
+ optionsBuilder.append(",");
+ optionsBuilder.append("SALT_BUCKETS=4");
+ }
return String.format(format, isMultiTenant ? "TENANT_ID VARCHAR NOT NULL, " : "",
isMultiTenant ? "TENANT_ID, " : "", optionsBuilder.toString());
}
@@ -130,16 +138,17 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
+ " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)"
+ " ) %s";
conn.createStatement().execute(generateDDL(ddlFormat));
- assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
+ assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, true, "ID", "COL1", "COL2");
viewConn.createStatement().execute("CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM " + tableName);
- assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, true, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
// adding a new pk column and a new regular column
conn.createStatement().execute("ALTER TABLE " + tableName + " ADD COL3 varchar(10) PRIMARY KEY, COL4 integer");
- assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 2 : 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3", "COL4");
- // add/drop column to a base table are no longer propagated to child views
- assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 2 : 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, false, "ID", "COL1", "COL2", "COL3", "COL4");
+ // TODO PHOENIX-4766 add/drop column to a base table are no longer propagated to child views
+ // assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, true, "ID", "COL1", "COL2", "COL3", "COL4", "VIEW_COL1", "VIEW_COL2");
}
}
@@ -234,22 +243,21 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
+ " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)" + " ) %s";
conn.createStatement().execute(generateDDL(ddlFormat));
assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 6,
- QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3", "COL4",
- "COL5");
+ QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, true, "ID", "COL1", "COL2", "COL3",
+ "COL4", "COL5");
viewConn.createStatement()
.execute(
"CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM " + tableName);
assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 8, 6,
- "ID", "COL1", "COL2", "COL3", "COL4", "COL5", "VIEW_COL1", "VIEW_COL2");
+ true, "ID", "COL1", "COL2", "COL3", "COL4", "COL5", "VIEW_COL1", "VIEW_COL2");
// drop two columns from the base table
conn.createStatement().execute("ALTER TABLE " + tableName + " DROP COLUMN COL3, COL5");
assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 2 : 1, 4,
- QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL4");
- // the columns will still exist in the view metadata , but are excluded while combining parent table columns
+ QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, false, "ID", "COL1", "COL2", "COL4");
assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 8, 6,
- "ID", "COL1", "COL2", "COL3", "COL4", "COL5", "VIEW_COL1", "VIEW_COL2");
+ true, "ID", "COL1", "COL2", "COL4", "VIEW_COL1", "VIEW_COL2");
}
}
@@ -270,10 +278,10 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
+ " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)"
+ " ) %s";
conn.createStatement().execute(generateDDL(ddlFormat));
- assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 4, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3");
+ assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 4, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, true, "ID", "COL1", "COL2", "COL3");
viewConn.createStatement().execute("CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256), VIEW_COL3 VARCHAR, VIEW_COL4 DECIMAL, VIEW_COL5 DECIMAL(10,2), VIEW_COL6 VARCHAR, CONSTRAINT pk PRIMARY KEY (VIEW_COL5, VIEW_COL6) ) AS SELECT * FROM " + tableName);
- assertTableDefinition(viewConn,viewOfTable, PTableType.VIEW, tableName, 0, 10, 4, "ID", "COL1", "COL2", "COL3", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6");
+ assertTableDefinition(viewConn,viewOfTable, PTableType.VIEW, tableName, 0, 10, 4, true, "ID", "COL1", "COL2", "COL3", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6");
// upsert single row into view
String dml = "UPSERT INTO " + viewOfTable + " VALUES(?,?,?,?,?, ?, ?, ?, ?, ?)";
@@ -328,8 +336,8 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
}
// validate that there were no columns added to the table or view, if its table is column encoded the sequence number changes when we increment the cq counter
- assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 1 : 0, 4, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3");
- assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 10, 4, "ID", "COL1", "COL2", "COL3", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6");
+ assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 1 : 0, 4, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, true, "ID", "COL1", "COL2", "COL3");
+ assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 10, 4, true, "ID", "COL1", "COL2", "COL3", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6");
if (columnEncoded) {
try {
@@ -343,9 +351,9 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
else {
// should succeed
conn.createStatement().execute("ALTER TABLE " + tableName + " ADD VIEW_COL4 DECIMAL, VIEW_COL2 VARCHAR(256)");
- assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 2 : 1, 6, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3", "VIEW_COL4", "VIEW_COL2");
+ assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 2 : 1, 6, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, false, "ID", "COL1", "COL2", "COL3", "VIEW_COL4", "VIEW_COL2");
// even though we added columns to the base table, the view metadata remains the same as the base table metadata changes are no longer propagated to the chid view
- assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 10, 4, "ID", "COL1", "COL2", "COL3", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6");
+ assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 10, 4, true, "ID", "COL1", "COL2", "COL3", "VIEW_COL4", "VIEW_COL2", "VIEW_COL1", "VIEW_COL3", "VIEW_COL5", "VIEW_COL6");
// query table
ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);
@@ -376,7 +384,7 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
// the base column count and ordinal positions of columns is updated in the ptable (at read time)
PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null;
PTable view = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable));
- assertEquals(isMultiTenant ? 5: 4, view.getBaseColumnCount());
+ assertBaseColumnCount(4, view.getBaseColumnCount());
assertColumnsMatch(view.getColumns(), "ID", "COL1", "COL2", "COL3", "VIEW_COL4", "VIEW_COL2", "VIEW_COL1", "VIEW_COL3", "VIEW_COL5", "VIEW_COL6");
}
}
@@ -398,14 +406,10 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
+ " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)"
+ " ) %s";
conn.createStatement().execute(generateDDL(ddlFormat));
- assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
- PTable table = PhoenixRuntime.getTableNoCache(conn, tableName.toUpperCase());
- assertColumnsMatch(table.getColumns(), "ID", "COL1", "COL2");
+ assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, true, "ID", "COL1", "COL2");
viewConn.createStatement().execute("CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM " + tableName);
- assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
- PTable view = PhoenixRuntime.getTableNoCache(viewConn, viewOfTable.toUpperCase());
- assertColumnsMatch(view.getColumns(), "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, true, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
// upsert single row into view
String dml = "UPSERT INTO " + viewOfTable + " VALUES(?,?,?,?,?)";
@@ -474,9 +478,9 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
// add the pk column of the view to the base table
conn.createStatement().execute("ALTER TABLE " + tableName + " ADD VIEW_COL1 DECIMAL(10,2) PRIMARY KEY, VIEW_COL2 VARCHAR(256) PRIMARY KEY");
- assertTableDefinition(conn, tableName, PTableType.TABLE, null, 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(conn, tableName, PTableType.TABLE, null, 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, false, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
// even though we added columns to the base table, the sequence number and base column count is not updated in the view metadata (in SYSTEM.CATALOG)
- assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, true, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
// query table
ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);
@@ -500,8 +504,9 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
// the base column count is updated in the ptable
PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null;
+ PTable view = PhoenixRuntime.getTableNoCache(viewConn, viewOfTable.toUpperCase());
view = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable));
- assertEquals(isMultiTenant ? 4 : 3, view.getBaseColumnCount());
+ assertBaseColumnCount(3, view.getBaseColumnCount());
}
}
@@ -520,16 +525,16 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
+ " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)"
+ " ) %s";
conn.createStatement().execute(generateDDL(ddlFormat));
- assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
+ assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, true, "ID", "COL1", "COL2");
viewConn.createStatement().execute("CREATE VIEW " + viewOfTable1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM " + tableName);
- assertTableDefinition(viewConn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(viewConn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, true, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
viewConn.createStatement().execute("CREATE VIEW " + viewOfTable2 + " ( VIEW_COL3 VARCHAR(256), VIEW_COL4 DECIMAL(10,2) CONSTRAINT pk PRIMARY KEY (VIEW_COL3, VIEW_COL4)) AS SELECT * FROM " + tableName);
- assertTableDefinition(viewConn, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL3", "VIEW_COL4");
+ assertTableDefinition(viewConn, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, true, "ID", "COL1", "COL2", "VIEW_COL3", "VIEW_COL4");
try {
- // should fail because there are two view with different pk columns
+ // should fail because there are two views with different pk columns
conn.createStatement().execute("ALTER TABLE " + tableName + " ADD VIEW_COL1 DECIMAL(10,2) PRIMARY KEY, VIEW_COL2 VARCHAR(256) PRIMARY KEY");
fail();
}
@@ -585,13 +590,13 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
+ " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)"
+ " ) %s";
conn.createStatement().execute(generateDDL(ddlFormat));
- assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
+ assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, true, "ID", "COL1", "COL2");
viewConn.createStatement().execute("CREATE VIEW " + viewOfTable1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM " + tableName);
- assertTableDefinition(viewConn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(viewConn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, true, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
viewConn2.createStatement().execute("CREATE VIEW " + viewOfTable2 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM " + tableName);
- assertTableDefinition(viewConn2, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(viewConn2, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, true, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
// upsert single row into both view
String dml = "UPSERT INTO " + viewOfTable1 + " VALUES(?,?,?,?,?)";
@@ -641,10 +646,10 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
}
conn.createStatement().execute("ALTER TABLE " + tableName + " ADD VIEW_COL1 DECIMAL(10,2) PRIMARY KEY, VIEW_COL2 VARCHAR(256) PRIMARY KEY");
- assertTableDefinition(conn, tableName, PTableType.TABLE, null, 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(conn, tableName, PTableType.TABLE, null, 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, false, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
// even though we added columns to the base table, the sequence number and base column count is not updated in the view metadata (in SYSTEM.CATALOG)
- assertTableDefinition(viewConn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
- assertTableDefinition(viewConn, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(viewConn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, true, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(viewConn, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, true, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
// query table
ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);
@@ -674,17 +679,20 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
assertEquals("view5", rs.getString("VIEW_COL2"));
assertFalse(rs.next());
- // the base column count is updated in the ptable
- PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null;
- PTable view1 = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable1));
- PTable view2 = viewConn2.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable2));
- assertEquals(isMultiTenant ? 4 : 3, view1.getBaseColumnCount());
- assertEquals(isMultiTenant ? 4 : 3, view2.getBaseColumnCount());
+ // the column count is updated in the base table
+ PTable table = conn.unwrap(PhoenixConnection.class).getTable(new PTableKey(null, tableName));
+ assertColumnsMatch(table.getColumns(), "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
}
}
- public void assertTableDefinition(Connection conn, String fullTableName, PTableType tableType, String parentTableName, int sequenceNumber, int columnCount, int baseColumnCount, String... columnNames) throws Exception {
- int delta = isMultiTenant ? 1 : 0;
+ public void assertTableDefinition(Connection conn, String fullTableName, PTableType tableType, String parentTableName, int sequenceNumber, int columnCount, int baseColumnCount, boolean offsetCountsForSaltedTables, String... columnNames) throws Exception {
+ int delta= 0;
+ delta += isMultiTenant ? 1 : 0;
+ // when we create a salted table we include the salt num in the column count, but after we
+ // add or drop a column we don't include the salted table in the column count, so if a table
+ // is salted take this into account for the column count but no the base column count
+ if (offsetCountsForSaltedTables)
+ delta += salted ? 1 : 0;
String[] cols;
if (isMultiTenant && tableType!=PTableType.VIEW) {
cols = (String[])ArrayUtils.addAll(new String[]{"TENANT_ID"}, columnNames);
@@ -696,11 +704,20 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
baseColumnCount==QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT ? baseColumnCount : baseColumnCount +delta, cols);
}
- public void assertColumnsMatch(List<PColumn> actual, String... expected) {
+ private void assertBaseColumnCount(int expected, int actual) {
+ if (salted) ++expected;
+ if (isMultiTenant) ++expected;
+ assertEquals("Base column count does not match", expected, actual);
+ }
+
+ private void assertColumnsMatch(List<PColumn> actual, String... expected) {
List<String> expectedCols = Lists.newArrayList(expected);
if (isMultiTenant) {
expectedCols.add(0, "TENANT_ID");
}
+ if (salted) {
+ expectedCols.add(0, "_SALT");
+ }
assertEquals(expectedCols, Lists.transform(actual, function));
}
@@ -810,59 +827,82 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
PTable table = PhoenixRuntime.getTableNoCache(viewConn, view1);
assertEquals(QueryConstants.DIVERGED_VIEW_BASE_COLUMN_COUNT, table.getBaseColumnCount());
+ try {
+ viewConn.createStatement().execute("SELECT V2 FROM " + view1);
+ fail("V2 should have been droppped");
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
+ }
+
// Add a new regular column and pk column to the base table
String alterBaseTable = "ALTER TABLE " + baseTable + " ADD V3 VARCHAR, PK2 VARCHAR PRIMARY KEY";
conn.createStatement().execute(alterBaseTable);
// Column V3 shouldn't have propagated to the diverged view.
- String sql = "SELECT V3 FROM " + view1;
try {
- viewConn.createStatement().execute(sql);
+ viewConn.createStatement().execute("SELECT V3 FROM " + view1);
+ fail();
} catch (SQLException e) {
assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
}
// However, column V3 should have propagated to the non-diverged view.
- sql = "SELECT V3 FROM " + view2;
- viewConn2.createStatement().execute(sql);
+ viewConn2.createStatement().execute("SELECT V3 FROM " + view2);
// PK2 should be in both views
- sql = "SELECT PK2 FROM " + view1;
- viewConn.createStatement().execute(sql);
- sql = "SELECT PK2 FROM " + view2;
- viewConn2.createStatement().execute(sql);
+ viewConn.createStatement().execute("SELECT PK2 FROM " + view1);
+ viewConn2.createStatement().execute("SELECT PK2 FROM " + view2);
// Drop a column from the base table
alterBaseTable = "ALTER TABLE " + baseTable + " DROP COLUMN V1";
conn.createStatement().execute(alterBaseTable);
+
+ // V1 should be dropped from the base table
+ try {
+ conn.createStatement().execute("SELECT V1 FROM " + baseTable);
+ fail();
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
+ }
// V1 should be dropped from both diverged and non-diverged views
- sql = "SELECT V1 FROM " + view1;
try {
- viewConn.createStatement().execute(sql);
+ viewConn2.createStatement().execute("SELECT V1 FROM " + view2);
+ fail();
} catch (SQLException e) {
assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
}
- sql = "SELECT V1 FROM " + view2;
try {
- viewConn2.createStatement().execute(sql);
+ viewConn.createStatement().execute("SELECT V1 FROM " + view1);
+// TODO since the view is diverged we can't filter out the parent table column metadata
+// while building the view. After the client stops sending parent table column metadata (see PHOENIX-4766)
+// while creating a view dropping a parent table column will also be reflected in a diverged view
+// fail();
} catch (SQLException e) {
assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
}
// V0 should be still exist in both diverged and non-diverged views
- sql = "SELECT V0 FROM " + view1;
- viewConn.createStatement().execute(sql);
- sql = "SELECT V0 FROM " + view2;
- viewConn2.createStatement().execute(sql);
+ viewConn.createStatement().execute("SELECT V0 FROM " + view1);
+ viewConn2.createStatement().execute("SELECT V0 FROM " + view2);
- // add the column that was dropped back to the view
- String addColumn = "ALTER VIEW " + view1 + " ADD V2 VARCHAR";
- viewConn.createStatement().execute(addColumn);
+ // we currently cannot add a column that was dropped back to the view because the excluded column
+ // doesn't contain data type information see PHOENIX-4868
+ try {
+ viewConn.createStatement().execute("ALTER VIEW " + view1 + " ADD V2 VARCHAR");
+ fail();
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
+ }
+
// V2 should not exist in the view
- sql = "SELECT V0 FROM " + view1;
- viewConn.createStatement().execute(sql);
- }
+ try {
+ viewConn.createStatement().execute("SELECT V2 FROM " + view1);
+ fail();
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
+ }
+ }
}
@Test
@@ -879,10 +919,10 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
+ " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)"
+ " ) %s";
conn.createStatement().execute(generateDDL(ddlFormat));
- assertTableDefinition(conn, baseTableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
+ assertTableDefinition(conn, baseTableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, true, "ID", "COL1", "COL2");
viewConn.createStatement().execute("CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM "+baseTableName);
- assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, baseTableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+ assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, baseTableName, 0, 5, 3, true, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null;
PhoenixConnection phoenixConn = conn.unwrap(PhoenixConnection.class);
@@ -1037,6 +1077,10 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
.getString());
assertEquals("Unexpected index ", fullNameViewIndex2 , view.getIndexes().get(1).getName()
.getString());
+ assertEquals("Unexpected salt buckets", view.getBucketNum(),
+ view.getIndexes().get(0).getBucketNum());
+ assertEquals("Unexpected salt buckets", view.getBucketNum(),
+ view.getIndexes().get(1).getBucketNum());
// drop two columns
conn.createStatement().execute("ALTER TABLE " + tableWithView + " DROP COLUMN v2, v3 ");
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3467445/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
index 796c3d9..bfcc729 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
@@ -724,7 +724,7 @@ public class ViewIT extends SplitSystemCatalogIT {
conn.getMetaData().getPrimaryKeys(null,
SchemaUtil.getSchemaNameFromFullName(fullViewName),
SchemaUtil.getTableNameFromFullName(fullViewName));
- assertPKs(rs, new String[] {"K3"});
+ assertPKs(rs, new String[] {"K1", "K2", "K3"});
// sanity check upserts into base table and view
conn.createStatement().executeUpdate("upsert into " + fullTableName + " (k1, k2, v1) values (1, 1, 1)");
@@ -753,12 +753,14 @@ public class ViewIT extends SplitSystemCatalogIT {
ddl = "CREATE VIEW " + fullViewName + "(v2 VARCHAR, k3 VARCHAR, k4 INTEGER NOT NULL, CONSTRAINT PKVEW PRIMARY KEY (k3, k4)) AS SELECT * FROM " + fullTableName + " WHERE K1 = 1";
conn.createStatement().execute(ddl);
+ PTable view = PhoenixRuntime.getTableNoCache(conn, fullViewName);
+
// assert PK metadata
ResultSet rs =
conn.getMetaData().getPrimaryKeys(null,
SchemaUtil.getSchemaNameFromFullName(fullViewName),
SchemaUtil.getTableNameFromFullName(fullViewName));
- assertPKs(rs, new String[] {"K3", "K4"});
+ assertPKs(rs, new String[] {"K1", "K2", "K3", "K4"});
}
@Test
@@ -778,7 +780,7 @@ public class ViewIT extends SplitSystemCatalogIT {
// assert PK metadata
ResultSet rs = conn.getMetaData().getPrimaryKeys(null, SCHEMA2, viewName);
- assertPKs(rs, new String[] {"K3", "K4"});
+ assertPKs(rs, new String[] {"K1", "K2", "K3", "K4"});
}
@Test
@@ -1005,8 +1007,8 @@ public class ViewIT extends SplitSystemCatalogIT {
+ tableName + " WHERE KEY_PREFIX = 'ab4' ");
// upsert rows
- upsertRows(viewName1, tenantConn);
- upsertRows(viewName2, tenantConn);
+ upsertRows(tableName, viewName1, tenantConn);
+ upsertRows(tableName, viewName2, tenantConn);
// run queries
String[] whereClauses =
@@ -1123,7 +1125,7 @@ public class ViewIT extends SplitSystemCatalogIT {
}
}
- private void upsertRows(String viewName1, Connection tenantConn) throws SQLException {
+ private void upsertRows(String tableName, String viewName1, Connection tenantConn) throws SQLException, IOException {
tenantConn.createStatement().execute("UPSERT INTO " + viewName1
+ " (pk1, pk2, col1, col3) VALUES ('testa', 'testb', TO_DATE('2017-10-16 22:00:00', 'yyyy-MM-dd HH:mm:ss'), 10)");
tenantConn.createStatement().execute("UPSERT INTO " + viewName1
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3467445/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 cf5828d..83c7f4d 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
@@ -249,7 +249,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.cache.Cache;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.protobuf.ByteString;
@@ -417,6 +416,10 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
private static final KeyValue COLUMN_DEF_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, COLUMN_DEF_BYTES);
private static final KeyValue IS_ROW_TIMESTAMP_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, IS_ROW_TIMESTAMP_BYTES);
private static final KeyValue COLUMN_QUALIFIER_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, COLUMN_QUALIFIER_BYTES);
+ // this key value is used to represent a column derived from a parent that was deleted (by
+ // storing a value of LinkType.EXCLUDED_COLUMN)
+ private static final KeyValue LINK_TYPE_KV =
+ createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, LINK_TYPE_BYTES);
private static final List<KeyValue> COLUMN_KV_COLUMNS = Arrays.<KeyValue>asList(
DECIMAL_DIGITS_KV,
@@ -431,7 +434,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
IS_VIEW_REFERENCED_KV,
COLUMN_DEF_KV,
IS_ROW_TIMESTAMP_KV,
- COLUMN_QUALIFIER_KV
+ COLUMN_QUALIFIER_KV,
+ LINK_TYPE_KV
);
static {
Collections.sort(COLUMN_KV_COLUMNS, KeyValue.COMPARATOR);
@@ -449,7 +453,12 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
private static final int COLUMN_DEF_INDEX = COLUMN_KV_COLUMNS.indexOf(COLUMN_DEF_KV);
private static final int IS_ROW_TIMESTAMP_INDEX = COLUMN_KV_COLUMNS.indexOf(IS_ROW_TIMESTAMP_KV);
private static final int COLUMN_QUALIFIER_INDEX = COLUMN_KV_COLUMNS.indexOf(COLUMN_QUALIFIER_KV);
+ // the index of the key value is used to represent a column derived from a parent that was
+ // deleted (by storing a value of LinkType.EXCLUDED_COLUMN)
+ private static final int EXCLUDED_COLUMN_LINK_TYPE_KV_INDEX =
+ COLUMN_KV_COLUMNS.indexOf(LINK_TYPE_KV);
+ // index for link type key value that is used to store linking rows
private static final int LINK_TYPE_INDEX = 0;
private static final KeyValue CLASS_NAME_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, CLASS_NAME_BYTES);
@@ -496,6 +505,10 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
private static final int DEFAULT_VALUE_INDEX = FUNCTION_ARG_KV_COLUMNS.indexOf(DEFAULT_VALUE_KV);
private static final int MIN_VALUE_INDEX = FUNCTION_ARG_KV_COLUMNS.indexOf(MIN_VALUE_KV);
private static final int MAX_VALUE_INDEX = FUNCTION_ARG_KV_COLUMNS.indexOf(MAX_VALUE_KV);
+
+ private static PName newPName(byte[] buffer) {
+ return buffer==null ? null : newPName(buffer, 0, buffer.length);
+ }
private static PName newPName(byte[] keyBuffer, int keyOffset, int keyLength) {
if (keyLength <= 0) {
@@ -725,9 +738,9 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
List<PColumn> excludedColumns = Lists.newArrayList();
// add my own columns first in reverse order
List<PColumn> myColumns = table.getColumns();
- // skip salted column as it will be added from the base table columns
- int startIndex = table.getBucketNum() != null ? 1 : 0;
- for (int i = myColumns.size() - 1; i >= startIndex; i--) {
+ // skip salted column as it will be created automatically
+ myColumns = myColumns.subList(isSalted ? 1 : 0, myColumns.size());
+ for (int i = myColumns.size() - 1; i >= 0; i--) {
PColumn pColumn = myColumns.get(i);
if (pColumn.isExcluded()) {
excludedColumns.add(pColumn);
@@ -804,17 +817,17 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
if (hasIndexId) {
// add all pk columns of parent tables to indexes
// skip salted column as it will be added from the base table columns
- startIndex = pTable.getBucketNum() != null ? 1 : 0;
+ int startIndex = pTable.getBucketNum() != null ? 1 : 0;
for (int index=startIndex; index<pTable.getPKColumns().size(); index++) {
- PColumn column = pTable.getPKColumns().get(index);
+ PColumn pkColumn = pTable.getPKColumns().get(index);
// don't add the salt column of ancestor tables for view indexes
- if (column.equals(SaltingUtil.SALTING_COLUMN) || column.isExcluded()) {
+ if (pkColumn.equals(SaltingUtil.SALTING_COLUMN) || pkColumn.isExcluded()) {
continue;
}
- column = IndexUtil.getIndexPKColumn(++numPKCols, column);
- int existingColumnIndex = allColumns.indexOf(column);
+ pkColumn = IndexUtil.getIndexPKColumn(++numPKCols, pkColumn);
+ int existingColumnIndex = allColumns.indexOf(pkColumn);
if (existingColumnIndex == -1) {
- allColumns.add(0, column);
+ allColumns.add(0, pkColumn);
}
}
for (int j = 0; j < pTable.getColumns().size(); j++) {
@@ -832,6 +845,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
} else {
List<PColumn> currAncestorTableCols = PTableImpl.getColumnsToClone(pTable);
if (currAncestorTableCols != null) {
+ // add the ancestor columns in reverse order so that the final column list
+ // contains ancestor columns and then the view columns in the right order
for (int j = currAncestorTableCols.size() - 1; j >= 0; j--) {
PColumn column = currAncestorTableCols.get(j);
// for diverged views we always include pk columns of the base table. We
@@ -861,10 +876,15 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
} else {
int existingColumnIndex = allColumns.indexOf(column);
if (existingColumnIndex != -1) {
- // if the same column exists in a parent and child, we keep the
- // latest column
+ // for diverged views if the view was created before
+ // PHOENIX-3534 the parent table columns will be present in the
+ // view PTable (since the base column count is
+ // QueryConstants.DIVERGED_VIEW_BASE_COLUMN_COUNT we can't
+ // filter them out) so we always pick the parent column
+ // for non diverged views if the same column exists in a parent
+ // and child, we keep the latest column
PColumn existingColumn = allColumns.get(existingColumnIndex);
- if (column.getTimestamp() > existingColumn.getTimestamp()) {
+ if (isDiverged || column.getTimestamp() > existingColumn.getTimestamp()) {
allColumns.remove(existingColumnIndex);
allColumns.add(column);
}
@@ -892,8 +912,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
}
}
}
- // lets remove the excluded columns first if the timestamp is newer than
- // the added column
+ // remove the excluded columns if the timestamp is newer than the added column
for (PColumn excludedColumn : excludedColumns) {
int index = allColumns.indexOf(excludedColumn);
if (index != -1) {
@@ -904,27 +923,26 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
}
List<PColumn> columnsToAdd = Lists.newArrayList();
int position = isSalted ? 1 : 0;
+ // allColumns contains the columns in the reverse order
for (int i = allColumns.size() - 1; i >= 0; i--) {
PColumn column = allColumns.get(i);
if (table.getColumns().contains(column)) {
// for views this column is not derived from an ancestor
- columnsToAdd.add(new PColumnImpl(column, position));
+ columnsToAdd.add(new PColumnImpl(column, position++));
} else {
- columnsToAdd.add(new PColumnImpl(column, true, position));
+ columnsToAdd.add(new PColumnImpl(column, true, position++));
}
- position++;
}
- // need to have the columns in the PTable to use the WhereCompiler
- // unfortunately so this needs to be done
- // twice....
- // TODO set the view properties correctly instead of just setting them
- // same as the base table
+ // we need to include the salt column when setting the base table column count in order to
+ // maintain b/w compatibility
int baseTableColumnCount =
isDiverged ? QueryConstants.DIVERGED_VIEW_BASE_COLUMN_COUNT
- : columnsToAdd.size() - myColumns.size();
+ : columnsToAdd.size() - myColumns.size() + (isSalted ? 1 : 0);
+ // TODO Implement PHOENIX-4763 to set the view properties correctly instead of just
+ // setting them same as the base table
PTableImpl pTable =
PTableImpl.makePTable(table, baseTable, columnsToAdd, maxTableTimestamp,
- baseTableColumnCount);
+ baseTableColumnCount, excludedColumns);
return WhereConstantParser.addViewInfoToPColumnsIfNeeded(pTable);
}
@@ -1057,7 +1075,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
}
private void addColumnToTable(List<Cell> results, PName colName, PName famName,
- Cell[] colKeyValues, List<PColumn> columns, boolean isSalted) {
+ Cell[] colKeyValues, List<PColumn> columns, boolean isSalted, int baseColumnCount,
+ boolean isRegularView) {
int i = 0;
int j = 0;
while (i < results.size() && j < COLUMN_KV_COLUMNS.size()) {
@@ -1082,7 +1101,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
throw new IllegalStateException("Didn't find all required key values in '"
+ colName.getString() + "' column metadata row");
}
-
+
Cell columnSizeKv = colKeyValues[COLUMN_SIZE_INDEX];
Integer maxLength =
columnSizeKv == null ? null : PInteger.INSTANCE.getCodec().decodeInt(
@@ -1094,7 +1113,37 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
Cell ordinalPositionKv = colKeyValues[ORDINAL_POSITION_INDEX];
int position =
PInteger.INSTANCE.getCodec().decodeInt(ordinalPositionKv.getValueArray(),
- ordinalPositionKv.getValueOffset(), SortOrder.getDefault()) + (isSalted ? 1 : 0);
+ ordinalPositionKv.getValueOffset(), SortOrder.getDefault()) + (isSalted ? 1 : 0);;
+
+ // Prior to PHOENIX-4766 we were sending the parent table column metadata while creating a
+ // child view, now that we combine columns by resolving the parent table hierarchy we
+ // don't need to include the parent table column while loading the PTable of the view
+ if (isRegularView && position <= baseColumnCount) {
+ return;
+ }
+
+ // if this column was inherited from a parent and was dropped that we create an excluded
+ // column, this check is only needed to handle view metadata that was created before
+ // PHOENIX-4766 where we were sending the parent table column metadata when creating a
+ // childview
+ Cell excludedColumnKv = colKeyValues[EXCLUDED_COLUMN_LINK_TYPE_KV_INDEX];
+ if (excludedColumnKv != null && colKeyValues[DATA_TYPE_INDEX]
+ .getTimestamp() <= excludedColumnKv.getTimestamp()) {
+ LinkType linkType =
+ LinkType.fromSerializedValue(
+ excludedColumnKv.getValueArray()[excludedColumnKv.getValueOffset()]);
+ if (linkType == LinkType.EXCLUDED_COLUMN) {
+ addExcludedColumnToTable(columns, colName, famName, excludedColumnKv.getTimestamp());
+ } else {
+ // if we have a column metadata row that has a link type keyvalue it should
+ // represent an excluded column by containing the LinkType.EXCLUDED_COLUMN
+ throw new IllegalStateException(
+ "Link type should be EXCLUDED_COLUMN but found an unxpected link type for key value "
+ + excludedColumnKv);
+ }
+ return;
+ }
+
Cell nullableKv = colKeyValues[NULLABLE_INDEX];
boolean isNullable =
PInteger.INSTANCE.getCodec().decodeInt(nullableKv.getValueArray(),
@@ -1136,8 +1185,11 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
Arrays.copyOfRange(columnQualifierKV.getValueArray(),
columnQualifierKV.getValueOffset(), columnQualifierKV.getValueOffset()
+ columnQualifierKV.getValueLength()) : (isPkColumn ? null : colName.getBytes());
- PColumn column = new PColumnImpl(colName, famName, dataType, maxLength, scale, isNullable, position-1, sortOrder, arraySize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, false, columnQualifierBytes,
- results.get(0).getTimestamp());
+ PColumn column =
+ new PColumnImpl(colName, famName, dataType, maxLength, scale, isNullable,
+ position - 1, sortOrder, arraySize, viewConstant, isViewReferenced,
+ expressionStr, isRowTimestamp, false, columnQualifierBytes,
+ results.get(0).getTimestamp());
columns.add(column);
}
@@ -1427,7 +1479,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
addExcludedColumnToTable(columns, colName, famName, colKv.getTimestamp());
}
} else {
- addColumnToTable(results, colName, famName, colKeyValues, columns, saltBucketNum != null);
+ boolean isRegularView = (tableType == PTableType.VIEW && viewType!=ViewType.MAPPED);
+ addColumnToTable(results, colName, famName, colKeyValues, columns, saltBucketNum != null, baseColumnCount, isRegularView);
}
}
// Avoid querying the stats table because we're holding the rowLock here. Issuing an RPC to a remote
@@ -1911,42 +1964,6 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
dropChildMetadata(schemaName, tableName, tenantIdBytes);
}
- // Here we are passed the parent's columns to add to a view, PHOENIX-3534 allows for a splittable
- // System.Catalog thus we only store the columns that are new to the view, not the parents columns,
- // thus here we remove everything that is ORDINAL.POSITION <= baseColumnCount and update the
- // ORDINAL.POSITIONS to be shifted accordingly.
- // TODO PHOENIX-4767 remove the following code that removes the base table column metadata in the next release
- if (PTableType.VIEW.equals(tableType) && !ViewType.MAPPED.equals(viewType)) {
- boolean isSalted = MetaDataUtil.getSaltBuckets(tableMetadata, GenericKeyValueBuilder.INSTANCE, new ImmutableBytesWritable()) > 0;
- int baseColumnCount = MetaDataUtil.getBaseColumnCount(tableMetadata) - (isSalted ? 1 : 0);
- if (baseColumnCount > 0) {
- Iterator<Mutation> mutationIterator = tableMetadata.iterator();
- while (mutationIterator.hasNext()) {
- Mutation mutation = mutationIterator.next();
- // if not null and ordinal position < base column count remove this mutation
- ImmutableBytesWritable ptr = new ImmutableBytesWritable();
- MetaDataUtil.getMutationValue(mutation, PhoenixDatabaseMetaData.ORDINAL_POSITION_BYTES,
- GenericKeyValueBuilder.INSTANCE, ptr);
- if (MetaDataUtil.getMutationValue(mutation, PhoenixDatabaseMetaData.ORDINAL_POSITION_BYTES,
- GenericKeyValueBuilder.INSTANCE, ptr)) {
- int ordinalValue = PInteger.INSTANCE.getCodec().decodeInt(ptr, SortOrder.ASC);
- if (ordinalValue <= baseColumnCount) {
- mutationIterator.remove();
- } else {
- if (mutation instanceof Put) {
- byte[] ordinalPositionBytes = new byte[PInteger.INSTANCE.getByteSize()];
- int newOrdinalValue = ordinalValue - baseColumnCount;
- PInteger.INSTANCE.getCodec()
- .encodeInt(newOrdinalValue, ordinalPositionBytes, 0);
- byte[] family = Iterables.getOnlyElement(mutation.getFamilyCellMap().keySet());
- MetaDataUtil.mutatePutValue((Put) mutation, family, PhoenixDatabaseMetaData.ORDINAL_POSITION_BYTES, ordinalPositionBytes);
- }
- }
- }
- }
- }
- }
-
byte[] parentTableKey = null;
Mutation viewPhysicalTableRow = null;
Set<TableName> indexes = new HashSet<TableName>();;
@@ -2931,6 +2948,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
byte[] tableName = rowKeyMetaData[TABLE_NAME_INDEX];
List<Put> columnPutsForBaseTable =
Lists.newArrayListWithExpectedSize(tableMetadata.size());
+ boolean salted = basePhysicalTable.getBucketNum()!=null;
// Isolate the puts relevant to adding columns
for (Mutation m : tableMetadata) {
if (m instanceof Put) {
@@ -2970,9 +2988,15 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
return new MetaDataMutationResult(MutationCode.UNALLOWED_TABLE_MUTATION, EnvironmentEdgeManager.currentTimeMillis(), basePhysicalTable);
}
- //add the new columns to the child view
+ // add the new columns to the child view
List<PColumn> viewPkCols = new ArrayList<>(view.getPKColumns());
- boolean addingExistingPkCol = false;
+ // remove salted column
+ if (salted) {
+ viewPkCols.remove(0);
+ }
+ // remove pk columns that are present in the parent
+ viewPkCols.removeAll(basePhysicalTable.getPKColumns());
+ boolean addedPkColumn = false;
for (Put columnToBeAdded : columnPutsForBaseTable) {
PColumn existingViewColumn = null;
byte[][] rkmd = new byte[5][];
@@ -2993,7 +3017,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
// ignore since it means the column is not present in the view
}
- boolean isColumnToBeAddPkCol = columnFamily == null;
+ boolean isCurrColumnToBeAddPkCol = columnFamily == null;
+ addedPkColumn |= isCurrColumnToBeAddPkCol;
if (existingViewColumn != null) {
if (EncodedColumnsUtil.usesEncodedColumnNames(basePhysicalTable)
&& !SchemaUtil.isPKColumn(existingViewColumn)) {
@@ -3057,7 +3082,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
// if the column to be added to the base table is a pk column, then we need to
// validate that the key slot position is the same
- if (isColumnToBeAddPkCol) {
+ if (isCurrColumnToBeAddPkCol) {
List<Cell> keySeqCells =
columnToBeAdded.get(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES,
PhoenixDatabaseMetaData.KEY_SEQ_BYTES);
@@ -3066,10 +3091,13 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
int keySeq =
PSmallint.INSTANCE.getCodec().decodeInt(cell.getValueArray(),
cell.getValueOffset(), SortOrder.getDefault());
+ // we need to take into account the columns inherited from the base table
+ // if the table is salted we don't include the salted column (which is
+ // present in getPKColumns())
int pkPosition =
basePhysicalTable.getPKColumns().size()
- + SchemaUtil.getPKPosition(view, existingViewColumn)
- + 1;
+ + SchemaUtil.getPKPosition(view, existingViewColumn) + 1
+ - (salted ? 2 : 0);
if (pkPosition != keySeq) {
return new MetaDataMutationResult(
MutationCode.UNALLOWED_TABLE_MUTATION,
@@ -3079,9 +3107,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
}
}
}
- if (isColumnToBeAddPkCol) {
+ if (existingViewColumn!=null && isCurrColumnToBeAddPkCol) {
viewPkCols.remove(existingViewColumn);
- addingExistingPkCol = true;
}
}
/*
@@ -3089,7 +3116,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
* the same as the base table pk columns 2. if we are adding all the existing view pk
* columns to the base table
*/
- if (addingExistingPkCol && !viewPkCols.isEmpty()) {
+ if (addedPkColumn && !viewPkCols.isEmpty()) {
return new MetaDataMutationResult(MutationCode.UNALLOWED_TABLE_MUTATION,
EnvironmentEdgeManager.currentTimeMillis(), basePhysicalTable);
}
@@ -3268,16 +3295,27 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
&& Bytes.compareTo(tableName, rowKeyMetaData[TABLE_NAME_INDEX]) == 0) {
try {
addingCol = true;
- if (pkCount > FAMILY_NAME_INDEX
- && rowKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX].length > 0) {
+ byte[] familyName = null;
+ byte[] colName = null;
+ if (pkCount > FAMILY_NAME_INDEX) {
+ familyName = rowKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX];
+ }
+ if (pkCount > COLUMN_NAME_INDEX) {
+ colName = rowKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX];
+ }
+ if (table.getExcludedColumns().contains(
+ PColumnImpl.createExcludedColumn(newPName(familyName), newPName(colName), 0l))) {
+ // if this column was previously dropped in a view do not allow adding the column back
+ return new MetaDataMutationResult(
+ MutationCode.UNALLOWED_TABLE_MUTATION, EnvironmentEdgeManager.currentTimeMillis(), null);
+ }
+ if (familyName!=null && familyName.length > 0) {
PColumnFamily family =
- table.getColumnFamily(rowKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]);
- family.getPColumnForColumnNameBytes(rowKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX]);
- } else if (pkCount > COLUMN_NAME_INDEX
- && rowKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX].length > 0) {
+ table.getColumnFamily(familyName);
+ family.getPColumnForColumnNameBytes(colName);
+ } else if (colName!=null && colName.length > 0) {
addingPKColumn = true;
- table.getPKColumn(new String(
- rowKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX]));
+ table.getPKColumn(new String(colName));
} else {
continue;
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3467445/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 1b5760d..18c9000 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
@@ -26,6 +26,7 @@ import java.sql.Statement;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import org.apache.hadoop.hbase.Cell;
@@ -491,6 +492,7 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
buf.append(buf.length() == 0 ? "" : " and ");
}
+ // While creating the PColumns we don't care about the ordinal positiion so set it to 1
private static final PColumnImpl TENANT_ID_COLUMN = new PColumnImpl(PNameFactory.newName(TENANT_ID),
PNameFactory.newName(TABLE_FAMILY_BYTES), PVarchar.INSTANCE, null, null, false, 1, SortOrder.getDefault(),
0, null, false, null, false, false, DATA_TYPE_BYTES, HConstants.LATEST_TIMESTAMP);
@@ -578,6 +580,14 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
private static final PColumnImpl KEY_SEQ_COLUMN = new PColumnImpl(PNameFactory.newName(KEY_SEQ),
PNameFactory.newName(TABLE_FAMILY_BYTES), PSmallint.INSTANCE, null, null, false, 1, SortOrder.getDefault(),
0, null, false, null, false, false, KEY_SEQ_BYTES, HConstants.LATEST_TIMESTAMP);
+ private static final PColumnImpl PK_NAME_COLUMN = new PColumnImpl(PNameFactory.newName(PK_NAME),
+ PNameFactory.newName(TABLE_FAMILY_BYTES), PVarchar.INSTANCE, null, null, false, 1, SortOrder.getDefault(),
+ 0, null, false, null, false, false, PK_NAME_BYTES, HConstants.LATEST_TIMESTAMP);
+ public static final String ASC_OR_DESC = "ASC_OR_DESC";
+ public static final byte[] ASC_OR_DESC_BYTES = Bytes.toBytes(ASC_OR_DESC);
+ private static final PColumnImpl ASC_OR_DESC_COLUMN = new PColumnImpl(PNameFactory.newName(ASC_OR_DESC),
+ PNameFactory.newName(TABLE_FAMILY_BYTES), PVarchar.INSTANCE, null, null, false, 1, SortOrder.getDefault(),
+ 0, null, false, null, false, false, ASC_OR_DESC_BYTES, HConstants.LATEST_TIMESTAMP);
private static final List<PColumnImpl> PK_DATUM_LIST = Lists.newArrayList(TENANT_ID_COLUMN, TABLE_SCHEM_COLUMN, TABLE_NAME_COLUMN, COLUMN_NAME_COLUMN);
@@ -647,6 +657,43 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
new KeyValueColumnExpression(KEY_SEQ_COLUMN), false)
), 0, true);
+ private static final RowProjector GET_PRIMARY_KEYS_ROW_PROJECTOR =
+ new RowProjector(
+ Arrays.<ColumnProjector> asList(
+ new ExpressionProjector(TABLE_CAT, SYSTEM_CATALOG,
+ new RowKeyColumnExpression(TENANT_ID_COLUMN,
+ new RowKeyValueAccessor(PK_DATUM_LIST, 0)),
+ false),
+ new ExpressionProjector(TABLE_SCHEM, SYSTEM_CATALOG,
+ new RowKeyColumnExpression(TABLE_SCHEM_COLUMN,
+ new RowKeyValueAccessor(PK_DATUM_LIST, 1)),
+ false),
+ new ExpressionProjector(TABLE_NAME, SYSTEM_CATALOG,
+ new RowKeyColumnExpression(TABLE_NAME_COLUMN,
+ new RowKeyValueAccessor(PK_DATUM_LIST, 2)),
+ false),
+ new ExpressionProjector(COLUMN_NAME, SYSTEM_CATALOG,
+ new RowKeyColumnExpression(COLUMN_NAME_COLUMN,
+ new RowKeyValueAccessor(PK_DATUM_LIST, 3)),
+ false),
+ new ExpressionProjector(KEY_SEQ, SYSTEM_CATALOG,
+ new KeyValueColumnExpression(KEY_SEQ_COLUMN), false),
+ new ExpressionProjector(PK_NAME, SYSTEM_CATALOG,
+ new KeyValueColumnExpression(PK_NAME_COLUMN), false),
+ new ExpressionProjector(ASC_OR_DESC, SYSTEM_CATALOG,
+ new KeyValueColumnExpression(ASC_OR_DESC_COLUMN), false),
+ new ExpressionProjector(DATA_TYPE, SYSTEM_CATALOG,
+ new KeyValueColumnExpression(DATA_TYPE_COLUMN), false),
+ new ExpressionProjector(TYPE_NAME, SYSTEM_CATALOG,
+ new KeyValueColumnExpression(TYPE_NAME_COLUMN), false),
+ new ExpressionProjector(COLUMN_SIZE, SYSTEM_CATALOG,
+ new KeyValueColumnExpression(COLUMN_SIZE_COLUMN), false),
+ new ExpressionProjector(TYPE_ID, SYSTEM_CATALOG,
+ new KeyValueColumnExpression(TYPE_ID_COLUMN), false),
+ new ExpressionProjector(VIEW_CONSTANT, SYSTEM_CATALOG,
+ new KeyValueColumnExpression(VIEW_CONSTANT_COLUMN), false)),
+ 0, true);
+
private boolean match(String str, String pattern) throws SQLException {
LiteralExpression strExpr = LiteralExpression.newConstant(str, PVarchar.INSTANCE, SortOrder.ASC);
LiteralExpression patternExpr = LiteralExpression.newConstant(pattern, PVarchar.INSTANCE, SortOrder.ASC);
@@ -686,10 +733,12 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
String tableName = rs.getString(TABLE_NAME);
String tenantId = rs.getString(TABLE_CAT);
String fullTableName = SchemaUtil.getTableName(schemaName, tableName);
- PTable table = PhoenixRuntime.getTable(connection, fullTableName);
+ PTable table = PhoenixRuntime.getTableNoCache(connection, fullTableName);
boolean isSalted = table.getBucketNum()!=null;
boolean tenantColSkipped = false;
- for (PColumn column : table.getColumns()) {
+ List<PColumn> columns = table.getColumns();
+ columns = Lists.newArrayList(columns.subList(isSalted ? 1 : 0, columns.size()));
+ for (PColumn column : columns) {
if (isTenantSpecificConnection && column.equals(table.getPKColumns().get(0))) {
// skip the tenant column
tenantColSkipped = true;
@@ -1080,33 +1129,88 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
}
@Override
- public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
- if (table == null || table.length() == 0) {
+ public ResultSet getPrimaryKeys(String catalog, String schemaName, String tableName)
+ throws SQLException {
+ if (tableName == null || tableName.length() == 0) {
return emptyResultSet;
}
- StringBuilder buf = new StringBuilder("select \n" +
- TENANT_ID + " " + TABLE_CAT + "," + // use catalog for tenant_id
- TABLE_SCHEM + "," +
- TABLE_NAME + " ," +
- COLUMN_NAME + "," +
- KEY_SEQ + "," +
- PK_NAME + "," +
- "CASE WHEN " + SORT_ORDER + " = " + (SortOrder.DESC.getSystemValue()) + " THEN 'D' ELSE 'A' END ASC_OR_DESC," +
- ExternalSqlTypeIdFunction.NAME + "(" + DATA_TYPE + ") AS " + DATA_TYPE + "," +
- SqlTypeNameFunction.NAME + "(" + DATA_TYPE + ") AS " + TYPE_NAME + "," +
- COLUMN_SIZE + "," +
- DATA_TYPE + " " + TYPE_ID + "," + // raw type id
- VIEW_CONSTANT +
- " from " + SYSTEM_CATALOG + " " + SYSTEM_CATALOG_ALIAS +
- " where ");
- buf.append(TABLE_SCHEM + (schema == null || schema.length() == 0 ? " is null" : " = '" + StringUtil.escapeStringConstant(schema) + "'" ));
- buf.append(" and " + TABLE_NAME + " = '" + StringUtil.escapeStringConstant(table) + "'" );
- buf.append(" and " + COLUMN_NAME + " is not null");
- buf.append(" and " + COLUMN_FAMILY + " is null");
- addTenantIdFilter(buf, catalog);
- buf.append(" order by " + TENANT_ID + "," + TABLE_SCHEM + "," + TABLE_NAME + " ," + COLUMN_NAME);
- ResultSet rs = connection.createStatement().executeQuery(buf.toString());
- return rs;
+ List<Tuple> tuples = Lists.newArrayListWithExpectedSize(10);
+ ResultSet rs = getTables(catalog, schemaName, tableName, null);
+ while (rs.next()) {
+ String tenantId = rs.getString(TABLE_CAT);
+ String fullTableName = SchemaUtil.getTableName(schemaName, tableName);
+ PTable table = PhoenixRuntime.getTableNoCache(connection, fullTableName);
+ boolean isSalted = table.getBucketNum() != null;
+ boolean tenantColSkipped = false;
+ List<PColumn> pkColumns = table.getPKColumns();
+ List<PColumn> sorderPkColumns =
+ Lists.newArrayList(pkColumns.subList(isSalted ? 1 : 0, pkColumns.size()));
+ // sort the columns by name
+ Collections.sort(sorderPkColumns, new Comparator<PColumn>(){
+ @Override public int compare(PColumn c1, PColumn c2) {
+ return c1.getName().getString().compareTo(c2.getName().getString());
+ }
+ });
+
+ for (PColumn column : sorderPkColumns) {
+ String columnName = column.getName().getString();
+ // generate row key
+ // TENANT_ID, TABLE_SCHEM, TABLE_NAME , COLUMN_NAME are row key columns
+ byte[] rowKey =
+ SchemaUtil.getColumnKey(tenantId, schemaName, tableName, columnName, null);
+
+ // add one cell for each column info
+ List<Cell> cells = Lists.newArrayListWithCapacity(8);
+ // KEY_SEQ_COLUMN
+ byte[] keySeqBytes = ByteUtil.EMPTY_BYTE_ARRAY;
+ int pkPos = pkColumns.indexOf(column);
+ if (pkPos != -1) {
+ short keySeq =
+ (short) (pkPos + 1 - (isSalted ? 1 : 0) - (tenantColSkipped ? 1 : 0));
+ keySeqBytes = PSmallint.INSTANCE.toBytes(keySeq);
+ }
+ cells.add(KeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES, KEY_SEQ_BYTES,
+ MetaDataProtocol.MIN_TABLE_TIMESTAMP, keySeqBytes));
+ // PK_NAME
+ cells.add(KeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES, PK_NAME_BYTES,
+ MetaDataProtocol.MIN_TABLE_TIMESTAMP, table.getPKName() != null
+ ? table.getPKName().getBytes() : ByteUtil.EMPTY_BYTE_ARRAY));
+ // ASC_OR_DESC
+ char sortOrder = column.getSortOrder() == SortOrder.ASC ? 'A' : 'D';
+ cells.add(KeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ ASC_OR_DESC_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ Bytes.toBytes(sortOrder)));
+ // DATA_TYPE
+ cells.add(KeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES, DATA_TYPE_BYTES,
+ MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ PInteger.INSTANCE.toBytes(column.getDataType().getResultSetSqlType())));
+ // TYPE_NAME
+ cells.add(KeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(TYPE_NAME), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ column.getDataType().getSqlTypeNameBytes()));
+ // COLUMN_SIZE
+ cells.add(
+ KeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES, COLUMN_SIZE_BYTES,
+ MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ column.getMaxLength() != null
+ ? PInteger.INSTANCE.toBytes(column.getMaxLength())
+ : ByteUtil.EMPTY_BYTE_ARRAY));
+ // TYPE_ID
+ cells.add(KeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(TYPE_ID), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ PInteger.INSTANCE.toBytes(column.getDataType().getSqlType())));
+ // VIEW_CONSTANT
+ cells.add(KeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES, VIEW_CONSTANT_BYTES,
+ MetaDataProtocol.MIN_TABLE_TIMESTAMP, column.getViewConstant() != null
+ ? column.getViewConstant() : ByteUtil.EMPTY_BYTE_ARRAY));
+ Collections.sort(cells, new CellComparator());
+ Tuple tuple = new MultiKeyValueTuple(cells);
+ tuples.add(tuple);
+ }
+ }
+ return new PhoenixResultSet(new MaterializedResultIterator(tuples),
+ GET_PRIMARY_KEYS_ROW_PROJECTOR,
+ new StatementContext(new PhoenixStatement(connection), false));
}
@Override
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3467445/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
index 50bb722..bf2bc59 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
@@ -81,6 +81,11 @@ public class DelegateTable implements PTable {
public List<PColumn> getColumns() {
return delegate.getColumns();
}
+
+ @Override
+ public List<PColumn> getExcludedColumns() {
+ return delegate.getExcludedColumns();
+ }
@Override
public List<PColumnFamily> getColumnFamilies() {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3467445/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 649f4c6..d4f4ae3 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
@@ -198,8 +198,6 @@ import org.apache.phoenix.parse.PSchema;
import org.apache.phoenix.parse.ParseNode;
import org.apache.phoenix.parse.ParseNodeFactory;
import org.apache.phoenix.parse.PrimaryKeyConstraint;
-import org.apache.phoenix.parse.SQLParser;
-import org.apache.phoenix.parse.SelectStatement;
import org.apache.phoenix.parse.TableName;
import org.apache.phoenix.parse.UpdateStatisticsStatement;
import org.apache.phoenix.parse.UseSchemaStatement;
@@ -2456,7 +2454,7 @@ public class MetaDataClient {
.build().buildException();
}
if (tableType == PTableType.VIEW && viewType != ViewType.MAPPED) {
- throwIfLastPKOfParentIsFixedLength(parent, schemaName, tableName, colDef);
+ throwIfLastPKOfParentIsVariableLength(parent, schemaName, tableName, colDef);
}
if (!pkColumns.add(column)) {
throw new ColumnAlreadyExistsException(schemaName, tableName, column.getName().getString());
@@ -3391,7 +3389,7 @@ public class MetaDataClient {
}
}
if (colDef != null && colDef.isPK() && table.getType() == VIEW && table.getViewType() != MAPPED) {
- throwIfLastPKOfParentIsFixedLength(getParentOfView(table), schemaName, tableName, colDef);
+ throwIfLastPKOfParentIsVariableLength(getParentOfView(table), schemaName, tableName, colDef);
}
if (colDef != null && colDef.isRowTimestamp()) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.ROWTIMESTAMP_CREATE_ONLY)
@@ -3898,11 +3896,21 @@ public class MetaDataClient {
Map<String, List<TableRef>> tenantIdTableRefMap = Maps.newHashMap();
if (result.getSharedTablesToDelete() != null) {
for (SharedTableState sharedTableState : result.getSharedTablesToDelete()) {
- PTableImpl viewIndexTable = new PTableImpl(sharedTableState.getTenantId(),
- sharedTableState.getSchemaName(), sharedTableState.getTableName(), ts,
- table.getColumnFamilies(), sharedTableState.getColumns(),
- sharedTableState.getPhysicalNames(), sharedTableState.getViewIndexType(), sharedTableState.getViewIndexId(),
- table.isMultiTenant(), table.isNamespaceMapped(), table.getImmutableStorageScheme(), table.getEncodingScheme(), table.getEncodedCQCounter(), table.useStatsForParallelization());
+ PTableImpl viewIndexTable =
+ new PTableImpl(sharedTableState.getTenantId(),
+ sharedTableState.getSchemaName(),
+ sharedTableState.getTableName(), ts,
+ table.getColumnFamilies(),
+ sharedTableState.getColumns(),
+ sharedTableState.getPhysicalNames(),
+ sharedTableState.getViewIndexType(),
+ sharedTableState.getViewIndexId(),
+ table.isMultiTenant(), table.isNamespaceMapped(),
+ table.getImmutableStorageScheme(),
+ table.getEncodingScheme(),
+ table.getEncodedCQCounter(),
+ table.useStatsForParallelization(),
+ table.getBucketNum());
TableRef indexTableRef = new TableRef(viewIndexTable);
PName indexTableTenantId = sharedTableState.getTenantId();
if (indexTableTenantId==null) {
@@ -4119,7 +4127,11 @@ public class MetaDataClient {
connection.addSchema(result.getSchema());
}
- private void throwIfLastPKOfParentIsFixedLength(PTable parent, String viewSchemaName, String viewName, ColumnDef col) throws SQLException {
+ private void throwIfLastPKOfParentIsVariableLength(PTable parent, String viewSchemaName, String viewName, ColumnDef col) throws SQLException {
+ // if the last pk column is variable length then we read all the
+ // bytes of the rowkey without looking for a separator byte see
+ // https://issues.apache.org/jira/browse/PHOENIX-978?focusedCommentId=14617847&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-14617847
+ // so we cannot add a pk column to a view if the last pk column of the parent is variable length
if (isLastPKVariableLength(parent)) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_MODIFY_VIEW_PK)
.setSchemaName(viewSchemaName)
@@ -4134,10 +4146,8 @@ public class MetaDataClient {
}
private PTable getParentOfView(PTable view) throws SQLException {
- //TODO just use view.getParentName().getString() after implementing https://issues.apache.org/jira/browse/PHOENIX-2114
- SelectStatement select = new SQLParser(view.getViewStatement()).parseQuery();
- String parentName = SchemaUtil.normalizeFullTableName(select.getFrom().toString().trim());
- return connection.getTable(new PTableKey(view.getTenantId(), parentName));
+ return connection
+ .getTable(new PTableKey(view.getTenantId(), view.getParentName().getString()));
}
public MutationState createSchema(CreateSchemaStatement create) throws SQLException {