You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ja...@apache.org on 2014/12/03 21:27:35 UTC

phoenix git commit: PHOENIX-1484 Index creation failed due to specifying DEFAULT_COLUMN_FAMILY option (Rajeshbabu, James Taylor)

Repository: phoenix
Updated Branches:
  refs/heads/master 684976029 -> f47e1700d


PHOENIX-1484 Index creation failed due to specifying
 DEFAULT_COLUMN_FAMILY option (Rajeshbabu, James Taylor)


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/f47e1700
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/f47e1700
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/f47e1700

Branch: refs/heads/master
Commit: f47e1700d073485dce957c68c4cbb0c8d5c1e12f
Parents: 6849760
Author: James Taylor <jt...@salesforce.com>
Authored: Wed Dec 3 11:13:06 2014 -0800
Committer: James Taylor <jt...@salesforce.com>
Committed: Wed Dec 3 12:25:42 2014 -0800

----------------------------------------------------------------------
 .../phoenix/end2end/index/LocalIndexIT.java     | 19 ++++++
 .../apache/phoenix/schema/MetaDataClient.java   | 68 +++++++++++++++-----
 .../phoenix/compile/QueryCompilerTest.java      | 20 ++++++
 3 files changed, 90 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/f47e1700/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
index b1f4a3c..2f4f1b0 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
@@ -29,6 +29,7 @@ import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.Statement;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CountDownLatch;
@@ -671,6 +672,24 @@ public class LocalIndexIT extends BaseIndexIT {
     }
 
     @Test
+    public void testLocalIndexCreationWithDefaultFamilyOption() throws Exception {
+        Connection conn1 = DriverManager.getConnection(getUrl());
+        try{
+            Statement statement = conn1.createStatement();
+            statement.execute("create table example (id integer not null,fn varchar,"
+                    + "ln varchar constraint pk primary key(id)) DEFAULT_COLUMN_FAMILY='F'");
+            statement.execute("upsert into example values(1,'fn','ln')");
+            statement
+                    .execute("create local index my_idx on example (fn)");
+            statement.execute("upsert into example values(2,'fn1','ln1')");
+            ResultSet rs = statement.executeQuery("SELECT COUNT(*) FROM my_idx");
+            assertTrue(rs.next());
+       } finally {
+            conn1.close();
+        }
+    }
+
+    @Test
     public void testLocalIndexScanAfterRegionSplit() throws Exception {
         createBaseTable(DATA_TABLE_NAME, null, "('e','j','o')");
         Connection conn1 = DriverManager.getConnection(getUrl());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f47e1700/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 0085470..ea333ac 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
@@ -66,6 +66,7 @@ import static org.apache.phoenix.schema.PDataType.VARCHAR;
 import java.io.IOException;
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.sql.ParameterMetaData;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
@@ -97,11 +98,13 @@ import org.apache.hadoop.hbase.io.TimeRange;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.compile.ColumnResolver;
+import org.apache.phoenix.compile.ExplainPlan;
 import org.apache.phoenix.compile.FromCompiler;
 import org.apache.phoenix.compile.MutationPlan;
 import org.apache.phoenix.compile.PostDDLCompiler;
 import org.apache.phoenix.compile.PostIndexDDLCompiler;
 import org.apache.phoenix.compile.QueryPlan;
+import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
 import org.apache.phoenix.coprocessor.MetaDataProtocol;
 import org.apache.phoenix.coprocessor.MetaDataProtocol.MetaDataMutationResult;
@@ -113,6 +116,7 @@ import org.apache.phoenix.hbase.index.covered.update.ColumnReference;
 import org.apache.phoenix.index.IndexMaintainer;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.jdbc.PhoenixParameterMetaData;
 import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.parse.AddColumnStatement;
 import org.apache.phoenix.parse.AlterIndexStatement;
@@ -723,7 +727,7 @@ public class MetaDataClient {
         connection.rollback();
         try {
             connection.setAutoCommit(true);
-            MutationState state;
+            MutationPlan mutationPlan;
             
             // For local indexes, we optimize the initial index population by *not* sending Puts over
             // the wire for the index rows, as we don't need to do that. Instead, we tap into our
@@ -732,7 +736,7 @@ public class MetaDataClient {
                 final PhoenixStatement statement = new PhoenixStatement(connection);
                 String tableName = getFullTableName(dataTableRef);
                 String query = "SELECT count(*) FROM " + tableName;
-                QueryPlan plan = statement.compileQuery(query);
+                final QueryPlan plan = statement.compileQuery(query);
                 TableRef tableRef = plan.getContext().getResolver().getTables().get(0);
                 // Set attribute on scan that UngroupedAggregateRegionObserver will switch on.
                 // We'll detect that this attribute was set the server-side and write the index
@@ -775,24 +779,54 @@ public class MetaDataClient {
                 for (ColumnReference columnRef : indexMaintainer.getAllColumns()) {
                     scan.addColumn(columnRef.getFamily(), columnRef.getQualifier());
                 }
-                Cell kv = plan.iterator().next().getValue(0);
-                ImmutableBytesWritable tmpPtr = new ImmutableBytesWritable(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength());
-                // A single Cell will be returned with the count(*) - we decode that here
-                long rowCount = PDataType.LONG.getCodec().decodeLong(tmpPtr, SortOrder.getDefault());
-                // The contract is to return a MutationState that contains the number of rows modified. In this
-                // case, it's the number of rows in the data table which corresponds to the number of index
-                // rows that were added.
-                state = new MutationState(0, connection, rowCount);
+                
+                // Go through MutationPlan abstraction so that we can create local indexes
+                // with a connectionless connection (which makes testing easier).
+                mutationPlan = new MutationPlan() {
+
+                    @Override
+                    public StatementContext getContext() {
+                        return plan.getContext();
+                    }
+
+                    @Override
+                    public ParameterMetaData getParameterMetaData() {
+                        return PhoenixParameterMetaData.EMPTY_PARAMETER_META_DATA;
+                    }
+
+                    @Override
+                    public ExplainPlan getExplainPlan() throws SQLException {
+                        return ExplainPlan.EMPTY_PLAN;
+                    }
+
+                    @Override
+                    public PhoenixConnection getConnection() {
+                        return connection;
+                    }
+
+                    @Override
+                    public MutationState execute() throws SQLException {
+                        Cell kv = plan.iterator().next().getValue(0);
+                        ImmutableBytesWritable tmpPtr = new ImmutableBytesWritable(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength());
+                        // A single Cell will be returned with the count(*) - we decode that here
+                        long rowCount = PDataType.LONG.getCodec().decodeLong(tmpPtr, SortOrder.getDefault());
+                        // The contract is to return a MutationState that contains the number of rows modified. In this
+                        // case, it's the number of rows in the data table which corresponds to the number of index
+                        // rows that were added.
+                        return new MutationState(0, connection, rowCount);
+                    }
+                    
+                };
             } else {
                 PostIndexDDLCompiler compiler = new PostIndexDDLCompiler(connection, dataTableRef);
-                MutationPlan plan = compiler.compile(index);
+                mutationPlan = compiler.compile(index);
                 try {
-                    plan.getContext().setScanTimeRange(new TimeRange(dataTableRef.getLowerBoundTimeStamp(), Long.MAX_VALUE));
+                    mutationPlan.getContext().setScanTimeRange(new TimeRange(dataTableRef.getLowerBoundTimeStamp(), Long.MAX_VALUE));
                 } catch (IOException e) {
                     throw new SQLException(e);
                 }
-                state = connection.getQueryServices().updateData(plan);
             }            
+            MutationState state = connection.getQueryServices().updateData(mutationPlan);
             indexStatement = FACTORY.alterIndex(FACTORY.namedTable(null, 
                 TableName.create(index.getSchemaName().getString(), index.getTableName().getString())),
                 dataTableRef.getTable().getTableName().getString(), false, PIndexState.ACTIVE);
@@ -1002,7 +1036,7 @@ public class MetaDataClient {
                 }
                 // Set DEFAULT_COLUMN_FAMILY_NAME of index to match data table
                 // We need this in the props so that the correct column family is created
-                if (dataTable.getDefaultFamilyName() != null && dataTable.getType() != PTableType.VIEW) {
+                if (dataTable.getDefaultFamilyName() != null && dataTable.getType() != PTableType.VIEW && indexId == null) {
                     statement.getProps().put("", new Pair<String,Object>(DEFAULT_COLUMN_FAMILY_NAME,dataTable.getDefaultFamilyName().getString()));
                 }
                 CreateTableStatement tableStatement = FACTORY.createTable(indexTableName, statement.getProps(), columnDefs, pk, statement.getSplitNodes(), PTableType.INDEX, statement.ifNotExists(), null, null, statement.getBindCount());
@@ -1202,11 +1236,10 @@ public class MetaDataClient {
             }
             
             boolean removedProp = false;
-            // Can't set MULTI_TENANT or DEFAULT_COLUMN_FAMILY_NAME on an index
+            // 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);
                 multiTenant = Boolean.TRUE.equals(multiTenantProp);
-                // Remove, but add back after our check below
                 defaultFamilyName = (String)tableProps.remove(PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME);  
                 removedProp = (defaultFamilyName != null);
             }
@@ -1218,7 +1251,8 @@ public class MetaDataClient {
             }
             // 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();
+                throw new SQLExceptionInfo.Builder(SQLExceptionCode.VIEW_WITH_PROPERTIES).build()
+                        .buildException();
             }
             if (removedProp) {
                 tableProps.put(PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME, defaultFamilyName);  

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f47e1700/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 3857736..314431a 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
@@ -1452,4 +1452,24 @@ public class QueryCompilerTest extends BaseConnectionlessQueryTest {
             assertFalse("Did not expected to find GROUP BY limit optimization in: " + query, QueryUtil.getExplainPlan(rs).contains(" LIMIT 3 GROUPS"));
         }
     }
+    
+    @Test
+    public void testLocalIndexCreationWithDefaultFamilyOption() throws Exception {
+        Connection conn1 = DriverManager.getConnection(getUrl());
+        try{
+            Statement statement = conn1.createStatement();
+            statement.execute("create table example (id integer not null,fn varchar,"
+                    + "ln varchar constraint pk primary key(id)) DEFAULT_COLUMN_FAMILY='F'");
+            try {
+                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());
+            }
+            statement.execute("create local index my_idx on example (fn)");
+       } finally {
+            conn1.close();
+        }
+    }
+
 }