You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ja...@apache.org on 2015/03/12 00:24:20 UTC
phoenix git commit: Store whether or not a table is transactional in
SYSTEM.CATALOG instead of in HTableDescriptor
Repository: phoenix
Updated Branches:
refs/heads/txn 995e352c6 -> 8119bee57
Store whether or not a table is transactional in SYSTEM.CATALOG instead of in HTableDescriptor
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/8119bee5
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/8119bee5
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/8119bee5
Branch: refs/heads/txn
Commit: 8119bee5787dc2973d9a1ea34a577984842fbab5
Parents: 995e352
Author: James Taylor <jt...@salesforce.com>
Authored: Wed Mar 11 16:24:19 2015 -0700
Committer: James Taylor <jt...@salesforce.com>
Committed: Wed Mar 11 16:24:19 2015 -0700
----------------------------------------------------------------------
.../apache/phoenix/end2end/AlterTableIT.java | 20 ++-
.../apache/phoenix/compile/FromCompiler.java | 4 +-
.../apache/phoenix/compile/JoinCompiler.java | 2 +-
.../compile/TupleProjectionCompiler.java | 6 +-
.../coprocessor/MetaDataEndpointImpl.java | 8 +-
.../coprocessor/generated/PTableProtos.java | 103 +++++++++++-
.../phoenix/exception/SQLExceptionCode.java | 4 +
.../apache/phoenix/execute/MutationState.java | 12 +-
.../phoenix/iterate/TableResultIterator.java | 10 +-
.../query/ConnectionQueryServicesImpl.java | 45 +++---
.../org/apache/phoenix/query/HTableFactory.java | 6 -
.../apache/phoenix/query/QueryConstants.java | 6 +-
.../org/apache/phoenix/query/QueryServices.java | 1 +
.../phoenix/query/QueryServicesOptions.java | 4 +-
.../apache/phoenix/schema/DelegateTable.java | 5 +
.../apache/phoenix/schema/MetaDataClient.java | 156 +++++++++++--------
.../java/org/apache/phoenix/schema/PTable.java | 1 +
.../org/apache/phoenix/schema/PTableImpl.java | 39 +++--
.../apache/phoenix/schema/TableProperty.java | 5 +-
.../org/apache/phoenix/util/MetaDataUtil.java | 15 +-
.../org/apache/phoenix/util/SchemaUtil.java | 23 +--
.../phoenix/compile/QueryCompilerTest.java | 2 +-
phoenix-protocol/src/main/PTable.proto | 1 +
23 files changed, 324 insertions(+), 154 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
index 9c0171f..9e7a4a9 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
@@ -38,7 +38,6 @@ import java.util.Collections;
import java.util.Map;
import java.util.Properties;
-import co.cask.tephra.hbase98.TransactionAwareHTable;
import co.cask.tephra.hbase98.coprocessor.TransactionProcessor;
import org.apache.hadoop.hbase.HColumnDescriptor;
@@ -55,7 +54,6 @@ import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.schema.PTableKey;
-import org.apache.phoenix.schema.TableAlreadyExistsException;
import org.apache.phoenix.schema.TableNotFoundException;
import org.apache.phoenix.util.IndexUtil;
import org.apache.phoenix.util.PhoenixRuntime;
@@ -2019,9 +2017,9 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
String ddl = "CREATE TABLE TEST_TRANSACTIONAL_TABLE (k varchar primary key) transactional=true";
conn.createStatement().execute(ddl);
PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class);
+ PTable table = pconn.getMetaDataCache().getTable(new PTableKey(null, "TEST_TRANSACTIONAL_TABLE"));
HTableInterface htable = pconn.getQueryServices().getTable(Bytes.toBytes("TEST_TRANSACTIONAL_TABLE"));
- assertTrue(SchemaUtil.isTransactional(htable.getTableDescriptor()));
- assertTrue(htable instanceof TransactionAwareHTable);
+ assertTrue(table.isTransactional());
assertTrue(htable.getTableDescriptor().getCoprocessors().contains(TransactionProcessor.class.getName()));
HBaseAdmin admin = pconn.getQueryServices().getAdmin();
@@ -2032,15 +2030,15 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
ddl = "CREATE TABLE TXN_TEST_EXISTING (k varchar primary key) transactional=true";
conn.createStatement().execute(ddl);
fail();
- } catch (TableAlreadyExistsException e) {
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.MAY_NOT_MAP_TO_EXISTING_TABLE_AS_TRANSACTIONAL.getErrorCode(), e.getErrorCode());
}
- // stays transactional
+ // Should be ok, as HBase metadata should match existing metadata.
ddl = "CREATE TABLE IF NOT EXISTS TEST_TRANSACTIONAL_TABLE (k varchar primary key)";
conn.createStatement().execute(ddl);
- assertTrue(SchemaUtil.isTransactional(pconn.getQueryServices().getTable(Bytes.toBytes("TEST_TRANSACTIONAL_TABLE")).getTableDescriptor()));
- // stays non transactional
- ddl = "CREATE TABLE IF NOT EXISTS TXN_TEST_EXISTING (k varchar primary key) transactional=true";
- conn.createStatement().execute(ddl);
- assertFalse(SchemaUtil.isTransactional(pconn.getQueryServices().getTable(Bytes.toBytes("TXN_TEST_EXISTING")).getTableDescriptor()));
+ table = pconn.getMetaDataCache().getTable(new PTableKey(null, "TEST_TRANSACTIONAL_TABLE"));
+ htable = pconn.getQueryServices().getTable(Bytes.toBytes("TEST_TRANSACTIONAL_TABLE"));
+ assertTrue(table.isTransactional());
+ assertTrue(htable.getTableDescriptor().getCoprocessors().contains(TransactionProcessor.class.getName()));
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/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 a57250e..e1f64f3 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
@@ -65,6 +65,7 @@ import org.apache.phoenix.schema.PColumnImpl;
import org.apache.phoenix.schema.PName;
import org.apache.phoenix.schema.PNameFactory;
import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTable.IndexType;
import org.apache.phoenix.schema.PTableImpl;
import org.apache.phoenix.schema.PTableKey;
import org.apache.phoenix.schema.PTableType;
@@ -72,7 +73,6 @@ import org.apache.phoenix.schema.ProjectedColumn;
import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.schema.TableNotFoundException;
import org.apache.phoenix.schema.TableRef;
-import org.apache.phoenix.schema.PTable.IndexType;
import org.apache.phoenix.util.Closeables;
import org.apache.phoenix.util.IndexUtil;
import org.apache.phoenix.util.LogUtil;
@@ -485,7 +485,7 @@ public class FromCompiler {
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);
+ null, 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/8119bee5/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 98b7edb..daec761 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
@@ -1297,7 +1297,7 @@ public class JoinCompiler {
return PTableImpl.makePTable(left.getTenantId(), left.getSchemaName(),
PNameFactory.newName(SchemaUtil.getTableName(left.getName().getString(), right.getName().getString())), left.getType(), left.getIndexState(), left.getTimeStamp(), left.getSequenceNumber(), left.getPKName(), left.getBucketNum(), merged,
- left.getParentSchemaName(), left.getParentTableName(), left.getIndexes(), left.isImmutableRows(), Collections.<PName>emptyList(), null, null, PTable.DEFAULT_DISABLE_WAL, left.isMultiTenant(), left.getStoreNulls(), left.getViewType(), left.getViewIndexId(), left.getIndexType());
+ left.getParentSchemaName(), left.getParentTableName(), left.getIndexes(), left.isImmutableRows(), Collections.<PName>emptyList(), null, null, PTable.DEFAULT_DISABLE_WAL, left.isMultiTenant(), left.getStoreNulls(), left.getViewType(), left.getViewIndexId(), left.getIndexType(), left.isTransactional());
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/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 72e2a26..b41107b 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
@@ -43,11 +43,11 @@ import org.apache.phoenix.schema.PColumn;
import org.apache.phoenix.schema.PName;
import org.apache.phoenix.schema.PNameFactory;
import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTable.IndexType;
import org.apache.phoenix.schema.PTableImpl;
import org.apache.phoenix.schema.PTableType;
import org.apache.phoenix.schema.ProjectedColumn;
import org.apache.phoenix.schema.TableRef;
-import org.apache.phoenix.schema.PTable.IndexType;
import org.apache.phoenix.util.IndexUtil;
import org.apache.phoenix.util.SchemaUtil;
@@ -151,7 +151,7 @@ public class TupleProjectionCompiler {
table.getBucketNum(), projectedColumns, table.getParentSchemaName(),
table.getParentName(), table.getIndexes(), table.isImmutableRows(), Collections.<PName>emptyList(), null, null,
table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(),
- table.getIndexType());
+ table.getIndexType(), table.isTransactional());
}
public static PTable createProjectedTable(TableRef tableRef, List<ColumnRef> sourceColumnRefs, boolean retainPKColumns) throws SQLException {
@@ -178,7 +178,7 @@ public class TupleProjectionCompiler {
retainPKColumns ? table.getBucketNum() : null, projectedColumns, null,
null, Collections.<PTable>emptyList(), table.isImmutableRows(), Collections.<PName>emptyList(), null, null,
table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(),
- null);
+ null, table.isTransactional());
}
// For extracting column references from single select statement
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/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 e234498..1a412c6 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
@@ -47,6 +47,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME_INDEX;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SEQ_NUM_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_TYPE_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TENANT_ID_INDEX;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TRANSACTIONAL_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_CONSTANT_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_INDEX_ID_BYTES;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_STATEMENT_BYTES;
@@ -196,6 +197,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
private static final KeyValue INDEX_TYPE_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, INDEX_TYPE_BYTES);
private static final KeyValue INDEX_DISABLE_TIMESTAMP_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, INDEX_DISABLE_TIMESTAMP_BYTES);
private static final KeyValue STORE_NULLS_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, STORE_NULLS_BYTES);
+ private static final KeyValue TRANSACTIONAL_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, TRANSACTIONAL_BYTES);
private static final KeyValue EMPTY_KEYVALUE_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES);
private static final List<KeyValue> TABLE_KV_COLUMNS = Arrays.<KeyValue>asList(
EMPTY_KEYVALUE_KV,
@@ -215,6 +217,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
VIEW_INDEX_ID_KV,
INDEX_TYPE_KV,
INDEX_DISABLE_TIMESTAMP_KV,
+ TRANSACTIONAL_KV,
STORE_NULLS_KV
);
static {
@@ -236,6 +239,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
private static final int VIEW_INDEX_ID_INDEX = TABLE_KV_COLUMNS.indexOf(VIEW_INDEX_ID_KV);
private static final int INDEX_TYPE_INDEX = TABLE_KV_COLUMNS.indexOf(INDEX_TYPE_KV);
private static final int STORE_NULLS_INDEX = TABLE_KV_COLUMNS.indexOf(STORE_NULLS_KV);
+ private static final int TRANSACTIONAL_INDEX = TABLE_KV_COLUMNS.indexOf(TRANSACTIONAL_KV);
// KeyValues for Column
private static final KeyValue DECIMAL_DIGITS_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, DECIMAL_DIGITS_BYTES);
@@ -592,6 +596,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
boolean multiTenant = multiTenantKv == null ? false : Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(multiTenantKv.getValueArray(), multiTenantKv.getValueOffset(), multiTenantKv.getValueLength()));
Cell storeNullsKv = tableKeyValues[STORE_NULLS_INDEX];
boolean storeNulls = storeNullsKv == null ? false : Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(storeNullsKv.getValueArray(), storeNullsKv.getValueOffset(), storeNullsKv.getValueLength()));
+ Cell transactionalKv = tableKeyValues[TRANSACTIONAL_INDEX];
+ boolean transactional = transactionalKv == null ? false : Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(transactionalKv.getValueArray(), transactionalKv.getValueOffset(), transactionalKv.getValueLength()));
Cell viewTypeKv = tableKeyValues[VIEW_TYPE_INDEX];
ViewType viewType = viewTypeKv == null ? null : ViewType.fromSerializedValue(viewTypeKv.getValueArray()[viewTypeKv.getValueOffset()]);
Cell viewIndexIdKv = tableKeyValues[VIEW_INDEX_ID_INDEX];
@@ -643,7 +649,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
return PTableImpl.makePTable(tenantId, schemaName, tableName, tableType, indexState, timeStamp,
tableSeqNum, pkName, saltBucketNum, columns, tableType == INDEX ? schemaName : null,
tableType == INDEX ? dataTableName : null, indexes, isImmutableRows, physicalTables, defaultFamilyName, viewStatement,
- disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, stats);
+ disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, transactional, stats);
}
private PTable buildDeletedTable(byte[] key, ImmutableBytesPtr cacheKey, HRegion region,
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/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 7d389ac..02b1fa3 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
@@ -3108,6 +3108,16 @@ public final class PTableProtos {
* <code>optional bool storeNulls = 24;</code>
*/
boolean getStoreNulls();
+
+ // optional bool transactional = 25;
+ /**
+ * <code>optional bool transactional = 25;</code>
+ */
+ boolean hasTransactional();
+ /**
+ * <code>optional bool transactional = 25;</code>
+ */
+ boolean getTransactional();
}
/**
* Protobuf type {@code PTable}
@@ -3298,6 +3308,11 @@ public final class PTableProtos {
storeNulls_ = input.readBool();
break;
}
+ case 200: {
+ bitField0_ |= 0x00100000;
+ transactional_ = input.readBool();
+ break;
+ }
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -3828,6 +3843,22 @@ public final class PTableProtos {
return storeNulls_;
}
+ // optional bool transactional = 25;
+ public static final int TRANSACTIONAL_FIELD_NUMBER = 25;
+ private boolean transactional_;
+ /**
+ * <code>optional bool transactional = 25;</code>
+ */
+ public boolean hasTransactional() {
+ return ((bitField0_ & 0x00100000) == 0x00100000);
+ }
+ /**
+ * <code>optional bool transactional = 25;</code>
+ */
+ public boolean getTransactional() {
+ return transactional_;
+ }
+
private void initFields() {
schemaNameBytes_ = com.google.protobuf.ByteString.EMPTY;
tableNameBytes_ = com.google.protobuf.ByteString.EMPTY;
@@ -3853,6 +3884,7 @@ public final class PTableProtos {
indexType_ = com.google.protobuf.ByteString.EMPTY;
statsTimeStamp_ = 0L;
storeNulls_ = false;
+ transactional_ = false;
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
@@ -3992,6 +4024,9 @@ public final class PTableProtos {
if (((bitField0_ & 0x00080000) == 0x00080000)) {
output.writeBool(24, storeNulls_);
}
+ if (((bitField0_ & 0x00100000) == 0x00100000)) {
+ output.writeBool(25, transactional_);
+ }
getUnknownFields().writeTo(output);
}
@@ -4102,6 +4137,10 @@ public final class PTableProtos {
size += com.google.protobuf.CodedOutputStream
.computeBoolSize(24, storeNulls_);
}
+ if (((bitField0_ & 0x00100000) == 0x00100000)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBoolSize(25, transactional_);
+ }
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
@@ -4233,6 +4272,11 @@ public final class PTableProtos {
result = result && (getStoreNulls()
== other.getStoreNulls());
}
+ result = result && (hasTransactional() == other.hasTransactional());
+ if (hasTransactional()) {
+ result = result && (getTransactional()
+ == other.getTransactional());
+ }
result = result &&
getUnknownFields().equals(other.getUnknownFields());
return result;
@@ -4342,6 +4386,10 @@ public final class PTableProtos {
hash = (37 * hash) + STORENULLS_FIELD_NUMBER;
hash = (53 * hash) + hashBoolean(getStoreNulls());
}
+ if (hasTransactional()) {
+ hash = (37 * hash) + TRANSACTIONAL_FIELD_NUMBER;
+ hash = (53 * hash) + hashBoolean(getTransactional());
+ }
hash = (29 * hash) + getUnknownFields().hashCode();
memoizedHashCode = hash;
return hash;
@@ -4514,6 +4562,8 @@ public final class PTableProtos {
bitField0_ = (bitField0_ & ~0x00400000);
storeNulls_ = false;
bitField0_ = (bitField0_ & ~0x00800000);
+ transactional_ = false;
+ bitField0_ = (bitField0_ & ~0x01000000);
return this;
}
@@ -4654,6 +4704,10 @@ public final class PTableProtos {
to_bitField0_ |= 0x00080000;
}
result.storeNulls_ = storeNulls_;
+ if (((from_bitField0_ & 0x01000000) == 0x01000000)) {
+ to_bitField0_ |= 0x00100000;
+ }
+ result.transactional_ = transactional_;
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
@@ -4820,6 +4874,9 @@ public final class PTableProtos {
if (other.hasStoreNulls()) {
setStoreNulls(other.getStoreNulls());
}
+ if (other.hasTransactional()) {
+ setTransactional(other.getTransactional());
+ }
this.mergeUnknownFields(other.getUnknownFields());
return this;
}
@@ -6424,6 +6481,39 @@ public final class PTableProtos {
return this;
}
+ // optional bool transactional = 25;
+ private boolean transactional_ ;
+ /**
+ * <code>optional bool transactional = 25;</code>
+ */
+ public boolean hasTransactional() {
+ return ((bitField0_ & 0x01000000) == 0x01000000);
+ }
+ /**
+ * <code>optional bool transactional = 25;</code>
+ */
+ public boolean getTransactional() {
+ return transactional_;
+ }
+ /**
+ * <code>optional bool transactional = 25;</code>
+ */
+ public Builder setTransactional(boolean value) {
+ bitField0_ |= 0x01000000;
+ transactional_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bool transactional = 25;</code>
+ */
+ public Builder clearTransactional() {
+ bitField0_ = (bitField0_ & ~0x01000000);
+ transactional_ = false;
+ onChanged();
+ return this;
+ }
+
// @@protoc_insertion_point(builder_scope:PTable)
}
@@ -6470,7 +6560,7 @@ public final class PTableProtos {
"values\030\002 \003(\014\022\033\n\023guidePostsByteCount\030\003 \001(" +
"\003\022\025\n\rkeyBytesCount\030\004 \001(\003\022\027\n\017guidePostsCo",
"unt\030\005 \001(\005\022!\n\013pGuidePosts\030\006 \001(\0132\014.PGuideP" +
- "osts\"\266\004\n\006PTable\022\027\n\017schemaNameBytes\030\001 \002(\014" +
+ "osts\"\315\004\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\016" +
"sequenceNumber\030\005 \002(\003\022\021\n\ttimeStamp\030\006 \002(\003\022" +
@@ -6484,10 +6574,11 @@ public final class PTableProtos {
"nt\030\022 \001(\014\022\025\n\rphysicalNames\030\023 \003(\014\022\020\n\010tenan" +
"tId\030\024 \001(\014\022\023\n\013viewIndexId\030\025 \001(\005\022\021\n\tindexT" +
"ype\030\026 \001(\014\022\026\n\016statsTimeStamp\030\027 \001(\003\022\022\n\nsto" +
- "reNulls\030\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\004" +
- "B@\n(org.apache.phoenix.coprocessor.gener" +
- "atedB\014PTableProtosH\001\210\001\001\240\001\001"
+ "reNulls\030\030 \001(\010\022\025\n\rtransactional\030\031 \001(\010*A\n\n" +
+ "PTableType\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.ph" +
+ "oenix.coprocessor.generatedB\014PTableProto" +
+ "sH\001\210\001\001\240\001\001"
};
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -6511,7 +6602,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", });
+ 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", "Transactional", });
return null;
}
};
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/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 f4b4f98..207f80b 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
@@ -240,6 +240,10 @@ public enum SQLExceptionCode {
NO_LOCAL_INDEXES(1054, "43A11", "Local secondary indexes are not supported for HBase versions " +
MetaDataUtil.decodeHBaseVersionAsString(PhoenixDatabaseMetaData.MIN_LOCAL_SI_VERSION_DISALLOW) + " through " + MetaDataUtil.decodeHBaseVersionAsString(PhoenixDatabaseMetaData.MAX_LOCAL_SI_VERSION_DISALLOW) + " inclusive."),
UNALLOWED_LOCAL_INDEXES(1055, "43A12", "Local secondary indexes are configured to not be allowed."),
+
+ DEFAULT_COLUMN_FAMILY_ON_SHARED_TABLE(1056, "43A13", "Default column family not allowed on VIEW or shared INDEX"),
+ ONLY_TABLE_MAY_BE_DECLARED_TRANSACTIONAL(1070, "44A01", "Only tables may be declared as transactional"),
+ MAY_NOT_MAP_TO_EXISTING_TABLE_AS_TRANSACTIONAL(1071, "44A02", "An existing HBase table may not be mapped to as a transactional table"),
/** Sequence related */
SEQUENCE_ALREADY_EXIST(1200, "42Z00", "Sequence already exists.", new Factory() {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java
index b98d705..4270ef9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java
@@ -17,6 +17,10 @@
*/
package org.apache.phoenix.execute;
+import static org.apache.phoenix.monitoring.PhoenixMetrics.SizeMetric.MUTATION_BATCH_SIZE;
+import static org.apache.phoenix.monitoring.PhoenixMetrics.SizeMetric.MUTATION_BYTES;
+import static org.apache.phoenix.monitoring.PhoenixMetrics.SizeMetric.MUTATION_COMMIT_TIME;
+
import java.io.IOException;
import java.sql.SQLException;
import java.util.Collections;
@@ -24,6 +28,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import co.cask.tephra.hbase98.TransactionAwareHTable;
+
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.Mutation;
@@ -62,9 +68,6 @@ import org.slf4j.LoggerFactory;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import static org.apache.phoenix.monitoring.PhoenixMetrics.SizeMetric.MUTATION_BYTES;
-import static org.apache.phoenix.monitoring.PhoenixMetrics.SizeMetric.MUTATION_BATCH_SIZE;
-import static org.apache.phoenix.monitoring.PhoenixMetrics.SizeMetric.MUTATION_COMMIT_TIME;
/**
*
@@ -414,6 +417,9 @@ public class MutationState implements SQLCloseable {
SQLException sqlE = null;
HTableInterface hTable = connection.getQueryServices().getTable(htableName);
+ if (table.isTransactional()) {
+ hTable = new TransactionAwareHTable(hTable);
+ }
try {
logMutationSize(hTable, mutations, connection);
MUTATION_BATCH_SIZE.update(mutations.size());
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java
index ea13dfd..91aa573 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java
@@ -21,9 +21,12 @@ import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
+import co.cask.tephra.hbase98.TransactionAwareHTable;
+
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.schema.TableRef;
import org.apache.phoenix.schema.tuple.Tuple;
import org.apache.phoenix.util.Closeables;
@@ -80,7 +83,12 @@ public class TableResultIterator extends ExplainTable implements ResultIterator
public TableResultIterator(StatementContext context, TableRef tableRef, Scan scan, ScannerCreation creationMode) throws SQLException {
super(context, tableRef);
this.scan = scan;
- htable = context.getConnection().getQueryServices().getTable(tableRef.getTable().getPhysicalName().getBytes());
+ PTable table = tableRef.getTable();
+ HTableInterface htable = context.getConnection().getQueryServices().getTable(table.getPhysicalName().getBytes());
+ if (table.isTransactional()) {
+ htable = new TransactionAwareHTable(htable);
+ }
+ this.htable = htable;
if (creationMode == ScannerCreation.IMMEDIATE) {
getDelegate(false);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/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 8a8e072..f005c3d 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
@@ -606,8 +606,10 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
new HTableDescriptor(TableName.valueOf(tableName));
for (Entry<String,Object> entry : tableProps.entrySet()) {
String key = entry.getKey();
- Object value = entry.getValue();
- tableDescriptor.setValue(key, value == null ? null : value.toString());
+ if (!TableProperty.isPhoenixTableProperty(key)) {
+ Object value = entry.getValue();
+ tableDescriptor.setValue(key, value == null ? null : value.toString());
+ }
}
if (families.isEmpty()) {
if (tableType != PTableType.VIEW) {
@@ -638,11 +640,11 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
}
}
}
- addCoprocessors(tableName, tableDescriptor, tableType);
+ addCoprocessors(tableName, tableDescriptor, tableType, tableProps);
return tableDescriptor;
}
- private void addCoprocessors(byte[] tableName, HTableDescriptor descriptor, PTableType tableType) throws SQLException {
+ private void addCoprocessors(byte[] tableName, HTableDescriptor descriptor, PTableType tableType, Map<String,Object> tableProps) throws SQLException {
// The phoenix jar must be available on HBase classpath
int priority = props.getInt(QueryServices.COPROCESSOR_PRIORITY_ATTRIB, QueryServicesOptions.DEFAULT_COPROCESSOR_PRIORITY);
try {
@@ -705,7 +707,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
}
}
- if (SchemaUtil.isTransactional(descriptor) && !descriptor.hasCoprocessor(TransactionProcessor.class.getName())) {
+ if (Boolean.TRUE.equals(tableProps.get(TableProperty.TRANSACTIONAL.name())) && !descriptor.hasCoprocessor(TransactionProcessor.class.getName())) {
descriptor.addCoprocessor(TransactionProcessor.class.getName(), null, priority - 10, null);
}
} catch (IOException e) {
@@ -863,8 +865,11 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
checkClientServerCompatibility();
}
- if (!modifyExistingMetaData || existingDesc.equals(newDesc)) {
- return existingDesc;
+ if (!modifyExistingMetaData) {
+ return existingDesc; // Caller already knows that no metadata was changed
+ }
+ if (existingDesc.equals(newDesc)) {
+ return null; // Indicate that no metadata was changed
}
// Don't allow TRANSACTIONAL attribute to change, as we may have issued
@@ -1209,6 +1214,17 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
// For views this will ensure that metadata already exists
// For tables and indexes, this will create the metadata if it doesn't already exist
tableDescriptor = ensureTableCreated(tableName, tableType, tableProps, families, splits, true);
+ // This means the HTable already existed and is transactional which is an error case for now,
+ // as the timestamps are likely not scaled and the table may have delete markers (which isn't
+ // handled by Tephra currently). It's possible that we could allow this, but only allow queries
+ // after a major compaction and some conversion process runs.
+ ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+ boolean isTransactional = MetaDataUtil.isTransactional(m, kvBuilder, ptr);
+ if (tableDescriptor != null && isTransactional) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.MAY_NOT_MAP_TO_EXISTING_TABLE_AS_TRANSACTIONAL)
+ .setSchemaName(Bytes.toString(schemaBytes)).setTableName(Bytes.toString(tableBytes))
+ .build().buildException();
+ }
}
ImmutableBytesWritable ptr = new ImmutableBytesWritable();
if (tableType == PTableType.INDEX) { // Index on view
@@ -1263,12 +1279,6 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
return rpcCallback.get();
}
});
- // This means the HTable already existed and is transactional which is an
- // error case unless IF NOT EXISTS was supplied (which the caller will check).
- Object isTransactional = tableProps.get(PhoenixDatabaseMetaData.TRANSACTIONAL);
- if (tableDescriptor != null && Boolean.TRUE.equals(isTransactional) != SchemaUtil.isTransactional(tableDescriptor)) {
- return new MetaDataMutationResult(MutationCode.TABLE_ALREADY_EXISTS, result.getMutationTime(), result.getTable());
- }
return result;
}
@@ -1470,13 +1480,6 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
SQLException sqlE = null;
if (tableDescriptor != null) {
try {
- if (SchemaUtil.hasTransactional(tableDescriptor)) {
- throw new SQLExceptionInfo.Builder(
- SQLExceptionCode.SET_UNSUPPORTED_PROP_ON_ALTER_TABLE)
- .setMessage(PhoenixDatabaseMetaData.TRANSACTIONAL)
- .setSchemaName(table.getSchemaName().getString())
- .setTableName(table.getTableName().getString()).build().buildException();
- }
boolean pollingNotNeeded = (!tableProps.isEmpty() && families.isEmpty() && colFamiliesForPColumnsToBeAdded.isEmpty());
modifyTable(table.getPhysicalName().getBytes(), tableDescriptor, !pollingNotNeeded);
} catch (IOException e) {
@@ -2020,7 +2023,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
public MutationState updateData(MutationPlan plan) throws SQLException {
PTable table = plan.getContext().getCurrentTable().getTable();
HTableDescriptor desc = this.getTableDescriptor(table.getPhysicalName().getBytes());
- if (SchemaUtil.isTransactional(desc)) {
+ if (table.isTransactional()) {
return new MutationState(1, plan.getConnection());
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/phoenix-core/src/main/java/org/apache/phoenix/query/HTableFactory.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/HTableFactory.java b/phoenix-core/src/main/java/org/apache/phoenix/query/HTableFactory.java
index 4e1c089..f44fb09 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/HTableFactory.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/HTableFactory.java
@@ -20,11 +20,8 @@ package org.apache.phoenix.query;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
-import co.cask.tephra.hbase98.TransactionAwareHTable;
-
import org.apache.hadoop.hbase.client.HConnection;
import org.apache.hadoop.hbase.client.HTableInterface;
-import org.apache.phoenix.util.SchemaUtil;
/**
* Creates clients to access HBase tables.
@@ -51,9 +48,6 @@ public interface HTableFactory {
@Override
public HTableInterface getTable(byte[] tableName, HConnection connection, ExecutorService pool) throws IOException {
HTableInterface htable = connection.getTable(tableName, pool);
- if (SchemaUtil.isTransactional(htable.getTableDescriptor())) {
- return new TransactionAwareHTable(htable);
- }
return htable;
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/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 6470b72..b317d77 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
@@ -63,7 +63,6 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.PK_NAME;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.REF_GENERATION;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.REGION_NAME;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.REMARKS;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.STORE_NULLS;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SALT_BUCKETS;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SCOPE_CATALOG;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SCOPE_SCHEMA;
@@ -76,6 +75,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SOURCE_DATA_TYPE;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SQL_DATA_TYPE;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SQL_DATETIME_SUB;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.START_WITH;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.STORE_NULLS;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_TABLE;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_STATS_TABLE;
@@ -84,6 +84,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SEQ_NUM;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_TYPE;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TENANT_ID;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TRANSACTIONAL;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TYPE_NAME;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TYPE_SEQUENCE;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_CONSTANT;
@@ -230,7 +231,8 @@ public interface QueryConstants {
IS_AUTOINCREMENT + " VARCHAR," +
INDEX_TYPE + " UNSIGNED_TINYINT," +
INDEX_DISABLE_TIMESTAMP + " BIGINT," +
- STORE_NULLS + " BOOLEAN," +
+ STORE_NULLS + " BOOLEAN," +
+ TRANSACTIONAL + " 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/8119bee5/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
index 2eab5dd..0d2c36f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
@@ -153,6 +153,7 @@ public interface QueryServices extends SQLCloseable {
public static final String DEFAULT_KEEP_DELETED_CELLS_ATTRIB = "phoenix.table.default.keep.deleted.cells";
public static final String DEFAULT_STORE_NULLS_ATTRIB = "phoenix.table.default.store.nulls";
public static final String METRICS_ENABLED = "phoenix.query.metrics.enabled";
+ public static final String DEFAULT_TRANSACTIONAL_ATTRIB = "phoenix.transactions.default.enabled";
/**
* Get executor service used for parallel scans
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
index 8cd740a..1e0de9d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
@@ -41,6 +41,7 @@ import static org.apache.phoenix.query.QueryServices.MAX_SERVER_CACHE_TIME_TO_LI
import static org.apache.phoenix.query.QueryServices.MAX_SERVER_METADATA_CACHE_SIZE_ATTRIB;
import static org.apache.phoenix.query.QueryServices.MAX_SPOOL_TO_DISK_BYTES_ATTRIB;
import static org.apache.phoenix.query.QueryServices.MAX_TENANT_MEMORY_PERC_ATTRIB;
+import static org.apache.phoenix.query.QueryServices.METRICS_ENABLED;
import static org.apache.phoenix.query.QueryServices.MIN_STATS_UPDATE_FREQ_MS_ATTRIB;
import static org.apache.phoenix.query.QueryServices.MUTATE_BATCH_SIZE_ATTRIB;
import static org.apache.phoenix.query.QueryServices.NUM_RETRIES_FOR_SCHEMA_UPDATE_CHECK;
@@ -61,7 +62,6 @@ import static org.apache.phoenix.query.QueryServices.STATS_USE_CURRENT_TIME_ATTR
import static org.apache.phoenix.query.QueryServices.THREAD_POOL_SIZE_ATTRIB;
import static org.apache.phoenix.query.QueryServices.THREAD_TIMEOUT_MS_ATTRIB;
import static org.apache.phoenix.query.QueryServices.USE_INDEXES_ATTRIB;
-import static org.apache.phoenix.query.QueryServices.METRICS_ENABLED;
import java.util.Map.Entry;
@@ -181,8 +181,10 @@ public class QueryServicesOptions {
public static final boolean DEFAULT_STORE_NULLS = false;
// TODO Change this to true as part of PHOENIX-1543
+ // We'll also need this for transactions to work correctly
public static final boolean DEFAULT_AUTO_COMMIT = false;
public static final boolean DEFAULT_IS_METRICS_ENABLED = true;
+ public static final boolean DEFAULT_TRANSACTIONAL = false;
private final Configuration config;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/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 b719aae..89c2283 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
@@ -236,4 +236,9 @@ public class DelegateTable implements PTable {
public PName getParentSchemaName() {
return delegate.getParentSchemaName();
}
+
+ @Override
+ public boolean isTransactional() {
+ return delegate.isTransactional();
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/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 b2b1bc9..54a5c7e 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
@@ -58,6 +58,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SEQ_NUM;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_TYPE;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TENANT_ID;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TRANSACTIONAL;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_CONSTANT;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_INDEX_ID;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_STATEMENT;
@@ -198,8 +199,9 @@ public class MetaDataClient {
VIEW_TYPE + "," +
VIEW_INDEX_ID + "," +
INDEX_TYPE + "," +
- STORE_NULLS +
- ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+ STORE_NULLS + "," +
+ TRANSACTIONAL +
+ ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static final String CREATE_LINK =
"UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\"( " +
TENANT_ID + "," +
@@ -1204,54 +1206,58 @@ public class MetaDataClient {
String tenantIdStr = tenantId == null ? null : connection.getTenantId().getString();
boolean multiTenant = false;
boolean storeNulls = false;
+ boolean transactional = false;
Integer saltBucketNum = null;
String defaultFamilyName = null;
boolean isImmutableRows = false;
List<PName> physicalNames = Collections.emptyList();
boolean addSaltColumn = false;
- if (parent != null && tableType == PTableType.INDEX) {
- // 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
- // from the table to the index, though.
- if (indexType == IndexType.LOCAL || (parent.getType() == PTableType.VIEW && parent.getViewType() != ViewType.MAPPED)) {
- PName physicalName = parent.getPhysicalName();
- saltBucketNum = parent.getBucketNum();
- addSaltColumn = (saltBucketNum != null && indexType != IndexType.LOCAL);
- defaultFamilyName = parent.getDefaultFamilyName() == null ? null : parent.getDefaultFamilyName().getString();
- if (indexType == IndexType.LOCAL) {
- saltBucketNum = null;
- // Set physical name of local index table
- physicalNames = Collections.singletonList(PNameFactory.newName(MetaDataUtil.getLocalIndexPhysicalName(physicalName.getBytes())));
- } else {
- // Set physical name of view index table
- physicalNames = Collections.singletonList(PNameFactory.newName(MetaDataUtil.getViewIndexPhysicalName(physicalName.getBytes())));
+ if (parent != null) {
+ transactional = parent.isTransactional();
+ storeNulls = parent.getStoreNulls();
+ if (tableType == PTableType.INDEX) {
+ // 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
+ // from the table to the index, though.
+ if (indexType == IndexType.LOCAL || (parent.getType() == PTableType.VIEW && parent.getViewType() != ViewType.MAPPED)) {
+ PName physicalName = parent.getPhysicalName();
+ saltBucketNum = parent.getBucketNum();
+ addSaltColumn = (saltBucketNum != null && indexType != IndexType.LOCAL);
+ defaultFamilyName = parent.getDefaultFamilyName() == null ? null : parent.getDefaultFamilyName().getString();
+ if (indexType == IndexType.LOCAL) {
+ saltBucketNum = null;
+ // Set physical name of local index table
+ physicalNames = Collections.singletonList(PNameFactory.newName(MetaDataUtil.getLocalIndexPhysicalName(physicalName.getBytes())));
+ } else {
+ // Set physical name of view index table
+ physicalNames = Collections.singletonList(PNameFactory.newName(MetaDataUtil.getViewIndexPhysicalName(physicalName.getBytes())));
+ }
}
+
+ multiTenant = parent.isMultiTenant();
+ parentTableName = parent.getTableName().getString();
+ // Pass through data table sequence number so we can check it hasn't changed
+ PreparedStatement incrementStatement = connection.prepareStatement(INCREMENT_SEQ_NUM);
+ incrementStatement.setString(1, connection.getTenantId() == null ? null : connection.getTenantId().getString());
+ incrementStatement.setString(2, schemaName);
+ incrementStatement.setString(3, parentTableName);
+ incrementStatement.setLong(4, parent.getSequenceNumber());
+ incrementStatement.execute();
+ // Get list of mutations and add to table meta data that will be passed to server
+ // to guarantee order. This row will always end up last
+ tableMetaData.addAll(connection.getMutationState().toMutations().next().getSecond());
+ connection.rollback();
+
+ // Add row linking from data table row to index table row
+ PreparedStatement linkStatement = connection.prepareStatement(CREATE_LINK);
+ linkStatement.setString(1, connection.getTenantId() == null ? null : connection.getTenantId().getString());
+ linkStatement.setString(2, schemaName);
+ linkStatement.setString(3, parentTableName);
+ linkStatement.setString(4, tableName);
+ linkStatement.setByte(5, LinkType.INDEX_TABLE.getSerializedValue());
+ linkStatement.execute();
}
-
- multiTenant = parent.isMultiTenant();
- storeNulls = parent.getStoreNulls();
- parentTableName = parent.getTableName().getString();
- // Pass through data table sequence number so we can check it hasn't changed
- PreparedStatement incrementStatement = connection.prepareStatement(INCREMENT_SEQ_NUM);
- incrementStatement.setString(1, connection.getTenantId() == null ? null : connection.getTenantId().getString());
- incrementStatement.setString(2, schemaName);
- incrementStatement.setString(3, parentTableName);
- incrementStatement.setLong(4, parent.getSequenceNumber());
- incrementStatement.execute();
- // Get list of mutations and add to table meta data that will be passed to server
- // to guarantee order. This row will always end up last
- tableMetaData.addAll(connection.getMutationState().toMutations().next().getSecond());
- connection.rollback();
-
- // Add row linking from data table row to index table row
- PreparedStatement linkStatement = connection.prepareStatement(CREATE_LINK);
- linkStatement.setString(1, connection.getTenantId() == null ? null : connection.getTenantId().getString());
- linkStatement.setString(2, schemaName);
- linkStatement.setString(3, parentTableName);
- linkStatement.setString(4, tableName);
- linkStatement.setByte(5, LinkType.INDEX_TABLE.getSerializedValue());
- linkStatement.execute();
}
PrimaryKeyConstraint pkConstraint = statement.getPrimaryKeyConstraint();
@@ -1284,7 +1290,7 @@ public class MetaDataClient {
// 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)) {
- Boolean isImmutableRowsProp = (Boolean) tableProps.remove(PTable.IS_IMMUTABLE_ROWS_PROP_NAME);
+ Boolean isImmutableRowsProp = (Boolean) tableProps.get(PTable.IS_IMMUTABLE_ROWS_PROP_NAME);
if (isImmutableRowsProp == null) {
isImmutableRows = connection.getQueryServices().getProps().getBoolean(QueryServices.IMMUTABLE_ROWS_ATTRIB, QueryServicesOptions.DEFAULT_IMMUTABLE_ROWS);
} else {
@@ -1294,7 +1300,7 @@ public class MetaDataClient {
// Can't set any of these on views or shared indexes on views
if (tableType != PTableType.VIEW && indexId == null) {
- saltBucketNum = (Integer) tableProps.remove(PhoenixDatabaseMetaData.SALT_BUCKETS);
+ saltBucketNum = (Integer) tableProps.get(PhoenixDatabaseMetaData.SALT_BUCKETS);
if (saltBucketNum != null) {
if (saltBucketNum < 0 || saltBucketNum > SaltingUtil.MAX_BUCKET_NUM) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_BUCKET_NUM).build().buildException();
@@ -1311,35 +1317,56 @@ public class MetaDataClient {
addSaltColumn = (saltBucketNum != null);
}
- boolean removedProp = false;
// Can't set MULTI_TENANT or DEFAULT_COLUMN_FAMILY_NAME on an INDEX or a non mapped VIEW
if (tableType != PTableType.INDEX && (tableType != PTableType.VIEW || viewType == ViewType.MAPPED)) {
- Boolean multiTenantProp = (Boolean) tableProps.remove(PhoenixDatabaseMetaData.MULTI_TENANT);
+ Boolean multiTenantProp = (Boolean) tableProps.get(PhoenixDatabaseMetaData.MULTI_TENANT);
multiTenant = Boolean.TRUE.equals(multiTenantProp);
- defaultFamilyName = (String)tableProps.remove(PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME);
- removedProp = (defaultFamilyName != null);
+ defaultFamilyName = (String)tableProps.get(PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME);
}
boolean disableWAL = false;
- Boolean disableWALProp = (Boolean) tableProps.remove(PhoenixDatabaseMetaData.DISABLE_WAL);
+ Boolean disableWALProp = (Boolean) tableProps.get(PhoenixDatabaseMetaData.DISABLE_WAL);
if (disableWALProp != null) {
disableWAL = disableWALProp;
}
- Boolean storeNullsProp = (Boolean) tableProps.remove(PhoenixDatabaseMetaData.STORE_NULLS);
- storeNulls = storeNullsProp == null
- ? connection.getQueryServices().getProps().getBoolean(
- QueryServices.DEFAULT_STORE_NULLS_ATTRIB,
- QueryServicesOptions.DEFAULT_STORE_NULLS)
- : storeNullsProp;
+ Boolean storeNullsProp = (Boolean) tableProps.get(PhoenixDatabaseMetaData.STORE_NULLS);
+ if (storeNullsProp == null) {
+ if (parent == null) {
+ storeNulls = connection.getQueryServices().getProps().getBoolean(
+ QueryServices.DEFAULT_STORE_NULLS_ATTRIB,
+ QueryServicesOptions.DEFAULT_STORE_NULLS);
+ }
+ } else {
+ storeNulls = storeNullsProp;
+ }
+ Boolean transactionalProp = (Boolean) tableProps.get(PhoenixDatabaseMetaData.TRANSACTIONAL);
+ if (transactionalProp != null && parent != null) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.ONLY_TABLE_MAY_BE_DECLARED_TRANSACTIONAL)
+ .setSchemaName(schemaName).setTableName(tableName)
+ .build().buildException();
+ }
+ if (parent == null) {
+ if (transactionalProp == null) {
+ transactional = connection.getQueryServices().getProps().getBoolean(
+ QueryServices.DEFAULT_TRANSACTIONAL_ATTRIB,
+ QueryServicesOptions.DEFAULT_TRANSACTIONAL);
+ } else {
+ transactional = transactionalProp;
+ }
+ }
// Delay this check as it is supported to have IMMUTABLE_ROWS and SALT_BUCKETS defined on views
- if ((statement.getTableType() == PTableType.VIEW || indexId != null) && !tableProps.isEmpty()) {
- throw new SQLExceptionInfo.Builder(SQLExceptionCode.VIEW_WITH_PROPERTIES).build()
- .buildException();
- }
- if (removedProp) {
- tableProps.put(PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME, defaultFamilyName);
+ if (statement.getTableType() == PTableType.VIEW || indexId != null) {
+ if (tableProps.get(PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME) != null) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.DEFAULT_COLUMN_FAMILY_ON_SHARED_TABLE)
+ .setSchemaName(schemaName).setTableName(tableName)
+ .build().buildException();
+ }
+ if (SchemaUtil.hasHTableDescriptorProps(tableProps)) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.VIEW_WITH_PROPERTIES).build()
+ .buildException();
+ }
}
List<ColumnDef> colDefs = statement.getColumnDefs();
@@ -1561,7 +1588,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);
+ Boolean.TRUE.equals(disableWAL), false, false, null, indexId, indexType, false);
connection.addTable(table);
} else if (tableType == PTableType.INDEX && indexId == null) {
if (tableProps.get(HTableDescriptor.MAX_FILESIZE) == null) {
@@ -1658,6 +1685,7 @@ public class MetaDataClient {
tableUpsert.setByte(18, indexType.getSerializedValue());
}
tableUpsert.setBoolean(19, storeNulls);
+ tableUpsert.setBoolean(20, transactional);
tableUpsert.execute();
tableMetaData.addAll(connection.getMutationState().toMutations().next().getSecond());
@@ -1712,7 +1740,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);
+ indexId, indexType, transactional);
result = new MetaDataMutationResult(code, result.getMutationTime(), table, true);
addTableToCache(result);
return table;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/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 d0fea88..6b7f8c6 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
@@ -314,6 +314,7 @@ public interface PTable {
boolean isWALDisabled();
boolean isMultiTenant();
boolean getStoreNulls();
+ boolean isTransactional();
ViewType getViewType();
String getViewStatement();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/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 658ff23..163daa2 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
@@ -119,6 +119,7 @@ public class PTableImpl implements PTable {
private boolean disableWAL;
private boolean multiTenant;
private boolean storeNulls;
+ private boolean isTransactional;
private ViewType viewType;
private Short viewIndexId;
private int estimatedSize;
@@ -192,7 +193,7 @@ public class PTableImpl implements PTable {
table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), timeStamp,
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.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.isTransactional(), table.getTableStats());
}
public static PTableImpl makePTable(PTable table, List<PColumn> columns) throws SQLException {
@@ -200,7 +201,7 @@ public class PTableImpl implements PTable {
table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), table.getTimeStamp(),
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.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.isTransactional(), table.getTableStats());
}
public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns) throws SQLException {
@@ -208,7 +209,7 @@ public class PTableImpl implements PTable {
table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), timeStamp,
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.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.isTransactional(), table.getTableStats());
}
public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns, boolean isImmutableRows) throws SQLException {
@@ -216,7 +217,7 @@ public class PTableImpl implements PTable {
table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), timeStamp,
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.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.isTransactional(), table.getTableStats());
}
public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns, boolean isImmutableRows, boolean isWalDisabled, boolean isMultitenant, boolean storeNulls) throws SQLException {
@@ -224,7 +225,7 @@ public class PTableImpl implements PTable {
table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), timeStamp,
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());
+ isWalDisabled, isMultitenant, storeNulls, table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.isTransactional(), table.getTableStats());
}
public static PTableImpl makePTable(PTable table, PIndexState state) throws SQLException {
@@ -233,7 +234,7 @@ public class PTableImpl implements PTable {
table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), getColumnsToClone(table),
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.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.isTransactional(), table.getTableStats());
}
public static PTableImpl makePTable(PTable table, PTableStats stats) throws SQLException {
@@ -242,28 +243,28 @@ public class PTableImpl implements PTable {
table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), getColumnsToClone(table),
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.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.isTransactional(), stats);
}
public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type, PIndexState state, long timeStamp, long sequenceNumber,
PName pkName, Integer bucketNum, List<PColumn> columns, PName dataSchemaName, PName dataTableName, List<PTable> indexes,
boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression, boolean disableWAL, boolean multiTenant,
- boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType) throws SQLException {
+ boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType, boolean isTransactional) 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);
+ indexType, isTransactional, PTableStats.EMPTY_STATS);
}
public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type,
PIndexState state, long timeStamp, long sequenceNumber, PName pkName, Integer bucketNum,
List<PColumn> columns, PName dataSchemaName, PName dataTableName, List<PTable> indexes,
boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression,
- boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType, @NotNull PTableStats stats)
+ boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType, boolean isTransactional, @NotNull PTableStats stats)
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);
+ defaultFamilyName, viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, isTransactional, stats);
}
private PTableImpl(PName tenantId, PName schemaName, PName tableName, PTableType type, PIndexState state,
@@ -271,10 +272,10 @@ 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) throws SQLException {
+ boolean isTransactional, PTableStats stats) 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);
+ viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, isTransactional);
}
@Override
@@ -302,7 +303,7 @@ 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 ) throws SQLException {
+ IndexType indexType, boolean isTransactional ) 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 +
@@ -331,6 +332,7 @@ public class PTableImpl implements PTable {
this.viewType = viewType;
this.viewIndexId = viewIndexId;
this.indexType = indexType;
+ this.isTransactional = isTransactional;
this.tableStats = stats;
List<PColumn> pkColumns;
PColumn[] allColumns;
@@ -950,6 +952,7 @@ public class PTableImpl implements PTable {
boolean disableWAL = table.getDisableWAL();
boolean multiTenant = table.getMultiTenant();
boolean storeNulls = table.getStoreNulls();
+ boolean isTransactional = table.getTransactional();
ViewType viewType = null;
String viewStatement = null;
List<PName> physicalNames = Collections.emptyList();
@@ -971,7 +974,7 @@ public class PTableImpl implements PTable {
result.init(tenantId, schemaName, tableName, tableType, indexState, timeStamp, sequenceNumber, pkName,
(bucketNum == NO_SALTING) ? null : bucketNum, columns, stats, schemaName,dataTableName, indexes,
isImmutableRows, physicalNames, defaultFamilyName, viewStatement, disableWAL,
- multiTenant, storeNulls, viewType, viewIndexId, indexType);
+ multiTenant, storeNulls, viewType, viewIndexId, indexType, isTransactional);
return result;
} catch (SQLException e) {
throw new RuntimeException(e); // Impossible
@@ -1051,6 +1054,7 @@ public class PTableImpl implements PTable {
builder.setDisableWAL(table.isWALDisabled());
builder.setMultiTenant(table.isMultiTenant());
builder.setStoreNulls(table.getStoreNulls());
+ builder.setTransactional(table.isTransactional());
if(table.getType() == PTableType.VIEW){
builder.setViewType(HBaseZeroCopyByteString.wrap(new byte[]{table.getViewType().getSerializedValue()}));
builder.setViewStatement(HBaseZeroCopyByteString.wrap(PVarchar.INSTANCE.toBytes(table.getViewStatement())));
@@ -1079,4 +1083,9 @@ public class PTableImpl implements PTable {
return parentSchemaName;
}
+ @Override
+ public boolean isTransactional() {
+ return isTransactional;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/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 c429ac4..3c96405 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
@@ -46,7 +46,10 @@ public enum TableProperty {
TTL(HColumnDescriptor.TTL, COLUMN_FAMILY_NOT_ALLOWED_FOR_TTL, true, CANNOT_ALTER_PROPERTY, false),
- STORE_NULLS(PhoenixDatabaseMetaData.STORE_NULLS, COLUMN_FAMILY_NOT_ALLOWED_TABLE_PROPERTY, true, false);
+ STORE_NULLS(PhoenixDatabaseMetaData.STORE_NULLS, COLUMN_FAMILY_NOT_ALLOWED_TABLE_PROPERTY, true, false),
+
+ TRANSACTIONAL(PhoenixDatabaseMetaData.TRANSACTIONAL, COLUMN_FAMILY_NOT_ALLOWED_TABLE_PROPERTY, false, CANNOT_ALTER_PROPERTY, false),
+ ;
private final String propertyName;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/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 c1aa2cc..529c80a 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
@@ -49,16 +49,16 @@ import org.apache.phoenix.hbase.index.util.VersionUtil;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
import org.apache.phoenix.query.QueryConstants;
-import org.apache.phoenix.schema.types.PBoolean;
-import org.apache.phoenix.schema.types.PDataType;
-import org.apache.phoenix.schema.types.PLong;
import org.apache.phoenix.schema.PName;
-import org.apache.phoenix.schema.types.PSmallint;
import org.apache.phoenix.schema.PTable;
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.types.PBoolean;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PLong;
+import org.apache.phoenix.schema.types.PSmallint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -259,6 +259,13 @@ public class MetaDataUtil {
return false;
}
+ public static boolean isTransactional(Mutation m, KeyValueBuilder builder, ImmutableBytesWritable ptr) {
+ if (getMutationValue(m, PhoenixDatabaseMetaData.TRANSACTIONAL_BYTES, builder, ptr)) {
+ return Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(ptr));
+ }
+ return false;
+ }
+
public static boolean isSalted(Mutation m, KeyValueBuilder builder, ImmutableBytesWritable ptr) {
return MetaDataUtil.getMutationValue(m, PhoenixDatabaseMetaData.SALT_BUCKETS_BYTES, builder, ptr);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
index a94e8ef..47db678 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
@@ -29,11 +29,11 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import javax.annotation.Nullable;
-import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
import org.apache.hadoop.hbase.util.Bytes;
@@ -57,6 +57,7 @@ import org.apache.phoenix.schema.RowKeySchema;
import org.apache.phoenix.schema.RowKeySchema.RowKeySchemaBuilder;
import org.apache.phoenix.schema.SaltingUtil;
import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.TableProperty;
import org.apache.phoenix.schema.ValueSchema.Field;
import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.schema.types.PVarbinary;
@@ -371,16 +372,6 @@ public class SchemaUtil {
.getName().getBytesPtr();
}
- public static boolean isTransactional(HTableDescriptor descriptor) {
- byte[] isTransactional = descriptor.getValue(PhoenixDatabaseMetaData.TRANSACTIONAL_BYTES);
- return (isTransactional != null && Boolean.TRUE.toString().equalsIgnoreCase(Bytes.toString(isTransactional)));
- }
-
- public static boolean hasTransactional(HTableDescriptor descriptor) {
- byte[] isTransactional = descriptor.getValue(PhoenixDatabaseMetaData.TRANSACTIONAL_BYTES);
- return (isTransactional != null);
- }
-
public static boolean isMetaTable(byte[] tableName) {
return Bytes.compareTo(tableName, SYSTEM_CATALOG_NAME_BYTES) == 0;
}
@@ -689,4 +680,14 @@ public class SchemaUtil {
checkArgument(!isNullOrEmpty(columnName), "Column name cannot be null or empty");
return columnFamilyName == null ? ("\"" + columnName + "\"") : ("\"" + columnFamilyName + "\"" + QueryConstants.NAME_SEPARATOR + "\"" + columnName + "\"");
}
+
+ public static boolean hasHTableDescriptorProps(Map<String, Object> tableProps) {
+ int pTablePropCount = 0;
+ for (String prop : tableProps.keySet()) {
+ if (TableProperty.isPhoenixTableProperty(prop)) {
+ pTablePropCount++;
+ }
+ }
+ return tableProps.size() - pTablePropCount > 0;
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
index 4accd38..7c36245 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
@@ -1473,7 +1473,7 @@ public class QueryCompilerTest extends BaseConnectionlessQueryTest {
statement.execute("create local index my_idx on example (fn) DEFAULT_COLUMN_FAMILY='F'");
fail();
} catch (SQLException e) {
- assertEquals(SQLExceptionCode.VIEW_WITH_PROPERTIES.getErrorCode(),e.getErrorCode());
+ assertEquals(SQLExceptionCode.DEFAULT_COLUMN_FAMILY_ON_SHARED_TABLE.getErrorCode(),e.getErrorCode());
}
statement.execute("create local index my_idx on example (fn)");
} finally {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8119bee5/phoenix-protocol/src/main/PTable.proto
----------------------------------------------------------------------
diff --git a/phoenix-protocol/src/main/PTable.proto b/phoenix-protocol/src/main/PTable.proto
index 348631f..ababd23 100644
--- a/phoenix-protocol/src/main/PTable.proto
+++ b/phoenix-protocol/src/main/PTable.proto
@@ -83,4 +83,5 @@ message PTable {
optional bytes indexType = 22;
optional int64 statsTimeStamp = 23;
optional bool storeNulls = 24;
+ optional bool transactional = 25;
}