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/02/07 01:13:25 UTC
[1/3] phoenix git commit: PHOENIX-1644 Check for min HBase version
before creating local index and provide means of disabling usage
Repository: phoenix
Updated Branches:
refs/heads/master 2d7703339 -> 9db37bd90
PHOENIX-1644 Check for min HBase version before creating local index and provide means of disabling usage
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/54c4ed80
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/54c4ed80
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/54c4ed80
Branch: refs/heads/master
Commit: 54c4ed80869f6ac0011a65d1247285cfae0a6759
Parents: f3c675b
Author: James Taylor <jt...@salesforce.com>
Authored: Fri Feb 6 14:43:04 2015 -0800
Committer: James Taylor <jt...@salesforce.com>
Committed: Fri Feb 6 14:59:01 2015 -0800
----------------------------------------------------------------------
.../phoenix/end2end/DisableLocalIndexIT.java | 99 ++++++++++++++++++++
.../phoenix/exception/SQLExceptionCode.java | 3 +
.../phoenix/jdbc/PhoenixDatabaseMetaData.java | 5 +-
.../query/ConnectionQueryServicesImpl.java | 8 ++
.../org/apache/phoenix/query/HTableFactory.java | 3 +-
.../org/apache/phoenix/query/QueryServices.java | 1 +
.../phoenix/query/QueryServicesOptions.java | 1 +
.../apache/phoenix/schema/MetaDataClient.java | 13 ++-
8 files changed, 127 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/54c4ed80/phoenix-core/src/it/java/org/apache/phoenix/end2end/DisableLocalIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DisableLocalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DisableLocalIndexIT.java
new file mode 100644
index 0000000..5f18a1c
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DisableLocalIndexIT.java
@@ -0,0 +1,99 @@
+/*
+ * 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.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTableInterface;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.util.MetaDataUtil;
+import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.apache.phoenix.util.TestUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.Maps;
+
+public class DisableLocalIndexIT extends BaseHBaseManagedTimeIT {
+ @BeforeClass
+ @Shadower(classBeingShadowed = BaseHBaseManagedTimeIT.class)
+ public static void doSetup() throws Exception {
+ Map<String,String> props = Maps.newHashMapWithExpectedSize(1);
+ // Must update config before starting server
+ props.put(QueryServices.ALLOW_LOCAL_INDEX_ATTRIB, Boolean.FALSE.toString());
+ setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
+ }
+
+ @Test
+ public void testDisabledLocalIndexes() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ conn.setAutoCommit(true);
+ String tableName = "DISABLE_LOCAL_INDEX_TEST";
+ conn.createStatement().execute("CREATE TABLE " + tableName + " (k1 VARCHAR NOT NULL, k2 VARCHAR, CONSTRAINT PK PRIMARY KEY(K1,K2)) MULTI_TENANT=true");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('t1','x')");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('t2','y')");
+ HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin();
+ assertFalse(admin.tableExists(Bytes.toBytes(MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + tableName)));
+ admin.close();
+ try {
+ HTableInterface t = conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes(MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + tableName));
+ t.getTableDescriptor(); // Exception no longer thrown by getTable, but instead need to force an RPC
+ fail("Local index table should not have been created");
+ } catch (org.apache.hadoop.hbase.TableNotFoundException e) {
+ //expected
+ } finally {
+ admin.close();
+ }
+
+ Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
+ props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, "t1");
+ Connection tsconn = DriverManager.getConnection(getUrl(), props);
+
+ tsconn.createStatement().execute("CREATE VIEW A.BAR(V1 VARCHAR) AS SELECT * FROM " + tableName);
+ tsconn.createStatement().execute("CREATE INDEX I1 ON A.BAR(V1)");
+ tsconn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes(MetaDataUtil.VIEW_INDEX_TABLE_PREFIX + tableName));
+
+ try {
+ conn.createStatement().execute("CREATE LOCAL INDEX I2 ON " + tableName + "(k2)");
+ fail("Should not allow creation of local index");
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.UNALLOWED_LOCAL_INDEXES.getErrorCode(), e.getErrorCode());
+ }
+ try {
+ tsconn.createStatement().execute("CREATE LOCAL INDEX I2 ON A.BAR(k2, v1)");
+ fail("Should not allow creation of local index");
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.UNALLOWED_LOCAL_INDEXES.getErrorCode(), e.getErrorCode());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/54c4ed80/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 8a6b8d0..19e7cdf 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
@@ -236,6 +236,9 @@ public enum SQLExceptionCode {
CANNOT_SET_PROPERTY_FOR_COLUMN_NOT_ADDED(1052, "43A09", "Property cannot be specified for a column family that is not being added or modified"),
CANNOT_SET_TABLE_PROPERTY_ADD_COLUMN(1053, "43A10", "Table level property cannot be set when adding a column"),
+ NO_LOCAL_INDEXES(1054, "43A11", "Local secondary indexes are only supported for HBase version " + MetaDataUtil.decodeHBaseVersionAsString(PhoenixDatabaseMetaData.LOCAL_SI_VERSION_THRESHOLD) + " and above."),
+ UNALLOWED_LOCAL_INDEXES(1055, "43A12", "Local secondary indexes are configured to not be allowed."),
+
/** Sequence related */
SEQUENCE_ALREADY_EXIST(1200, "42Z00", "Sequence already exists.", new Factory() {
@Override
http://git-wip-us.apache.org/repos/asf/phoenix/blob/54c4ed80/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 b26f408..7ac2bb6 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
@@ -52,17 +52,17 @@ import org.apache.phoenix.iterate.DelegateResultIterator;
import org.apache.phoenix.iterate.MaterializedResultIterator;
import org.apache.phoenix.iterate.ResultIterator;
import org.apache.phoenix.query.QueryConstants;
-import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.schema.PDatum;
import org.apache.phoenix.schema.PName;
import org.apache.phoenix.schema.PTable.LinkType;
import org.apache.phoenix.schema.PTableType;
-import org.apache.phoenix.schema.types.PVarchar;
import org.apache.phoenix.schema.RowKeyValueAccessor;
import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.schema.tuple.ResultTuple;
import org.apache.phoenix.schema.tuple.SingleKeyValueTuple;
import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PVarchar;
import org.apache.phoenix.util.ByteUtil;
import org.apache.phoenix.util.KeyValueUtil;
import org.apache.phoenix.util.SchemaUtil;
@@ -274,6 +274,7 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData, org.apache.pho
public static final int ESSENTIAL_FAMILY_VERSION_THRESHOLD = VersionUtil.encodeVersion("0", "94", "7");
// Version below which we should disallow usage of mutable secondary indexing.
public static final int MUTABLE_SI_VERSION_THRESHOLD = VersionUtil.encodeVersion("0", "94", "10");
+ public static final int LOCAL_SI_VERSION_THRESHOLD = VersionUtil.encodeVersion("0", "98", "9");
/** Version below which we fall back on the generic KeyValueBuilder */
public static final int CLIENT_KEY_VALUE_BUILDER_THRESHOLD = VersionUtil.encodeVersion("0", "94", "14");
http://git-wip-us.apache.org/repos/asf/phoenix/blob/54c4ed80/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 97efc43..6d58f57 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
@@ -1069,6 +1069,14 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
}
private void ensureLocalIndexTableCreated(byte[] physicalTableName, Map<String, Object> tableProps, List<Pair<byte[], Map<String, Object>>> families, byte[][] splits) throws SQLException, TableAlreadyExistsException {
+
+ // If we're not allowing local indexes or the hbase version is too low,
+ // don't create the local index table
+ if ( !this.getProps().getBoolean(QueryServices.ALLOW_LOCAL_INDEX_ATTRIB, QueryServicesOptions.DEFAULT_ALLOW_LOCAL_INDEX)
+ || getLowestClusterHBaseVersion() < PhoenixDatabaseMetaData.LOCAL_SI_VERSION_THRESHOLD) {
+ return;
+ }
+
tableProps.put(MetaDataUtil.IS_LOCAL_INDEX_TABLE_PROP_NAME, TRUE_BYTES_AS_STRING);
HTableDescriptor desc = ensureTableCreated(physicalTableName, PTableType.TABLE, tableProps, families, splits, true);
if (desc != null) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/54c4ed80/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 447267c..7a10683 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
@@ -21,7 +21,6 @@ import java.io.IOException;
import java.util.concurrent.ExecutorService;
import org.apache.hadoop.hbase.client.HConnection;
-import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.HTableInterface;
/**
@@ -48,7 +47,7 @@ public interface HTableFactory {
static class HTableFactoryImpl implements HTableFactory {
@Override
public HTableInterface getTable(byte[] tableName, HConnection connection, ExecutorService pool) throws IOException {
- return new HTable(tableName, connection, pool);
+ return connection.getTable(tableName, pool);
}
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/54c4ed80/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 ce9016d..d21695d 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
@@ -123,6 +123,7 @@ public interface QueryServices extends SQLCloseable {
public static final String MIN_INDEX_PRIOIRTY_ATTRIB = "phoenix.regionserver.index.priority.min";
public static final String MAX_INDEX_PRIOIRTY_ATTRIB = "phoenix.regionserver.index.priority.max";
public static final String INDEX_HANDLER_COUNT_ATTRIB = "phoenix.regionserver.index.handler.count";
+ public static final String ALLOW_LOCAL_INDEX_ATTRIB = "phoenix.index.allowLocalIndex";
// Config parameters for for configuring tracing
public static final String TRACING_FREQ_ATTRIB = "phoenix.trace.frequency";
http://git-wip-us.apache.org/repos/asf/phoenix/blob/54c4ed80/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 5913796..0f9139f 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
@@ -144,6 +144,7 @@ public class QueryServicesOptions {
*/
public static final int DEFAULT_INDEX_MIN_PRIORITY = 1000;
public static final int DEFAULT_INDEX_HANDLER_COUNT = 30;
+ public static final boolean DEFAULT_ALLOW_LOCAL_INDEX = true;
public static final int DEFAULT_TRACING_PAGE_SIZE = 100;
/**
http://git-wip-us.apache.org/repos/asf/phoenix/blob/54c4ed80/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 09d2f66..effdb54 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
@@ -909,6 +909,16 @@ public class MetaDataClient {
boolean retry = true;
Short indexId = null;
boolean allocateIndexId = false;
+ boolean isLocalIndex = statement.getIndexType() == IndexType.LOCAL;
+ int hbaseVersion = connection.getQueryServices().getLowestClusterHBaseVersion();
+ if (isLocalIndex) {
+ if (!connection.getQueryServices().getProps().getBoolean(QueryServices.ALLOW_LOCAL_INDEX_ATTRIB, QueryServicesOptions.DEFAULT_ALLOW_LOCAL_INDEX)) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.UNALLOWED_LOCAL_INDEXES).setTableName(indexTableName.getTableName()).build().buildException();
+ }
+ if (hbaseVersion < PhoenixDatabaseMetaData.LOCAL_SI_VERSION_THRESHOLD) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.NO_LOCAL_INDEXES).setTableName(indexTableName.getTableName()).build().buildException();
+ }
+ }
while (true) {
try {
ColumnResolver resolver = FromCompiler.getResolver(statement, connection);
@@ -920,7 +930,6 @@ public class MetaDataClient {
throw new SQLFeatureNotSupportedException("An index may only be created for a VIEW through a tenant-specific connection");
}
}
- int hbaseVersion = connection.getQueryServices().getLowestClusterHBaseVersion();
if (!dataTable.isImmutableRows()) {
if (hbaseVersion < PhoenixDatabaseMetaData.MUTABLE_SI_VERSION_THRESHOLD) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.NO_MUTABLE_INDEXES).setTableName(indexTableName.getTableName()).build().buildException();
@@ -960,7 +969,7 @@ public class MetaDataClient {
* 1) for a local index, as all local indexes will reside in the same HBase table
* 2) for a view on an index.
*/
- if (statement.getIndexType() == IndexType.LOCAL || (dataTable.getType() == PTableType.VIEW && dataTable.getViewType() != ViewType.MAPPED)) {
+ if (isLocalIndex || (dataTable.getType() == PTableType.VIEW && dataTable.getViewType() != ViewType.MAPPED)) {
allocateIndexId = true;
// Next add index ID column
PDataType dataType = MetaDataUtil.getViewIndexIdDataType();
[2/3] phoenix git commit: PHOENIX-1620 Add API for getting tenant ID
from an HBase row of a Phoenix table
Posted by ja...@apache.org.
PHOENIX-1620 Add API for getting tenant ID from an HBase row of a Phoenix table
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/f3c675bf
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/f3c675bf
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/f3c675bf
Branch: refs/heads/master
Commit: f3c675bf735d7d4e4534433f3406af15360ed5d9
Parents: 2d77033
Author: James Taylor <jt...@salesforce.com>
Authored: Fri Feb 6 11:14:26 2015 -0800
Committer: James Taylor <jt...@salesforce.com>
Committed: Fri Feb 6 14:59:01 2015 -0800
----------------------------------------------------------------------
.../phoenix/end2end/PhoenixRuntimeIT.java | 138 +++++++++++++++++++
.../org/apache/phoenix/util/PhoenixRuntime.java | 39 +++++-
.../org/apache/phoenix/util/SchemaUtil.java | 4 +
.../java/org/apache/phoenix/query/BaseTest.java | 20 ++-
.../apache/phoenix/util/PhoenixRuntimeTest.java | 58 ++++++++
5 files changed, 255 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3c675bf/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixRuntimeIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixRuntimeIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixRuntimeIT.java
new file mode 100644
index 0000000..234ea1c
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixRuntimeIT.java
@@ -0,0 +1,138 @@
+/*
+ * 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.jdbc.PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.client.HTableInterface;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
+import org.apache.hadoop.hbase.filter.Filter;
+import org.apache.hadoop.hbase.filter.FilterList;
+import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter;
+import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.schema.PTableType;
+import org.apache.phoenix.schema.tuple.ResultTuple;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.util.MetaDataUtil;
+import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.TestUtil;
+import org.junit.Test;
+
+import com.google.common.collect.Lists;
+
+public class PhoenixRuntimeIT extends BaseHBaseManagedTimeIT {
+ private static void assertTenantIds(Expression e, HTableInterface htable, Filter filter, String[] tenantIds) throws IOException {
+ ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+ Scan scan = new Scan();
+ scan.setFilter(filter);
+ ResultScanner scanner = htable.getScanner(scan);
+ Result result = null;
+ ResultTuple tuple = new ResultTuple();
+ List<String> actualTenantIds = Lists.newArrayListWithExpectedSize(tenantIds.length);
+ List<String> expectedTenantIds = Arrays.asList(tenantIds);
+ while ((result = scanner.next()) != null) {
+ tuple.setResult(result);
+ e.evaluate(tuple, ptr);
+ String tenantId = (String)PVarchar.INSTANCE.toObject(ptr);
+ actualTenantIds.add(tenantId == null ? "" : tenantId);
+ }
+ // Need to sort because of salting
+ Collections.sort(actualTenantIds);
+ assertEquals(expectedTenantIds, actualTenantIds);
+ }
+
+ @Test
+ public void testGetTenantIdExpressionForSaltedTable() throws Exception {
+ testGetTenantIdExpression(true);
+ }
+
+ @Test
+ public void testGetTenantIdExpressionForUnsaltedTable() throws Exception {
+ testGetTenantIdExpression(false);
+ }
+
+ private static Filter getUserTableAndViewsFilter() {
+ SingleColumnValueFilter tableFilter = new SingleColumnValueFilter(TABLE_FAMILY_BYTES, PhoenixDatabaseMetaData.TABLE_TYPE_BYTES, CompareOp.EQUAL, Bytes.toBytes(PTableType.TABLE.getSerializedValue()));
+ tableFilter.setFilterIfMissing(true);
+ SingleColumnValueFilter viewFilter = new SingleColumnValueFilter(TABLE_FAMILY_BYTES, PhoenixDatabaseMetaData.TABLE_TYPE_BYTES, CompareOp.EQUAL, Bytes.toBytes(PTableType.VIEW.getSerializedValue()));
+ viewFilter.setFilterIfMissing(true);
+ FilterList filter = new FilterList(FilterList.Operator.MUST_PASS_ONE, Arrays.asList(new Filter[] {tableFilter, viewFilter}));
+ return filter;
+ }
+
+ private void testGetTenantIdExpression(boolean isSalted) throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ conn.setAutoCommit(true);
+ String tableName = "FOO_" + (isSalted ? "SALTED" : "UNSALTED");
+ conn.createStatement().execute("CREATE TABLE " + tableName + " (k1 VARCHAR NOT NULL, k2 VARCHAR, CONSTRAINT PK PRIMARY KEY(K1,K2)) MULTI_TENANT=true" + (isSalted ? ",SALT_BUCKETS=3" : ""));
+ conn.createStatement().execute("CREATE SEQUENCE s1");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('t1','x')");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('t2','y')");
+
+ Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
+ props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, "t1");
+ Connection tsconn = DriverManager.getConnection(getUrl(), props);
+ tsconn.createStatement().execute("CREATE SEQUENCE s1");
+ Expression e1 = PhoenixRuntime.getTenantIdExpression(tsconn, PhoenixDatabaseMetaData.SEQUENCE_FULLNAME);
+ HTableInterface htable1 = tsconn.unwrap(PhoenixConnection.class).getQueryServices().getTable(PhoenixDatabaseMetaData.SEQUENCE_FULLNAME_BYTES);
+ assertTenantIds(e1, htable1, new FirstKeyOnlyFilter(), new String[] {"", "t1"} );
+
+ tsconn.createStatement().execute("CREATE VIEW A.BAR(V1 VARCHAR) AS SELECT * FROM " + tableName);
+ Expression e2 = PhoenixRuntime.getTenantIdExpression(tsconn, PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME);
+ HTableInterface htable2 = conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES);
+ assertTenantIds(e2, htable2, getUserTableAndViewsFilter(), new String[] {"", "t1"} );
+
+ Expression e3 = PhoenixRuntime.getTenantIdExpression(conn, tableName);
+ HTableInterface htable3 = conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes(tableName));
+ assertTenantIds(e3, htable3, new FirstKeyOnlyFilter(), new String[] {"t1", "t2"} );
+
+ conn.createStatement().execute("CREATE TABLE BAS (k1 VARCHAR PRIMARY KEY)");
+ Expression e4 = PhoenixRuntime.getTenantIdExpression(conn, "BAS");
+ assertNull(e4);
+
+ tsconn.createStatement().execute("CREATE INDEX I1 ON A.BAR(V1)");
+ Expression e5 = PhoenixRuntime.getTenantIdExpression(tsconn, "A.I1");
+ HTableInterface htable5 = tsconn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes(MetaDataUtil.VIEW_INDEX_TABLE_PREFIX + tableName));
+ assertTenantIds(e5, htable5, new FirstKeyOnlyFilter(), new String[] {"t1"} );
+
+ conn.createStatement().execute("CREATE INDEX I2 ON " + tableName + "(k2)");
+ Expression e6 = PhoenixRuntime.getTenantIdExpression(conn, "I2");
+ HTableInterface htable6 = conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes("I2"));
+ assertTenantIds(e6, htable6, new FirstKeyOnlyFilter(), new String[] {"t1", "t2"} );
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3c675bf/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java b/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
index b2d7851..02a2776 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
@@ -28,6 +28,7 @@ import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
@@ -56,6 +57,7 @@ import org.apache.phoenix.coprocessor.MetaDataProtocol.MutationCode;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.LiteralExpression;
import org.apache.phoenix.expression.OrderByExpression;
+import org.apache.phoenix.expression.RowKeyColumnExpression;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixPreparedStatement;
import org.apache.phoenix.query.QueryConstants;
@@ -66,13 +68,15 @@ import org.apache.phoenix.schema.KeyValueSchema.KeyValueSchemaBuilder;
import org.apache.phoenix.schema.MetaDataClient;
import org.apache.phoenix.schema.PColumn;
import org.apache.phoenix.schema.PColumnFamily;
-import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTable.IndexType;
import org.apache.phoenix.schema.PTableKey;
import org.apache.phoenix.schema.PTableType;
import org.apache.phoenix.schema.RowKeySchema;
+import org.apache.phoenix.schema.RowKeyValueAccessor;
import org.apache.phoenix.schema.TableNotFoundException;
import org.apache.phoenix.schema.ValueBitSet;
+import org.apache.phoenix.schema.types.PDataType;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
@@ -927,5 +931,38 @@ public class PhoenixRuntime {
}
return pColumn;
}
+
+ /**
+ * Get expression that may be used to evaluate the tenant ID of a given row in a
+ * multi-tenant table. Both the SYSTEM.CATALOG table and the SYSTEM.SEQUENCE
+ * table are considered multi-tenant.
+ * @param conn open Phoenix connection
+ * @param fullTableName full table name
+ * @return An expression that may be evaluated for a row in the provided table or
+ * null if the table is not a multi-tenant table.
+ * @throws SQLException if the table name is not found, a TableNotFoundException
+ * is thrown. If a multi-tenant local index is supplied a SQLFeatureNotSupportedException
+ * is thrown.
+ */
+ public static Expression getTenantIdExpression(Connection conn, String fullTableName) throws SQLException {
+ PTable table = getTable(conn, fullTableName);
+ // TODO: consider setting MULTI_TENANT = true for SYSTEM.CATALOG and SYSTEM.SEQUENCE
+ if (!SchemaUtil.isMetaTable(table) && !SchemaUtil.isSequenceTable(table) && !table.isMultiTenant()) {
+ return null;
+ }
+ if (table.getIndexType() == IndexType.LOCAL) {
+ /*
+ * With some hackery, we could deduce the tenant ID from a multi-tenant local index,
+ * however it's not clear that we'd want to maintain the same prefixing of the region
+ * start key, as the region boundaries may end up being different on a cluster being
+ * replicated/backed-up to (which is the use case driving the method).
+ */
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ int pkPosition = table.getBucketNum() == null ? 0 : 1;
+ List<PColumn> pkColumns = table.getPKColumns();
+ return new RowKeyColumnExpression(pkColumns.get(pkPosition), new RowKeyValueAccessor(pkColumns, pkPosition));
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3c675bf/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 9ab0692..afd61ad 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
@@ -376,6 +376,10 @@ public class SchemaUtil {
return Bytes.compareTo(tableName, PhoenixDatabaseMetaData.SEQUENCE_FULLNAME_BYTES) == 0;
}
+ public static boolean isSequenceTable(PTable table) {
+ return PhoenixDatabaseMetaData.SEQUENCE_FULLNAME.equals(table.getName().getString());
+ }
+
public static boolean isMetaTable(PTable table) {
return PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA.equals(table.getSchemaName().getString()) && PhoenixDatabaseMetaData.SYSTEM_CATALOG_TABLE.equals(table.getTableName().getString());
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3c675bf/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
index f81c3a9..9947440 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
@@ -821,14 +821,28 @@ public abstract class BaseTest {
}
}
- private static void deletePriorSequences(long ts, Connection conn) throws Exception {
+ private static void deletePriorSequences(long ts, Connection globalConn) throws Exception {
// TODO: drop tenant-specific sequences too
- ResultSet rs = conn.createStatement().executeQuery("SELECT "
+ ResultSet rs = globalConn.createStatement().executeQuery("SELECT "
+ + PhoenixDatabaseMetaData.TENANT_ID + ","
+ PhoenixDatabaseMetaData.SEQUENCE_SCHEMA + ","
+ PhoenixDatabaseMetaData.SEQUENCE_NAME
+ " FROM " + PhoenixDatabaseMetaData.SEQUENCE_FULLNAME_ESCAPED);
+ String lastTenantId = null;
+ Connection conn = globalConn;
while (rs.next()) {
- conn.createStatement().execute("DROP SEQUENCE " + SchemaUtil.getEscapedTableName(rs.getString(1), rs.getString(2)));
+ String tenantId = rs.getString(1);
+ if (tenantId != null && !tenantId.equals(lastTenantId)) {
+ if (lastTenantId != null) {
+ conn.close();
+ }
+ // Open tenant-specific connection when we find a new one
+ Properties props = new Properties(globalConn.getClientInfo());
+ props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
+ conn = DriverManager.getConnection(url, props);
+ lastTenantId = tenantId;
+ }
+ conn.createStatement().execute("DROP SEQUENCE " + SchemaUtil.getEscapedTableName(rs.getString(2), rs.getString(3)));
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f3c675bf/phoenix-core/src/test/java/org/apache/phoenix/util/PhoenixRuntimeTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/util/PhoenixRuntimeTest.java b/phoenix-core/src/test/java/org/apache/phoenix/util/PhoenixRuntimeTest.java
index a642e80..c1f3244 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/util/PhoenixRuntimeTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/util/PhoenixRuntimeTest.java
@@ -20,6 +20,7 @@ package org.apache.phoenix.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -27,6 +28,7 @@ import static org.junit.Assert.fail;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
+import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
@@ -34,7 +36,10 @@ import java.util.Properties;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.phoenix.compile.QueryPlan;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
import org.apache.phoenix.query.BaseConnectionlessQueryTest;
+import org.apache.phoenix.schema.TableNotFoundException;
import org.apache.phoenix.schema.types.PDataType;
import org.junit.Test;
@@ -155,4 +160,57 @@ public class PhoenixRuntimeTest extends BaseConnectionlessQueryTest {
fail("Failed sql: " + sb.toString() + ExceptionUtils.getStackTrace(e));
}
}
+
+ @Test
+ public void testGetTenantIdExpression() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ Expression e1 = PhoenixRuntime.getTenantIdExpression(conn, PhoenixDatabaseMetaData.SYSTEM_STATS_NAME);
+ assertNull(e1);
+ Expression e2 = PhoenixRuntime.getTenantIdExpression(conn, PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME);
+ assertNotNull(e2);
+
+ Expression e3 = PhoenixRuntime.getTenantIdExpression(conn, PhoenixDatabaseMetaData.SEQUENCE_FULLNAME);
+ assertNotNull(e3);
+
+ conn.createStatement().execute("CREATE TABLE FOO (k VARCHAR PRIMARY KEY)");
+ Expression e4 = PhoenixRuntime.getTenantIdExpression(conn, "FOO");
+ assertNull(e4);
+
+ conn.createStatement().execute("CREATE TABLE A.BAR (k1 VARCHAR NOT NULL, k2 VARCHAR, CONSTRAINT PK PRIMARY KEY(K1,K2)) MULTI_TENANT=true");
+ Expression e5 = PhoenixRuntime.getTenantIdExpression(conn, "A.BAR");
+ assertNotNull(e5);
+
+ conn.createStatement().execute("CREATE INDEX I1 ON A.BAR (K2)");
+ Expression e5A = PhoenixRuntime.getTenantIdExpression(conn, "A.I1");
+ assertNotNull(e5A);
+
+ conn.createStatement().execute("CREATE TABLE BAS (k1 VARCHAR NOT NULL, k2 VARCHAR, CONSTRAINT PK PRIMARY KEY(K1,K2)) MULTI_TENANT=true, SALT_BUCKETS=3");
+ Expression e6 = PhoenixRuntime.getTenantIdExpression(conn, "BAS");
+ assertNotNull(e6);
+
+ conn.createStatement().execute("CREATE INDEX I2 ON BAS (K2)");
+ Expression e6A = PhoenixRuntime.getTenantIdExpression(conn, "I2");
+ assertNotNull(e6A);
+
+ try {
+ PhoenixRuntime.getTenantIdExpression(conn, "NOT.ATABLE");
+ fail();
+ } catch (TableNotFoundException e) {
+ // Expected
+ }
+
+ Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
+ props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, "t1");
+ Connection tsconn = DriverManager.getConnection(getUrl(), props);
+ tsconn.createStatement().execute("CREATE VIEW V(V1 VARCHAR) AS SELECT * FROM BAS");
+ Expression e7 = PhoenixRuntime.getTenantIdExpression(tsconn, "V");
+ assertNotNull(e7);
+ tsconn.createStatement().execute("CREATE LOCAL INDEX I3 ON V (V1)");
+ try {
+ PhoenixRuntime.getTenantIdExpression(tsconn, "I3");
+ fail();
+ } catch (SQLFeatureNotSupportedException e) {
+ // Expected
+ }
+ }
}
[3/3] phoenix git commit: PHOENIX-1643 Ensure index usage is backward
compatible for 4.2 client against 4.3 server (Thomas D'Silva)
Posted by ja...@apache.org.
PHOENIX-1643 Ensure index usage is backward compatible for 4.2 client against 4.3 server (Thomas D'Silva)
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/9db37bd9
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/9db37bd9
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/9db37bd9
Branch: refs/heads/master
Commit: 9db37bd90005695c703f9d092651891a5e39a80a
Parents: 54c4ed8
Author: James Taylor <jt...@salesforce.com>
Authored: Fri Feb 6 16:08:43 2015 -0800
Committer: James Taylor <jt...@salesforce.com>
Committed: Fri Feb 6 16:08:43 2015 -0800
----------------------------------------------------------------------
.../apache/phoenix/index/IndexMaintainer.java | 9 ++------
.../parse/IndexExpressionParseNodeRewriter.java | 6 ++---
.../org/apache/phoenix/schema/PColumnImpl.java | 2 +-
.../java/org/apache/phoenix/util/IndexUtil.java | 16 +++++++------
.../org/apache/phoenix/util/SchemaUtil.java | 24 ++++++++++++--------
5 files changed, 29 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/9db37bd9/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java b/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
index 31f6c76..7199dad 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
@@ -282,9 +282,6 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
int indexedExpressionCount = 0;
for (int i = indexPosOffset; i<index.getPKColumns().size();i++) {
PColumn indexColumn = index.getPKColumns().get(i);
- if (!IndexUtil.isIndexColumn(indexColumn)) {
- continue;
- }
String indexColumnName = indexColumn.getName().getString();
String dataFamilyName = IndexUtil.getDataColumnFamilyName(indexColumnName);
String dataColumnName = IndexUtil.getDataColumnName(indexColumnName);
@@ -341,14 +338,12 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
IndexExpressionCompiler expressionIndexCompiler = new IndexExpressionCompiler(context);
for (int i = indexPosOffset; i < index.getPKColumns().size(); i++) {
PColumn indexColumn = index.getPKColumns().get(i);
- if (!IndexUtil.isIndexColumn(indexColumn)) {
- continue;
- }
int indexPos = i - indexPosOffset;
Expression expression = null;
try {
expressionIndexCompiler.reset();
- ParseNode parseNode = SQLParser.parseCondition(indexColumn.getExpressionStr());
+ String expressionStr = IndexUtil.getIndexColumnExpressionStr(indexColumn);
+ ParseNode parseNode = SQLParser.parseCondition(expressionStr);
expression = parseNode.accept(expressionIndexCompiler);
} catch (SQLException e) {
throw new RuntimeException(e); // Impossible
http://git-wip-us.apache.org/repos/asf/phoenix/blob/9db37bd9/phoenix-core/src/main/java/org/apache/phoenix/parse/IndexExpressionParseNodeRewriter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/IndexExpressionParseNodeRewriter.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/IndexExpressionParseNodeRewriter.java
index efa3835..43cb9f3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/IndexExpressionParseNodeRewriter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/IndexExpressionParseNodeRewriter.java
@@ -71,10 +71,8 @@ public class IndexExpressionParseNodeRewriter extends ParseNodeRewriter {
List<PColumn> pkColumns = index.getPKColumns();
for (int i=indexPosOffset; i<pkColumns.size(); ++i) {
PColumn column = pkColumns.get(i);
- if (column.getExpressionStr()==null) {
- continue;
- }
- ParseNode expressionParseNode = SQLParser.parseCondition(column.getExpressionStr());
+ String expressionStr = IndexUtil.getIndexColumnExpressionStr(column);
+ ParseNode expressionParseNode = SQLParser.parseCondition(expressionStr);
columnParseNodeVisitor.reset();
expressionParseNode.accept(columnParseNodeVisitor);
String colName = column.getName().getString();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/9db37bd9/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
index 11cc53d..ac044df 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
@@ -38,7 +38,7 @@ public class PColumnImpl implements PColumn {
private byte[] viewConstant;
private boolean isViewReferenced;
private String expressionStr;
-
+
public PColumnImpl() {
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/9db37bd9/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
index 8dd4f4d..c058eb8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
@@ -137,12 +137,9 @@ public class IndexUtil {
return name.substring(0,name.indexOf(INDEX_COLUMN_NAME_SEP));
}
- public static String getDataColumnFullName(String name) {
+ public static String getCaseSensitiveDataColumnFullName(String name) {
int index = name.indexOf(INDEX_COLUMN_NAME_SEP) ;
- if (index == 0) {
- return name.substring(index+1);
- }
- return SchemaUtil.getColumnDisplayName(name.substring(0, index), name.substring(index+1));
+ return SchemaUtil.getCaseSensitiveColumnDisplayName(name.substring(0, index), name.substring(index+1));
}
public static String getIndexColumnName(String dataColumnFamilyName, String dataColumnName) {
@@ -272,8 +269,8 @@ public class IndexUtil {
return column.getName().getString().startsWith(INDEX_COLUMN_NAME_SEP);
}
- public static boolean isIndexColumn(PColumn column) {
- return column.getName().getString().contains(INDEX_COLUMN_NAME_SEP);
+ public static boolean isIndexColumn(String name) {
+ return name.contains(INDEX_COLUMN_NAME_SEP);
}
public static boolean getViewConstantValue(PColumn column, ImmutableBytesWritable ptr) {
@@ -627,4 +624,9 @@ public class IndexUtil {
result.set(i, newCell);
}
}
+
+ public static String getIndexColumnExpressionStr(PColumn col) {
+ return col.getExpressionStr() == null ? IndexUtil.getCaseSensitiveDataColumnFullName(col.getName().getString())
+ : col.getExpressionStr();
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/9db37bd9/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 afd61ad..c9574e3 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
@@ -206,14 +206,16 @@ public class SchemaUtil {
}
public static String getTableName(String schemaName, String tableName) {
- return getName(schemaName,tableName);
+ return getName(schemaName,tableName, false);
}
- private static String getName(String optionalQualifier, String name) {
+ private static String getName(String optionalQualifier, String name, boolean caseSensitive) {
+ String cq = caseSensitive ? "\"" + name + "\"" : name;
if (optionalQualifier == null || optionalQualifier.isEmpty()) {
- return name;
+ return cq;
}
- return optionalQualifier + QueryConstants.NAME_SEPARATOR + name;
+ String cf = caseSensitive ? "\"" + optionalQualifier + "\"" : optionalQualifier;
+ return cf + QueryConstants.NAME_SEPARATOR + cq;
}
public static String getTableName(byte[] schemaName, byte[] tableName) {
@@ -225,21 +227,25 @@ public class SchemaUtil {
}
public static String getColumnDisplayName(String cf, String cq) {
- return getName(cf == null || cf.isEmpty() ? null : cf, cq);
+ return getName(cf == null || cf.isEmpty() ? null : cf, cq, false);
+ }
+
+ public static String getCaseSensitiveColumnDisplayName(String cf, String cq) {
+ return getName(cf == null || cf.isEmpty() ? null : cf, cq, true);
}
public static String getMetaDataEntityName(String schemaName, String tableName, String familyName, String columnName) {
if ((schemaName == null || schemaName.isEmpty()) && (tableName == null || tableName.isEmpty())) {
- return getName(familyName, columnName);
+ return getName(familyName, columnName, false);
}
if ((familyName == null || familyName.isEmpty()) && (columnName == null || columnName.isEmpty())) {
- return getName(schemaName, tableName);
+ return getName(schemaName, tableName, false);
}
- return getName(getName(schemaName, tableName), getName(familyName, columnName));
+ return getName(getName(schemaName, tableName, false), getName(familyName, columnName, false), false);
}
public static String getColumnName(String familyName, String columnName) {
- return getName(familyName, columnName);
+ return getName(familyName, columnName, false);
}
public static byte[] getTableNameAsBytes(String schemaName, String tableName) {