PHOENIX-4669 NoSuchColumnFamilyException when creating index on views that are 
built on tables which have named column family

Signed-off-by: ss77892 <s...@apache.org>


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

Branch: refs/heads/4.x-HBase-1.1
Commit: 697d871a7a02bf0380c26733670840d39d303c79
Parents: 9905126
Author: Toshihiro Suzuki <brfrn...@gmail.com>
Authored: Thu Mar 29 17:17:37 2018 +0900
Committer: ss77892 <s...@apache.org>
Committed: Mon Apr 9 21:50:09 2018 -0700

----------------------------------------------------------------------
 .../phoenix/end2end/index/ViewIndexIT.java      | 45 +++++++++++++++++++-
 .../query/ConnectionQueryServicesImpl.java      | 27 ++++++------
 2 files changed, 57 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/697d871a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java
index 53bb550..8ffd798 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java
@@ -31,6 +31,7 @@ import java.sql.DriverManager;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.Statement;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
@@ -443,5 +444,47 @@ public class ViewIndexIT extends ParallelStatsDisabledIT {
         assertFalse(rs.next());
         assertEquals(indexName, 
stmt.getQueryPlan().getContext().getCurrentTable().getTable().getName().getString());
     }
-    
+
+    @Test
+    public void 
testCreatingIndexOnViewBuiltOnTableWithOnlyNamedColumnFamilies() throws 
Exception {
+        try (Connection c = getConnection(); Statement s = 
c.createStatement()) {
+            String tableName = generateUniqueName();
+            String viewName = generateUniqueName();
+            String indexName = generateUniqueName();
+
+            c.setAutoCommit(true);
+            s.execute("CREATE TABLE " + tableName + " (COL1 VARCHAR PRIMARY 
KEY, CF.COL2 VARCHAR)");
+            s.executeUpdate("UPSERT INTO " + tableName + " VALUES ('AAA', 
'BBB')");
+            s.execute("CREATE VIEW " + viewName + " AS SELECT * FROM " + 
tableName);
+            s.execute("CREATE INDEX " + indexName + " ON " + viewName + " 
(CF.COL2)");
+
+            try (ResultSet rs = s.executeQuery("SELECT * FROM " + viewName + " 
WHERE CF.COL2 = 'BBB'")) {
+                assertTrue(rs.next());
+                assertEquals("AAA", rs.getString("COL1"));
+                assertEquals("BBB", rs.getString("COL2"));
+            }
+        }
+        try (Connection c = getConnection(); Statement s = 
c.createStatement()) {
+            String tableName = generateUniqueName();
+            String viewName = generateUniqueName();
+            String index1Name = generateUniqueName();
+            String index2Name = generateUniqueName();
+
+            c.setAutoCommit(true);
+            s.execute("create table " + tableName + " (i1 integer primary key, 
c2.i2 integer, c3.i3 integer, c4.i4 integer)");
+            s.execute("create view " + viewName + " as select * from " + 
tableName + " where c2.i2 = 1");
+            s.executeUpdate("upsert into " + viewName + "(i1, c3.i3, c4.i4) 
VALUES (1, 1, 1)");
+            s.execute("create index " + index1Name + " ON " + viewName + " 
(c3.i3)");
+            s.execute("create index " + index2Name + " ON " + viewName + " 
(c3.i3) include (c4.i4)");
+            s.executeUpdate("upsert into " + viewName + "(i1, c3.i3, c4.i4) 
VALUES (2, 2, 2)");
+
+            try (ResultSet rs = s.executeQuery("select * from " + viewName + " 
WHERE c3.i3 = 1")) {
+                assertTrue(rs.next());
+                assertEquals(1, rs.getInt("i1"));
+                assertEquals(1, rs.getInt("i2"));
+                assertEquals(1, rs.getInt("i3"));
+                assertEquals(1, rs.getInt("i4"));
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/697d871a/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 77aa376..e383e7d 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
@@ -1687,22 +1687,20 @@ public class ConnectionQueryServicesImpl extends 
DelegateQueryServices implement
             throws SQLException {
         byte[] physicalTableName = table.getPhysicalName().getBytes();
         HTableDescriptor htableDesc = 
this.getTableDescriptor(physicalTableName);
-        Map<String,Object> tableProps = 
createPropertiesMap(htableDesc.getValues());
-        List<Pair<byte[],Map<String,Object>>> families = 
Lists.newArrayListWithExpectedSize(Math.max(1, 
table.getColumnFamilies().size()+1));
-        if (families.isEmpty()) {
-            byte[] familyName = SchemaUtil.getEmptyColumnFamily(table);
+        List<Pair<byte[],Map<String,Object>>> families = 
Lists.newArrayListWithExpectedSize(Math.max(1, table.getColumnFamilies().size() 
+ 1));
+
+        // Create all column families that the parent table has
+        for (PColumnFamily family : table.getColumnFamilies()) {
+            byte[] familyName = family.getName().getBytes();
             Map<String,Object> familyProps = 
createPropertiesMap(htableDesc.getFamily(familyName).getValues());
-            families.add(new Pair<byte[],Map<String,Object>>(familyName, 
familyProps));
-        } else {
-            for (PColumnFamily family : table.getColumnFamilies()) {
-                byte[] familyName = family.getName().getBytes();
-                Map<String,Object> familyProps = 
createPropertiesMap(htableDesc.getFamily(familyName).getValues());
-                families.add(new Pair<byte[],Map<String,Object>>(familyName, 
familyProps));
-            }
-            // Always create default column family, because we don't know in 
advance if we'll
-            // need it for an index with no covered columns.
-            families.add(new 
Pair<byte[],Map<String,Object>>(table.getDefaultFamilyName().getBytes(), 
Collections.<String,Object>emptyMap()));
+            families.add(new Pair<>(familyName, familyProps));
         }
+        // Always create default column family, because we don't know in 
advance if we'll
+        // need it for an index with no covered columns.
+        byte[] defaultFamilyName = table.getDefaultFamilyName() == null ?
+          QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES : 
table.getDefaultFamilyName().getBytes();
+        families.add(new Pair<>(defaultFamilyName, 
Collections.<String,Object>emptyMap()));
+
         byte[][] splits = null;
         if (table.getBucketNum() != null) {
             splits = SaltingUtil.getSalteByteSplitPoints(table.getBucketNum());
@@ -1710,6 +1708,7 @@ public class ConnectionQueryServicesImpl extends 
DelegateQueryServices implement
 
         // Transfer over table values into tableProps
         // TODO: encapsulate better
+        Map<String,Object> tableProps = 
createPropertiesMap(htableDesc.getValues());
         tableProps.put(PhoenixDatabaseMetaData.TRANSACTIONAL, 
table.isTransactional());
         tableProps.put(PhoenixDatabaseMetaData.IMMUTABLE_ROWS, 
table.isImmutableRows());
         ensureViewIndexTableCreated(physicalTableName, tableProps, families, 
splits, timestamp, isNamespaceMapped);

Reply via email to