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 2018/09/24 15:28:13 UTC
[08/50] [abbrv] phoenix git commit: PHOENIX-3534 Support multi region
SYSTEM.CATALOG table (Thomas D'Silva and Rahul Gidwani)
http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
----------------------------------------------------------------------
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 34292ba..fdfd75b 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
@@ -28,172 +28,119 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.io.IOException;
+import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
+import org.apache.curator.shaded.com.google.common.collect.Lists;
+import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.Mutation;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.coprocessor.ObserverContext;
+import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
+import org.apache.hadoop.hbase.coprocessor.SimpleRegionObserver;
+import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
import org.apache.phoenix.compile.QueryPlan;
+import org.apache.phoenix.exception.PhoenixIOException;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.query.KeyRange;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.schema.ColumnAlreadyExistsException;
+import org.apache.phoenix.schema.PColumn;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTableType;
import org.apache.phoenix.schema.ReadOnlyTableException;
import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.util.MetaDataUtil;
import org.apache.phoenix.util.PhoenixRuntime;
import org.apache.phoenix.util.QueryUtil;
+import org.apache.phoenix.util.ReadOnlyProps;
import org.apache.phoenix.util.SchemaUtil;
+import org.apache.phoenix.util.TestUtil;
+import org.junit.BeforeClass;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Maps;
+@RunWith(Parameterized.class)
+public class ViewIT extends SplitSystemCatalogIT {
-public class ViewIT extends BaseViewIT {
-
- public ViewIT(boolean transactional) {
- super(transactional);
- }
-
- @Test
- public void testReadOnlyOnReadOnlyView() throws Exception {
- Connection earlierCon = DriverManager.getConnection(getUrl());
- Connection conn = DriverManager.getConnection(getUrl());
- String ddl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE) "+ tableDDLOptions;
- conn.createStatement().execute(ddl);
- String fullParentViewName = "V_" + generateUniqueName();
- ddl = "CREATE VIEW " + fullParentViewName + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
- conn.createStatement().execute(ddl);
- try {
- conn.createStatement().execute("UPSERT INTO " + fullParentViewName + " VALUES(1)");
- fail();
- } catch (ReadOnlyTableException e) {
-
- }
- for (int i = 0; i < 10; i++) {
- conn.createStatement().execute("UPSERT INTO " + fullTableName + " VALUES(" + i + ")");
- }
- conn.commit();
-
- analyzeTable(conn, fullParentViewName, transactional);
-
- List<KeyRange> splits = getAllSplits(conn, fullParentViewName);
- assertEquals(4, splits.size());
-
- int count = 0;
- ResultSet rs = conn.createStatement().executeQuery("SELECT k FROM " + fullTableName);
- while (rs.next()) {
- assertEquals(count++, rs.getInt(1));
- }
- assertEquals(10, count);
-
- count = 0;
- rs = conn.createStatement().executeQuery("SELECT k FROM " + fullParentViewName);
- while (rs.next()) {
- count++;
- assertEquals(count + 5, rs.getInt(1));
- }
- assertEquals(4, count);
- count = 0;
- rs = earlierCon.createStatement().executeQuery("SELECT k FROM " + fullParentViewName);
- while (rs.next()) {
- count++;
- assertEquals(count + 5, rs.getInt(1));
- }
- assertEquals(4, count);
- String fullViewName = "V_" + generateUniqueName();
- ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullParentViewName + " WHERE k < 9";
- conn.createStatement().execute(ddl);
- try {
- conn.createStatement().execute("UPSERT INTO " + fullViewName + " VALUES(1)");
- fail();
- } catch (ReadOnlyTableException e) {
-
- } finally {
- conn.close();
- }
+ protected String tableDDLOptions;
+ protected boolean transactional;
- conn = DriverManager.getConnection(getUrl());
- count = 0;
- rs = conn.createStatement().executeQuery("SELECT k FROM " + fullViewName);
- while (rs.next()) {
- count++;
- assertEquals(count + 5, rs.getInt(1));
+ public ViewIT(boolean transactional) {
+ StringBuilder optionBuilder = new StringBuilder();
+ this.transactional = transactional;
+ if (transactional) {
+ optionBuilder.append(" TRANSACTIONAL=true ");
}
- assertEquals(3, count);
+ this.tableDDLOptions = optionBuilder.toString();
}
- @Test
- public void testNonSaltedUpdatableViewWithIndex() throws Exception {
- testUpdatableViewWithIndex(null, false);
- }
-
- @Test
- public void testNonSaltedUpdatableViewWithLocalIndex() throws Exception {
- testUpdatableViewWithIndex(null, true);
+ @Parameters(name = "transactional = {0}")
+ public static Collection<Boolean> data() {
+ return Arrays.asList(new Boolean[] { false, true });
}
- @Test
- public void testUpdatableOnUpdatableView() throws Exception {
- String viewName = testUpdatableView(null);
- Connection conn = DriverManager.getConnection(getUrl());
- String fullViewName = "V_" + generateUniqueName();
- String ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + viewName + " WHERE k3 = 2";
- conn.createStatement().execute(ddl);
- ResultSet rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName);
- assertTrue(rs.next());
- assertEquals(1, rs.getInt(1));
- assertEquals(109, rs.getInt(2));
- assertEquals(2, rs.getInt(3));
- assertFalse(rs.next());
-
- conn.createStatement().execute("UPSERT INTO " + fullViewName + "(k2) VALUES(122)");
- conn.commit();
- rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName + " WHERE k2 >= 120");
- assertTrue(rs.next());
- assertEquals(1, rs.getInt(1));
- assertEquals(122, rs.getInt(2));
- assertEquals(2, rs.getInt(3));
- assertFalse(rs.next());
-
- try {
- conn.createStatement().execute("UPSERT INTO " + fullViewName + "(k2,k3) VALUES(123,3)");
- fail();
- } catch (SQLException e) {
- assertEquals(SQLExceptionCode.CANNOT_UPDATE_VIEW_COLUMN.getErrorCode(), e.getErrorCode());
- }
-
- try {
- conn.createStatement().execute("UPSERT INTO " + fullViewName + "(k2,k3) select k2, 3 from " + fullViewName);
- fail();
- } catch (SQLException e) {
- assertEquals(SQLExceptionCode.CANNOT_UPDATE_VIEW_COLUMN.getErrorCode(), e.getErrorCode());
+ @BeforeClass
+ public static void doSetup() throws Exception {
+ NUM_SLAVES_BASE = 6;
+ Map<String, String> props = Collections.emptyMap();
+ boolean splitSystemCatalog = (driver == null);
+ Map<String, String> serverProps = Maps.newHashMapWithExpectedSize(1);
+ serverProps.put("hbase.coprocessor.region.classes", FailingRegionObserver.class.getName());
+ serverProps.put("hbase.coprocessor.abortonerror", "false");
+ setUpTestDriver(new ReadOnlyProps(serverProps.entrySet().iterator()), new ReadOnlyProps(props.entrySet().iterator()));
+ // Split SYSTEM.CATALOG once after the mini-cluster is started
+ if (splitSystemCatalog) {
+ splitSystemCatalog();
}
}
-
+
@Test
public void testReadOnlyOnUpdatableView() throws Exception {
- String viewName = testUpdatableView(null);
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+ String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+ String ddl =
+ "CREATE VIEW " + fullViewName2 + " AS SELECT * FROM " + fullViewName1
+ + " WHERE k3 > 1 and k3 < 50";
+ testUpdatableView(fullTableName, fullViewName1, fullViewName2, ddl, null, tableDDLOptions);
Connection conn = DriverManager.getConnection(getUrl());
- String fullViewName = "V_" + generateUniqueName();
- String ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + viewName + " WHERE k3 > 1 and k3 < 50";
- conn.createStatement().execute(ddl);
- ResultSet rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName);
+ ResultSet rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName2);
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertEquals(109, rs.getInt(2));
assertEquals(2, rs.getInt(3));
assertFalse(rs.next());
-
try {
- conn.createStatement().execute("UPSERT INTO " + fullViewName + " VALUES(1)");
+ conn.createStatement().execute("UPSERT INTO " + fullViewName2 + " VALUES(1)");
fail();
} catch (ReadOnlyTableException e) {
@@ -201,22 +148,27 @@ public class ViewIT extends BaseViewIT {
conn.createStatement().execute("UPSERT INTO " + fullTableName + "(k1, k2,k3) VALUES(1, 122, 5)");
conn.commit();
- rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName + " WHERE k2 >= 120");
+ rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName2 + " WHERE k2 >= 120");
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertEquals(122, rs.getInt(2));
assertEquals(5, rs.getInt(3));
assertFalse(rs.next());
}
-
+
@Test
public void testDisallowDropOfReferencedColumn() throws Exception {
Connection conn = DriverManager.getConnection(getUrl());
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+ String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+
String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
conn.createStatement().execute(ddl);
- String fullViewName1 = "V_" + generateUniqueName();
ddl = "CREATE VIEW " + fullViewName1 + "(v2 VARCHAR, v3 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
conn.createStatement().execute(ddl);
+ ddl = "CREATE VIEW " + fullViewName2 + " AS SELECT * FROM " + fullViewName1 + " WHERE v2 != 'foo'";
+ conn.createStatement().execute(ddl);
try {
conn.createStatement().execute("ALTER VIEW " + fullViewName1 + " DROP COLUMN v1");
@@ -225,10 +177,6 @@ public class ViewIT extends BaseViewIT {
assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
}
- String fullViewName2 = "V_" + generateUniqueName();
- ddl = "CREATE VIEW " + fullViewName2 + " AS SELECT * FROM " + fullViewName1 + " WHERE v2 != 'foo'";
- conn.createStatement().execute(ddl);
-
try {
conn.createStatement().execute("ALTER VIEW " + fullViewName2 + " DROP COLUMN v1");
fail();
@@ -249,12 +197,16 @@ public class ViewIT extends BaseViewIT {
public void testReadOnlyViewWithCaseSensitiveTableNames() throws Exception {
Connection earlierCon = DriverManager.getConnection(getUrl());
Connection conn = DriverManager.getConnection(getUrl());
+ String schemaName = TestUtil.DEFAULT_SCHEMA_NAME + "_" + generateUniqueName();
String caseSensitiveTableName = "\"t_" + generateUniqueName() + "\"" ;
- String ddl = "CREATE TABLE " + caseSensitiveTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
- conn.createStatement().execute(ddl);
+ String fullTableName = SchemaUtil.getTableName(schemaName, caseSensitiveTableName);
String caseSensitiveViewName = "\"v_" + generateUniqueName() + "\"" ;
- ddl = "CREATE VIEW " + caseSensitiveViewName + " (v2 VARCHAR) AS SELECT * FROM " + caseSensitiveTableName + " WHERE k > 5";
+
+ String ddl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
conn.createStatement().execute(ddl);
+ ddl = "CREATE VIEW " + caseSensitiveViewName + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
+ conn.createStatement().execute(ddl);
+
try {
conn.createStatement().execute("UPSERT INTO " + caseSensitiveViewName + " VALUES(1)");
fail();
@@ -262,7 +214,7 @@ public class ViewIT extends BaseViewIT {
}
for (int i = 0; i < 10; i++) {
- conn.createStatement().execute("UPSERT INTO " + caseSensitiveTableName + " VALUES(" + i + ")");
+ conn.createStatement().execute("UPSERT INTO " + fullTableName + " VALUES(" + i + ")");
}
conn.commit();
@@ -285,11 +237,14 @@ public class ViewIT extends BaseViewIT {
@Test
public void testReadOnlyViewWithCaseSensitiveColumnNames() throws Exception {
Connection conn = DriverManager.getConnection(getUrl());
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
String ddl = "CREATE TABLE " + fullTableName + " (\"k\" INTEGER NOT NULL PRIMARY KEY, \"v1\" INTEGER, \"a\".v2 VARCHAR)" + tableDDLOptions;
+
conn.createStatement().execute(ddl);
- String viewName = "V_" + generateUniqueName();
ddl = "CREATE VIEW " + viewName + " (v VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE \"k\" > 5 and \"v1\" > 1";
conn.createStatement().execute(ddl);
+
try {
conn.createStatement().execute("UPSERT INTO " + viewName + " VALUES(1)");
fail();
@@ -313,11 +268,14 @@ public class ViewIT extends BaseViewIT {
@Test
public void testViewWithCurrentDate() throws Exception {
Connection conn = DriverManager.getConnection(getUrl());
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+
String ddl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 INTEGER, v2 DATE)" + tableDDLOptions;
conn.createStatement().execute(ddl);
- String viewName = "V_" + generateUniqueName();
ddl = "CREATE VIEW " + viewName + " (v VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE v2 > CURRENT_DATE()-5 AND v2 > DATE '2010-01-01'";
conn.createStatement().execute(ddl);
+
try {
conn.createStatement().execute("UPSERT INTO " + viewName + " VALUES(1)");
fail();
@@ -354,27 +312,33 @@ public class ViewIT extends BaseViewIT {
Properties props = new Properties();
props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(isNamespaceMapped));
Connection conn = DriverManager.getConnection(getUrl(),props);
- String schemaName1 = "S_" + generateUniqueName();
+ String tableName = "T_" + generateUniqueName();
+ String schemaName1 = SCHEMA1;
String fullTableName1 = SchemaUtil.getTableName(schemaName1, tableName);
+ String viewName1 = "V_" + generateUniqueName();
+ String viewSchemaName = SCHEMA2;
+ String fullViewName1 = SchemaUtil.getTableName(viewSchemaName, viewName1);
+ String viewName2 = "V_" + generateUniqueName();
+ String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, viewName1);
+
if (isNamespaceMapped) {
conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS " + schemaName1);
}
- String ddl = "CREATE TABLE " + fullTableName1 + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+ String ddl = "CREATE TABLE " + fullTableName1 + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin();
conn.createStatement().execute(ddl);
assertTrue(admin.tableExists(SchemaUtil.getPhysicalTableName(SchemaUtil.normalizeIdentifier(fullTableName1),
conn.unwrap(PhoenixConnection.class).getQueryServices().getProps())));
- String viewName = "V_" + generateUniqueName();
- String viewSchemaName = "S_" + generateUniqueName();
- String fullViewName1 = SchemaUtil.getTableName(viewSchemaName, viewName);
+
ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
conn.createStatement().execute(ddl);
- String fullViewName2 = "V_" + generateUniqueName();
+
ddl = "CREATE VIEW " + fullViewName2 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
conn.createStatement().execute(ddl);
+
conn.createStatement().executeQuery("SELECT * FROM " + fullViewName1);
conn.createStatement().executeQuery("SELECT * FROM " + fullViewName2);
- ddl = "DROP VIEW " + viewName;
+ ddl = "DROP VIEW " + viewName1;
try {
conn.createStatement().execute(ddl);
fail();
@@ -389,20 +353,20 @@ public class ViewIT extends BaseViewIT {
} catch (TableNotFoundException ignore) {
}
ddl = "DROP TABLE " + fullTableName1;
- validateCannotDropTableWithChildViewsWithoutCascade(conn, fullTableName1);
ddl = "DROP VIEW " + fullViewName2;
conn.createStatement().execute(ddl);
ddl = "DROP TABLE " + fullTableName1;
conn.createStatement().execute(ddl);
}
-
+
@Test
public void testDisallowDropOfColumnOnParentTable() throws Exception {
Connection conn = DriverManager.getConnection(getUrl());
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
conn.createStatement().execute(ddl);
- String viewName = "V_" + generateUniqueName();
ddl = "CREATE VIEW " + viewName + "(v2 VARCHAR, v3 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
conn.createStatement().execute(ddl);
@@ -416,46 +380,171 @@ public class ViewIT extends BaseViewIT {
@Test
public void testViewAndTableAndDropCascade() throws Exception {
- // Setup
Connection conn = DriverManager.getConnection(getUrl());
- String ddl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
- conn.createStatement().execute(ddl);
- String viewName = "V_" + generateUniqueName();
- String viewSchemaName = "S_" + generateUniqueName();
- String fullViewName1 = SchemaUtil.getTableName(viewSchemaName, viewName);
- ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+ String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+
+ String tableDdl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+ conn.createStatement().execute(tableDdl);
+ String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
conn.createStatement().execute(ddl);
- ddl = "CREATE LOCAL INDEX idx on " + fullViewName1 + "(v2)";
+ String indexName = generateUniqueName();
+ ddl = "CREATE LOCAL INDEX " + indexName + " on " + fullViewName1 + "(v2)";
conn.createStatement().execute(ddl);
- String fullViewName2 = SchemaUtil.getTableName(viewSchemaName, "V_" + generateUniqueName());
ddl = "CREATE VIEW " + fullViewName2 + "(v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 10";
conn.createStatement().execute(ddl);
+
+ // dropping base table without cascade should fail
+ try {
+ conn.createStatement().execute("DROP TABLE " + fullTableName );
+ fail();
+ }
+ catch (SQLException e) {
+ assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
+ }
- validateCannotDropTableWithChildViewsWithoutCascade(conn, fullTableName);
+ // drop table cascade should succeed
+ conn.createStatement().execute("DROP TABLE " + fullTableName + " CASCADE");
- // Execute DROP...CASCADE
+ validateViewDoesNotExist(conn, fullViewName1);
+ validateViewDoesNotExist(conn, fullViewName2);
+
+ }
+
+ @Test
+ public void testRecreateDroppedTableWithChildViews() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+ String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+
+ String tableDdl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+ conn.createStatement().execute(tableDdl);
+ String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
+ conn.createStatement().execute(ddl);
+ String indexName = generateUniqueName();
+ ddl = "CREATE INDEX " + indexName + " on " + fullViewName1 + "(v2)";
+ conn.createStatement().execute(ddl);
+ ddl = "CREATE VIEW " + fullViewName2 + "(v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 10";
+ conn.createStatement().execute(ddl);
+
+ // drop table cascade should succeed
conn.createStatement().execute("DROP TABLE " + fullTableName + " CASCADE");
validateViewDoesNotExist(conn, fullViewName1);
validateViewDoesNotExist(conn, fullViewName2);
+
+ // recreate the table that was dropped
+ conn.createStatement().execute(tableDdl);
+ // the two child views should still not exist
+ try {
+ PhoenixRuntime.getTableNoCache(conn, fullViewName1);
+ fail();
+ } catch (SQLException e) {
+ }
+ try {
+ PhoenixRuntime.getTableNoCache(conn, fullViewName2);
+ fail();
+ } catch (SQLException e) {
+ }
}
@Test
- public void testViewAndTableAndDropCascadeWithIndexes() throws Exception {
+ public void testRecreateIndexWhoseAncestorWasDropped() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ String fullTableName1 = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+ String fullTableName2 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
- // Setup - Tables and Views with Indexes
- Connection conn = DriverManager.getConnection(getUrl());
- if (tableDDLOptions.length()!=0)
- tableDDLOptions+=",";
- tableDDLOptions+="IMMUTABLE_ROWS=true";
+ String tableDdl = "CREATE TABLE " + fullTableName1 + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+ conn.createStatement().execute(tableDdl);
+ tableDdl = "CREATE TABLE " + fullTableName2 + " (k INTEGER NOT NULL PRIMARY KEY, v3 DATE)" + tableDDLOptions;
+ conn.createStatement().execute(tableDdl);
+ String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
+ conn.createStatement().execute(ddl);
+ String indexName = generateUniqueName();
+ ddl = "CREATE INDEX " + indexName + " on " + fullViewName1 + "(v2)";
+ conn.createStatement().execute(ddl);
+ try {
+ // this should fail because an index with this name is present
+ ddl = "CREATE INDEX " + indexName + " on " + fullTableName2 + "(v1)";
+ conn.createStatement().execute(ddl);
+ fail();
+ }
+ catch(SQLException e) {
+ }
+
+ // drop table cascade should succeed
+ conn.createStatement().execute("DROP TABLE " + fullTableName1 + " CASCADE");
+
+ // should be able to reuse the index name
+ ddl = "CREATE INDEX " + indexName + " on " + fullTableName2 + "(v3)";
+ conn.createStatement().execute(ddl);
+
+ String fullIndexName = SchemaUtil.getTableName(SCHEMA2, indexName);
+ PTable index = PhoenixRuntime.getTableNoCache(conn, fullIndexName);
+ // the index should have v3 but not v2
+ validateCols(index);
+ }
+
+ @Test
+ public void testRecreateViewWhoseParentWasDropped() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ String fullTableName1 = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+ String fullTableName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+
+ String tableDdl = "CREATE TABLE " + fullTableName1 + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+ conn.createStatement().execute(tableDdl);
+ tableDdl = "CREATE TABLE " + fullTableName2 + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+ conn.createStatement().execute(tableDdl);
+ String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
+ conn.createStatement().execute(ddl);
+
+ // drop table cascade should succeed
+ conn.createStatement().execute("DROP TABLE " + fullTableName1 + " CASCADE");
+
+ // should be able to reuse the view name
+ ddl = "CREATE VIEW " + fullViewName1 + " (v3 VARCHAR) AS SELECT * FROM " + fullTableName2 + " WHERE k > 5";
+ conn.createStatement().execute(ddl);
+
+ PTable view = PhoenixRuntime.getTableNoCache(conn, fullViewName1);
+ // the view should have v3 but not v2
+ validateCols(view);
+ }
+
+ private void validateCols(PTable table) {
+ final String prefix = table.getType() == PTableType.INDEX ? "0:" : "";
+ Predicate<PColumn> predicate = new Predicate<PColumn>() {
+ @Override
+ public boolean apply(PColumn col) {
+ return col.getName().getString().equals(prefix + "V3")
+ || col.getName().getString().equals(prefix + "V2");
+ }
+ };
+ List<PColumn> colList = table.getColumns();
+ Collection<PColumn> filteredCols = Collections2.filter(colList, predicate);
+ assertEquals(1, filteredCols.size());
+ assertEquals(prefix + "V3", filteredCols.iterator().next().getName().getString());
+ }
+
+ @Test
+ public void testViewAndTableAndDropCascadeWithIndexes() throws Exception {
+ // Setup - Tables and Views with Indexes
+ Connection conn = DriverManager.getConnection(getUrl());
+ if (tableDDLOptions.length()!=0)
+ tableDDLOptions+=",";
+ tableDDLOptions+="IMMUTABLE_ROWS=true";
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
String ddl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
conn.createStatement().execute(ddl);
- String viewSchemaName = "S_" + generateUniqueName();
- String fullViewName1 = SchemaUtil.getTableName(viewSchemaName, "V_" + generateUniqueName());
- String fullViewName2 = SchemaUtil.getTableName(viewSchemaName, "V_" + generateUniqueName());
+ String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+ String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
String indexName1 = "I_" + generateUniqueName();
String indexName2 = "I_" + generateUniqueName();
String indexName3 = "I_" + generateUniqueName();
+
ddl = "CREATE INDEX " + indexName1 + " ON " + fullTableName + " (v1)";
conn.createStatement().execute(ddl);
ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
@@ -466,9 +555,8 @@ public class ViewIT extends BaseViewIT {
conn.createStatement().execute(ddl);
ddl = "CREATE INDEX " + indexName3 + " ON " + fullViewName2 + " (v2)";
conn.createStatement().execute(ddl);
-
- validateCannotDropTableWithChildViewsWithoutCascade(conn, fullTableName);
+
// Execute DROP...CASCADE
conn.createStatement().execute("DROP TABLE " + fullTableName + " CASCADE");
@@ -478,28 +566,16 @@ public class ViewIT extends BaseViewIT {
}
- private void validateCannotDropTableWithChildViewsWithoutCascade(Connection conn, String tableName) throws SQLException {
- String ddl;
- try {
- ddl = "DROP TABLE " + tableName;
- conn.createStatement().execute(ddl);
- fail("Should not be able to drop table " + tableName + " with child views without explictly specifying CASCADE");
- } catch (SQLException e) {
- assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
- }
- }
-
-
- private void validateViewDoesNotExist(Connection conn, String fullViewName) throws SQLException {
- try {
- String ddl1 = "DROP VIEW " + fullViewName;
+ private void validateViewDoesNotExist(Connection conn, String fullViewName) throws SQLException {
+ try {
+ String ddl1 = "DROP VIEW " + fullViewName;
conn.createStatement().execute(ddl1);
fail("View " + fullViewName + " should have been deleted when parent was dropped");
} catch (TableNotFoundException e) {
- //Expected
+ //Expected
}
- }
-
+ }
+
@Test
public void testViewUsesTableGlobalIndex() throws Exception {
testViewUsesTableIndex(false);
@@ -515,17 +591,17 @@ public class ViewIT extends BaseViewIT {
ResultSet rs;
// Use unique name for table with local index as otherwise we run into issues
// when we attempt to drop the table (with the drop metadata option set to false
- String fullTableName = this.fullTableName + (localIndex ? "_WITH_LI" : "_WITHOUT_LI");
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()) + (localIndex ? "_WITH_LI" : "_WITHOUT_LI");
Connection conn = DriverManager.getConnection(getUrl());
String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, k3 DECIMAL, s1 VARCHAR, s2 VARCHAR CONSTRAINT pk PRIMARY KEY (k1, k2, k3))" + tableDDLOptions;
conn.createStatement().execute(ddl);
String indexName1 = "I_" + generateUniqueName();
- String fullIndexName1 = SchemaUtil.getTableName(schemaName, indexName1);
+ String fullIndexName1 = SchemaUtil.getTableName(SCHEMA1, indexName1);
conn.createStatement().execute("CREATE " + (localIndex ? "LOCAL " : "") + " INDEX " + indexName1 + " ON " + fullTableName + "(k3, k2) INCLUDE(s1, s2)");
String indexName2 = "I_" + generateUniqueName();
conn.createStatement().execute("CREATE INDEX " + indexName2 + " ON " + fullTableName + "(k3, k2, s2)");
- String fullViewName = "V_" + generateUniqueName();
+ String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullTableName + " WHERE s1 = 'foo'";
conn.createStatement().execute(ddl);
String[] s1Values = {"foo","bar"};
@@ -564,15 +640,20 @@ public class ViewIT extends BaseViewIT {
@Test
public void testCreateViewDefinesPKColumn() throws Exception {
Connection conn = DriverManager.getConnection(getUrl());
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+
String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
conn.createStatement().execute(ddl);
- String fullViewName = "V_" + generateUniqueName();
ddl = "CREATE VIEW " + fullViewName + "(v2 VARCHAR, k3 VARCHAR PRIMARY KEY) AS SELECT * FROM " + fullTableName + " WHERE K1 = 1";
conn.createStatement().execute(ddl);
// assert PK metadata
- ResultSet rs = conn.getMetaData().getPrimaryKeys(null, null, fullViewName);
- assertPKs(rs, new String[] {"K1", "K2", "K3"});
+ ResultSet rs =
+ conn.getMetaData().getPrimaryKeys(null,
+ SchemaUtil.getSchemaNameFromFullName(fullViewName),
+ SchemaUtil.getTableNameFromFullName(fullViewName));
+ assertPKs(rs, new String[] {"K3"});
// sanity check upserts into base table and view
conn.createStatement().executeUpdate("upsert into " + fullTableName + " (k1, k2, v1) values (1, 1, 1)");
@@ -593,43 +674,54 @@ public class ViewIT extends BaseViewIT {
@Test
public void testCreateViewDefinesPKConstraint() throws Exception {
Connection conn = DriverManager.getConnection(getUrl());
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+
String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
conn.createStatement().execute(ddl);
- String fullViewName = "V_" + generateUniqueName();
ddl = "CREATE VIEW " + fullViewName + "(v2 VARCHAR, k3 VARCHAR, k4 INTEGER NOT NULL, CONSTRAINT PKVEW PRIMARY KEY (k3, k4)) AS SELECT * FROM " + fullTableName + " WHERE K1 = 1";
conn.createStatement().execute(ddl);
-
+
// assert PK metadata
- ResultSet rs = conn.getMetaData().getPrimaryKeys(null, null, fullViewName);
- assertPKs(rs, new String[] {"K1", "K2", "K3", "K4"});
+ ResultSet rs =
+ conn.getMetaData().getPrimaryKeys(null,
+ SchemaUtil.getSchemaNameFromFullName(fullViewName),
+ SchemaUtil.getTableNameFromFullName(fullViewName));
+ assertPKs(rs, new String[] {"K3", "K4"});
}
@Test
public void testViewAddsPKColumn() throws Exception {
Connection conn = DriverManager.getConnection(getUrl());
- String fullTableName2 = fullTableName;
- String ddl = "CREATE TABLE " + fullTableName2 + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String viewName = generateUniqueName();
+ String fullViewName = SchemaUtil.getTableName(SCHEMA2, viewName);
+
+ String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
conn.createStatement().execute(ddl);
- String fullViewName = "V_" + generateUniqueName();
ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
conn.createStatement().execute(ddl);
+
ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR PRIMARY KEY, k4 VARCHAR PRIMARY KEY, v2 INTEGER";
conn.createStatement().execute(ddl);
// assert PK metadata
- ResultSet rs = conn.getMetaData().getPrimaryKeys(null, null, fullViewName);
- assertPKs(rs, new String[] {"K1", "K2", "K3", "K4"});
+ ResultSet rs = conn.getMetaData().getPrimaryKeys(null, SCHEMA2, viewName);
+ assertPKs(rs, new String[] {"K3", "K4"});
}
@Test
public void testViewAddsPKColumnWhoseParentsLastPKIsVarLength() throws Exception {
Connection conn = DriverManager.getConnection(getUrl());
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+
String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 VARCHAR NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
conn.createStatement().execute(ddl);
- String fullViewName1 = "V_" + generateUniqueName();
- ddl = "CREATE VIEW " + fullViewName1 + " AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
+ ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
conn.createStatement().execute(ddl);
- ddl = "ALTER VIEW " + fullViewName1 + " ADD k3 VARCHAR PRIMARY KEY, k4 VARCHAR PRIMARY KEY, v2 INTEGER";
+
+ ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR PRIMARY KEY, k4 VARCHAR PRIMARY KEY, v2 INTEGER";
try {
conn.createStatement().execute(ddl);
fail("View cannot extend PK if parent's last PK is variable length. See https://issues.apache.org/jira/browse/PHOENIX-978.");
@@ -639,7 +731,7 @@ public class ViewIT extends BaseViewIT {
String fullViewName2 = "V_" + generateUniqueName();
ddl = "CREATE VIEW " + fullViewName2 + " (k3 VARCHAR PRIMARY KEY) AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
try {
- conn.createStatement().execute(ddl);
+ conn.createStatement().execute(ddl);
} catch (SQLException e) {
assertEquals(CANNOT_MODIFY_VIEW_PK.getErrorCode(), e.getErrorCode());
}
@@ -648,23 +740,28 @@ public class ViewIT extends BaseViewIT {
@Test(expected=ColumnAlreadyExistsException.class)
public void testViewAddsClashingPKColumn() throws Exception {
Connection conn = DriverManager.getConnection(getUrl());
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+
String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
conn.createStatement().execute(ddl);
- String fullViewName = "V_" + generateUniqueName();
ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
conn.createStatement().execute(ddl);
+
ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR PRIMARY KEY, k2 VARCHAR PRIMARY KEY, v2 INTEGER";
conn.createStatement().execute(ddl);
}
-
+
@Test
public void testViewAddsNotNullPKColumn() throws Exception {
Connection conn = DriverManager.getConnection(getUrl());
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
conn.createStatement().execute(ddl);
- String fullViewName = "V_" + generateUniqueName();
ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
conn.createStatement().execute(ddl);
+
try {
ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR NOT NULL PRIMARY KEY";
conn.createStatement().execute(ddl);
@@ -677,15 +774,17 @@ public class ViewIT extends BaseViewIT {
@Test
public void testQueryViewStatementOptimization() throws Exception {
Connection conn = DriverManager.getConnection(getUrl());
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+ String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
String sql = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
conn.createStatement().execute(sql);
- String fullViewName1 = "V_" + generateUniqueName();
sql = "CREATE VIEW " + fullViewName1 + " AS SELECT * FROM " + fullTableName;
conn.createStatement().execute(sql);
- String fullViewName2 = "V_" + generateUniqueName();
sql = "CREATE VIEW " + fullViewName2 + " AS SELECT * FROM " + fullTableName + " WHERE k1 = 1.0";
conn.createStatement().execute(sql);
+
sql = "SELECT * FROM " + fullViewName1 + " order by k1, k2";
PreparedStatement stmt = conn.prepareStatement(sql);
QueryPlan plan = PhoenixRuntime.getOptimizedQueryPlan(stmt);
@@ -702,13 +801,14 @@ public class ViewIT extends BaseViewIT {
Properties props = new Properties();
Connection conn1 = DriverManager.getConnection(getUrl(), props);
conn1.setAutoCommit(true);
- String tableName=generateUniqueName();
- String viewName=generateUniqueName();
+ String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
conn1.createStatement().execute(
"CREATE TABLE "+tableName+" (k VARCHAR PRIMARY KEY, v1 VARCHAR, v2 VARCHAR) UPDATE_CACHE_FREQUENCY=1000000");
conn1.createStatement().execute("upsert into "+tableName+" values ('row1', 'value1', 'key1')");
conn1.createStatement().execute(
"CREATE VIEW "+viewName+" (v43 VARCHAR) AS SELECT * FROM "+tableName+" WHERE v1 = 'value1'");
+
ResultSet rs = conn1.createStatement()
.executeQuery("SELECT * FROM "+tableName+" WHERE v1 = 'value1'");
assertTrue(rs.next());
@@ -724,60 +824,59 @@ public class ViewIT extends BaseViewIT {
props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.TRUE.toString());
try (Connection conn = DriverManager.getConnection(getUrl(), props);
- HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
+ HBaseAdmin admin =
+ conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
conn.createStatement().execute("CREATE SCHEMA " + NS);
// test for a view that is in non-default schema
- {
- HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(NS, TBL));
- desc.addFamily(new HColumnDescriptor(CF));
- admin.createTable(desc);
+ HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(NS, TBL));
+ desc.addFamily(new HColumnDescriptor(CF));
+ admin.createTable(desc);
- String view = NS + "." + TBL;
- conn.createStatement().execute(
- "CREATE VIEW " + view + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
+ String view1 = NS + "." + TBL;
+ conn.createStatement().execute(
+ "CREATE VIEW " + view1 + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
- assertTrue(QueryUtil.getExplainPlan(
- conn.createStatement().executeQuery("explain select * from " + view))
+ assertTrue(QueryUtil
+ .getExplainPlan(
+ conn.createStatement().executeQuery("explain select * from " + view1))
.contains(NS + ":" + TBL));
- conn.createStatement().execute("DROP VIEW " + view);
- }
+
- // test for a view whose name contains a dot (e.g. "AAA.BBB") in default schema (for backward compatibility)
- {
- HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(NS + "." + TBL));
- desc.addFamily(new HColumnDescriptor(CF));
- admin.createTable(desc);
+ // test for a view whose name contains a dot (e.g. "AAA.BBB") in default schema (for
+ // backward compatibility)
+ desc = new HTableDescriptor(TableName.valueOf(NS + "." + TBL));
+ desc.addFamily(new HColumnDescriptor(CF));
+ admin.createTable(desc);
- String view = "\"" + NS + "." + TBL + "\"";
- conn.createStatement().execute(
- "CREATE VIEW " + view + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
+ String view2 = "\"" + NS + "." + TBL + "\"";
+ conn.createStatement().execute(
+ "CREATE VIEW " + view2 + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
- assertTrue(QueryUtil.getExplainPlan(
- conn.createStatement().executeQuery("explain select * from " + view))
+ assertTrue(QueryUtil
+ .getExplainPlan(
+ conn.createStatement().executeQuery("explain select * from " + view2))
.contains(NS + "." + TBL));
- conn.createStatement().execute("DROP VIEW " + view);
- }
-
// test for a view whose name contains a dot (e.g. "AAA.BBB") in non-default schema
- {
- HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(NS, NS + "." + TBL));
- desc.addFamily(new HColumnDescriptor(CF));
- admin.createTable(desc);
+ desc = new HTableDescriptor(TableName.valueOf(NS, NS + "." + TBL));
+ desc.addFamily(new HColumnDescriptor(CF));
+ admin.createTable(desc);
- String view = NS + ".\"" + NS + "." + TBL + "\"";
- conn.createStatement().execute(
- "CREATE VIEW " + view + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
+ String view3 = NS + ".\"" + NS + "." + TBL + "\"";
+ conn.createStatement().execute(
+ "CREATE VIEW " + view3 + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
- assertTrue(QueryUtil.getExplainPlan(
- conn.createStatement().executeQuery("explain select * from " + view))
+ assertTrue(QueryUtil
+ .getExplainPlan(
+ conn.createStatement().executeQuery("explain select * from " + view3))
.contains(NS + ":" + NS + "." + TBL));
-
- conn.createStatement().execute("DROP VIEW " + view);
- }
+
+ conn.createStatement().execute("DROP VIEW " + view1);
+ conn.createStatement().execute("DROP VIEW " + view2);
+ conn.createStatement().execute("DROP VIEW " + view3);
conn.createStatement().execute("DROP SCHEMA " + NS);
}
@@ -793,14 +892,14 @@ public class ViewIT extends BaseViewIT {
}
@Test
- public void testCompositeDescPK() throws SQLException {
+ public void testCompositeDescPK() throws Exception {
Properties props = new Properties();
try (Connection globalConn = DriverManager.getConnection(getUrl(), props)) {
- String tableName = generateUniqueName();
- String viewName1 = generateUniqueName();
- String viewName2 = generateUniqueName();
- String viewName3 = generateUniqueName();
- String viewName4 = generateUniqueName();
+ String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String viewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+ String viewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+ String viewName3 = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String viewName4 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
// create global base table
globalConn.createStatement().execute("CREATE TABLE " + tableName
@@ -823,6 +922,17 @@ public class ViewIT extends BaseViewIT {
+ " (pk1 VARCHAR(10) NOT NULL, pk2 VARCHAR(10) NOT NULL, col1 DATE, col3 DECIMAL CONSTRAINT PK PRIMARY KEY (pk1 DESC, pk2 DESC)) AS SELECT * FROM "
+ tableName + " WHERE KEY_PREFIX = 'abc' ");
+ // view with composite PK with multiple Date PK values DESC
+ tenantConn.createStatement()
+ .execute("CREATE VIEW " + viewName3
+ + " (pk1 DATE(10) NOT NULL, pk2 DATE(10) NOT NULL, col1 VARCHAR(10), col3 DECIMAL CONSTRAINT PK PRIMARY KEY (pk1 DESC, pk2 DESC)) AS SELECT * FROM "
+ + tableName + " WHERE KEY_PREFIX = 'ab3' ");
+
+ tenantConn.createStatement()
+ .execute("CREATE VIEW " + viewName4
+ + " (pk1 DATE(10) NOT NULL, pk2 DECIMAL NOT NULL, pk3 VARCHAR(10) NOT NULL, col3 DECIMAL CONSTRAINT PK PRIMARY KEY (pk1 DESC, pk2 DESC, pk3 DESC)) AS SELECT * FROM "
+ + tableName + " WHERE KEY_PREFIX = 'ab4' ");
+
// upsert rows
upsertRows(viewName1, tenantConn);
upsertRows(viewName2, tenantConn);
@@ -835,12 +945,6 @@ public class ViewIT extends BaseViewIT {
validate(viewName1, tenantConn, whereClauses, expectedArray);
validate(viewName2, tenantConn, whereClauses, expectedArray);
- // view with composite PK with multiple Date PK values DESC
- tenantConn.createStatement()
- .execute("CREATE VIEW " + viewName3
- + " (pk1 DATE(10) NOT NULL, pk2 DATE(10) NOT NULL, col1 VARCHAR(10), col3 DECIMAL CONSTRAINT PK PRIMARY KEY (pk1 DESC, pk2 DESC)) AS SELECT * FROM "
- + tableName + " WHERE KEY_PREFIX = 'ab3' ");
-
tenantConn.createStatement().execute("UPSERT INTO " + viewName3
+ " (pk1, pk2, col1, col3) VALUES (TO_DATE('2017-10-16 22:00:00', 'yyyy-MM-dd HH:mm:ss'), TO_DATE('2017-10-16 21:00:00', 'yyyy-MM-dd HH:mm:ss'), 'txt1', 10)");
tenantConn.createStatement().execute("UPSERT INTO " + viewName3
@@ -862,11 +966,6 @@ public class ViewIT extends BaseViewIT {
"pk1 < TO_DATE('2017-10-16 22:00:00', 'yyyy-MM-dd HH:mm:ss')" };
validate(viewName3, tenantConn, view3WhereClauses, expectedArray);
- tenantConn.createStatement()
- .execute("CREATE VIEW " + viewName4
- + " (pk1 DATE(10) NOT NULL, pk2 DECIMAL NOT NULL, pk3 VARCHAR(10) NOT NULL, col3 DECIMAL CONSTRAINT PK PRIMARY KEY (pk1 DESC, pk2 DESC, pk3 DESC)) AS SELECT * FROM "
- + tableName + " WHERE KEY_PREFIX = 'ab4' ");
-
tenantConn.createStatement().execute("UPSERT INTO " + viewName4
+ " (pk1, pk2, pk3, col3) VALUES (TO_DATE('2017-10-16 22:00:00', 'yyyy-MM-dd HH:mm:ss'), 1, 'txt1', 10)");
tenantConn.createStatement().execute("UPSERT INTO " + viewName4
@@ -901,8 +1000,8 @@ public class ViewIT extends BaseViewIT {
Connection conn2 = DriverManager.getConnection(getUrl());
Statement s = conn.createStatement();
Statement s2 = conn2.createStatement()) {
- String tableName = generateUniqueName();
- String viewName = generateUniqueName();
+ String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
String indexName = generateUniqueName();
helpTestQueryForViewOnTableThatHasIndex(s, s2, tableName, viewName, indexName);
}
@@ -912,8 +1011,8 @@ public class ViewIT extends BaseViewIT {
public void testQueryForViewOnTableThatHasIndex() throws SQLException {
try (Connection conn = DriverManager.getConnection(getUrl());
Statement s = conn.createStatement()) {
- String tableName = generateUniqueName();
- String viewName = generateUniqueName();
+ String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
String indexName = generateUniqueName();
helpTestQueryForViewOnTableThatHasIndex(s, s, tableName, viewName, indexName);
}
@@ -966,4 +1065,237 @@ public class ViewIT extends BaseViewIT {
+ " (pk1, pk2, col1, col3) VALUES ('testb', 'testa', TO_DATE('2017-10-16 22:00:00', 'yyyy-MM-dd HH:mm:ss'), 10)");
tenantConn.commit();
}
+
+ @Test
+ public void testUpdatingPropertyOnBaseTable() throws Exception {
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+ try (Connection conn = DriverManager.getConnection(getUrl())) {
+ conn.createStatement()
+ .execute("create table " + fullTableName
+ + "(tenantId CHAR(15) NOT NULL, pk1 integer NOT NULL, v varchar CONSTRAINT PK PRIMARY KEY "
+ + "(tenantId, pk1)) MULTI_TENANT=true");
+ conn.createStatement().execute("CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullTableName);
+
+ conn.createStatement()
+ .execute("ALTER TABLE " + fullTableName + " set IMMUTABLE_ROWS = true");
+
+ // fetch the latest tables
+ PTable table = PhoenixRuntime.getTableNoCache(conn, fullTableName);
+ PTable view = PhoenixRuntime.getTableNoCache(conn, fullViewName);
+ assertEquals("IMMUTABLE_ROWS property set incorrectly", true, table.isImmutableRows());
+ assertEquals("IMMUTABLE_ROWS property set incorrectly", true, view.isImmutableRows());
+ }
+ }
+
+ public static String testUpdatableView(String fullTableName, String fullViewName, String fullChildViewName,
+ String childViewDDL, Integer saltBuckets, String tableDDLOptions) throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ if (saltBuckets != null) {
+ if (tableDDLOptions.length() != 0)
+ tableDDLOptions += ",";
+ tableDDLOptions += (" SALT_BUCKETS=" + saltBuckets);
+ }
+ String ddl = "CREATE TABLE " + fullTableName
+ + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, k3 DECIMAL, s VARCHAR CONSTRAINT pk PRIMARY KEY (k1, k2, k3))"
+ + tableDDLOptions;
+ conn.createStatement().execute(ddl);
+ ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullTableName + " WHERE k1 = 1";
+ conn.createStatement().execute(ddl);
+ ArrayList<String> splitPoints = Lists.newArrayList(fullTableName, fullViewName);
+ if (fullChildViewName != null) {
+ conn.createStatement().execute(childViewDDL);
+ splitPoints.add(fullChildViewName);
+ }
+
+ for (int i = 0; i < 10; i++) {
+ conn.createStatement().execute("UPSERT INTO " + fullTableName + " VALUES(" + (i % 4) + "," + (i + 100) + ","
+ + (i > 5 ? 2 : 1) + ")");
+ }
+ conn.commit();
+ ResultSet rs;
+
+ rs = conn.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName);
+ assertTrue(rs.next());
+ assertEquals(10, rs.getInt(1));
+ rs = conn.createStatement().executeQuery("SELECT count(*) FROM " + fullViewName);
+ assertTrue(rs.next());
+ assertEquals(3, rs.getInt(1));
+ rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName);
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(101, rs.getInt(2));
+ assertEquals(1, rs.getInt(3));
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(105, rs.getInt(2));
+ assertEquals(1, rs.getInt(3));
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(109, rs.getInt(2));
+ assertEquals(2, rs.getInt(3));
+ assertFalse(rs.next());
+
+ conn.createStatement().execute("UPSERT INTO " + fullViewName + "(k2,S,k3) VALUES(120,'foo',50.0)");
+ conn.createStatement().execute("UPSERT INTO " + fullViewName + "(k2,S,k3) VALUES(121,'bar',51.0)");
+ conn.commit();
+ rs = conn.createStatement().executeQuery("SELECT k1, k2 FROM " + fullViewName + " WHERE k2 >= 120");
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(120, rs.getInt(2));
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(121, rs.getInt(2));
+ assertFalse(rs.next());
+ conn.close();
+ return fullViewName;
+ }
+
+ public static Pair<String, Scan> testUpdatableViewIndex(String fullTableName, Integer saltBuckets,
+ boolean localIndex, String viewName) throws Exception {
+ ResultSet rs;
+ Connection conn = DriverManager.getConnection(getUrl());
+ String viewIndexName1 = "I_" + generateUniqueName();
+ String viewIndexPhysicalName = MetaDataUtil.getViewIndexPhysicalName(fullTableName);
+ if (localIndex) {
+ conn.createStatement().execute("CREATE LOCAL INDEX " + viewIndexName1 + " on " + viewName + "(k3)");
+ } else {
+ conn.createStatement().execute("CREATE INDEX " + viewIndexName1 + " on " + viewName + "(k3) include (s)");
+ }
+ conn.createStatement().execute("UPSERT INTO " + viewName + "(k2,S,k3) VALUES(120,'foo',50.0)");
+ conn.commit();
+
+ analyzeTable(conn, viewName);
+ List<KeyRange> splits = getAllSplits(conn, viewIndexName1);
+ // More guideposts with salted, since it's already pre-split at salt
+ // buckets
+ assertEquals(saltBuckets == null ? 6 : 8, splits.size());
+
+ String query = "SELECT k1, k2, k3, s FROM " + viewName + " WHERE k3 = 51.0";
+ rs = conn.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(121, rs.getInt(2));
+ assertTrue(BigDecimal.valueOf(51.0).compareTo(rs.getBigDecimal(3)) == 0);
+ assertEquals("bar", rs.getString(4));
+ assertFalse(rs.next());
+ rs = conn.createStatement().executeQuery("EXPLAIN " + query);
+ String queryPlan = QueryUtil.getExplainPlan(rs);
+ if (localIndex) {
+ assertEquals("CLIENT PARALLEL " + (saltBuckets == null ? 1 : saltBuckets) + "-WAY RANGE SCAN OVER "
+ + fullTableName + " [1,51]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT",
+ queryPlan);
+ } else {
+ assertEquals(saltBuckets == null
+ ? "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + viewIndexPhysicalName + " [" + Short.MIN_VALUE + ",51]"
+ : "CLIENT PARALLEL " + saltBuckets + "-WAY RANGE SCAN OVER " + viewIndexPhysicalName + " [0,"
+ + Short.MIN_VALUE + ",51] - [" + (saltBuckets.intValue() - 1) + "," + Short.MIN_VALUE
+ + ",51]\nCLIENT MERGE SORT",
+ queryPlan);
+ }
+
+ String viewIndexName2 = "I_" + generateUniqueName();
+ if (localIndex) {
+ conn.createStatement().execute("CREATE LOCAL INDEX " + viewIndexName2 + " on " + viewName + "(s)");
+ } else {
+ conn.createStatement().execute("CREATE INDEX " + viewIndexName2 + " on " + viewName + "(s)");
+ }
+
+ // new index hasn't been analyzed yet
+ splits = getAllSplits(conn, viewIndexName2);
+ assertEquals(saltBuckets == null ? 1 : 3, splits.size());
+
+ // analyze table should analyze all view data
+ analyzeTable(conn, fullTableName);
+ splits = getAllSplits(conn, viewIndexName2);
+ assertEquals(saltBuckets == null ? 6 : 8, splits.size());
+
+ query = "SELECT k1, k2, s FROM " + viewName + " WHERE s = 'foo'";
+ Statement statement = conn.createStatement();
+ rs = statement.executeQuery(query);
+ Scan scan = statement.unwrap(PhoenixStatement.class).getQueryPlan().getContext().getScan();
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(120, rs.getInt(2));
+ assertEquals("foo", rs.getString(3));
+ assertFalse(rs.next());
+ rs = conn.createStatement().executeQuery("EXPLAIN " + query);
+ String physicalTableName;
+ if (localIndex) {
+ physicalTableName = fullTableName;
+ assertEquals("CLIENT PARALLEL " + (saltBuckets == null ? 1 : saltBuckets) + "-WAY RANGE SCAN OVER "
+ + fullTableName + " [" + (2) + ",'foo']\n" + " SERVER FILTER BY FIRST KEY ONLY\n"
+ + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ } else {
+ physicalTableName = viewIndexPhysicalName;
+ assertEquals(
+ saltBuckets == null
+ ? "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + viewIndexPhysicalName + " ["
+ + (Short.MIN_VALUE + 1) + ",'foo']\n" + " SERVER FILTER BY FIRST KEY ONLY"
+ : "CLIENT PARALLEL " + saltBuckets + "-WAY RANGE SCAN OVER " + viewIndexPhysicalName
+ + " [0," + (Short.MIN_VALUE + 1) + ",'foo'] - [" + (saltBuckets.intValue() - 1)
+ + "," + (Short.MIN_VALUE + 1) + ",'foo']\n"
+ + " SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT",
+ QueryUtil.getExplainPlan(rs));
+ }
+ conn.close();
+ return new Pair<>(physicalTableName, scan);
+ }
+
+ @Test
+ public void testChildViewCreationFails() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+ String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, FAILED_VIEWNAME);
+ String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+
+ String tableDdl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+ conn.createStatement().execute(tableDdl);
+ String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
+ try {
+ conn.createStatement().execute(ddl);
+ fail();
+ }
+ catch (PhoenixIOException e){
+ }
+ ddl = "CREATE VIEW " + fullViewName2 + "(v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 10";
+ conn.createStatement().execute(ddl);
+
+ // the first child view should not exist
+ try {
+ PhoenixRuntime.getTableNoCache(conn, fullViewName1);
+ fail();
+ } catch (SQLException e) {
+ }
+
+ // we should be able to load the table
+ PhoenixRuntime.getTableNoCache(conn, fullTableName);
+ // we should be able to load the second view
+ PhoenixRuntime.getTableNoCache(conn, fullViewName2);
+ }
+
+ private static final String FAILED_VIEWNAME = "FAILED_VIEW";
+ private static final byte[] ROWKEY_TO_FAIL_BYTES = SchemaUtil.getTableKey(null, Bytes.toBytes(SCHEMA2),
+ Bytes.toBytes(FAILED_VIEWNAME));
+
+ public static class FailingRegionObserver extends SimpleRegionObserver {
+ @Override
+ public void preBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c,
+ MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
+ if (shouldFail(c, miniBatchOp.getOperation(0))) {
+ // throwing anything other than instances of IOException result
+ // in this coprocessor being unloaded
+ // DoNotRetryIOException tells HBase not to retry this mutation
+ // multiple times
+ throw new DoNotRetryIOException();
+ }
+ }
+
+ private boolean shouldFail(ObserverContext<RegionCoprocessorEnvironment> c, Mutation m) {
+ TableName tableName = c.getEnvironment().getRegion().getRegionInfo().getTable();
+ return tableName.equals(PhoenixDatabaseMetaData.SYSTEM_CATALOG_HBASE_TABLE_NAME)
+ && (Bytes.equals(ROWKEY_TO_FAIL_BYTES, m.getRow()));
+ }
+
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/BaseIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/BaseIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/BaseIndexIT.java
index f914256..d86037c 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/BaseIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/BaseIndexIT.java
@@ -48,6 +48,7 @@ import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
@@ -124,6 +125,7 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
String tableName = "TBL_" + generateUniqueName();
String indexName = "IND_" + generateUniqueName();
String fullTableName = SchemaUtil.getTableName(TestUtil.DEFAULT_SCHEMA_NAME, tableName);
+ String fullIndexName = SchemaUtil.getTableName(TestUtil.DEFAULT_SCHEMA_NAME, indexName);
try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
conn.setAutoCommit(false);
@@ -140,12 +142,12 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
ResultSet rs = conn.createStatement().executeQuery("EXPLAIN " + query);
if(localIndex) {
assertEquals(
- "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + tableName + " [1]\n" +
+ "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + fullTableName + " [1]\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
"CLIENT MERGE SORT",
QueryUtil.getExplainPlan(rs));
} else {
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + indexName + "\n"
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + fullIndexName + "\n"
+ " SERVER FILTER BY FIRST KEY ONLY", QueryUtil.getExplainPlan(rs));
}
@@ -168,7 +170,7 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
- query = "SELECT char_col1, int_col1 from "+indexName;
+ query = "SELECT char_col1, int_col1 from "+fullIndexName;
try{
rs = conn.createStatement().executeQuery(query);
fail();
@@ -500,7 +502,7 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
Statement stmt = conn.createStatement();
stmt.execute(ddl);
- query = "SELECT * FROM " + tableName;
+ query = "SELECT * FROM " + fullTableName;
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
@@ -772,10 +774,25 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
conn.createStatement().execute(ddl);
stmt = conn.prepareStatement("UPSERT INTO " + fullTableName + "(k, v1) VALUES(?,?)");
- stmt.setString(1, "a");
- stmt.setString(2, "y");
+ if (mutable) {
+ stmt.setString(1, "a");
+ stmt.setString(2, "y");
+ stmt.execute();
+ conn.commit();
+ }
+ stmt.setString(1, "b");
+ stmt.setString(2, "x");
stmt.execute();
conn.commit();
+
+ // the index table is one row
+ HTable table = new HTable(getUtility().getConfiguration(), fullTableName);
+ ResultScanner resultScanner = table.getScanner(new Scan());
+ for (Result result : resultScanner) {
+ System.out.println(result);
+ }
+ resultScanner.close();
+ table.close();
query = "SELECT * FROM " + fullTableName;
@@ -783,10 +800,15 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
assertEquals("a", rs.getString(1));
- assertEquals("y", rs.getString(2));
+ assertEquals(mutable ? "y" : "x", rs.getString(2));
+ assertEquals("1", rs.getString(3));
+ assertTrue(rs.next());
+ assertEquals("b", rs.getString(1));
+ assertEquals("x", rs.getString(2));
+ assertNull(rs.getString(3));
assertFalse(rs.next());
+ }
}
- }
@Test
public void testMultipleUpdatesAcrossRegions() throws Exception {
@@ -1069,6 +1091,7 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
String tableName = "TBL_" + generateUniqueName();
String indexName = "IND_" + generateUniqueName();
String fullTableName = SchemaUtil.getTableName(TestUtil.DEFAULT_SCHEMA_NAME, tableName);
+ String fullIndexeName = SchemaUtil.getTableName(TestUtil.DEFAULT_SCHEMA_NAME, indexName);
// Check system tables priorities.
try (HBaseAdmin admin = driver.getConnectionQueryServices(null, null).getAdmin();
Connection c = DriverManager.getConnection(getUrl())) {
@@ -1107,7 +1130,7 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
if (!localIndex && mutable) {
HTableDescriptor indexTable = admin.getTableDescriptor(
- org.apache.hadoop.hbase.TableName.valueOf(indexName));
+ org.apache.hadoop.hbase.TableName.valueOf(fullIndexeName));
val = indexTable.getValue("PRIORITY");
assertNotNull("PRIORITY is not set for table:" + indexTable, val);
assertTrue(Integer.parseInt(val) >= PhoenixRpcSchedulerFactory.getIndexPriority(config));
@@ -1140,7 +1163,7 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
ddl += "(p1 desc, p2))";
}
stmt.executeUpdate(ddl);
- ddl = "CREATE "+ (localIndex ? "LOCAL " : "") + " INDEX " + fullIndexName + " on " + fullTableName + "(a)";
+ ddl = "CREATE "+ (localIndex ? "LOCAL " : "") + " INDEX " + indexName + " on " + fullTableName + "(a)";
stmt.executeUpdate(ddl);
// upsert a single row
http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ChildViewsUseParentViewIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ChildViewsUseParentViewIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ChildViewsUseParentViewIndexIT.java
index 6c8f9e8..f3ee2cb 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ChildViewsUseParentViewIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ChildViewsUseParentViewIndexIT.java
@@ -29,7 +29,11 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
+import org.apache.hadoop.hbase.HConstants;
import org.apache.phoenix.end2end.ParallelStatsDisabledIT;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.util.PhoenixRuntime;
import org.apache.phoenix.util.QueryUtil;
import org.junit.Test;
@@ -111,7 +115,8 @@ public class ChildViewsUseParentViewIndexIT extends ParallelStatsDisabledIT {
// create child of parent view that should be able to use the parent's index
String childViewDdl = "CREATE VIEW " + childViewName1 + " AS SELECT * FROM " + parentViewName + " WHERE A2 = 'Y'";
conn.createStatement().execute(childViewDdl);
-
+
+ PTable childViewPTable = PhoenixRuntime.getTableNoCache(conn, childViewName1);
// create child of parent view that should *not* be able to use the parent's index
String grandChildViewDdl1 = "CREATE VIEW " + childViewName2 + " AS SELECT * FROM " + childViewName1 + " WHERE A3 = 'Z'";
conn.createStatement().execute(grandChildViewDdl1);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropColumnIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropColumnIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropColumnIT.java
index 28aa1e9..e19284a 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropColumnIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropColumnIT.java
@@ -17,7 +17,6 @@
*/
package org.apache.phoenix.end2end.index;
-import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -50,7 +49,6 @@ import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.schema.ColumnNotFoundException;
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.PTableImpl;
import org.apache.phoenix.schema.PTableKey;
@@ -411,119 +409,4 @@ public class DropColumnIT extends ParallelStatsDisabledIT {
}
}
- @Test
- public void testDroppingIndexedColDropsViewIndex() throws Exception {
- helpTestDroppingIndexedColDropsViewIndex(false);
- }
-
- @Test
- public void testDroppingIndexedColDropsMultiTenantViewIndex() throws Exception {
- helpTestDroppingIndexedColDropsViewIndex(true);
- }
-
- public void helpTestDroppingIndexedColDropsViewIndex(boolean isMultiTenant) throws Exception {
- Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
- props.setProperty(TENANT_ID_ATTRIB, TENANT_ID);
- try (Connection conn = getConnection();
- Connection viewConn = isMultiTenant ? getConnection(props) : conn ) {
- String tableWithView = generateUniqueName();
- String viewOfTable = generateUniqueName();
- String viewIndex1 = generateUniqueName();
- String viewIndex2 = generateUniqueName();
-
- conn.setAutoCommit(false);
- viewConn.setAutoCommit(false);
- String ddlFormat = "CREATE TABLE " + tableWithView + " (%s k VARCHAR NOT NULL, v1 VARCHAR, v2 VARCHAR, v3 VARCHAR, v4 VARCHAR CONSTRAINT PK PRIMARY KEY(%s k))%s";
- String ddl = String.format(ddlFormat, isMultiTenant ? "TENANT_ID VARCHAR NOT NULL, " : "",
- isMultiTenant ? "TENANT_ID, " : "", isMultiTenant ? "MULTI_TENANT=true" : "");
- conn.createStatement().execute(ddl);
- viewConn.createStatement()
- .execute(
- "CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM " + tableWithView );
- // create an index with the column that will be dropped
- viewConn.createStatement().execute("CREATE INDEX " + viewIndex1 + " ON " + viewOfTable + "(v2) INCLUDE (v4)");
- // create an index without the column that will be dropped
- viewConn.createStatement().execute("CREATE INDEX " + viewIndex2 + " ON " + viewOfTable + "(v1) INCLUDE (v4)");
- // verify index was created
- try {
- viewConn.createStatement().execute("SELECT * FROM " + viewIndex1 );
- } catch (TableNotFoundException e) {
- fail("Index on view was not created");
- }
-
- // upsert a single row
- PreparedStatement stmt = viewConn.prepareStatement("UPSERT INTO " + viewOfTable + " VALUES(?,?,?,?,?,?,?)");
- stmt.setString(1, "a");
- stmt.setString(2, "b");
- stmt.setString(3, "c");
- stmt.setString(4, "d");
- stmt.setString(5, "e");
- stmt.setInt(6, 1);
- stmt.setString(7, "g");
- stmt.execute();
- viewConn.commit();
-
- // verify the index was created
- PhoenixConnection pconn = viewConn.unwrap(PhoenixConnection.class);
- PName tenantId = isMultiTenant ? PNameFactory.newName("tenant1") : null;
- PTable view = pconn.getTable(new PTableKey(tenantId, viewOfTable ));
- PTable viewIndex = pconn.getTable(new PTableKey(tenantId, viewIndex1 ));
- byte[] viewIndexPhysicalTable = viewIndex.getPhysicalName().getBytes();
- assertNotNull("Can't find view index", viewIndex);
- assertEquals("Unexpected number of indexes ", 2, view.getIndexes().size());
- assertEquals("Unexpected index ", viewIndex1 , view.getIndexes().get(0).getName()
- .getString());
- assertEquals("Unexpected index ", viewIndex2 , view.getIndexes().get(1).getName()
- .getString());
-
- // drop two columns
- conn.createStatement().execute("ALTER TABLE " + tableWithView + " DROP COLUMN v2, v3 ");
-
- // verify columns were dropped
- try {
- conn.createStatement().execute("SELECT v2 FROM " + tableWithView );
- fail("Column should have been dropped");
- } catch (ColumnNotFoundException e) {
- }
- try {
- conn.createStatement().execute("SELECT v3 FROM " + tableWithView );
- fail("Column should have been dropped");
- } catch (ColumnNotFoundException e) {
- }
-
- // verify index metadata was dropped
- try {
- viewConn.createStatement().execute("SELECT * FROM " + viewIndex1 );
- fail("Index metadata should have been dropped");
- } catch (TableNotFoundException e) {
- }
-
- pconn = viewConn.unwrap(PhoenixConnection.class);
- view = pconn.getTable(new PTableKey(tenantId, viewOfTable ));
- try {
- viewIndex = pconn.getTable(new PTableKey(tenantId, viewIndex1 ));
- fail("View index should have been dropped");
- } catch (TableNotFoundException e) {
- }
- assertEquals("Unexpected number of indexes ", 1, view.getIndexes().size());
- assertEquals("Unexpected index ", viewIndex2 , view.getIndexes().get(0).getName().getString());
-
- // verify that the physical index view table is *not* dropped
- conn.unwrap(PhoenixConnection.class).getQueryServices().getTableDescriptor(viewIndexPhysicalTable);
-
- // scan the physical table and verify there is a single row for the second local index
- Scan scan = new Scan();
- HTable table = (HTable) conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(viewIndexPhysicalTable);
- ResultScanner results = table.getScanner(scan);
- Result result = results.next();
- assertNotNull(result);
- PTable viewIndexPTable = pconn.getTable(new PTableKey(pconn.getTenantId(), viewIndex2));
- PColumn column = viewIndexPTable.getColumnForColumnName(IndexUtil.getIndexColumnName(QueryConstants.DEFAULT_COLUMN_FAMILY, "V4"));
- byte[] cq = column.getColumnQualifierBytes();
- // there should be a single row belonging to VIEWINDEX2
- assertNotNull(viewIndex2 + " row is missing", result.getValue(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, cq));
- assertNull(results.next());
- }
- }
-
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java
index 986c317..21fa312 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java
@@ -422,7 +422,7 @@ public class IndexMetadataIT extends ParallelStatsDisabledIT {
Connection conn = DriverManager.getConnection(getUrl(), props);
conn.setAutoCommit(false);
try {
- String ddl = "create table test_table (char_pk varchar not null,"
+ String ddl = "create table " + generateUniqueName() + " (char_pk varchar not null,"
+ " int_col integer, long_col integer, int_col integer"
+ " constraint pk primary key (char_pk))";
conn.createStatement().execute(ddl);
@@ -440,7 +440,7 @@ public class IndexMetadataIT extends ParallelStatsDisabledIT {
Connection conn = DriverManager.getConnection(getUrl(), props);
conn.setAutoCommit(false);
try {
- String ddl = "create table test_table (char_pk varchar not null,"
+ String ddl = "create table " + generateUniqueName() + " (char_pk varchar not null,"
+ " a.int_col integer, a.long_col integer,"
+ " a.int_col integer, b.long_col integer"
+ " constraint pk primary key (char_pk))";