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 2016/05/10 23:05:15 UTC
[1/2] phoenix git commit: PHOENIX-2791 Support append only schema
declaration
Repository: phoenix
Updated Branches:
refs/heads/master a8a3616fe -> a0504fba1
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/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 076264a..70414d5 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
@@ -140,6 +140,7 @@ public class PTableImpl implements PTable {
private long updateCacheFrequency;
private boolean isNamespaceMapped;
private String autoPartitionSeqName;
+ private boolean isAppendOnlySchema;
public PTableImpl() {
this.indexes = Collections.emptyList();
@@ -185,7 +186,7 @@ public class PTableImpl implements PTable {
init(tenantId, this.schemaName, this.tableName, PTableType.INDEX, state, timeStamp, sequenceNumber, pkName, bucketNum, columns,
PTableStats.EMPTY_STATS, this.schemaName, parentTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
null, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
- isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMpped, null);
+ isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMpped, null, false);
}
public PTableImpl(long timeStamp) { // For delete marker
@@ -228,7 +229,8 @@ public class PTableImpl implements PTable {
table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), getColumnsToClone(table), parentSchemaName, table.getParentTableName(),
indexes, table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), viewStatement,
table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
- table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName());
+ table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(),
+ table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName(), table.isAppendOnlySchema());
}
public static PTableImpl makePTable(PTable table, List<PColumn> columns) throws SQLException {
@@ -237,7 +239,8 @@ public class PTableImpl implements PTable {
table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(),
table.getIndexes(), table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
- table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName());
+ table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(),
+ table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName(), table.isAppendOnlySchema());
}
public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns) throws SQLException {
@@ -246,7 +249,8 @@ public class PTableImpl implements PTable {
sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(),
table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(),
- table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName());
+ table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(),
+ table.isNamespaceMapped(), table.getAutoPartitionSeqName(), table.isAppendOnlySchema());
}
public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns, boolean isImmutableRows) throws SQLException {
@@ -255,7 +259,8 @@ public class PTableImpl implements PTable {
sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(),
table.getIndexes(), isImmutableRows, table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(),
- table.getIndexType(), table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName());
+ table.getIndexType(), table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(),
+ table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName(), table.isAppendOnlySchema());
}
public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns, boolean isImmutableRows, boolean isWalDisabled,
@@ -265,7 +270,8 @@ public class PTableImpl implements PTable {
sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(),
table.getIndexes(), isImmutableRows, table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
isWalDisabled, isMultitenant, storeNulls, table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(),
- table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), isTransactional, updateCacheFrequency, table.getIndexDisableTimestamp(), isNamespaceMapped, table.getAutoPartitionSeqName());
+ table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), isTransactional, updateCacheFrequency, table.getIndexDisableTimestamp(),
+ isNamespaceMapped, table.getAutoPartitionSeqName(), table.isAppendOnlySchema());
}
public static PTableImpl makePTable(PTable table, PIndexState state) throws SQLException {
@@ -275,7 +281,8 @@ public class PTableImpl implements PTable {
table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
- table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName());
+ table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(),
+ table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName(), table.isAppendOnlySchema());
}
public static PTableImpl makePTable(PTable table, boolean rowKeyOrderOptimizable) throws SQLException {
@@ -285,7 +292,8 @@ public class PTableImpl implements PTable {
table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(),
- table.getBaseColumnCount(), rowKeyOrderOptimizable, table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName());
+ table.getBaseColumnCount(), rowKeyOrderOptimizable, table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(),
+ table.getAutoPartitionSeqName(), table.isAppendOnlySchema());
}
public static PTableImpl makePTable(PTable table, PTableStats stats) throws SQLException {
@@ -295,7 +303,8 @@ public class PTableImpl implements PTable {
table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), stats,
- table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName());
+ table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(),
+ table.isNamespaceMapped(), table.getAutoPartitionSeqName(), table.isAppendOnlySchema());
}
public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type,
@@ -304,12 +313,12 @@ public class PTableImpl implements PTable {
boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression,
boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId,
IndexType indexType, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency,
- long indexDisableTimestamp, boolean isNamespaceMapped, String autoPartitionSeqName) throws SQLException {
+ long indexDisableTimestamp, boolean isNamespaceMapped, String autoPartitionSeqName, boolean isAppendOnlySchema) throws SQLException {
return new PTableImpl(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName, bucketNum, columns, dataSchemaName,
dataTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId,
indexType, PTableStats.EMPTY_STATS, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, rowKeyOrderOptimizable, isTransactional,
- updateCacheFrequency,indexDisableTimestamp, isNamespaceMapped, autoPartitionSeqName);
+ updateCacheFrequency,indexDisableTimestamp, isNamespaceMapped, autoPartitionSeqName, isAppendOnlySchema);
}
public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type,
@@ -318,12 +327,14 @@ public class PTableImpl implements PTable {
boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression,
boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId,
IndexType indexType, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency,
- @NotNull PTableStats stats, int baseColumnCount, long indexDisableTimestamp, boolean isNamespaceMapped, String autoPartitionSeqName)
+ @NotNull PTableStats stats, int baseColumnCount, long indexDisableTimestamp, boolean isNamespaceMapped,
+ String autoPartitionSeqName, boolean isAppendOnlySchema)
throws SQLException {
return new PTableImpl(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName,
bucketNum, columns, dataSchemaName, dataTableName, indexes, isImmutableRows, physicalNames,
defaultFamilyName, viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId,
- indexType, stats, baseColumnCount, rowKeyOrderOptimizable, isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, autoPartitionSeqName);
+ indexType, stats, baseColumnCount, rowKeyOrderOptimizable, isTransactional, updateCacheFrequency,
+ indexDisableTimestamp, isNamespaceMapped, autoPartitionSeqName, isAppendOnlySchema);
}
private PTableImpl(PName tenantId, PName schemaName, PName tableName, PTableType type, PIndexState state,
@@ -331,11 +342,12 @@ public class PTableImpl implements PTable {
PName parentSchemaName, PName parentTableName, List<PTable> indexes, boolean isImmutableRows,
List<PName> physicalNames, PName defaultFamilyName, String viewExpression, boolean disableWAL, boolean multiTenant,
boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType,
- PTableStats stats, int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp, boolean isNamespaceMapped, String autoPartitionSeqName) throws SQLException {
+ PTableStats stats, int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency,
+ long indexDisableTimestamp, boolean isNamespaceMapped, String autoPartitionSeqName, boolean isAppendOnlySchema) throws SQLException {
init(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName, bucketNum, columns,
stats, schemaName, parentTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
- isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, autoPartitionSeqName);
+ isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, autoPartitionSeqName, isAppendOnlySchema);
}
@Override
@@ -368,7 +380,8 @@ public class PTableImpl implements PTable {
PName pkName, Integer bucketNum, List<PColumn> columns, PTableStats stats, PName parentSchemaName, PName parentTableName,
List<PTable> indexes, boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression, boolean disableWAL,
boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId,
- IndexType indexType , int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp, boolean isNamespaceMapped, String autoPartitionSeqName) throws SQLException {
+ IndexType indexType , int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp,
+ boolean isNamespaceMapped, String autoPartitionSeqName, boolean isAppendOnlySchema) 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 +
@@ -404,6 +417,7 @@ public class PTableImpl implements PTable {
this.updateCacheFrequency = updateCacheFrequency;
this.isNamespaceMapped = isNamespaceMapped;
this.autoPartitionSeqName = autoPartitionSeqName;
+ this.isAppendOnlySchema = isAppendOnlySchema;
List<PColumn> pkColumns;
PColumn[] allColumns;
@@ -1110,6 +1124,10 @@ public class PTableImpl implements PTable {
if (table.hasAutoParititonSeqName()) {
autoParititonSeqName = table.getAutoParititonSeqName();
}
+ boolean isAppendOnlySchema = false;
+ if (table.hasIsAppendOnlySchema()) {
+ isAppendOnlySchema = table.getIsAppendOnlySchema();
+ }
try {
PTableImpl result = new PTableImpl();
@@ -1117,7 +1135,7 @@ public class PTableImpl implements PTable {
(bucketNum == NO_SALTING) ? null : bucketNum, columns, stats, schemaName,dataTableName, indexes,
isImmutableRows, physicalNames, defaultFamilyName, viewStatement, disableWAL,
multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
- isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, autoParititonSeqName);
+ isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, autoParititonSeqName, isAppendOnlySchema);
return result;
} catch (SQLException e) {
throw new RuntimeException(e); // Impossible
@@ -1212,6 +1230,7 @@ public class PTableImpl implements PTable {
if (table.getAutoPartitionSeqName()!= null) {
builder.setAutoParititonSeqName(table.getAutoPartitionSeqName());
}
+ builder.setIsAppendOnlySchema(table.isAppendOnlySchema());
return builder.build();
}
@@ -1255,7 +1274,13 @@ public class PTableImpl implements PTable {
return isNamespaceMapped;
}
+ @Override
public String getAutoPartitionSeqName() {
return autoPartitionSeqName;
}
+
+ @Override
+ public boolean isAppendOnlySchema() {
+ return isAppendOnlySchema;
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java
index abfc8a5..7e521e6 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java
@@ -69,9 +69,10 @@ public enum TableProperty {
},
AUTO_PARTITION_SEQ(PhoenixDatabaseMetaData.AUTO_PARTITION_SEQ, COLUMN_FAMILY_NOT_ALLOWED_TABLE_PROPERTY, false, false),
+
+ APPEND_ONLY_SCHEMA(PhoenixDatabaseMetaData.APPEND_ONLY_SCHEMA, COLUMN_FAMILY_NOT_ALLOWED_TABLE_PROPERTY, true, true),
;
-
private final String propertyName;
private final SQLExceptionCode colFamSpecifiedException;
private final boolean isMutable; // whether or not a property can be changed through statements like ALTER TABLE.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java
index 52c5c71..995f44b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java
@@ -36,6 +36,7 @@ import java.util.Set;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
+import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionLocation;
import org.apache.hadoop.hbase.HTableDescriptor;
@@ -69,6 +70,7 @@ import org.apache.phoenix.schema.PTableType;
import org.apache.phoenix.schema.SequenceKey;
import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.schema.TableProperty;
import org.apache.phoenix.schema.types.PBoolean;
import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.schema.types.PLong;
@@ -533,7 +535,7 @@ public class MetaDataUtil {
}
public static String getAutoPartitionColumnName(PTable parentTable) {
- List<PColumn> parentTableColumns = parentTable.getColumns();
+ List<PColumn> parentTableColumns = parentTable.getPKColumns();
PColumn column = parentTableColumns.get(getAutoPartitionColIndex(parentTable));
return column.getName().getString();
}
@@ -555,4 +557,12 @@ public class MetaDataUtil {
+ PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR + zkClientPort
+ PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR + zkParentNode;
}
+
+ public static boolean isHColumnProperty(String propName) {
+ return HColumnDescriptor.getDefaultValues().containsKey(propName);
+ }
+
+ public static boolean isHTableProperty(String propName) {
+ return !isHColumnProperty(propName) && !TableProperty.isPhoenixTableProperty(propName);
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
index aaf158a..62aafa5 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
@@ -256,7 +256,7 @@ public class CorrelatePlanTest {
PTableType.SUBQUERY, null, MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM,
null, null, columns, null, null, Collections.<PTable>emptyList(),
false, Collections.<PName>emptyList(), null, null, false, false, false, null,
- null, null, true, false, 0, 0L, Boolean.FALSE, null);
+ null, null, true, false, 0, 0L, Boolean.FALSE, null, false);
TableRef sourceTable = new TableRef(pTable);
List<ColumnRef> sourceColumnRefs = Lists.<ColumnRef> newArrayList();
for (PColumn column : sourceTable.getTable().getColumns()) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
index 04ed6b4..1b16d40 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
@@ -177,7 +177,7 @@ public class LiteralResultIteratorPlanTest {
PTable pTable = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME, PTableType.SUBQUERY, null,
MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM, null, null, columns, null, null,
Collections.<PTable> emptyList(), false, Collections.<PName> emptyList(), null, null, false, false,
- false, null, null, null, true, false, 0, 0L, false, null);
+ false, null, null, null, true, false, 0, 0L, false, null, false);
TableRef sourceTable = new TableRef(pTable);
List<ColumnRef> sourceColumnRefs = Lists.<ColumnRef> newArrayList();
for (PColumn column : sourceTable.getTable().getColumns()) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/phoenix-protocol/src/main/PTable.proto
----------------------------------------------------------------------
diff --git a/phoenix-protocol/src/main/PTable.proto b/phoenix-protocol/src/main/PTable.proto
index 9521fba..2696430 100644
--- a/phoenix-protocol/src/main/PTable.proto
+++ b/phoenix-protocol/src/main/PTable.proto
@@ -92,4 +92,5 @@ message PTable {
optional int64 indexDisableTimestamp = 29;
optional bool isNamespaceMapped = 30;
optional string autoParititonSeqName = 31;
+ optional bool isAppendOnlySchema = 32;
}
[2/2] phoenix git commit: PHOENIX-2791 Support append only schema
declaration
Posted by td...@apache.org.
PHOENIX-2791 Support append only schema declaration
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/a0504fba
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/a0504fba
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/a0504fba
Branch: refs/heads/master
Commit: a0504fba12363eaa27ea3fd224671e92cb11a468
Parents: a8a3616
Author: Thomas D'Silva <td...@salesforce.com>
Authored: Thu May 5 15:38:18 2016 -0700
Committer: Thomas D'Silva <tw...@gmail.com>
Committed: Tue May 10 15:10:25 2016 -0700
----------------------------------------------------------------------
.../phoenix/end2end/AppendOnlySchemaIT.java | 330 +++++++++++++++++++
.../phoenix/end2end/AutoPartitionViewsIT.java | 6 +-
.../apache/phoenix/compile/FromCompiler.java | 2 +-
.../apache/phoenix/compile/JoinCompiler.java | 3 +-
.../compile/TupleProjectionCompiler.java | 5 +-
.../apache/phoenix/compile/UnionCompiler.java | 2 +-
.../coprocessor/MetaDataEndpointImpl.java | 17 +-
.../coprocessor/generated/PTableProtos.java | 103 +++++-
.../phoenix/exception/SQLExceptionCode.java | 4 +
.../phoenix/jdbc/PhoenixDatabaseMetaData.java | 3 +
.../org/apache/phoenix/parse/ColumnDef.java | 7 +-
.../query/ConnectionQueryServicesImpl.java | 26 +-
.../apache/phoenix/query/QueryConstants.java | 2 +
.../apache/phoenix/schema/DelegateTable.java | 6 +
.../apache/phoenix/schema/MetaDataClient.java | 203 +++++++++---
.../java/org/apache/phoenix/schema/PTable.java | 9 +-
.../org/apache/phoenix/schema/PTableImpl.java | 59 +++-
.../apache/phoenix/schema/TableProperty.java | 3 +-
.../org/apache/phoenix/util/MetaDataUtil.java | 12 +-
.../phoenix/execute/CorrelatePlanTest.java | 2 +-
.../execute/LiteralResultIteratorPlanTest.java | 2 +-
phoenix-protocol/src/main/PTable.proto | 1 +
22 files changed, 706 insertions(+), 101 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/phoenix-core/src/it/java/org/apache/phoenix/end2end/AppendOnlySchemaIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AppendOnlySchemaIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AppendOnlySchemaIT.java
new file mode 100644
index 0000000..d764445
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AppendOnlySchemaIT.java
@@ -0,0 +1,330 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.end2end;
+
+import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyList;
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyMap;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.client.Mutation;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixEmbeddedDriver;
+import org.apache.phoenix.query.ConnectionQueryServices;
+import org.apache.phoenix.schema.PColumn;
+import org.apache.phoenix.schema.PName;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTableKey;
+import org.apache.phoenix.schema.PTableType;
+import org.apache.phoenix.schema.TableAlreadyExistsException;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class AppendOnlySchemaIT extends BaseHBaseManagedTimeIT {
+
+ private void createTableWithSameSchema(boolean notExists, boolean sameClient) throws Exception {
+ // use a spyed ConnectionQueryServices so we can verify calls to getTable
+ ConnectionQueryServices connectionQueryServices =
+ Mockito.spy(driver.getConnectionQueryServices(getUrl(),
+ PropertiesUtil.deepCopy(TEST_PROPERTIES)));
+ Properties props = new Properties();
+ props.putAll(PhoenixEmbeddedDriver.DEFFAULT_PROPS.asMap());
+
+ try (Connection conn1 = connectionQueryServices.connect(getUrl(), props);
+ Connection conn2 = sameClient ? conn1 : connectionQueryServices.connect(getUrl(), props)) {
+ // create sequence for auto partition
+ conn1.createStatement().execute("CREATE SEQUENCE metric_id_seq CACHE 1");
+ // create base table
+ conn1.createStatement().execute("CREATE TABLE metric_table (metricId INTEGER NOT NULL, metricVal DOUBLE, CONSTRAINT PK PRIMARY KEY(metricId))"
+ + " APPEND_ONLY_SCHEMA = true, UPDATE_CACHE_FREQUENCY=1, AUTO_PARTITION_SEQ=metric_id_seq");
+ // create view
+ String ddl =
+ "CREATE VIEW " + (notExists ? "IF NOT EXISTS" : "")
+ + " view1( hostName varchar NOT NULL,"
+ + " CONSTRAINT HOSTNAME_PK PRIMARY KEY (hostName))"
+ + " AS SELECT * FROM metric_table"
+ + " APPEND_ONLY_SCHEMA = true, UPDATE_CACHE_FREQUENCY=300000";
+ conn1.createStatement().execute(ddl);
+ conn1.createStatement().execute("UPSERT INTO view1(hostName, metricVal) VALUES('host1', 1.0)");
+ conn1.commit();
+ reset(connectionQueryServices);
+
+ // execute same ddl
+ try {
+ conn2.createStatement().execute(ddl);
+ if (!notExists) {
+ fail("Create Table should fail");
+ }
+ }
+ catch (TableAlreadyExistsException e) {
+ if (notExists) {
+ fail("Create Table should not fail");
+ }
+ }
+
+ // verify getTable rpcs
+ verify(connectionQueryServices, sameClient ? never() : atMost(1)).getTable((PName)isNull(), eq(new byte[0]), eq(Bytes.toBytes("VIEW1")), anyLong(), anyLong());
+
+ // verify create table rpcs
+ verify(connectionQueryServices, never()).createTable(anyListOf(Mutation.class),
+ any(byte[].class), any(PTableType.class), anyMap(), anyList(), any(byte[][].class),
+ eq(false));
+
+ // upsert one row
+ conn2.createStatement().execute("UPSERT INTO view1(hostName, metricVal) VALUES('host2', 2.0)");
+ conn2.commit();
+ // verify data in base table
+ ResultSet rs = conn2.createStatement().executeQuery("SELECT * from metric_table");
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(1.0, rs.getDouble(2), 1e-6);
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(2.0, rs.getDouble(2), 1e-6);
+ assertFalse(rs.next());
+ // verify data in view
+ rs = conn2.createStatement().executeQuery("SELECT * from view1");
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(1.0, rs.getDouble(2), 1e-6);
+ assertEquals("host1", rs.getString(3));
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(2.0, rs.getDouble(2), 1e-6);
+ assertEquals("host2", rs.getString(3));
+ assertFalse(rs.next());
+ }
+ }
+
+ @Test
+ public void testSameSchemaWithNotExistsSameClient() throws Exception {
+ createTableWithSameSchema(true, true);
+ }
+
+ @Test
+ public void testSameSchemaWithNotExistsDifferentClient() throws Exception {
+ createTableWithSameSchema(true, false);
+ }
+
+ @Test
+ public void testSameSchemaSameClient() throws Exception {
+ createTableWithSameSchema(false, true);
+ }
+
+ @Test
+ public void testSameSchemaDifferentClient() throws Exception {
+ createTableWithSameSchema(false, false);
+ }
+
+ private void createTableAddColumns(boolean sameClient) throws Exception {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ try (Connection conn1 = DriverManager.getConnection(getUrl(), props);
+ Connection conn2 = sameClient ? conn1 : DriverManager.getConnection(getUrl(), props)) {
+ // create sequence for auto partition
+ conn1.createStatement().execute("CREATE SEQUENCE metric_id_seq CACHE 1");
+ // create base table
+ conn1.createStatement().execute("CREATE TABLE metric_table (metricId INTEGER NOT NULL, metricVal DOUBLE, CONSTRAINT PK PRIMARY KEY(metricId))"
+ + " APPEND_ONLY_SCHEMA = true, UPDATE_CACHE_FREQUENCY=1, AUTO_PARTITION_SEQ=metric_id_seq");
+ // create view
+ String ddl =
+ "CREATE VIEW IF NOT EXISTS"
+ + " view1( hostName varchar NOT NULL,"
+ + " CONSTRAINT HOSTNAME_PK PRIMARY KEY (hostName))"
+ + " AS SELECT * FROM metric_table"
+ + " APPEND_ONLY_SCHEMA = true, UPDATE_CACHE_FREQUENCY=300000";
+ conn1.createStatement().execute(ddl);
+
+ conn1.createStatement().execute("UPSERT INTO view1(hostName, metricVal) VALUES('host1', 1.0)");
+ conn1.commit();
+
+ // execute ddl adding a pk column and regular column
+ ddl =
+ "CREATE VIEW IF NOT EXISTS"
+ + " view1( hostName varchar NOT NULL, instanceName varchar, metricVal2 double"
+ + " CONSTRAINT HOSTNAME_PK PRIMARY KEY (hostName, instancename))"
+ + " AS SELECT * FROM metric_table"
+ + " APPEND_ONLY_SCHEMA = true, UPDATE_CACHE_FREQUENCY=300000";
+ conn2.createStatement().execute(ddl);
+
+ conn2.createStatement().execute(
+ "UPSERT INTO view1(hostName, instanceName, metricVal, metricval2) VALUES('host2', 'instance2', 21.0, 22.0)");
+ conn2.commit();
+
+ conn1.createStatement().execute("UPSERT INTO view1(hostName, metricVal) VALUES('host3', 3.0)");
+ conn1.commit();
+
+ // verify data exists
+ ResultSet rs = conn2.createStatement().executeQuery("SELECT * from view1");
+
+ // verify the two columns were added correctly
+ PTable table =
+ conn2.unwrap(PhoenixConnection.class).getTable(new PTableKey(null, "VIEW1"));
+ List<PColumn> pkColumns = table.getPKColumns();
+ assertEquals(3,table.getPKColumns().size());
+ assertEquals("METRICID", pkColumns.get(0).getName().getString());
+ assertEquals("HOSTNAME", pkColumns.get(1).getName().getString());
+ assertEquals("INSTANCENAME", pkColumns.get(2).getName().getString());
+ List<PColumn> columns = table.getColumns();
+ assertEquals("METRICID", columns.get(0).getName().getString());
+ assertEquals("METRICVAL", columns.get(1).getName().getString());
+ assertEquals("HOSTNAME", columns.get(2).getName().getString());
+ assertEquals("INSTANCENAME", columns.get(3).getName().getString());
+ assertEquals("METRICVAL2", columns.get(4).getName().getString());
+
+ // verify the data
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(1.0, rs.getDouble(2), 1e-6);
+ assertEquals("host1", rs.getString(3));
+ assertEquals(null, rs.getString(4));
+ assertEquals(0.0, rs.getDouble(5), 1e-6);
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(21.0, rs.getDouble(2), 1e-6);
+ assertEquals("host2", rs.getString(3));
+ assertEquals("instance2", rs.getString(4));
+ assertEquals(22.0, rs.getDouble(5), 1e-6);
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(3.0, rs.getDouble(2), 1e-6);
+ assertEquals("host3", rs.getString(3));
+ assertEquals(null, rs.getString(4));
+ assertEquals(0.0, rs.getDouble(5), 1e-6);
+ assertFalse(rs.next());
+ }
+ }
+
+ @Test
+ public void testCreateTableAddColumnsSameClient() throws Exception {
+ createTableAddColumns(true);
+ }
+
+ @Test
+ public void testCreateTableAddColumnsDifferentClient() throws Exception {
+ createTableAddColumns(false);
+ }
+
+ public void testCreateTableDropColumns() throws Exception {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
+ String ddl =
+ "create table IF NOT EXISTS TEST( id1 char(2) NOT NULL," + " col1 integer,"
+ + " col2 integer," + " CONSTRAINT NAME_PK PRIMARY KEY (id1))"
+ + " APPEND_ONLY_SCHEMA = true, UPDATE_CACHE_FREQUENCY=300000";
+ conn.createStatement().execute(ddl);
+ conn.createStatement().execute("UPSERT INTO TEST VALUES('a', 11)");
+ conn.commit();
+
+ // execute ddl while dropping a column
+ ddl = "alter table TEST drop column col1";
+ try {
+ conn.createStatement().execute(ddl);
+ fail("Dropping a column from a table with APPEND_ONLY_SCHEMA=true should fail");
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.CANNOT_DROP_COL_APPEND_ONLY_SCHEMA.getErrorCode(),
+ e.getErrorCode());
+ }
+ }
+ }
+
+ @Test
+ public void testValidateAttributes() throws Exception {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
+ try {
+ conn.createStatement().execute(
+ "create table IF NOT EXISTS TEST1 ( id char(1) NOT NULL,"
+ + " col1 integer NOT NULL,"
+ + " CONSTRAINT NAME_PK PRIMARY KEY (id, col1))"
+ + " APPEND_ONLY_SCHEMA = true");
+ fail("UPDATE_CACHE_FREQUENCY attribute must not be set to ALWAYS if APPEND_ONLY_SCHEMA is true");
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.UPDATE_CACHE_FREQUENCY_INVALID.getErrorCode(),
+ e.getErrorCode());
+ }
+
+ conn.createStatement().execute(
+ "create table IF NOT EXISTS TEST1 ( id char(1) NOT NULL,"
+ + " col1 integer NOT NULL"
+ + " CONSTRAINT NAME_PK PRIMARY KEY (id, col1))"
+ + " APPEND_ONLY_SCHEMA = true, UPDATE_CACHE_FREQUENCY=1000");
+ try {
+ conn.createStatement().execute(
+ "create view IF NOT EXISTS MY_VIEW (val1 integer NOT NULL) AS SELECT * FROM TEST1"
+ + " UPDATE_CACHE_FREQUENCY=1000");
+ fail("APPEND_ONLY_SCHEMA must be true for a view if it is true for the base table ");
+ }
+ catch (SQLException e) {
+ assertEquals(SQLExceptionCode.VIEW_APPEND_ONLY_SCHEMA.getErrorCode(),
+ e.getErrorCode());
+ }
+ }
+ }
+
+ @Test
+ public void testUpsertRowToDeletedTable() throws Exception {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ try (Connection conn1 = DriverManager.getConnection(getUrl(), props);
+ Connection conn2 = DriverManager.getConnection(getUrl(), props)) {
+ // create sequence for auto partition
+ conn1.createStatement().execute("CREATE SEQUENCE metric_id_seq CACHE 1");
+ // create base table
+ conn1.createStatement().execute("CREATE TABLE metric_table (metricId INTEGER NOT NULL, metricVal DOUBLE, CONSTRAINT PK PRIMARY KEY(metricId))"
+ + " APPEND_ONLY_SCHEMA = true, UPDATE_CACHE_FREQUENCY=1, AUTO_PARTITION_SEQ=metric_id_seq");
+ // create view
+ String ddl =
+ "CREATE VIEW IF NOT EXISTS"
+ + " view1( hostName varchar NOT NULL,"
+ + " CONSTRAINT HOSTNAME_PK PRIMARY KEY (hostName))"
+ + " AS SELECT * FROM metric_table"
+ + " APPEND_ONLY_SCHEMA = true, UPDATE_CACHE_FREQUENCY=300000";
+ conn1.createStatement().execute(ddl);
+
+ // drop the table using a different connection
+ conn2.createStatement().execute("DROP VIEW view1");
+
+ // upsert one row
+ conn1.createStatement().execute("UPSERT INTO view1(hostName, metricVal) VALUES('host1', 1.0)");
+ // upsert doesn't fail since base table still exists
+ conn1.commit();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoPartitionViewsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoPartitionViewsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoPartitionViewsIT.java
index 2b3f932..b21b772 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoPartitionViewsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoPartitionViewsIT.java
@@ -167,11 +167,11 @@ public class AutoPartitionViewsIT extends BaseHBaseManagedTimeIT {
assertTrue("Partition column view referenced attribute should be true ",
partitionCol3.isViewReferenced());
// verify viewConstant was set correctly
- byte[] expectedPartition1 = new byte[Bytes.SIZEOF_LONG + 1];
+ byte[] expectedPartition1 = new byte[Bytes.SIZEOF_INT + 1];
PInteger.INSTANCE.toBytes(Integer.MAX_VALUE - 2, expectedPartition1, 0);
- byte[] expectedPartition2 = new byte[Bytes.SIZEOF_LONG + 1];
+ byte[] expectedPartition2 = new byte[Bytes.SIZEOF_INT + 1];
PInteger.INSTANCE.toBytes(Integer.MAX_VALUE - 1, expectedPartition2, 0);
- byte[] expectedPartition3 = new byte[Bytes.SIZEOF_LONG + 1];
+ byte[] expectedPartition3 = new byte[Bytes.SIZEOF_INT + 1];
PInteger.INSTANCE.toBytes(Integer.MAX_VALUE, expectedPartition3, 0);
assertArrayEquals("Unexpected Partition column view constant attribute",
expectedPartition1, partitionCol1.getViewConstant());
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/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 612adae..ca0a6c3 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
@@ -776,7 +776,7 @@ public class FromCompiler {
MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM, null, null, columns, null, null,
Collections.<PTable> emptyList(), false, Collections.<PName> emptyList(), null, null, false, false,
false, null, null, null, false, false, 0, 0L, SchemaUtil
- .isNamespaceMappingEnabled(PTableType.SUBQUERY, connection.getQueryServices().getProps()), null);
+ .isNamespaceMappingEnabled(PTableType.SUBQUERY, connection.getQueryServices().getProps()), null, false);
String alias = subselectNode.getAlias();
TableRef tableRef = new TableRef(alias, t, MetaDataProtocol.MIN_TABLE_TIMESTAMP, false);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/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 5317b49..4c18bf8 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
@@ -1307,7 +1307,8 @@ public class JoinCompiler {
left.isImmutableRows(), Collections.<PName> emptyList(), null, null, PTable.DEFAULT_DISABLE_WAL,
left.isMultiTenant(), left.getStoreNulls(), left.getViewType(), left.getViewIndexId(),
left.getIndexType(), left.rowKeyOrderOptimizable(), left.isTransactional(),
- left.getUpdateCacheFrequency(), left.getIndexDisableTimestamp(), left.isNamespaceMapped(), left.getAutoPartitionSeqName());
+ left.getUpdateCacheFrequency(), left.getIndexDisableTimestamp(), left.isNamespaceMapped(),
+ left.getAutoPartitionSeqName(), left.isAppendOnlySchema());
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
index 8c3d399..4d3c0cf 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
@@ -153,7 +153,8 @@ public class TupleProjectionCompiler {
table.getParentName(), table.getIndexes(), table.isImmutableRows(), Collections.<PName> emptyList(),
null, null, table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(),
table.getViewIndexId(),
- table.getIndexType(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName());
+ table.getIndexType(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(),
+ table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName(), table.isAppendOnlySchema());
}
public static PTable createProjectedTable(TableRef tableRef, List<ColumnRef> sourceColumnRefs, boolean retainPKColumns) throws SQLException {
@@ -181,7 +182,7 @@ public class TupleProjectionCompiler {
Collections.<PTable> emptyList(), table.isImmutableRows(), Collections.<PName> emptyList(), null, null,
table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(),
table.getViewIndexId(), null, table.rowKeyOrderOptimizable(), table.isTransactional(),
- table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName());
+ table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName(), table.isAppendOnlySchema());
}
// For extracting column references from single select statement
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
index 71cd7fc..8dd350c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
@@ -85,7 +85,7 @@ public class UnionCompiler {
scn == null ? HConstants.LATEST_TIMESTAMP : scn, null, null, projectedColumns, null, null, null, true,
null, null, null, true, true, true, null, null, null, false, false, 0, 0L,
SchemaUtil.isNamespaceMappingEnabled(PTableType.SUBQUERY,
- statement.getConnection().getQueryServices().getProps()), null);
+ statement.getConnection().getQueryServices().getProps()), null, false);
TableRef tableRef = new TableRef(null, tempTable, 0, false);
return tableRef;
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/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 25483a3..7f222bb 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
@@ -20,6 +20,7 @@ package org.apache.phoenix.coprocessor;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static org.apache.hadoop.hbase.KeyValueUtil.createFirstOnRow;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.APPEND_ONLY_SCHEMA_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ARRAY_SIZE_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.AUTO_PARTITION_SEQ_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CLASS_NAME_BYTES;
@@ -277,6 +278,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
private static final KeyValue IS_NAMESPACE_MAPPED_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY,
TABLE_FAMILY_BYTES, IS_NAMESPACE_MAPPED_BYTES);
private static final KeyValue AUTO_PARTITION_SEQ_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, AUTO_PARTITION_SEQ_BYTES);
+ private static final KeyValue APPEND_ONLY_SCHEMA_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, APPEND_ONLY_SCHEMA_BYTES);
private static final List<KeyValue> TABLE_KV_COLUMNS = Arrays.<KeyValue>asList(
EMPTY_KEYVALUE_KV,
@@ -302,7 +304,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
TRANSACTIONAL_KV,
UPDATE_CACHE_FREQUENCY_KV,
IS_NAMESPACE_MAPPED_KV,
- AUTO_PARTITION_SEQ_KV
+ AUTO_PARTITION_SEQ_KV,
+ APPEND_ONLY_SCHEMA_KV
);
static {
Collections.sort(TABLE_KV_COLUMNS, KeyValue.COMPARATOR);
@@ -331,6 +334,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
private static final int INDEX_DISABLE_TIMESTAMP = TABLE_KV_COLUMNS.indexOf(INDEX_DISABLE_TIMESTAMP_KV);
private static final int IS_NAMESPACE_MAPPED_INDEX = TABLE_KV_COLUMNS.indexOf(IS_NAMESPACE_MAPPED_KV);
private static final int AUTO_PARTITION_SEQ_INDEX = TABLE_KV_COLUMNS.indexOf(AUTO_PARTITION_SEQ_KV);
+ private static final int APPEND_ONLY_SCHEMA_INDEX = TABLE_KV_COLUMNS.indexOf(APPEND_ONLY_SCHEMA_KV);
// KeyValues for Column
private static final KeyValue DECIMAL_DIGITS_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, DECIMAL_DIGITS_BYTES);
@@ -914,6 +918,11 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
Cell autoPartitionSeqKv = tableKeyValues[AUTO_PARTITION_SEQ_INDEX];
String autoPartitionSeq = autoPartitionSeqKv != null ? (String) PVarchar.INSTANCE.toObject(autoPartitionSeqKv.getValueArray(), autoPartitionSeqKv.getValueOffset(),
autoPartitionSeqKv.getValueLength()) : null;
+ Cell isAppendOnlySchemaKv = tableKeyValues[APPEND_ONLY_SCHEMA_INDEX];
+ boolean isAppendOnlySchema = isAppendOnlySchemaKv == null ? false
+ : Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(isAppendOnlySchemaKv.getValueArray(),
+ isAppendOnlySchemaKv.getValueOffset(), isAppendOnlySchemaKv.getValueLength()));
+
List<PColumn> columns = Lists.newArrayListWithExpectedSize(columnCount);
List<PTable> indexes = new ArrayList<PTable>();
@@ -964,7 +973,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
tableType == INDEX ? dataTableName : null, indexes, isImmutableRows, physicalTables, defaultFamilyName,
viewStatement, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType,
rowKeyOrderOptimizable, transactional, updateCacheFrequency, stats, baseColumnCount,
- indexDisableTimestamp, isNamespaceMapped, autoPartitionSeq);
+ indexDisableTimestamp, isNamespaceMapped, autoPartitionSeq, isAppendOnlySchema);
}
private PSchema getSchema(RegionScanner scanner, long clientTimeStamp) throws IOException, SQLException {
@@ -1453,7 +1462,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
done.run(builder.build());
return;
}
- PColumn autoPartitionCol = parentTable.getColumns().get(MetaDataUtil.getAutoPartitionColIndex(parentTable));
+ PColumn autoPartitionCol = parentTable.getPKColumns().get(MetaDataUtil.getAutoPartitionColIndex(parentTable));
if (!PLong.INSTANCE.isCoercibleTo(autoPartitionCol.getDataType(), autoPartitionNum)) {
builder.setReturnCode(MetaDataProtos.MutationCode.CANNOT_COERCE_AUTO_PARTITION_ID);
builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
@@ -1490,9 +1499,9 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
familyCellMap = autoPartitionPut.getFamilyCellMap();
cells = familyCellMap.get(TABLE_FAMILY_BYTES);
cell = cells.get(0);
- byte[] bytes = new byte [Bytes.SIZEOF_LONG + 1];
PDataType dataType = autoPartitionCol.getDataType();
Object val = dataType.toObject(autoPartitionNum, PLong.INSTANCE);
+ byte[] bytes = new byte [dataType.getByteSize() + 1];
dataType.toBytes(val, bytes, 0);
Cell viewConstantCell = new KeyValue(cell.getRow(), cell.getFamily(), VIEW_CONSTANT_BYTES,
cell.getTimestamp(), Type.codeToType(cell.getTypeByte()), bytes);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/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 fca181d..4171680 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
@@ -3363,6 +3363,16 @@ public final class PTableProtos {
*/
com.google.protobuf.ByteString
getAutoParititonSeqNameBytes();
+
+ // optional bool isAppendOnlySchema = 32;
+ /**
+ * <code>optional bool isAppendOnlySchema = 32;</code>
+ */
+ boolean hasIsAppendOnlySchema();
+ /**
+ * <code>optional bool isAppendOnlySchema = 32;</code>
+ */
+ boolean getIsAppendOnlySchema();
}
/**
* Protobuf type {@code PTable}
@@ -3588,6 +3598,11 @@ public final class PTableProtos {
autoParititonSeqName_ = input.readBytes();
break;
}
+ case 256: {
+ bitField0_ |= 0x08000000;
+ isAppendOnlySchema_ = input.readBool();
+ break;
+ }
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -4257,6 +4272,22 @@ public final class PTableProtos {
}
}
+ // optional bool isAppendOnlySchema = 32;
+ public static final int ISAPPENDONLYSCHEMA_FIELD_NUMBER = 32;
+ private boolean isAppendOnlySchema_;
+ /**
+ * <code>optional bool isAppendOnlySchema = 32;</code>
+ */
+ public boolean hasIsAppendOnlySchema() {
+ return ((bitField0_ & 0x08000000) == 0x08000000);
+ }
+ /**
+ * <code>optional bool isAppendOnlySchema = 32;</code>
+ */
+ public boolean getIsAppendOnlySchema() {
+ return isAppendOnlySchema_;
+ }
+
private void initFields() {
schemaNameBytes_ = com.google.protobuf.ByteString.EMPTY;
tableNameBytes_ = com.google.protobuf.ByteString.EMPTY;
@@ -4289,6 +4320,7 @@ public final class PTableProtos {
indexDisableTimestamp_ = 0L;
isNamespaceMapped_ = false;
autoParititonSeqName_ = "";
+ isAppendOnlySchema_ = false;
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
@@ -4449,6 +4481,9 @@ public final class PTableProtos {
if (((bitField0_ & 0x04000000) == 0x04000000)) {
output.writeBytes(31, getAutoParititonSeqNameBytes());
}
+ if (((bitField0_ & 0x08000000) == 0x08000000)) {
+ output.writeBool(32, isAppendOnlySchema_);
+ }
getUnknownFields().writeTo(output);
}
@@ -4587,6 +4622,10 @@ public final class PTableProtos {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(31, getAutoParititonSeqNameBytes());
}
+ if (((bitField0_ & 0x08000000) == 0x08000000)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBoolSize(32, isAppendOnlySchema_);
+ }
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
@@ -4753,6 +4792,11 @@ public final class PTableProtos {
result = result && getAutoParititonSeqName()
.equals(other.getAutoParititonSeqName());
}
+ result = result && (hasIsAppendOnlySchema() == other.hasIsAppendOnlySchema());
+ if (hasIsAppendOnlySchema()) {
+ result = result && (getIsAppendOnlySchema()
+ == other.getIsAppendOnlySchema());
+ }
result = result &&
getUnknownFields().equals(other.getUnknownFields());
return result;
@@ -4890,6 +4934,10 @@ public final class PTableProtos {
hash = (37 * hash) + AUTOPARITITONSEQNAME_FIELD_NUMBER;
hash = (53 * hash) + getAutoParititonSeqName().hashCode();
}
+ if (hasIsAppendOnlySchema()) {
+ hash = (37 * hash) + ISAPPENDONLYSCHEMA_FIELD_NUMBER;
+ hash = (53 * hash) + hashBoolean(getIsAppendOnlySchema());
+ }
hash = (29 * hash) + getUnknownFields().hashCode();
memoizedHashCode = hash;
return hash;
@@ -5076,6 +5124,8 @@ public final class PTableProtos {
bitField0_ = (bitField0_ & ~0x20000000);
autoParititonSeqName_ = "";
bitField0_ = (bitField0_ & ~0x40000000);
+ isAppendOnlySchema_ = false;
+ bitField0_ = (bitField0_ & ~0x80000000);
return this;
}
@@ -5244,6 +5294,10 @@ public final class PTableProtos {
to_bitField0_ |= 0x04000000;
}
result.autoParititonSeqName_ = autoParititonSeqName_;
+ if (((from_bitField0_ & 0x80000000) == 0x80000000)) {
+ to_bitField0_ |= 0x08000000;
+ }
+ result.isAppendOnlySchema_ = isAppendOnlySchema_;
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
@@ -5433,6 +5487,9 @@ public final class PTableProtos {
autoParititonSeqName_ = other.autoParititonSeqName_;
onChanged();
}
+ if (other.hasIsAppendOnlySchema()) {
+ setIsAppendOnlySchema(other.getIsAppendOnlySchema());
+ }
this.mergeUnknownFields(other.getUnknownFields());
return this;
}
@@ -7309,6 +7366,39 @@ public final class PTableProtos {
return this;
}
+ // optional bool isAppendOnlySchema = 32;
+ private boolean isAppendOnlySchema_ ;
+ /**
+ * <code>optional bool isAppendOnlySchema = 32;</code>
+ */
+ public boolean hasIsAppendOnlySchema() {
+ return ((bitField0_ & 0x80000000) == 0x80000000);
+ }
+ /**
+ * <code>optional bool isAppendOnlySchema = 32;</code>
+ */
+ public boolean getIsAppendOnlySchema() {
+ return isAppendOnlySchema_;
+ }
+ /**
+ * <code>optional bool isAppendOnlySchema = 32;</code>
+ */
+ public Builder setIsAppendOnlySchema(boolean value) {
+ bitField0_ |= 0x80000000;
+ isAppendOnlySchema_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bool isAppendOnlySchema = 32;</code>
+ */
+ public Builder clearIsAppendOnlySchema() {
+ bitField0_ = (bitField0_ & ~0x80000000);
+ isAppendOnlySchema_ = false;
+ onChanged();
+ return this;
+ }
+
// @@protoc_insertion_point(builder_scope:PTable)
}
@@ -7356,7 +7446,7 @@ public final class PTableProtos {
"\016\n\006values\030\002 \003(\014\022\033\n\023guidePostsByteCount\030\003",
" \001(\003\022\025\n\rkeyBytesCount\030\004 \001(\003\022\027\n\017guidePost" +
"sCount\030\005 \001(\005\022!\n\013pGuidePosts\030\006 \001(\0132\014.PGui" +
- "dePosts\"\374\005\n\006PTable\022\027\n\017schemaNameBytes\030\001 " +
+ "dePosts\"\230\006\n\006PTable\022\027\n\017schemaNameBytes\030\001 " +
"\002(\014\022\026\n\016tableNameBytes\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" +
@@ -7375,10 +7465,11 @@ public final class PTableProtos {
"nsactional\030\033 \001(\010\022\034\n\024updateCacheFrequency" +
"\030\034 \001(\003\022\035\n\025indexDisableTimestamp\030\035 \001(\003\022\031\n",
"\021isNamespaceMapped\030\036 \001(\010\022\034\n\024autoParitito" +
- "nSeqName\030\037 \001(\t*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"
+ "nSeqName\030\037 \001(\t\022\032\n\022isAppendOnlySchema\030 \001" +
+ "(\010*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.apa" +
+ "che.phoenix.coprocessor.generatedB\014PTabl" +
+ "eProtosH\001\210\001\001\240\001\001"
};
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -7402,7 +7493,7 @@ public final class PTableProtos {
internal_static_PTable_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_PTable_descriptor,
- new java.lang.String[] { "SchemaNameBytes", "TableNameBytes", "TableType", "IndexState", "SequenceNumber", "TimeStamp", "PkNameBytes", "BucketNum", "Columns", "Indexes", "IsImmutableRows", "GuidePosts", "DataTableNameBytes", "DefaultFamilyName", "DisableWAL", "MultiTenant", "ViewType", "ViewStatement", "PhysicalNames", "TenantId", "ViewIndexId", "IndexType", "StatsTimeStamp", "StoreNulls", "BaseColumnCount", "RowKeyOrderOptimizable", "Transactional", "UpdateCacheFrequency", "IndexDisableTimestamp", "IsNamespaceMapped", "AutoParititonSeqName", });
+ new java.lang.String[] { "SchemaNameBytes", "TableNameBytes", "TableType", "IndexState", "SequenceNumber", "TimeStamp", "PkNameBytes", "BucketNum", "Columns", "Indexes", "IsImmutableRows", "GuidePosts", "DataTableNameBytes", "DefaultFamilyName", "DisableWAL", "MultiTenant", "ViewType", "ViewStatement", "PhysicalNames", "TenantId", "ViewIndexId", "IndexType", "StatsTimeStamp", "StoreNulls", "BaseColumnCount", "RowKeyOrderOptimizable", "Transactional", "UpdateCacheFrequency", "IndexDisableTimestamp", "IsNamespaceMapped", "AutoParititonSeqName", "IsAppendOnlySchema", });
return null;
}
};
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java b/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
index 5661098..8064ce1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
@@ -351,6 +351,10 @@ public enum SQLExceptionCode {
CANNOT_SALT_LOCAL_INDEX(1110,"XCL10", "Local index may not be salted."),
INDEX_FAILURE_BLOCK_WRITE(1120, "XCL20", "Writes to table blocked until index can be updated."),
+
+ UPDATE_CACHE_FREQUENCY_INVALID(1130, "XCL30", "UPDATE_CACHE_FREQUENCY cannot be set to ALWAYS if APPEND_ONLY_SCHEMA is true."),
+ CANNOT_DROP_COL_APPEND_ONLY_SCHEMA(1131, "XCL31", "Cannot drop column from table that with append only schema."),
+ VIEW_APPEND_ONLY_SCHEMA(1132, "XCL32", "APPEND_ONLY_SCHEMA property of view must match the base table"),
/**
* Implementation defined class. Phoenix internal error. (errorcode 20, sqlstate INT).
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/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 c571625..344fc3e 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
@@ -295,6 +295,9 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
public static final String AUTO_PARTITION_SEQ = "AUTO_PARTITION_SEQ";
public static final byte[] AUTO_PARTITION_SEQ_BYTES = Bytes.toBytes(AUTO_PARTITION_SEQ);
+ public static final String APPEND_ONLY_SCHEMA = "APPEND_ONLY_SCHEMA";
+ public static final byte[] APPEND_ONLY_SCHEMA_BYTES = Bytes.toBytes(APPEND_ONLY_SCHEMA);
+
public static final String ASYNC_CREATED_DATE = "ASYNC_CREATED_DATE";
private final PhoenixConnection connection;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/phoenix-core/src/main/java/org/apache/phoenix/parse/ColumnDef.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ColumnDef.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ColumnDef.java
index 278b4aa..401d57b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ColumnDef.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ColumnDef.java
@@ -43,7 +43,7 @@ public class ColumnDef {
private final Boolean isNull;
private final Integer maxLength;
private final Integer scale;
- private final boolean isPK;
+ private boolean isPK;
private final SortOrder sortOrder;
private final boolean isArray;
private final Integer arrSize;
@@ -185,6 +185,11 @@ public class ColumnDef {
public boolean isRowTimestamp() {
return isRowTimestamp;
}
+
+ public void setIsPK(boolean isPK) {
+ this.isPK = isPK;
+ }
+
@Override
public String toString() {
StringBuilder buf = new StringBuilder(columnDefName.getColumnNode().toString());
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index 667d89c..931ecfc 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@ -195,6 +195,12 @@ import org.apache.twill.zookeeper.ZKClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import co.cask.tephra.TransactionSystemClient;
+import co.cask.tephra.TxConstants;
+import co.cask.tephra.distributed.PooledClientProvider;
+import co.cask.tephra.distributed.TransactionServiceClient;
+import co.cask.tephra.zookeeper.TephraZKClientService;
+
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Throwables;
@@ -208,12 +214,6 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import co.cask.tephra.TransactionSystemClient;
-import co.cask.tephra.TxConstants;
-import co.cask.tephra.distributed.PooledClientProvider;
-import co.cask.tephra.distributed.TransactionServiceClient;
-import co.cask.tephra.zookeeper.TephraZKClientService;
-
public class ConnectionQueryServicesImpl extends DelegateQueryServices implements ConnectionQueryServices {
private static final Logger logger = LoggerFactory.getLogger(ConnectionQueryServicesImpl.class);
private static final int INITIAL_CHILD_SERVICES_CAPACITY = 100;
@@ -1937,13 +1937,13 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
for (Pair<String, Object> prop : propsList) {
String propName = prop.getFirst();
Object propValue = prop.getSecond();
- if ((isHTableProperty(propName) || TableProperty.isPhoenixTableProperty(propName)) && addingColumns) {
+ if ((MetaDataUtil.isHTableProperty(propName) || TableProperty.isPhoenixTableProperty(propName)) && addingColumns) {
// setting HTable and PhoenixTable properties while adding a column is not allowed.
throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_SET_TABLE_PROPERTY_ADD_COLUMN)
.setMessage("Property: " + propName).build()
.buildException();
}
- if (isHTableProperty(propName)) {
+ if (MetaDataUtil.isHTableProperty(propName)) {
// Can't have a column family name for a property that's an HTableProperty
if (!family.equals(QueryConstants.ALL_FAMILY_PROPERTIES_KEY)) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_TABLE_PROPERTY)
@@ -1964,7 +1964,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
tableProps.put(TxConstants.READ_NON_TX_DATA, propValue);
}
} else {
- if (isHColumnProperty(propName)) {
+ if (MetaDataUtil.isHColumnProperty(propName)) {
if (family.equals(QueryConstants.ALL_FAMILY_PROPERTIES_KEY)) {
commonFamilyProps.put(propName, propValue);
} else {
@@ -2170,14 +2170,6 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
}
}
- private boolean isHColumnProperty(String propName) {
- return HColumnDescriptor.getDefaultValues().containsKey(propName);
- }
-
- private boolean isHTableProperty(String propName) {
- return !isHColumnProperty(propName) && !TableProperty.isPhoenixTableProperty(propName);
- }
-
private HashSet<String> existingColumnFamiliesForBaseTable(PName baseTableName) throws TableNotFoundException {
synchronized (latestMetaDataLock) {
throwConnectionClosedIfNullMetaData();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/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 5c7ac1a..4efb708 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
@@ -18,6 +18,7 @@
package org.apache.phoenix.query;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.APPEND_ONLY_SCHEMA;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ARG_POSITION;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ARRAY_SIZE;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.AUTO_PARTITION_SEQ;
@@ -269,6 +270,7 @@ public interface QueryConstants {
UPDATE_CACHE_FREQUENCY + " BIGINT," +
IS_NAMESPACE_MAPPED + " BOOLEAN," +
AUTO_PARTITION_SEQ + " VARCHAR," +
+ APPEND_ONLY_SCHEMA + " BOOLEAN," +
"CONSTRAINT " + SYSTEM_TABLE_PK_NAME + " PRIMARY KEY (" + TENANT_ID + ","
+ TABLE_SCHEM + "," + TABLE_NAME + "," + COLUMN_NAME + "," + COLUMN_FAMILY + "))\n" +
HConstants.VERSIONS + "=" + MetaDataProtocol.DEFAULT_MAX_META_DATA_VERSIONS + ",\n" +
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/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 f1a7548..ddd2de0 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
@@ -277,7 +277,13 @@ public class DelegateTable implements PTable {
return delegate.isNamespaceMapped();
}
+ @Override
public String getAutoPartitionSeqName() {
return delegate.getAutoPartitionSeqName();
}
+
+ @Override
+ public boolean isAppendOnlySchema() {
+ return delegate.isAppendOnlySchema();
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/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 95fde4b..2658174 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
@@ -24,6 +24,7 @@ import static org.apache.hadoop.hbase.HColumnDescriptor.TTL;
import static org.apache.phoenix.coprocessor.BaseScannerRegionObserver.ANALYZE_TABLE;
import static org.apache.phoenix.coprocessor.BaseScannerRegionObserver.RUN_UPDATE_STATS_ASYNC_ATTRIB;
import static org.apache.phoenix.exception.SQLExceptionCode.INSUFFICIENT_MULTI_TENANT_COLUMNS;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.APPEND_ONLY_SCHEMA;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ARG_POSITION;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ARRAY_SIZE;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ASYNC_CREATED_DATE;
@@ -259,8 +260,9 @@ public class MetaDataClient {
TRANSACTIONAL + "," +
UPDATE_CACHE_FREQUENCY + "," +
IS_NAMESPACE_MAPPED + "," +
- AUTO_PARTITION_SEQ +
- ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+ AUTO_PARTITION_SEQ + "," +
+ APPEND_ONLY_SCHEMA +
+ ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static final String CREATE_SCHEMA = "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE
+ "\"( " + TABLE_SCHEM + "," + TABLE_NAME + ") VALUES (?,?)";
@@ -863,7 +865,87 @@ public class MetaDataClient {
}
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, null, null);
+ TableName tableName = statement.getTableName();
+ Map<String,Object> tableProps = Maps.newHashMapWithExpectedSize(statement.getProps().size());
+ Map<String,Object> commonFamilyProps = Maps.newHashMapWithExpectedSize(statement.getProps().size() + 1);
+ populatePropertyMaps(statement.getProps(), tableProps, commonFamilyProps);
+
+ boolean isAppendOnlySchema = false;
+ Boolean appendOnlySchemaProp = (Boolean) TableProperty.APPEND_ONLY_SCHEMA.getValue(tableProps);
+ if (appendOnlySchemaProp != null) {
+ isAppendOnlySchema = appendOnlySchemaProp;
+ }
+ long updateCacheFrequency = 0;
+ Long updateCacheFrequencyProp = (Long) TableProperty.UPDATE_CACHE_FREQUENCY.getValue(tableProps);
+ if (updateCacheFrequencyProp != null) {
+ updateCacheFrequency = updateCacheFrequencyProp;
+ }
+ // updateCacheFrequency cannot be set to ALWAYS if isAppendOnlySchema is true
+ if (isAppendOnlySchema && updateCacheFrequency==0) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.UPDATE_CACHE_FREQUENCY_INVALID)
+ .setSchemaName(tableName.getSchemaName()).setTableName(tableName.getTableName())
+ .build().buildException();
+ }
+ // view isAppendOnlySchema property must match the parent table
+ if (parent!=null && isAppendOnlySchema!= parent.isAppendOnlySchema()) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.VIEW_APPEND_ONLY_SCHEMA)
+ .setSchemaName(tableName.getSchemaName()).setTableName(tableName.getTableName())
+ .build().buildException();
+ }
+
+ PTable table = null;
+ // if the APPEND_ONLY_SCHEMA attribute is true first check if the table is present in the cache
+ // if it is add columns that are not already present
+ if (isAppendOnlySchema) {
+ // look up the table in the cache
+ MetaDataMutationResult result = updateCache(tableName.getSchemaName(), tableName.getTableName());
+ if (result.getMutationCode()==MutationCode.TABLE_ALREADY_EXISTS) {
+ table = result.getTable();
+ if (!statement.ifNotExists()) {
+ throw new NewerTableAlreadyExistsException(tableName.getSchemaName(), tableName.getTableName(), table);
+ }
+
+ List<ColumnDef> columnDefs = statement.getColumnDefs();
+ PrimaryKeyConstraint pkConstraint = statement.getPrimaryKeyConstraint();
+ // get the list of columns to add
+ List<ColumnDef> newColumnDefs = Lists.newArrayList();
+ for (ColumnDef columnDef : columnDefs) {
+ if (pkConstraint.contains(columnDef.getColumnDefName())) {
+ columnDef.setIsPK(true);
+ }
+ String familyName = columnDef.getColumnDefName().getFamilyName();
+ String columnName = columnDef.getColumnDefName().getColumnName();
+ if (familyName!=null) {
+ try {
+ PColumnFamily columnFamily = table.getColumnFamily(familyName);
+ columnFamily.getColumn(columnName);
+ }
+ catch (ColumnFamilyNotFoundException | ColumnNotFoundException e){
+ newColumnDefs.add(columnDef);
+ }
+ }
+ else {
+ try {
+ table.getColumn(columnName);
+ }
+ catch (ColumnNotFoundException e){
+ newColumnDefs.add(columnDef);
+ }
+ }
+ }
+ // if there are new columns to add
+ if (!newColumnDefs.isEmpty()) {
+ return addColumn(table, newColumnDefs, statement.getProps(),
+ statement.ifNotExists(), true,
+ NamedTableNode.create(statement.getTableName()), statement.getTableType());
+ }
+ else {
+ return new MutationState(0,connection);
+ }
+ }
+ }
+ table = createTableInternal(statement, splits, parent, viewStatement, viewType, viewColumnConstants, isViewColumnReferenced, null, null, null, tableProps, commonFamilyProps);
+
if (table == null || table.getType() == PTableType.VIEW || table.isTransactional()) {
return new MutationState(0,connection);
}
@@ -883,6 +965,22 @@ public class MetaDataClient {
return connection.getQueryServices().updateData(plan);
}
+ private void populatePropertyMaps(ListMultimap<String,Pair<String,Object>> props, Map<String, Object> tableProps,
+ Map<String, Object> commonFamilyProps) {
+ // Somewhat hacky way of determining if property is for HColumnDescriptor or HTableDescriptor
+ HColumnDescriptor defaultDescriptor = new HColumnDescriptor(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES);
+ if (!props.isEmpty()) {
+ Collection<Pair<String,Object>> propsList = props.get(QueryConstants.ALL_FAMILY_PROPERTIES_KEY);
+ for (Pair<String,Object> prop : propsList) {
+ if (defaultDescriptor.getValue(prop.getFirst()) == null) {
+ tableProps.put(prop.getFirst(), prop.getSecond());
+ } else {
+ commonFamilyProps.put(prop.getFirst(), prop.getSecond());
+ }
+ }
+ }
+ }
+
public MutationState updateStatistics(UpdateStatisticsStatement updateStatisticsStmt)
throws SQLException {
// Don't mistakenly commit pending rows
@@ -1160,11 +1258,14 @@ public class MetaDataClient {
IndexKeyConstraint ik = statement.getIndexConstraint();
TableName indexTableName = statement.getIndexTableName();
+ Map<String,Object> tableProps = Maps.newHashMapWithExpectedSize(statement.getProps().size());
+ Map<String,Object> commonFamilyProps = Maps.newHashMapWithExpectedSize(statement.getProps().size() + 1);
+ populatePropertyMaps(statement.getProps(), tableProps, commonFamilyProps);
List<Pair<ParseNode, SortOrder>> indexParseNodeAndSortOrderList = ik.getParseNodeAndSortOrderList();
List<ColumnName> includedColumns = statement.getIncludeColumns();
TableRef tableRef = null;
PTable table = null;
- boolean retry = true;
+ int numRetries = 0;
Short indexId = null;
boolean allocateIndexId = false;
boolean isLocalIndex = statement.getIndexType() == IndexType.LOCAL;
@@ -1359,11 +1460,11 @@ public class MetaDataClient {
}
PrimaryKeyConstraint pk = FACTORY.primaryKey(null, allPkColumns);
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, null, null, indexId, statement.getIndexType(), asyncCreatedDate);
+ table = createTableInternal(tableStatement, splits, dataTable, null, null, null, null, indexId, statement.getIndexType(), asyncCreatedDate, tableProps, commonFamilyProps);
break;
} catch (ConcurrentTableMutationException e) { // Can happen if parent data table changes while above is in progress
- if (retry) {
- retry = false;
+ if (numRetries<5) {
+ numRetries++;
continue;
}
throw e;
@@ -1541,7 +1642,12 @@ public class MetaDataClient {
return false;
}
- private PTable createTableInternal(CreateTableStatement statement, byte[][] splits, final PTable parent, String viewStatement, ViewType viewType, final byte[][] viewColumnConstants, final BitSet isViewColumnReferenced, Short indexId, IndexType indexType, Date asyncCreatedDate) throws SQLException {
+ private PTable createTableInternal(CreateTableStatement statement, byte[][] splits,
+ final PTable parent, String viewStatement, ViewType viewType,
+ final byte[][] viewColumnConstants, final BitSet isViewColumnReferenced, Short indexId,
+ IndexType indexType, Date asyncCreatedDate,
+ Map<String,Object> tableProps,
+ Map<String,Object> commonFamilyProps) throws SQLException {
final PTableType tableType = statement.getTableType();
boolean wasAutoCommit = connection.getAutoCommit();
connection.rollback();
@@ -1563,6 +1669,7 @@ public class MetaDataClient {
Integer saltBucketNum = null;
String defaultFamilyName = null;
boolean isImmutableRows = false;
+ boolean isAppendOnlySchema = false;
List<PName> physicalNames = Collections.emptyList();
boolean addSaltColumn = false;
boolean rowKeyOrderOptimizable = true;
@@ -1574,6 +1681,7 @@ public class MetaDataClient {
timestamp = TransactionUtil.getTableTimestamp(connection, transactional);
storeNulls = parent.getStoreNulls();
isImmutableRows = parent.isImmutableRows();
+ isAppendOnlySchema = parent.isAppendOnlySchema();
// Index on view
// TODO: Can we support a multi-tenant index directly on a multi-tenant
// table instead of only a view? We don't have anywhere to put the link
@@ -1630,21 +1738,6 @@ public class MetaDataClient {
pkName = pkConstraint.getName();
}
- Map<String,Object> tableProps = Maps.newHashMapWithExpectedSize(statement.getProps().size());
- Map<String,Object> commonFamilyProps = Maps.newHashMapWithExpectedSize(statement.getProps().size() + 1);
- // Somewhat hacky way of determining if property is for HColumnDescriptor or HTableDescriptor
- HColumnDescriptor defaultDescriptor = new HColumnDescriptor(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES);
- if (!statement.getProps().isEmpty()) {
- Collection<Pair<String,Object>> props = statement.getProps().get(QueryConstants.ALL_FAMILY_PROPERTIES_KEY);
- for (Pair<String,Object> prop : props) {
- if (defaultDescriptor.getValue(prop.getFirst()) == null) {
- tableProps.put(prop.getFirst(), prop.getSecond());
- } else {
- commonFamilyProps.put(prop.getFirst(), prop.getSecond());
- }
- }
- }
-
// Although unusual, it's possible to set a mapped VIEW as having immutable rows.
// This tells Phoenix that you're managing the index maintenance yourself.
if (tableType != PTableType.INDEX && (tableType != PTableType.VIEW || viewType == ViewType.MAPPED)) {
@@ -1655,6 +1748,11 @@ public class MetaDataClient {
isImmutableRows = isImmutableRowsProp;
}
}
+
+ if (tableType == PTableType.TABLE) {
+ Boolean isAppendOnlySchemaProp = (Boolean) TableProperty.APPEND_ONLY_SCHEMA.getValue(tableProps);
+ isAppendOnlySchema = isAppendOnlySchemaProp!=null ? isAppendOnlySchemaProp : false;
+ }
// Can't set any of these on views or shared indexes on views
if (tableType != PTableType.VIEW && indexId == null) {
@@ -1831,6 +1929,7 @@ public class MetaDataClient {
}
multiTenant = parent.isMultiTenant();
saltBucketNum = parent.getBucketNum();
+ isAppendOnlySchema = parent.isAppendOnlySchema();
isImmutableRows = parent.isImmutableRows();
disableWAL = (disableWALProp == null ? parent.isWALDisabled() : disableWALProp);
defaultFamilyName = parent.getDefaultFamilyName() == null ? null : parent.getDefaultFamilyName().getString();
@@ -2036,7 +2135,7 @@ public class MetaDataClient {
Collections.<PTable>emptyList(), isImmutableRows,
Collections.<PName>emptyList(), defaultFamilyName == null ? null :
PNameFactory.newName(defaultFamilyName), null,
- Boolean.TRUE.equals(disableWAL), false, false, null, indexId, indexType, true, false, 0, 0L, isNamespaceMapped, autoPartitionSeq);
+ Boolean.TRUE.equals(disableWAL), false, false, null, indexId, indexType, true, false, 0, 0L, isNamespaceMapped, autoPartitionSeq, isAppendOnlySchema);
connection.addTable(table, MetaDataProtocol.MIN_TABLE_TIMESTAMP);
} else if (tableType == PTableType.INDEX && indexId == null) {
if (tableProps.get(HTableDescriptor.MAX_FILESIZE) == null) {
@@ -2072,7 +2171,7 @@ public class MetaDataClient {
// For client-side cache, we need to update the column
// set the autoPartition column attributes
if (parent != null && parent.getAutoPartitionSeqName() != null
- && MetaDataUtil.getAutoPartitionColIndex(parent) == columnPosition) {
+ && parent.getPKColumns().get(MetaDataUtil.getAutoPartitionColIndex(parent)).equals(column)) {
columns.set(i, column = new DelegateColumn(column) {
@Override
public byte[] getViewConstant() {
@@ -2176,6 +2275,7 @@ public class MetaDataClient {
} else {
tableUpsert.setString(24, autoPartitionSeq);
}
+ tableUpsert.setBoolean(25, isAppendOnlySchema);
tableUpsert.execute();
if (asyncCreatedDate != null) {
@@ -2243,15 +2343,21 @@ public class MetaDataClient {
// If the parent table of the view has the auto partition sequence name attribute,
// set the view statement and relevant partition column attributes correctly
if (parent!=null && parent.getAutoPartitionSeqName()!=null) {
- int autoPartitionColIndex = parent.isMultiTenant() ? 1 : 0;
+ int autoPartitionColIndex = -1;
+ PColumn autoPartitionCol = parent.getPKColumns().get(MetaDataUtil.getAutoPartitionColIndex(parent));
+ for (int i=0; i<columns.size(); ++i) {
+ if (autoPartitionCol.getName().equals(columns.get(i).getName())) {
+ autoPartitionColIndex = i;
+ }
+ }
final Long autoPartitionNum = Long.valueOf(result.getAutoPartitionNum());
final PColumn column = columns.get(autoPartitionColIndex);
columns.set(autoPartitionColIndex, new DelegateColumn(column) {
@Override
public byte[] getViewConstant() {
- byte[] bytes = new byte [Bytes.SIZEOF_LONG + 1];
PDataType dataType = column.getDataType();
Object val = dataType.toObject(autoPartitionNum, PLong.INSTANCE);
+ byte[] bytes = new byte [dataType.getByteSize() + 1];
dataType.toBytes(val, bytes, 0);
return bytes;
}
@@ -2274,7 +2380,7 @@ public class MetaDataClient {
PTable.INITIAL_SEQ_NUM, pkName == null ? null : PNameFactory.newName(pkName), saltBucketNum, columns,
dataTableName == null ? null : newSchemaName, dataTableName == null ? null : PNameFactory.newName(dataTableName), Collections.<PTable>emptyList(), isImmutableRows,
physicalNames, defaultFamilyName == null ? null : PNameFactory.newName(defaultFamilyName), viewStatement, Boolean.TRUE.equals(disableWAL), multiTenant, storeNulls, viewType,
- indexId, indexType, rowKeyOrderOptimizable, transactional, updateCacheFrequency, 0L, isNamespaceMapped, autoPartitionSeq);
+ indexId, indexType, rowKeyOrderOptimizable, transactional, updateCacheFrequency, 0L, isNamespaceMapped, autoPartitionSeq, isAppendOnlySchema);
result = new MetaDataMutationResult(code, result.getMutationTime(), table, true);
addTableToCache(result);
return table;
@@ -2682,16 +2788,23 @@ public class MetaDataClient {
tableBoolUpsert.execute();
}
}
-
+
public MutationState addColumn(AddColumnStatement statement) throws SQLException {
+ PTable table = FromCompiler.getResolver(statement, connection).getTables().get(0).getTable();
+ return addColumn(table, statement.getColumnDefs(), statement.getProps(), statement.ifNotExists(), false, statement.getTable(), statement.getTableType());
+ }
+
+ public MutationState addColumn(PTable table, List<ColumnDef> columnDefs,
+ ListMultimap<String, Pair<String, Object>> stmtProperties, boolean ifNotExists,
+ boolean removeTableProps, NamedTableNode namedTableNode, PTableType tableType)
+ throws SQLException {
connection.rollback();
boolean wasAutoCommit = connection.getAutoCommit();
try {
connection.setAutoCommit(false);
PName tenantId = connection.getTenantId();
- TableName tableNameNode = statement.getTable().getName();
- String schemaName = tableNameNode.getSchemaName();
- String tableName = tableNameNode.getTableName();
+ String schemaName = table.getSchemaName().getString();
+ String tableName = table.getTableName().getString();
Boolean isImmutableRowsProp = null;
Boolean multiTenantProp = null;
@@ -2700,17 +2813,14 @@ public class MetaDataClient {
Boolean isTransactionalProp = null;
Long updateCacheFrequencyProp = null;
- ListMultimap<String,Pair<String,Object>> stmtProperties = statement.getProps();
Map<String, List<Pair<String, Object>>> properties = new HashMap<>(stmtProperties.size());
- TableRef tableRef = FromCompiler.getResolver(statement, connection).getTables().get(0);
- PTable table = tableRef.getTable();
- List<ColumnDef> columnDefs = statement.getColumnDefs();
if (columnDefs == null) {
columnDefs = Collections.emptyList();
}
for (String family : stmtProperties.keySet()) {
- List<Pair<String, Object>> propsList = stmtProperties.get(family);
- for (Pair<String, Object> prop : propsList) {
+ List<Pair<String, Object>> origPropsList = stmtProperties.get(family);
+ List<Pair<String, Object>> propsList = Lists.newArrayListWithExpectedSize(origPropsList.size());
+ for (Pair<String, Object> prop : origPropsList) {
String propName = prop.getFirst();
if (TableProperty.isPhoenixTableProperty(propName)) {
TableProperty tableProp = TableProperty.valueOf(propName);
@@ -2729,7 +2839,11 @@ public class MetaDataClient {
} else if (propName.equals(UPDATE_CACHE_FREQUENCY)) {
updateCacheFrequencyProp = (Long)value;
}
- }
+ }
+ // if removeTableProps is true only add the property if it is not a HTable or Phoenix Table property
+ if (!removeTableProps || (!TableProperty.isPhoenixTableProperty(propName) && !MetaDataUtil.isHTableProperty(propName))) {
+ propsList.add(prop);
+ }
}
properties.put(family, propsList);
}
@@ -2737,7 +2851,7 @@ public class MetaDataClient {
boolean changingPhoenixTableProperty = false;
boolean nonTxToTx = false;
while (true) {
- ColumnResolver resolver = FromCompiler.getResolver(statement, connection);
+ ColumnResolver resolver = FromCompiler.getResolver(namedTableNode, connection);
table = resolver.getTables().get(0).getTable();
int nIndexes = table.getIndexes().size();
int nNewColumns = columnDefs.size();
@@ -2929,7 +3043,7 @@ public class MetaDataClient {
}
long seqNum = table.getSequenceNumber();
if (changingPhoenixTableProperty || columnDefs.size() > 0) {
- seqNum = incrementTableSeqNum(table, statement.getTableType(), columnDefs.size(), isTransactional, updateCacheFrequency, isImmutableRows, disableWAL, multiTenant, storeNulls);
+ seqNum = incrementTableSeqNum(table, tableType, columnDefs.size(), isTransactional, updateCacheFrequency, isImmutableRows, disableWAL, multiTenant, storeNulls);
tableMetaData.addAll(connection.getMutationState().toMutations(timeStamp).next().getSecond());
connection.rollback();
}
@@ -2962,7 +3076,7 @@ public class MetaDataClient {
MutationCode code = processMutationResult(schemaName, tableName, result);
if (code == MutationCode.COLUMN_ALREADY_EXISTS) {
addTableToCache(result);
- if (!statement.ifNotExists()) {
+ if (!ifNotExists) {
throw new ColumnAlreadyExistsException(schemaName, tableName, SchemaUtil.findExistingColumn(result.getTable(), columns));
}
return new MutationState(0,connection);
@@ -3124,6 +3238,7 @@ public class MetaDataClient {
final ColumnResolver resolver = FromCompiler.getResolver(statement, connection);
TableRef tableRef = resolver.getTables().get(0);
PTable table = tableRef.getTable();
+
List<ColumnName> columnRefs = statement.getColumnRefs();
if(columnRefs == null) {
columnRefs = Lists.newArrayListWithCapacity(0);
@@ -3149,6 +3264,10 @@ public class MetaDataClient {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_DROP_PK)
.setColumnName(columnToDrop.getName().getString()).build().buildException();
}
+ else if (table.isAppendOnlySchema()) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_DROP_COL_APPEND_ONLY_SCHEMA)
+ .setColumnName(columnToDrop.getName().getString()).build().buildException();
+ }
columnsToDrop.add(new ColumnRef(columnRef.getTableRef(), columnToDrop.getPosition()));
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0504fba/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 5a3f18e..ca48fcb 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
@@ -349,9 +349,14 @@ public interface PTable extends PMetaDataEntity {
boolean isNamespaceMapped();
/**
- *
* @return The sequence name used to get the unique identifier for views
* that are automatically partitioned.
*/
- String getAutoPartitionSeqName();
+ String getAutoPartitionSeqName();
+
+ /**
+ * @return true if the you can only add (and never delete) columns to the table,
+ * you are also not allowed to delete the table
+ */
+ boolean isAppendOnlySchema();
}