This is an automated email from the ASF dual-hosted git repository.

pboado pushed a commit to branch 5.x-cdh6
in repository https://gitbox.apache.org/repos/asf/phoenix.git

commit 597ee0328a275a86b266f2a90cb8be59b60db99b
Author: Xinyi Yan <x...@salesforce.com>
AuthorDate: Sat Feb 9 00:05:55 2019 +0000

    PHOENIX-2265 Disallow creation of view over HBase table if PK not specified
    
    Signed-off-by: Geoffrey Jacoby <gjac...@apache.org>
---
 .../it/java/org/apache/phoenix/end2end/ViewIT.java | 51 +++++++++++++++++++++-
 .../phoenix/compile/CreateTableCompiler.java       | 17 ++++++++
 2 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
index bcf7eca..4daf012 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
@@ -57,6 +57,8 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.curator.shaded.com.google.common.collect.Lists;
 import org.apache.hadoop.hbase.DoNotRetryIOException;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.MiniHBaseCluster;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.client.Admin;
 import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
@@ -73,6 +75,7 @@ import org.apache.phoenix.exception.PhoenixIOException;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.mapreduce.util.ConnectionUtil;
 import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.ColumnAlreadyExistsException;
@@ -1368,7 +1371,53 @@ public class ViewIT extends SplitSystemCatalogIT {
         // we should be able to load the second view
         PhoenixRuntime.getTableNoCache(conn, fullViewName2);
     }
-    
+
+    @Test
+    public void testCreateViewFromHBaseTable() throws Exception {
+        String tableNameStr = generateUniqueName();
+        String familyNameStr = generateUniqueName();
+
+        TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(
+                TableName.valueOf(tableNameStr));
+        
builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(familyNameStr));
+
+        HBaseTestingUtility testUtil = getUtility();
+        Admin admin = testUtil.getAdmin();
+        admin.createTable(builder.build());
+        Connection conn = DriverManager.getConnection(getUrl());
+
+        //PK is not specified, without where clause
+        try {
+            conn.createStatement().executeUpdate("CREATE VIEW \"" + 
tableNameStr +
+                    "\" (ROWKEY VARCHAR, \"" + familyNameStr + "\".a 
VARCHAR)");
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.PRIMARY_KEY_MISSING.getErrorCode(), 
e.getErrorCode());
+        }
+
+        // No error, as PK is specified
+        conn.createStatement().executeUpdate("CREATE VIEW \"" + tableNameStr +
+                "\" (ROWKEY VARCHAR PRIMARY KEY, \"" + familyNameStr + "\".a 
VARCHAR)");
+
+        conn.createStatement().executeUpdate("DROP VIEW \"" + tableNameStr + 
"\"");
+
+        //PK is not specified, with where clause
+        try {
+            conn.createStatement().executeUpdate("CREATE VIEW \"" + 
tableNameStr +
+                    "\" (ROWKEY VARCHAR, \"" + familyNameStr + "\".a VARCHAR) 
AS SELECT * FROM \""
+                    + tableNameStr + "\" WHERE ROWKEY = '1'");
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.PRIMARY_KEY_MISSING.getErrorCode(), 
e.getErrorCode());
+        }
+
+        conn.createStatement().executeUpdate("CREATE VIEW \"" + tableNameStr +
+                "\" (ROWKEY VARCHAR PRIMARY KEY, \"" + familyNameStr + "\".a 
VARCHAR) AS SELECT " +
+                "* FROM \"" + tableNameStr + "\" WHERE ROWKEY = '1'");
+
+        conn.createStatement().executeUpdate("DROP VIEW \"" + tableNameStr + 
"\"");
+    }
+
     @Test
     public void testConcurrentViewCreationAndTableDrop() throws Exception {
         try (Connection conn = DriverManager.getConnection(getUrl())) {
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java
index 5293f8a..6329467 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java
@@ -158,6 +158,23 @@ public class CreateTableCompiler {
                     }
                 }
             }
+            if (viewTypeToBe == ViewType.MAPPED && 
parentToBe.getPKColumns().size() == 0) {
+                boolean isPKMissed = true;
+                if (pkConstraint.getColumnNames().size() > 0) {
+                    isPKMissed = false;
+                } else {
+                    for (ColumnDef columnDef: columnDefs) {
+                        if (columnDef.isPK()){
+                            isPKMissed = false;
+                            break;
+                        }
+                    }
+                }
+                if (isPKMissed) {
+                    throw new 
SQLExceptionInfo.Builder(SQLExceptionCode.PRIMARY_KEY_MISSING)
+                            .build().buildException();
+                }
+            }
         }
         final ViewType viewType = viewTypeToBe;
         final String viewStatement = viewStatementToBe;

Reply via email to