http://git-wip-us.apache.org/repos/asf/hive/blob/ba8a99e1/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestCatalogs.java ---------------------------------------------------------------------- diff --git a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestCatalogs.java b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestCatalogs.java new file mode 100644 index 0000000..02fb9eb --- /dev/null +++ b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestCatalogs.java @@ -0,0 +1,217 @@ +package org.apache.hadoop.hive.metastore.client; + +import org.apache.hadoop.hive.metastore.IMetaStoreClient; +import org.apache.hadoop.hive.metastore.MetaStoreTestUtils; +import org.apache.hadoop.hive.metastore.Warehouse; +import org.apache.hadoop.hive.metastore.annotation.MetastoreCheckinTest; +import org.apache.hadoop.hive.metastore.api.Catalog; +import org.apache.hadoop.hive.metastore.api.Database; +import org.apache.hadoop.hive.metastore.api.InvalidOperationException; +import org.apache.hadoop.hive.metastore.api.MetaException; +import org.apache.hadoop.hive.metastore.api.NoSuchObjectException; +import org.apache.hadoop.hive.metastore.client.builder.CatalogBuilder; +import org.apache.hadoop.hive.metastore.client.builder.DatabaseBuilder; +import org.apache.hadoop.hive.metastore.client.builder.TableBuilder; +import org.apache.hadoop.hive.metastore.minihms.AbstractMetaStoreService; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +import static org.apache.hadoop.hive.metastore.Warehouse.DEFAULT_DATABASE_NAME; + +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@RunWith(Parameterized.class) +@Category(MetastoreCheckinTest.class) +public class TestCatalogs extends MetaStoreClientTest { + private static final Logger LOG = LoggerFactory.getLogger(TestCatalogs.class); + private final AbstractMetaStoreService metaStore; + private IMetaStoreClient client; + + public TestCatalogs(String name, AbstractMetaStoreService metaStore) throws Exception { + this.metaStore = metaStore; + this.metaStore.start(); + } + + @Before + public void setUp() throws Exception { + // Get new client + client = metaStore.getClient(); + + } + + @After + public void tearDown() throws Exception { + // Drop any left over catalogs + List<String> catalogs = client.getCatalogs(); + for (String catName : catalogs) { + if (!catName.equalsIgnoreCase(Warehouse.DEFAULT_CATALOG_NAME)) { + // First drop any databases in catalog + List<String> databases = client.getAllDatabases(catName); + for (String db : databases) { + client.dropDatabase(catName, db, true, false, true); + } + client.dropCatalog(catName); + } else { + List<String> databases = client.getAllDatabases(catName); + for (String db : databases) { + if (!db.equalsIgnoreCase(DEFAULT_DATABASE_NAME)) { + client.dropDatabase(catName, db, true, false, true); + } + } + + } + } + try { + if (client != null) { + client.close(); + } + } finally { + client = null; + } + } + + @Test + public void catalogOperations() throws TException { + String[] catNames = {"cat1", "cat2", "ADifferentName"}; + String[] description = {"a description", "super descriptive", null}; + String[] location = {MetaStoreTestUtils.getTestWarehouseDir("cat1"), + MetaStoreTestUtils.getTestWarehouseDir("cat2"), + MetaStoreTestUtils.getTestWarehouseDir("different")}; + + for (int i = 0; i < catNames.length; i++) { + Catalog cat = new CatalogBuilder() + .setName(catNames[i]) + .setLocation(location[i]) + .setDescription(description[i]) + .build(); + client.createCatalog(cat); + File dir = new File(cat.getLocationUri()); + Assert.assertTrue(dir.exists() && dir.isDirectory()); + } + + for (int i = 0; i < catNames.length; i++) { + Catalog cat = client.getCatalog(catNames[i]); + Assert.assertTrue(catNames[i].equalsIgnoreCase(cat.getName())); + Assert.assertEquals(description[i], cat.getDescription()); + Assert.assertEquals(location[i], cat.getLocationUri()); + File dir = new File(cat.getLocationUri()); + Assert.assertTrue(dir.exists() && dir.isDirectory()); + + // Make sure there's a default database associated with each catalog + Database db = client.getDatabase(catNames[i], DEFAULT_DATABASE_NAME); + Assert.assertEquals("file:" + cat.getLocationUri(), db.getLocationUri()); + } + + List<String> catalogs = client.getCatalogs(); + Assert.assertEquals(4, catalogs.size()); + catalogs.sort(Comparator.naturalOrder()); + List<String> expected = new ArrayList<>(catNames.length + 1); + expected.add(Warehouse.DEFAULT_CATALOG_NAME); + expected.addAll(Arrays.asList(catNames)); + expected.sort(Comparator.naturalOrder()); + for (int i = 0; i < catalogs.size(); i++) { + Assert.assertTrue("Expected " + expected.get(i) + " actual " + catalogs.get(i), + catalogs.get(i).equalsIgnoreCase(expected.get(i))); + } + + for (int i = 0; i < catNames.length; i++) { + client.dropCatalog(catNames[i]); + File dir = new File(location[i]); + Assert.assertFalse(dir.exists()); + } + + catalogs = client.getCatalogs(); + Assert.assertEquals(1, catalogs.size()); + Assert.assertTrue(catalogs.get(0).equalsIgnoreCase(Warehouse.DEFAULT_CATALOG_NAME)); + } + + @Test(expected = NoSuchObjectException.class) + public void getNonExistentCatalog() throws TException { + client.getCatalog("noSuchCatalog"); + } + + @Test(expected = MetaException.class) + @Ignore // TODO This test passes fine locally but fails on Linux, not sure why + public void createCatalogWithBadLocation() throws TException { + Catalog cat = new CatalogBuilder() + .setName("goodluck") + .setLocation("/nosuch/nosuch") + .build(); + client.createCatalog(cat); + } + + @Test(expected = NoSuchObjectException.class) + public void dropNonExistentCatalog() throws TException { + client.dropCatalog("noSuchCatalog"); + } + + @Test(expected = MetaException.class) + public void dropHiveCatalog() throws TException { + client.dropCatalog(Warehouse.DEFAULT_CATALOG_NAME); + } + + @Test(expected = InvalidOperationException.class) + public void dropNonEmptyCatalog() throws TException { + String catName = "toBeDropped"; + Catalog cat = new CatalogBuilder() + .setName(catName) + .setLocation(MetaStoreTestUtils.getTestWarehouseDir(catName)) + .build(); + client.createCatalog(cat); + + String dbName = "dontDropMe"; + new DatabaseBuilder() + .setName(dbName) + .setCatalogName(catName) + .create(client, metaStore.getConf()); + + client.dropCatalog(catName); + } + + @Test(expected = InvalidOperationException.class) + public void dropCatalogWithNonEmptyDefaultDb() throws TException { + String catName = "toBeDropped2"; + new CatalogBuilder() + .setName(catName) + .setLocation(MetaStoreTestUtils.getTestWarehouseDir(catName)) + .create(client); + + new TableBuilder() + .setTableName("not_droppable") + .setCatName(catName) + .addCol("cola1", "bigint") + .create(client, metaStore.getConf()); + + client.dropCatalog(catName); + } +}
http://git-wip-us.apache.org/repos/asf/hive/blob/ba8a99e1/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestCheckConstraint.java ---------------------------------------------------------------------- diff --git a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestCheckConstraint.java b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestCheckConstraint.java new file mode 100644 index 0000000..7733b2d --- /dev/null +++ b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestCheckConstraint.java @@ -0,0 +1,360 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hive.metastore.client; + +import org.apache.hadoop.hive.metastore.IMetaStoreClient; +import org.apache.hadoop.hive.metastore.MetaStoreTestUtils; +import org.apache.hadoop.hive.metastore.annotation.MetastoreCheckinTest; +import org.apache.hadoop.hive.metastore.api.Catalog; +import org.apache.hadoop.hive.metastore.api.CheckConstraintsRequest; +import org.apache.hadoop.hive.metastore.api.Database; +import org.apache.hadoop.hive.metastore.api.InvalidObjectException; +import org.apache.hadoop.hive.metastore.api.NoSuchObjectException; +import org.apache.hadoop.hive.metastore.api.SQLCheckConstraint; +import org.apache.hadoop.hive.metastore.api.Table; +import org.apache.hadoop.hive.metastore.client.builder.CatalogBuilder; +import org.apache.hadoop.hive.metastore.client.builder.DatabaseBuilder; +import org.apache.hadoop.hive.metastore.client.builder.SQLCheckConstraintBuilder; +import org.apache.hadoop.hive.metastore.client.builder.TableBuilder; +import org.apache.hadoop.hive.metastore.minihms.AbstractMetaStoreService; +import org.apache.thrift.TApplicationException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.List; + +import static org.apache.hadoop.hive.metastore.Warehouse.DEFAULT_CATALOG_NAME; +import static org.apache.hadoop.hive.metastore.Warehouse.DEFAULT_DATABASE_NAME; + +@RunWith(Parameterized.class) +@Category(MetastoreCheckinTest.class) +public class TestCheckConstraint extends MetaStoreClientTest { + private static final String OTHER_DATABASE = "test_uc_other_database"; + private static final String OTHER_CATALOG = "test_uc_other_catalog"; + private static final String DATABASE_IN_OTHER_CATALOG = "test_uc_database_in_other_catalog"; + private final AbstractMetaStoreService metaStore; + private IMetaStoreClient client; + private Table[] testTables = new Table[3]; + private Database inOtherCatalog; + + public TestCheckConstraint(String name, AbstractMetaStoreService metaStore) throws Exception { + this.metaStore = metaStore; + this.metaStore.start(); + } + + @Before + public void setUp() throws Exception { + // Get new client + client = metaStore.getClient(); + + // Clean up the database + client.dropDatabase(OTHER_DATABASE, true, true, true); + // Drop every table in the default database + for(String tableName : client.getAllTables(DEFAULT_DATABASE_NAME)) { + client.dropTable(DEFAULT_DATABASE_NAME, tableName, true, true, true); + } + + client.dropDatabase(OTHER_CATALOG, DATABASE_IN_OTHER_CATALOG, true, true, true); + try { + client.dropCatalog(OTHER_CATALOG); + } catch (NoSuchObjectException e) { + // NOP + } + + // Clean up trash + metaStore.cleanWarehouseDirs(); + + new DatabaseBuilder().setName(OTHER_DATABASE).create(client, metaStore.getConf()); + + Catalog cat = new CatalogBuilder() + .setName(OTHER_CATALOG) + .setLocation(MetaStoreTestUtils.getTestWarehouseDir(OTHER_CATALOG)) + .build(); + client.createCatalog(cat); + + // For this one don't specify a location to make sure it gets put in the catalog directory + inOtherCatalog = new DatabaseBuilder() + .setName(DATABASE_IN_OTHER_CATALOG) + .setCatalogName(OTHER_CATALOG) + .create(client, metaStore.getConf()); + + testTables[0] = + new TableBuilder() + .setTableName("test_table_1") + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .create(client, metaStore.getConf()); + + testTables[1] = + new TableBuilder() + .setDbName(OTHER_DATABASE) + .setTableName("test_table_2") + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .create(client, metaStore.getConf()); + + testTables[2] = + new TableBuilder() + .inDb(inOtherCatalog) + .setTableName("test_table_3") + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .create(client, metaStore.getConf()); + + // Reload tables from the MetaStore + for(int i=0; i < testTables.length; i++) { + testTables[i] = client.getTable(testTables[i].getCatName(), testTables[i].getDbName(), + testTables[i].getTableName()); + } + } + + @After + public void tearDown() throws Exception { + try { + if (client != null) { + client.close(); + } + } finally { + client = null; + } + } + + @Test + public void createGetDrop() throws TException { + Table table = testTables[0]; + // Make sure get on a table with no key returns empty list + CheckConstraintsRequest rqst = + new CheckConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + List<SQLCheckConstraint> fetched = client.getCheckConstraints(rqst); + Assert.assertTrue(fetched.isEmpty()); + + // Single column unnamed primary key in default catalog and database + List<SQLCheckConstraint> cc = new SQLCheckConstraintBuilder() + .onTable(table) + .addColumn("col1") + .setCheckExpression("= 5") + .build(metaStore.getConf()); + client.addCheckConstraint(cc); + + rqst = new CheckConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + fetched = client.getCheckConstraints(rqst); + Assert.assertEquals(1, fetched.size()); + Assert.assertEquals(table.getDbName(), fetched.get(0).getTable_db()); + Assert.assertEquals(table.getTableName(), fetched.get(0).getTable_name()); + Assert.assertEquals("col1", fetched.get(0).getColumn_name()); + Assert.assertEquals("= 5", fetched.get(0).getCheck_expression()); + Assert.assertEquals(table.getTableName() + "_check_constraint", fetched.get(0).getDc_name()); + String table0PkName = fetched.get(0).getDc_name(); + Assert.assertTrue(fetched.get(0).isEnable_cstr()); + Assert.assertFalse(fetched.get(0).isValidate_cstr()); + Assert.assertFalse(fetched.get(0).isRely_cstr()); + Assert.assertEquals(table.getCatName(), fetched.get(0).getCatName()); + + // Drop a primary key + client.dropConstraint(table.getCatName(), table.getDbName(), + table.getTableName(), table0PkName); + rqst = new CheckConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + fetched = client.getCheckConstraints(rqst); + Assert.assertTrue(fetched.isEmpty()); + + // Make sure I can add it back + client.addCheckConstraint(cc); + } + + @Test + public void inOtherCatalog() throws TException { + String constraintName = "occc"; + // Table in non 'hive' catalog + List<SQLCheckConstraint> cc = new SQLCheckConstraintBuilder() + .onTable(testTables[2]) + .addColumn("col1") + .setConstraintName(constraintName) + .setCheckExpression("like s%") + .build(metaStore.getConf()); + client.addCheckConstraint(cc); + + CheckConstraintsRequest rqst = new CheckConstraintsRequest(testTables[2].getCatName(), + testTables[2].getDbName(), testTables[2].getTableName()); + List<SQLCheckConstraint> fetched = client.getCheckConstraints(rqst); + Assert.assertEquals(1, fetched.size()); + Assert.assertEquals(testTables[2].getDbName(), fetched.get(0).getTable_db()); + Assert.assertEquals(testTables[2].getTableName(), fetched.get(0).getTable_name()); + Assert.assertEquals("col1", fetched.get(0).getColumn_name()); + Assert.assertEquals("like s%", fetched.get(0).getCheck_expression()); + Assert.assertEquals(constraintName, fetched.get(0).getDc_name()); + Assert.assertTrue(fetched.get(0).isEnable_cstr()); + Assert.assertFalse(fetched.get(0).isValidate_cstr()); + Assert.assertFalse(fetched.get(0).isRely_cstr()); + Assert.assertEquals(testTables[2].getCatName(), fetched.get(0).getCatName()); + + client.dropConstraint(testTables[2].getCatName(), testTables[2].getDbName(), + testTables[2].getTableName(), constraintName); + rqst = new CheckConstraintsRequest(testTables[2].getCatName(), testTables[2].getDbName(), + testTables[2].getTableName()); + fetched = client.getCheckConstraints(rqst); + Assert.assertTrue(fetched.isEmpty()); + } + + @Test + public void createTableWithConstraintsPk() throws TException { + String constraintName = "ctwccc"; + Table table = new TableBuilder() + .setTableName("table_with_constraints") + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .build(metaStore.getConf()); + + List<SQLCheckConstraint> cc = new SQLCheckConstraintBuilder() + .onTable(table) + .addColumn("col1") + .setConstraintName(constraintName) + .setCheckExpression("> 0") + .build(metaStore.getConf()); + + client.createTableWithConstraints(table, null, null, null, null, null, cc); + CheckConstraintsRequest rqst = new CheckConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + List<SQLCheckConstraint> fetched = client.getCheckConstraints(rqst); + Assert.assertEquals(1, fetched.size()); + Assert.assertEquals(table.getDbName(), fetched.get(0).getTable_db()); + Assert.assertEquals(table.getTableName(), fetched.get(0).getTable_name()); + Assert.assertEquals("col1", fetched.get(0).getColumn_name()); + Assert.assertEquals("> 0", fetched.get(0).getCheck_expression()); + Assert.assertEquals(constraintName, fetched.get(0).getDc_name()); + Assert.assertTrue(fetched.get(0).isEnable_cstr()); + Assert.assertFalse(fetched.get(0).isValidate_cstr()); + Assert.assertFalse(fetched.get(0).isRely_cstr()); + Assert.assertEquals(table.getCatName(), fetched.get(0).getCatName()); + + client.dropConstraint(table.getCatName(), table.getDbName(), table.getTableName(), constraintName); + rqst = new CheckConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + fetched = client.getCheckConstraints(rqst); + Assert.assertTrue(fetched.isEmpty()); + + } + + @Test + public void createTableWithConstraintsPkInOtherCatalog() throws TException { + Table table = new TableBuilder() + .setTableName("table_in_other_catalog_with_constraints") + .inDb(inOtherCatalog) + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .build(metaStore.getConf()); + + List<SQLCheckConstraint> cc = new SQLCheckConstraintBuilder() + .onTable(table) + .addColumn("col1") + .setCheckExpression("> 0") + .build(metaStore.getConf()); + + client.createTableWithConstraints(table, null, null, null, null, null, cc); + CheckConstraintsRequest rqst = new CheckConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + List<SQLCheckConstraint> fetched = client.getCheckConstraints(rqst); + Assert.assertEquals(1, fetched.size()); + Assert.assertEquals(table.getDbName(), fetched.get(0).getTable_db()); + Assert.assertEquals(table.getTableName(), fetched.get(0).getTable_name()); + Assert.assertEquals("col1", fetched.get(0).getColumn_name()); + Assert.assertEquals("> 0", fetched.get(0).getCheck_expression()); + Assert.assertEquals(table.getTableName() + "_check_constraint", fetched.get(0).getDc_name()); + String tablePkName = fetched.get(0).getDc_name(); + Assert.assertTrue(fetched.get(0).isEnable_cstr()); + Assert.assertFalse(fetched.get(0).isValidate_cstr()); + Assert.assertFalse(fetched.get(0).isRely_cstr()); + Assert.assertEquals(table.getCatName(), fetched.get(0).getCatName()); + + client.dropConstraint(table.getCatName(), table.getDbName(), table.getTableName(), tablePkName); + rqst = new CheckConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + fetched = client.getCheckConstraints(rqst); + Assert.assertTrue(fetched.isEmpty()); + } + + @Test + public void doubleAddUniqueConstraint() throws TException { + Table table = testTables[0]; + // Make sure get on a table with no key returns empty list + CheckConstraintsRequest rqst = + new CheckConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + List<SQLCheckConstraint> fetched = client.getCheckConstraints(rqst); + Assert.assertTrue(fetched.isEmpty()); + + // Single column unnamed primary key in default catalog and database + List<SQLCheckConstraint> cc = new SQLCheckConstraintBuilder() + .onTable(table) + .addColumn("col1") + .setCheckExpression("> 0") + .build(metaStore.getConf()); + client.addCheckConstraint(cc); + + try { + cc = new SQLCheckConstraintBuilder() + .onTable(table) + .addColumn("col2") + .setCheckExpression("= 'this string intentionally left empty'") + .build(metaStore.getConf()); + client.addCheckConstraint(cc); + Assert.fail(); + } catch (InvalidObjectException |TApplicationException e) { + // NOP + } + } + + @Test + public void addNoSuchTable() throws TException { + try { + List<SQLCheckConstraint> cc = new SQLCheckConstraintBuilder() + .setTableName("nosuch") + .addColumn("col2") + .setCheckExpression("= 'this string intentionally left empty'") + .build(metaStore.getConf()); + client.addCheckConstraint(cc); + Assert.fail(); + } catch (InvalidObjectException |TApplicationException e) { + // NOP + } + } + + @Test + public void getNoSuchTable() throws TException { + CheckConstraintsRequest rqst = + new CheckConstraintsRequest(DEFAULT_CATALOG_NAME, DEFAULT_DATABASE_NAME, "nosuch"); + List<SQLCheckConstraint> cc = client.getCheckConstraints(rqst); + Assert.assertTrue(cc.isEmpty()); + } + + @Test + public void getNoSuchDb() throws TException { + CheckConstraintsRequest rqst = + new CheckConstraintsRequest(DEFAULT_CATALOG_NAME, "nosuch", testTables[0].getTableName()); + List<SQLCheckConstraint> cc = client.getCheckConstraints(rqst); + Assert.assertTrue(cc.isEmpty()); + } + + @Test + public void getNoSuchCatalog() throws TException { + CheckConstraintsRequest rqst = new CheckConstraintsRequest("nosuch", + testTables[0].getDbName(), testTables[0].getTableName()); + List<SQLCheckConstraint> cc = client.getCheckConstraints(rqst); + Assert.assertTrue(cc.isEmpty()); + } +} http://git-wip-us.apache.org/repos/asf/hive/blob/ba8a99e1/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestDatabases.java ---------------------------------------------------------------------- diff --git a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestDatabases.java b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestDatabases.java index f2d745e..24e3c56 100644 --- a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestDatabases.java +++ b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestDatabases.java @@ -20,8 +20,11 @@ package org.apache.hadoop.hive.metastore.client; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hive.metastore.IMetaStoreClient; +import org.apache.hadoop.hive.metastore.MetaStoreTestUtils; +import org.apache.hadoop.hive.metastore.Warehouse; import org.apache.hadoop.hive.metastore.annotation.MetastoreCheckinTest; import org.apache.hadoop.hive.metastore.api.AlreadyExistsException; +import org.apache.hadoop.hive.metastore.api.Catalog; import org.apache.hadoop.hive.metastore.api.Database; import org.apache.hadoop.hive.metastore.api.Function; import org.apache.hadoop.hive.metastore.api.InvalidObjectException; @@ -30,10 +33,13 @@ import org.apache.hadoop.hive.metastore.api.MetaException; import org.apache.hadoop.hive.metastore.api.NoSuchObjectException; import org.apache.hadoop.hive.metastore.api.PrincipalType; import org.apache.hadoop.hive.metastore.api.Table; +import org.apache.hadoop.hive.metastore.client.builder.CatalogBuilder; import org.apache.hadoop.hive.metastore.client.builder.DatabaseBuilder; import org.apache.hadoop.hive.metastore.client.builder.FunctionBuilder; import org.apache.hadoop.hive.metastore.client.builder.TableBuilder; import org.apache.hadoop.hive.metastore.minihms.AbstractMetaStoreService; +import org.apache.hadoop.hive.metastore.utils.SecurityUtils; +import org.apache.thrift.TException; import org.apache.thrift.transport.TTransportException; import org.junit.After; import org.junit.Assert; @@ -43,12 +49,20 @@ import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Set; + +import static org.apache.hadoop.hive.metastore.Warehouse.DEFAULT_CATALOG_NAME; /** * Test class for IMetaStoreClient API. Testing the Database related functions. */ + @RunWith(Parameterized.class) @Category(MetastoreCheckinTest.class) public class TestDatabases extends MetaStoreClientTest { @@ -74,17 +88,16 @@ public class TestDatabases extends MetaStoreClientTest { } testDatabases[0] = - new DatabaseBuilder().setName("test_database_1").build(); + new DatabaseBuilder().setName("test_database_1").create(client, metaStore.getConf()); testDatabases[1] = - new DatabaseBuilder().setName("test_database_to_find_1").build(); + new DatabaseBuilder().setName("test_database_to_find_1").create(client, metaStore.getConf()); testDatabases[2] = - new DatabaseBuilder().setName("test_database_to_find_2").build(); + new DatabaseBuilder().setName("test_database_to_find_2").create(client, metaStore.getConf()); testDatabases[3] = - new DatabaseBuilder().setName("test_database_hidden_1").build(); + new DatabaseBuilder().setName("test_database_hidden_1").create(client, metaStore.getConf()); // Create the databases, and reload them from the MetaStore - for(int i=0; i < testDatabases.length; i++) { - client.createDatabase(testDatabases[i]); + for (int i=0; i < testDatabases.length; i++) { testDatabases[i] = client.getDatabase(testDatabases[i].getName()); } } @@ -102,7 +115,6 @@ public class TestDatabases extends MetaStoreClientTest { /** * This test creates and queries a database and then drops it. Good for testing the happy path. - * @throws Exception */ @Test public void testCreateGetDeleteDatabase() throws Exception { @@ -127,10 +139,10 @@ public class TestDatabases extends MetaStoreClientTest { @Test public void testCreateDatabaseDefaultValues() throws Exception { - Database database = new Database(); - database.setName("dummy"); + Database database = new DatabaseBuilder() + .setName("dummy") + .create(client, metaStore.getConf()); - client.createDatabase(database); Database createdDatabase = client.getDatabase(database.getName()); Assert.assertNull("Comparing description", createdDatabase.getDescription()); @@ -139,7 +151,8 @@ public class TestDatabases extends MetaStoreClientTest { Assert.assertEquals("Comparing parameters", new HashMap<String, String>(), createdDatabase.getParameters()); Assert.assertNull("Comparing privileges", createdDatabase.getPrivileges()); - Assert.assertNull("Comparing owner name", createdDatabase.getOwnerName()); + Assert.assertEquals("Comparing owner name", SecurityUtils.getUser(), + createdDatabase.getOwnerName()); Assert.assertEquals("Comparing owner type", PrincipalType.USER, createdDatabase.getOwnerType()); } @@ -280,7 +293,7 @@ public class TestDatabases extends MetaStoreClientTest { @Test public void testDropDatabaseDeleteData() throws Exception { Database database = testDatabases[0]; - Path dataFile = new Path(database.getLocationUri().toString() + "/dataFile"); + Path dataFile = new Path(database.getLocationUri() + "/dataFile"); metaStore.createFile(dataFile, "100"); // Do not delete the data @@ -318,8 +331,7 @@ public class TestDatabases extends MetaStoreClientTest { .setDbName(database.getName()) .setTableName("test_table") .addCol("test_col", "int") - .build(); - client.createTable(testTable); + .create(client, metaStore.getConf()); client.dropDatabase(database.getName(), true, true, false); } @@ -332,8 +344,7 @@ public class TestDatabases extends MetaStoreClientTest { .setDbName(database.getName()) .setTableName("test_table") .addCol("test_col", "int") - .build(); - client.createTable(testTable); + .create(client, metaStore.getConf()); client.dropDatabase(database.getName(), true, true, true); Assert.assertFalse("The directory should be removed", @@ -349,9 +360,8 @@ public class TestDatabases extends MetaStoreClientTest { .setDbName(database.getName()) .setName("test_function") .setClass("org.apache.hadoop.hive.ql.udf.generic.GenericUDFUpper") - .build(); + .create(client, metaStore.getConf()); - client.createFunction(testFunction); client.dropDatabase(database.getName(), true, true, false); } @@ -365,16 +375,14 @@ public class TestDatabases extends MetaStoreClientTest { .setDbName(database.getName()) .setName("test_function") .setClass("org.apache.hadoop.hive.ql.udf.generic.GenericUDFUpper") - .build(); + .create(client, metaStore.getConf()); - client.createFunction(testFunction); client.dropDatabase(database.getName(), true, true, true); Assert.assertFalse("The directory should be removed", metaStore.isPathExists(new Path(database.getLocationUri()))); } - @Test public void testGetAllDatabases() throws Exception { List<String> allDatabases = client.getAllDatabases(); @@ -446,7 +454,7 @@ public class TestDatabases extends MetaStoreClientTest { .setDescription("dummy description 2") .addParam("param_key_1", "param_value_1_2") .addParam("param_key_2_3", "param_value_2_3") - .build(); + .build(metaStore.getConf()); client.alterDatabase(originalDatabase.getName(), newDatabase); Database alteredDatabase = client.getDatabase(newDatabase.getName()); @@ -460,6 +468,7 @@ public class TestDatabases extends MetaStoreClientTest { Database originalDatabase = client.getDatabase(database.getName()); Database newDatabase = new Database(); newDatabase.setName("new_name"); + newDatabase.setCatalogName(DEFAULT_CATALOG_NAME); client.alterDatabase(originalDatabase.getName(), newDatabase); // The name should not be changed, so reload the db with the original name @@ -480,7 +489,9 @@ public class TestDatabases extends MetaStoreClientTest { @Test(expected = NoSuchObjectException.class) public void testAlterDatabaseNoSuchDatabase() throws Exception { - Database newDatabase = new DatabaseBuilder().setName("test_database_altered").build(); + Database newDatabase = new DatabaseBuilder() + .setName("test_database_altered") + .build(metaStore.getConf()); client.alterDatabase("no_such_database", newDatabase); } @@ -505,6 +516,131 @@ public class TestDatabases extends MetaStoreClientTest { Assert.assertEquals("Comparing databases", newDatabase, alteredDatabase); } + @Test + public void databasesInCatalogs() throws TException, URISyntaxException { + String catName = "mycatalog"; + Catalog cat = new CatalogBuilder() + .setName(catName) + .setLocation(MetaStoreTestUtils.getTestWarehouseDir(catName)) + .build(); + client.createCatalog(cat); + + String[] dbNames = {"db1", "db9"}; + Database[] dbs = new Database[2]; + // For this one don't specify a location to make sure it gets put in the catalog directory + dbs[0] = new DatabaseBuilder() + .setName(dbNames[0]) + .setCatalogName(catName) + .create(client, metaStore.getConf()); + + // For the second one, explicitly set a location to make sure it ends up in the specified place. + String db1Location = MetaStoreTestUtils.getTestWarehouseDir(dbNames[1]); + dbs[1] = new DatabaseBuilder() + .setName(dbNames[1]) + .setCatalogName(catName) + .setLocation(db1Location) + .create(client, metaStore.getConf()); + + Database fetched = client.getDatabase(catName, dbNames[0]); + String expectedLocation = new File(cat.getLocationUri(), dbNames[0] + ".db").toURI().toString(); + Assert.assertEquals(expectedLocation, fetched.getLocationUri() + "/"); + String db0Location = new URI(fetched.getLocationUri()).getPath(); + File dir = new File(db0Location); + Assert.assertTrue(dir.exists() && dir.isDirectory()); + + fetched = client.getDatabase(catName, dbNames[1]); + Assert.assertEquals(new File(db1Location).toURI().toString(), fetched.getLocationUri() + "/"); + dir = new File(new URI(fetched.getLocationUri()).getPath()); + Assert.assertTrue(dir.exists() && dir.isDirectory()); + + Set<String> fetchedDbs = new HashSet<>(client.getAllDatabases(catName)); + Assert.assertEquals(3, fetchedDbs.size()); + for (String dbName : dbNames) Assert.assertTrue(fetchedDbs.contains(dbName)); + + fetchedDbs = new HashSet<>(client.getAllDatabases()); + Assert.assertEquals(5, fetchedDbs.size()); + Assert.assertTrue(fetchedDbs.contains(Warehouse.DEFAULT_DATABASE_NAME)); + + // Intentionally using the deprecated method to make sure it returns correct results. + fetchedDbs = new HashSet<>(client.getAllDatabases()); + Assert.assertEquals(5, fetchedDbs.size()); + Assert.assertTrue(fetchedDbs.contains(Warehouse.DEFAULT_DATABASE_NAME)); + + fetchedDbs = new HashSet<>(client.getDatabases(catName, "d*")); + Assert.assertEquals(3, fetchedDbs.size()); + for (String dbName : dbNames) Assert.assertTrue(fetchedDbs.contains(dbName)); + + fetchedDbs = new HashSet<>(client.getDatabases("d*")); + Assert.assertEquals(1, fetchedDbs.size()); + Assert.assertTrue(fetchedDbs.contains(Warehouse.DEFAULT_DATABASE_NAME)); + + // Intentionally using the deprecated method to make sure it returns correct results. + fetchedDbs = new HashSet<>(client.getDatabases("d*")); + Assert.assertEquals(1, fetchedDbs.size()); + Assert.assertTrue(fetchedDbs.contains(Warehouse.DEFAULT_DATABASE_NAME)); + + fetchedDbs = new HashSet<>(client.getDatabases(catName, "*1")); + Assert.assertEquals(1, fetchedDbs.size()); + Assert.assertTrue(fetchedDbs.contains(dbNames[0])); + + fetchedDbs = new HashSet<>(client.getDatabases("*9")); + Assert.assertEquals(0, fetchedDbs.size()); + + // Intentionally using the deprecated method to make sure it returns correct results. + fetchedDbs = new HashSet<>(client.getDatabases("*9")); + Assert.assertEquals(0, fetchedDbs.size()); + + fetchedDbs = new HashSet<>(client.getDatabases(catName, "*x")); + Assert.assertEquals(0, fetchedDbs.size()); + + // Check that dropping database from wrong catalog fails + try { + client.dropDatabase(dbNames[0], true, false, false); + Assert.fail(); + } catch (NoSuchObjectException e) { + // NOP + } + + // Check that dropping database from wrong catalog fails + try { + // Intentionally using deprecated method + client.dropDatabase(dbNames[0], true, false, false); + Assert.fail(); + } catch (NoSuchObjectException e) { + // NOP + } + + // Drop them from the proper catalog + client.dropDatabase(catName, dbNames[0], true, false, false); + dir = new File(db0Location); + Assert.assertFalse(dir.exists()); + + client.dropDatabase(catName, dbNames[1], true, false, false); + dir = new File(db1Location); + Assert.assertFalse(dir.exists()); + + fetchedDbs = new HashSet<>(client.getAllDatabases(catName)); + Assert.assertEquals(1, fetchedDbs.size()); + } + + @Test(expected = InvalidObjectException.class) + public void createDatabaseInNonExistentCatalog() throws TException { + Database db = new DatabaseBuilder() + .setName("doomed") + .setCatalogName("nosuch") + .create(client, metaStore.getConf()); + } + + @Test(expected = NoSuchObjectException.class) + public void fetchDatabaseInNonExistentCatalog() throws TException { + client.getDatabase("nosuch", Warehouse.DEFAULT_DATABASE_NAME); + } + + @Test(expected = NoSuchObjectException.class) + public void dropDatabaseInNonExistentCatalog() throws TException { + client.dropDatabase("nosuch", Warehouse.DEFAULT_DATABASE_NAME, true, false, false); + } + private Database getDatabaseWithAllParametersSet() throws Exception { return new DatabaseBuilder() .setName("dummy") @@ -514,6 +650,6 @@ public class TestDatabases extends MetaStoreClientTest { .setDescription("dummy description") .addParam("param_key_1", "param_value_1") .addParam("param_key_2", "param_value_2") - .build(); + .build(metaStore.getConf()); } } http://git-wip-us.apache.org/repos/asf/hive/blob/ba8a99e1/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestDefaultConstraint.java ---------------------------------------------------------------------- diff --git a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestDefaultConstraint.java b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestDefaultConstraint.java new file mode 100644 index 0000000..d56006b --- /dev/null +++ b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestDefaultConstraint.java @@ -0,0 +1,360 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hive.metastore.client; + +import org.apache.hadoop.hive.metastore.IMetaStoreClient; +import org.apache.hadoop.hive.metastore.MetaStoreTestUtils; +import org.apache.hadoop.hive.metastore.annotation.MetastoreCheckinTest; +import org.apache.hadoop.hive.metastore.api.Catalog; +import org.apache.hadoop.hive.metastore.api.Database; +import org.apache.hadoop.hive.metastore.api.DefaultConstraintsRequest; +import org.apache.hadoop.hive.metastore.api.InvalidObjectException; +import org.apache.hadoop.hive.metastore.api.NoSuchObjectException; +import org.apache.hadoop.hive.metastore.api.SQLDefaultConstraint; +import org.apache.hadoop.hive.metastore.api.Table; +import org.apache.hadoop.hive.metastore.client.builder.CatalogBuilder; +import org.apache.hadoop.hive.metastore.client.builder.DatabaseBuilder; +import org.apache.hadoop.hive.metastore.client.builder.SQLDefaultConstraintBuilder; +import org.apache.hadoop.hive.metastore.client.builder.TableBuilder; +import org.apache.hadoop.hive.metastore.minihms.AbstractMetaStoreService; +import org.apache.thrift.TApplicationException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.List; + +import static org.apache.hadoop.hive.metastore.Warehouse.DEFAULT_CATALOG_NAME; +import static org.apache.hadoop.hive.metastore.Warehouse.DEFAULT_DATABASE_NAME; + +@RunWith(Parameterized.class) +@Category(MetastoreCheckinTest.class) +public class TestDefaultConstraint extends MetaStoreClientTest { + private static final String OTHER_DATABASE = "test_uc_other_database"; + private static final String OTHER_CATALOG = "test_uc_other_catalog"; + private static final String DATABASE_IN_OTHER_CATALOG = "test_uc_database_in_other_catalog"; + private final AbstractMetaStoreService metaStore; + private IMetaStoreClient client; + private Table[] testTables = new Table[3]; + private Database inOtherCatalog; + + public TestDefaultConstraint(String name, AbstractMetaStoreService metaStore) throws Exception { + this.metaStore = metaStore; + this.metaStore.start(); + } + + @Before + public void setUp() throws Exception { + // Get new client + client = metaStore.getClient(); + + // Clean up the database + client.dropDatabase(OTHER_DATABASE, true, true, true); + // Drop every table in the default database + for(String tableName : client.getAllTables(DEFAULT_DATABASE_NAME)) { + client.dropTable(DEFAULT_DATABASE_NAME, tableName, true, true, true); + } + + client.dropDatabase(OTHER_CATALOG, DATABASE_IN_OTHER_CATALOG, true, true, true); + try { + client.dropCatalog(OTHER_CATALOG); + } catch (NoSuchObjectException e) { + // NOP + } + + // Clean up trash + metaStore.cleanWarehouseDirs(); + + new DatabaseBuilder().setName(OTHER_DATABASE).create(client, metaStore.getConf()); + + Catalog cat = new CatalogBuilder() + .setName(OTHER_CATALOG) + .setLocation(MetaStoreTestUtils.getTestWarehouseDir(OTHER_CATALOG)) + .build(); + client.createCatalog(cat); + + // For this one don't specify a location to make sure it gets put in the catalog directory + inOtherCatalog = new DatabaseBuilder() + .setName(DATABASE_IN_OTHER_CATALOG) + .setCatalogName(OTHER_CATALOG) + .create(client, metaStore.getConf()); + + testTables[0] = + new TableBuilder() + .setTableName("test_table_1") + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .create(client, metaStore.getConf()); + + testTables[1] = + new TableBuilder() + .setDbName(OTHER_DATABASE) + .setTableName("test_table_2") + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .create(client, metaStore.getConf()); + + testTables[2] = + new TableBuilder() + .inDb(inOtherCatalog) + .setTableName("test_table_3") + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .create(client, metaStore.getConf()); + + // Reload tables from the MetaStore + for(int i=0; i < testTables.length; i++) { + testTables[i] = client.getTable(testTables[i].getCatName(), testTables[i].getDbName(), + testTables[i].getTableName()); + } + } + + @After + public void tearDown() throws Exception { + try { + if (client != null) { + client.close(); + } + } finally { + client = null; + } + } + + @Test + public void createGetDrop() throws TException { + Table table = testTables[0]; + // Make sure get on a table with no key returns empty list + DefaultConstraintsRequest rqst = + new DefaultConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + List<SQLDefaultConstraint> fetched = client.getDefaultConstraints(rqst); + Assert.assertTrue(fetched.isEmpty()); + + // Single column unnamed primary key in default catalog and database + List<SQLDefaultConstraint> dv = new SQLDefaultConstraintBuilder() + .onTable(table) + .addColumn("col1") + .setDefaultVal(0) + .build(metaStore.getConf()); + client.addDefaultConstraint(dv); + + rqst = new DefaultConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + fetched = client.getDefaultConstraints(rqst); + Assert.assertEquals(1, fetched.size()); + Assert.assertEquals(table.getDbName(), fetched.get(0).getTable_db()); + Assert.assertEquals(table.getTableName(), fetched.get(0).getTable_name()); + Assert.assertEquals("col1", fetched.get(0).getColumn_name()); + Assert.assertEquals("0", fetched.get(0).getDefault_value()); + Assert.assertEquals(table.getTableName() + "_default_value", fetched.get(0).getDc_name()); + String table0PkName = fetched.get(0).getDc_name(); + Assert.assertTrue(fetched.get(0).isEnable_cstr()); + Assert.assertFalse(fetched.get(0).isValidate_cstr()); + Assert.assertFalse(fetched.get(0).isRely_cstr()); + Assert.assertEquals(table.getCatName(), fetched.get(0).getCatName()); + + // Drop a primary key + client.dropConstraint(table.getCatName(), table.getDbName(), + table.getTableName(), table0PkName); + rqst = new DefaultConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + fetched = client.getDefaultConstraints(rqst); + Assert.assertTrue(fetched.isEmpty()); + + // Make sure I can add it back + client.addDefaultConstraint(dv); + } + + @Test + public void inOtherCatalog() throws TException { + String constraintName = "ocdv"; + // Table in non 'hive' catalog + List<SQLDefaultConstraint> dv = new SQLDefaultConstraintBuilder() + .onTable(testTables[2]) + .addColumn("col1") + .setConstraintName(constraintName) + .setDefaultVal("empty") + .build(metaStore.getConf()); + client.addDefaultConstraint(dv); + + DefaultConstraintsRequest rqst = new DefaultConstraintsRequest(testTables[2].getCatName(), + testTables[2].getDbName(), testTables[2].getTableName()); + List<SQLDefaultConstraint> fetched = client.getDefaultConstraints(rqst); + Assert.assertEquals(1, fetched.size()); + Assert.assertEquals(testTables[2].getDbName(), fetched.get(0).getTable_db()); + Assert.assertEquals(testTables[2].getTableName(), fetched.get(0).getTable_name()); + Assert.assertEquals("col1", fetched.get(0).getColumn_name()); + Assert.assertEquals("empty", fetched.get(0).getDefault_value()); + Assert.assertEquals(constraintName, fetched.get(0).getDc_name()); + Assert.assertTrue(fetched.get(0).isEnable_cstr()); + Assert.assertFalse(fetched.get(0).isValidate_cstr()); + Assert.assertFalse(fetched.get(0).isRely_cstr()); + Assert.assertEquals(testTables[2].getCatName(), fetched.get(0).getCatName()); + + client.dropConstraint(testTables[2].getCatName(), testTables[2].getDbName(), + testTables[2].getTableName(), constraintName); + rqst = new DefaultConstraintsRequest(testTables[2].getCatName(), testTables[2].getDbName(), + testTables[2].getTableName()); + fetched = client.getDefaultConstraints(rqst); + Assert.assertTrue(fetched.isEmpty()); + } + + @Test + public void createTableWithConstraintsPk() throws TException { + String constraintName = "ctwcdv"; + Table table = new TableBuilder() + .setTableName("table_with_constraints") + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .build(metaStore.getConf()); + + List<SQLDefaultConstraint> dv = new SQLDefaultConstraintBuilder() + .onTable(table) + .addColumn("col1") + .setConstraintName(constraintName) + .setDefaultVal(0) + .build(metaStore.getConf()); + + client.createTableWithConstraints(table, null, null, null, null, dv, null); + DefaultConstraintsRequest rqst = new DefaultConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + List<SQLDefaultConstraint> fetched = client.getDefaultConstraints(rqst); + Assert.assertEquals(1, fetched.size()); + Assert.assertEquals(table.getDbName(), fetched.get(0).getTable_db()); + Assert.assertEquals(table.getTableName(), fetched.get(0).getTable_name()); + Assert.assertEquals("col1", fetched.get(0).getColumn_name()); + Assert.assertEquals("0", fetched.get(0).getDefault_value()); + Assert.assertEquals(constraintName, fetched.get(0).getDc_name()); + Assert.assertTrue(fetched.get(0).isEnable_cstr()); + Assert.assertFalse(fetched.get(0).isValidate_cstr()); + Assert.assertFalse(fetched.get(0).isRely_cstr()); + Assert.assertEquals(table.getCatName(), fetched.get(0).getCatName()); + + client.dropConstraint(table.getCatName(), table.getDbName(), table.getTableName(), constraintName); + rqst = new DefaultConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + fetched = client.getDefaultConstraints(rqst); + Assert.assertTrue(fetched.isEmpty()); + + } + + @Test + public void createTableWithConstraintsPkInOtherCatalog() throws TException { + Table table = new TableBuilder() + .setTableName("table_in_other_catalog_with_constraints") + .inDb(inOtherCatalog) + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .build(metaStore.getConf()); + + List<SQLDefaultConstraint> dv = new SQLDefaultConstraintBuilder() + .onTable(table) + .addColumn("col1") + .setDefaultVal(0) + .build(metaStore.getConf()); + + client.createTableWithConstraints(table, null, null, null, null, dv, null); + DefaultConstraintsRequest rqst = new DefaultConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + List<SQLDefaultConstraint> fetched = client.getDefaultConstraints(rqst); + Assert.assertEquals(1, fetched.size()); + Assert.assertEquals(table.getDbName(), fetched.get(0).getTable_db()); + Assert.assertEquals(table.getTableName(), fetched.get(0).getTable_name()); + Assert.assertEquals("col1", fetched.get(0).getColumn_name()); + Assert.assertEquals("0", fetched.get(0).getDefault_value()); + Assert.assertEquals(table.getTableName() + "_default_value", fetched.get(0).getDc_name()); + String tablePkName = fetched.get(0).getDc_name(); + Assert.assertTrue(fetched.get(0).isEnable_cstr()); + Assert.assertFalse(fetched.get(0).isValidate_cstr()); + Assert.assertFalse(fetched.get(0).isRely_cstr()); + Assert.assertEquals(table.getCatName(), fetched.get(0).getCatName()); + + client.dropConstraint(table.getCatName(), table.getDbName(), table.getTableName(), tablePkName); + rqst = new DefaultConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + fetched = client.getDefaultConstraints(rqst); + Assert.assertTrue(fetched.isEmpty()); + } + + @Test + public void doubleAddUniqueConstraint() throws TException { + Table table = testTables[0]; + // Make sure get on a table with no key returns empty list + DefaultConstraintsRequest rqst = + new DefaultConstraintsRequest(table.getCatName(), table.getDbName(), table.getTableName()); + List<SQLDefaultConstraint> fetched = client.getDefaultConstraints(rqst); + Assert.assertTrue(fetched.isEmpty()); + + // Single column unnamed primary key in default catalog and database + List<SQLDefaultConstraint> dv = new SQLDefaultConstraintBuilder() + .onTable(table) + .addColumn("col1") + .setDefaultVal(0) + .build(metaStore.getConf()); + client.addDefaultConstraint(dv); + + try { + dv = new SQLDefaultConstraintBuilder() + .onTable(table) + .addColumn("col2") + .setDefaultVal("this string intentionally left empty") + .build(metaStore.getConf()); + client.addDefaultConstraint(dv); + Assert.fail(); + } catch (InvalidObjectException |TApplicationException e) { + // NOP + } + } + + @Test + public void addNoSuchTable() throws TException { + try { + List<SQLDefaultConstraint> dv = new SQLDefaultConstraintBuilder() + .setTableName("nosuch") + .addColumn("col2") + .setDefaultVal("this string intentionally left empty") + .build(metaStore.getConf()); + client.addDefaultConstraint(dv); + Assert.fail(); + } catch (InvalidObjectException |TApplicationException e) { + // NOP + } + } + + @Test + public void getNoSuchTable() throws TException { + DefaultConstraintsRequest rqst = + new DefaultConstraintsRequest(DEFAULT_CATALOG_NAME, DEFAULT_DATABASE_NAME, "nosuch"); + List<SQLDefaultConstraint> dv = client.getDefaultConstraints(rqst); + Assert.assertTrue(dv.isEmpty()); + } + + @Test + public void getNoSuchDb() throws TException { + DefaultConstraintsRequest rqst = + new DefaultConstraintsRequest(DEFAULT_CATALOG_NAME, "nosuch", testTables[0].getTableName()); + List<SQLDefaultConstraint> dv = client.getDefaultConstraints(rqst); + Assert.assertTrue(dv.isEmpty()); + } + + @Test + public void getNoSuchCatalog() throws TException { + DefaultConstraintsRequest rqst = new DefaultConstraintsRequest("nosuch", + testTables[0].getDbName(), testTables[0].getTableName()); + List<SQLDefaultConstraint> dv = client.getDefaultConstraints(rqst); + Assert.assertTrue(dv.isEmpty()); + } +} http://git-wip-us.apache.org/repos/asf/hive/blob/ba8a99e1/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestDropPartitions.java ---------------------------------------------------------------------- diff --git a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestDropPartitions.java b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestDropPartitions.java index d2ba4be..9037001 100644 --- a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestDropPartitions.java +++ b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestDropPartitions.java @@ -18,25 +18,31 @@ package org.apache.hadoop.hive.metastore.client; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hive.metastore.IMetaStoreClient; +import org.apache.hadoop.hive.metastore.MetaStoreTestUtils; import org.apache.hadoop.hive.metastore.PartitionDropOptions; import org.apache.hadoop.hive.metastore.annotation.MetastoreCheckinTest; +import org.apache.hadoop.hive.metastore.api.Catalog; import org.apache.hadoop.hive.metastore.api.Database; import org.apache.hadoop.hive.metastore.api.FieldSchema; import org.apache.hadoop.hive.metastore.api.MetaException; import org.apache.hadoop.hive.metastore.api.NoSuchObjectException; import org.apache.hadoop.hive.metastore.api.Partition; import org.apache.hadoop.hive.metastore.api.Table; +import org.apache.hadoop.hive.metastore.client.builder.CatalogBuilder; import org.apache.hadoop.hive.metastore.client.builder.DatabaseBuilder; import org.apache.hadoop.hive.metastore.client.builder.PartitionBuilder; import org.apache.hadoop.hive.metastore.client.builder.TableBuilder; import org.apache.hadoop.hive.metastore.conf.MetastoreConf; import org.apache.hadoop.hive.metastore.minihms.AbstractMetaStoreService; +import org.apache.thrift.TException; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -48,6 +54,8 @@ import org.junit.runners.Parameterized; import com.google.common.collect.Lists; +import static org.apache.hadoop.hive.metastore.Warehouse.DEFAULT_DATABASE_NAME; + /** * Tests for dropping partitions. */ @@ -69,7 +77,7 @@ public class TestDropPartitions extends MetaStoreClientTest { public static void startMetaStores() { Map<MetastoreConf.ConfVars, String> msConf = new HashMap<MetastoreConf.ConfVars, String>(); // Enable trash, so it can be tested - Map<String, String> extraConf = new HashMap<String, String>(); + Map<String, String> extraConf = new HashMap<>(); extraConf.put("fs.trash.checkpoint.interval", "30"); // FS_TRASH_CHECKPOINT_INTERVAL_KEY extraConf.put("fs.trash.interval", "30"); // FS_TRASH_INTERVAL_KEY (hadoop-2) startMetaStores(msConf, extraConf); @@ -89,8 +97,7 @@ public class TestDropPartitions extends MetaStoreClientTest { metaStore.cleanWarehouseDirs(); Database db = new DatabaseBuilder(). setName(DB_NAME). - build(); - client.createDatabase(db); + create(client, metaStore.getConf()); // Create test tables with 3 partitions createTable(TABLE_NAME, getYearAndMonthPartCols(), null); @@ -489,7 +496,71 @@ public class TestDropPartitions extends MetaStoreClientTest { client.dropPartition(DB_NAME, TABLE_NAME, "", true); } - // Helper methods + @Test + public void otherCatalog() throws TException { + String catName = "drop_partition_catalog"; + Catalog cat = new CatalogBuilder() + .setName(catName) + .setLocation(MetaStoreTestUtils.getTestWarehouseDir(catName)) + .build(); + client.createCatalog(cat); + + String dbName = "drop_partition_database_in_other_catalog"; + Database db = new DatabaseBuilder() + .setName(dbName) + .setCatalogName(catName) + .create(client, metaStore.getConf()); + + String tableName = "table_in_other_catalog"; + Table table = new TableBuilder() + .inDb(db) + .setTableName(tableName) + .addCol("id", "int") + .addCol("name", "string") + .addPartCol("partcol", "string") + .create(client, metaStore.getConf()); + + Partition[] parts = new Partition[2]; + for (int i = 0; i < parts.length; i++) { + parts[i] = new PartitionBuilder() + .inTable(table) + .addValue("a" + i) + .build(metaStore.getConf()); + } + client.add_partitions(Arrays.asList(parts)); + List<Partition> fetched = client.listPartitions(catName, dbName, tableName, (short)-1); + Assert.assertEquals(parts.length, fetched.size()); + + Assert.assertTrue(client.dropPartition(catName, dbName, tableName, + Collections.singletonList("a0"), PartitionDropOptions.instance().ifExists(false))); + try { + client.getPartition(catName, dbName, tableName, Collections.singletonList("a0")); + Assert.fail(); + } catch (NoSuchObjectException e) { + // NOP + } + + Assert.assertTrue(client.dropPartition(catName, dbName, tableName, "partcol=a1", true)); + try { + client.getPartition(catName, dbName, tableName, Collections.singletonList("a1")); + Assert.fail(); + } catch (NoSuchObjectException e) { + // NOP + } + } + + @Test(expected = NoSuchObjectException.class) + public void testDropPartitionBogusCatalog() throws Exception { + client.dropPartition("nosuch", DB_NAME, TABLE_NAME, Lists.newArrayList("2017"), false); + } + + @Test(expected = NoSuchObjectException.class) + public void testDropPartitionByNameBogusCatalog() throws Exception { + client.dropPartition("nosuch", DB_NAME, TABLE_NAME, "year=2017", false); + } + + + // Helper methods private Table createTable(String tableName, List<FieldSchema> partCols, Map<String, String> tableParams) throws Exception { @@ -501,36 +572,33 @@ public class TestDropPartitions extends MetaStoreClientTest { .setPartCols(partCols) .setLocation(metaStore.getWarehouseRoot() + "/" + tableName) .setTableParams(tableParams) - .build(); - client.createTable(table); + .create(client, metaStore.getConf()); return table; } private Partition createPartition(List<String> values, List<FieldSchema> partCols) throws Exception { - Partition partition = new PartitionBuilder() + new PartitionBuilder() .setDbName(DB_NAME) .setTableName(TABLE_NAME) .setValues(values) .setCols(partCols) - .build(); - client.add_partition(partition); - partition = client.getPartition(DB_NAME, TABLE_NAME, values); + .addToTable(client, metaStore.getConf()); + Partition partition = client.getPartition(DB_NAME, TABLE_NAME, values); return partition; } private Partition createPartition(String tableName, String location, List<String> values, List<FieldSchema> partCols, Map<String, String> partParams) throws Exception { - Partition partition = new PartitionBuilder() + new PartitionBuilder() .setDbName(DB_NAME) .setTableName(tableName) .setValues(values) .setCols(partCols) .setLocation(location) .setPartParams(partParams) - .build(); - client.add_partition(partition); - partition = client.getPartition(DB_NAME, tableName, values); + .addToTable(client, metaStore.getConf()); + Partition partition = client.getPartition(DB_NAME, tableName, values); return partition; } http://git-wip-us.apache.org/repos/asf/hive/blob/ba8a99e1/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestExchangePartitions.java ---------------------------------------------------------------------- diff --git a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestExchangePartitions.java b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestExchangePartitions.java index 5a7c71c..473b171 100644 --- a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestExchangePartitions.java +++ b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestExchangePartitions.java @@ -27,7 +27,6 @@ import org.apache.hadoop.fs.Path; import org.apache.hadoop.hive.metastore.IMetaStoreClient; import org.apache.hadoop.hive.metastore.Warehouse; import org.apache.hadoop.hive.metastore.annotation.MetastoreCheckinTest; -import org.apache.hadoop.hive.metastore.api.Database; import org.apache.hadoop.hive.metastore.api.FieldSchema; import org.apache.hadoop.hive.metastore.api.MetaException; import org.apache.hadoop.hive.metastore.api.NoSuchObjectException; @@ -1162,10 +1161,9 @@ public class TestExchangePartitions extends MetaStoreClientTest { // Helper methods private void createDB(String dbName) throws TException { - Database db = new DatabaseBuilder() + new DatabaseBuilder() .setName(dbName) - .build(); - client.createDatabase(db); + .create(client, metaStore.getConf()); } private Table createSourceTable() throws Exception { @@ -1186,14 +1184,13 @@ public class TestExchangePartitions extends MetaStoreClientTest { private Table createTable(String dbName, String tableName, List<FieldSchema> partCols, List<FieldSchema> cols, String location) throws Exception { - Table table = new TableBuilder() + new TableBuilder() .setDbName(dbName) .setTableName(tableName) .setCols(cols) .setPartCols(partCols) .setLocation(location) - .build(); - client.createTable(table); + .create(client, metaStore.getConf()); return client.getTable(dbName, tableName); } @@ -1244,7 +1241,7 @@ public class TestExchangePartitions extends MetaStoreClientTest { .addStorageDescriptorParam("test_exch_sd_param_key", "test_exch_sd_param_value") .setCols(getYearMonthAndDayPartCols()) .setLocation(location) - .build(); + .build(metaStore.getConf()); return partition; } http://git-wip-us.apache.org/repos/asf/hive/blob/ba8a99e1/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestForeignKey.java ---------------------------------------------------------------------- diff --git a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestForeignKey.java b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestForeignKey.java new file mode 100644 index 0000000..d8192b1 --- /dev/null +++ b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestForeignKey.java @@ -0,0 +1,535 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hive.metastore.client; + +import org.apache.hadoop.hive.metastore.IMetaStoreClient; +import org.apache.hadoop.hive.metastore.MetaStoreTestUtils; +import org.apache.hadoop.hive.metastore.annotation.MetastoreCheckinTest; +import org.apache.hadoop.hive.metastore.api.Catalog; +import org.apache.hadoop.hive.metastore.api.Database; +import org.apache.hadoop.hive.metastore.api.ForeignKeysRequest; +import org.apache.hadoop.hive.metastore.api.InvalidObjectException; +import org.apache.hadoop.hive.metastore.api.MetaException; +import org.apache.hadoop.hive.metastore.api.NoSuchObjectException; +import org.apache.hadoop.hive.metastore.api.SQLForeignKey; +import org.apache.hadoop.hive.metastore.api.SQLPrimaryKey; +import org.apache.hadoop.hive.metastore.api.Table; +import org.apache.hadoop.hive.metastore.client.builder.CatalogBuilder; +import org.apache.hadoop.hive.metastore.client.builder.DatabaseBuilder; +import org.apache.hadoop.hive.metastore.client.builder.SQLForeignKeyBuilder; +import org.apache.hadoop.hive.metastore.client.builder.SQLPrimaryKeyBuilder; +import org.apache.hadoop.hive.metastore.client.builder.TableBuilder; +import org.apache.hadoop.hive.metastore.minihms.AbstractMetaStoreService; +import org.apache.thrift.TApplicationException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.List; + +import static org.apache.hadoop.hive.metastore.Warehouse.DEFAULT_DATABASE_NAME; + +@RunWith(Parameterized.class) +@Category(MetastoreCheckinTest.class) +public class TestForeignKey extends MetaStoreClientTest { + private static final String OTHER_DATABASE = "test_fk_other_database"; + private static final String OTHER_CATALOG = "test_fk_other_catalog"; + private static final String DATABASE_IN_OTHER_CATALOG = "test_fk_database_in_other_catalog"; + private final AbstractMetaStoreService metaStore; + private IMetaStoreClient client; + private Table[] testTables = new Table[4]; + private Database inOtherCatalog; + + public TestForeignKey(String name, AbstractMetaStoreService metaStore) throws Exception { + this.metaStore = metaStore; + this.metaStore.start(); + } + + @Before + public void setUp() throws Exception { + // Get new client + client = metaStore.getClient(); + + // Clean up the database + client.dropDatabase(OTHER_DATABASE, true, true, true); + // Drop every table in the default database + for(String tableName : client.getAllTables(DEFAULT_DATABASE_NAME)) { + client.dropTable(DEFAULT_DATABASE_NAME, tableName, true, true, true); + } + + client.dropDatabase(OTHER_CATALOG, DATABASE_IN_OTHER_CATALOG, true, true, true); + try { + client.dropCatalog(OTHER_CATALOG); + } catch (NoSuchObjectException e) { + // NOP + } + + // Clean up trash + metaStore.cleanWarehouseDirs(); + + new DatabaseBuilder().setName(OTHER_DATABASE).create(client, metaStore.getConf()); + + Catalog cat = new CatalogBuilder() + .setName(OTHER_CATALOG) + .setLocation(MetaStoreTestUtils.getTestWarehouseDir(OTHER_CATALOG)) + .build(); + client.createCatalog(cat); + + // For this one don't specify a location to make sure it gets put in the catalog directory + inOtherCatalog = new DatabaseBuilder() + .setName(DATABASE_IN_OTHER_CATALOG) + .setCatalogName(OTHER_CATALOG) + .create(client, metaStore.getConf()); + + testTables[0] = + new TableBuilder() + .setTableName("test_table_1") + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .create(client, metaStore.getConf()); + + testTables[1] = + new TableBuilder() + .setDbName(OTHER_DATABASE) + .setTableName("test_table_2") + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .create(client, metaStore.getConf()); + + testTables[2] = + new TableBuilder() + .inDb(inOtherCatalog) + .setTableName("test_table_3") + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .create(client, metaStore.getConf()); + + testTables[3] = + new TableBuilder() + .inDb(inOtherCatalog) + .setTableName("test_table_4") + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .create(client, metaStore.getConf()); + + // Reload tables from the MetaStore + for(int i=0; i < testTables.length; i++) { + testTables[i] = client.getTable(testTables[i].getCatName(), testTables[i].getDbName(), + testTables[i].getTableName()); + } + } + + @After + public void tearDown() throws Exception { + try { + if (client != null) { + client.close(); + } + } finally { + client = null; + } + } + + @Test + public void createGetDrop() throws TException { + Table parentTable = testTables[1]; + Table table = testTables[0]; + // Make sure get on a table with no key returns empty list + ForeignKeysRequest rqst = + new ForeignKeysRequest(parentTable.getDbName(), parentTable.getTableName(), + table.getDbName(), table.getTableName()); + rqst.setCatName(table.getCatName()); + List<SQLForeignKey> fetched = client.getForeignKeys(rqst); + Assert.assertTrue(fetched.isEmpty()); + + // Single column unnamed primary key in default catalog and database + List<SQLPrimaryKey> pk = new SQLPrimaryKeyBuilder() + .onTable(parentTable) + .addColumn("col1") + .build(metaStore.getConf()); + client.addPrimaryKey(pk); + + List<SQLForeignKey> fk = new SQLForeignKeyBuilder() + .fromPrimaryKey(pk) + .onTable(table) + .addColumn("col1") + .build(metaStore.getConf()); + client.addForeignKey(fk); + + + rqst = new ForeignKeysRequest(parentTable.getDbName(), parentTable.getTableName(), + table.getDbName(), table.getTableName()); + rqst.setCatName(table.getCatName()); + fetched = client.getForeignKeys(rqst); + Assert.assertEquals(1, fetched.size()); + Assert.assertEquals(table.getDbName(), fetched.get(0).getFktable_db()); + Assert.assertEquals(table.getTableName(), fetched.get(0).getFktable_name()); + Assert.assertEquals("col1", fetched.get(0).getFkcolumn_name()); + Assert.assertEquals(parentTable.getDbName(), fetched.get(0).getPktable_db()); + Assert.assertEquals(parentTable.getTableName(), fetched.get(0).getPktable_name()); + Assert.assertEquals("col1", fetched.get(0).getFkcolumn_name()); + Assert.assertEquals(1, fetched.get(0).getKey_seq()); + Assert.assertEquals(parentTable.getTableName() + "_primary_key", fetched.get(0).getPk_name()); + Assert.assertEquals(table.getTableName() + "_to_" + parentTable.getTableName() + + "_foreign_key", fetched.get(0).getFk_name()); + String table0FkName = fetched.get(0).getFk_name(); + Assert.assertTrue(fetched.get(0).isEnable_cstr()); + Assert.assertFalse(fetched.get(0).isValidate_cstr()); + Assert.assertFalse(fetched.get(0).isRely_cstr()); + Assert.assertEquals(table.getCatName(), fetched.get(0).getCatName()); + + // Drop a foreign key + client.dropConstraint(table.getCatName(), table.getDbName(), + table.getTableName(), table0FkName); + rqst = new ForeignKeysRequest(parentTable.getDbName(), parentTable.getTableName(), + table.getDbName(), table.getTableName()); + rqst.setCatName(table.getCatName()); + fetched = client.getForeignKeys(rqst); + Assert.assertTrue(fetched.isEmpty()); + + // Make sure I can add it back + client.addForeignKey(fk); + } + + @Test + public void createGetDrop2Column() throws TException { + Table parentTable = testTables[1]; + Table table = testTables[0]; + String constraintName = "2colfk"; + + // Single column unnamed primary key in default catalog and database + List<SQLPrimaryKey> pk = new SQLPrimaryKeyBuilder() + .onTable(parentTable) + .addColumn("col1") + .addColumn("col2") + .build(metaStore.getConf()); + client.addPrimaryKey(pk); + + List<SQLForeignKey> fk = new SQLForeignKeyBuilder() + .fromPrimaryKey(pk) + .onTable(table) + .addColumn("col1") + .addColumn("col2") + .setConstraintName(constraintName) + .build(metaStore.getConf()); + client.addForeignKey(fk); + + + ForeignKeysRequest rqst = new ForeignKeysRequest(parentTable.getDbName(), + parentTable.getTableName(), table.getDbName(), table.getTableName()); + rqst.setCatName(table.getCatName()); + List<SQLForeignKey> fetched = client.getForeignKeys(rqst); + Assert.assertEquals(2, fetched.size()); + Assert.assertEquals(table.getDbName(), fetched.get(0).getFktable_db()); + Assert.assertEquals(table.getTableName(), fetched.get(0).getFktable_name()); + Assert.assertEquals("col1", fetched.get(0).getFkcolumn_name()); + Assert.assertEquals("col2", fetched.get(1).getFkcolumn_name()); + Assert.assertEquals(parentTable.getDbName(), fetched.get(0).getPktable_db()); + Assert.assertEquals(parentTable.getTableName(), fetched.get(0).getPktable_name()); + Assert.assertEquals("col1", fetched.get(0).getFkcolumn_name()); + Assert.assertEquals("col2", fetched.get(1).getFkcolumn_name()); + Assert.assertEquals(1, fetched.get(0).getKey_seq()); + Assert.assertEquals(parentTable.getTableName() + "_primary_key", fetched.get(0).getPk_name()); + Assert.assertEquals(constraintName, fetched.get(0).getFk_name()); + String table0FkName = fetched.get(0).getFk_name(); + Assert.assertTrue(fetched.get(0).isEnable_cstr()); + Assert.assertFalse(fetched.get(0).isValidate_cstr()); + Assert.assertFalse(fetched.get(0).isRely_cstr()); + Assert.assertEquals(table.getCatName(), fetched.get(0).getCatName()); + + // Drop a foreign key + client.dropConstraint(table.getCatName(), table.getDbName(), + table.getTableName(), table0FkName); + rqst = new ForeignKeysRequest(parentTable.getDbName(), parentTable.getTableName(), + table.getDbName(), table.getTableName()); + rqst.setCatName(table.getCatName()); + fetched = client.getForeignKeys(rqst); + Assert.assertTrue(fetched.isEmpty()); + + // Make sure I can add it back + client.addForeignKey(fk); + } + + @Test + public void inOtherCatalog() throws TException { + Table parentTable = testTables[2]; + Table table = testTables[3]; + String constraintName = "othercatfk"; + + // Single column unnamed primary key in default catalog and database + List<SQLPrimaryKey> pk = new SQLPrimaryKeyBuilder() + .onTable(parentTable) + .addColumn("col1") + .build(metaStore.getConf()); + client.addPrimaryKey(pk); + + List<SQLForeignKey> fk = new SQLForeignKeyBuilder() + .fromPrimaryKey(pk) + .onTable(table) + .addColumn("col1") + .setConstraintName(constraintName) + .build(metaStore.getConf()); + client.addForeignKey(fk); + + + ForeignKeysRequest rqst = new ForeignKeysRequest(parentTable.getDbName(), + parentTable.getTableName(), table.getDbName(), table.getTableName()); + rqst.setCatName(table.getCatName()); + List<SQLForeignKey> fetched = client.getForeignKeys(rqst); + Assert.assertEquals(1, fetched.size()); + Assert.assertEquals(table.getDbName(), fetched.get(0).getFktable_db()); + Assert.assertEquals(table.getTableName(), fetched.get(0).getFktable_name()); + Assert.assertEquals("col1", fetched.get(0).getFkcolumn_name()); + Assert.assertEquals(parentTable.getDbName(), fetched.get(0).getPktable_db()); + Assert.assertEquals(parentTable.getTableName(), fetched.get(0).getPktable_name()); + Assert.assertEquals("col1", fetched.get(0).getFkcolumn_name()); + Assert.assertEquals(1, fetched.get(0).getKey_seq()); + Assert.assertEquals(parentTable.getTableName() + "_primary_key", fetched.get(0).getPk_name()); + Assert.assertEquals(constraintName, fetched.get(0).getFk_name()); + String table0FkName = fetched.get(0).getFk_name(); + Assert.assertTrue(fetched.get(0).isEnable_cstr()); + Assert.assertFalse(fetched.get(0).isValidate_cstr()); + Assert.assertFalse(fetched.get(0).isRely_cstr()); + Assert.assertEquals(table.getCatName(), fetched.get(0).getCatName()); + + // Drop a foreign key + client.dropConstraint(table.getCatName(), table.getDbName(), + table.getTableName(), table0FkName); + rqst = new ForeignKeysRequest(parentTable.getDbName(), parentTable.getTableName(), + table.getDbName(), table.getTableName()); + rqst.setCatName(table.getCatName()); + fetched = client.getForeignKeys(rqst); + Assert.assertTrue(fetched.isEmpty()); + + // Make sure I can add it back + client.addForeignKey(fk); + } + + @Test + public void createTableWithConstraints() throws TException { + String constraintName = "ctwckk"; + Table parentTable = testTables[0]; + Table table = new TableBuilder() + .setTableName("table_with_constraints") + .setDbName(parentTable.getDbName()) + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .build(metaStore.getConf()); + + List<SQLPrimaryKey> pk = new SQLPrimaryKeyBuilder() + .onTable(parentTable) + .addColumn("col1") + .build(metaStore.getConf()); + client.addPrimaryKey(pk); + + List<SQLForeignKey> fk = new SQLForeignKeyBuilder() + .fromPrimaryKey(pk) + .onTable(table) + .addColumn("col1") + .setConstraintName(constraintName) + .build(metaStore.getConf()); + + client.createTableWithConstraints(table, null, fk, null, null, null, null); + + ForeignKeysRequest rqst = new ForeignKeysRequest(parentTable.getDbName(), parentTable + .getTableName(), + table.getDbName(), table.getTableName()); + rqst.setCatName(table.getCatName()); + List<SQLForeignKey> fetched = client.getForeignKeys(rqst); + Assert.assertEquals(1, fetched.size()); + Assert.assertEquals(table.getDbName(), fetched.get(0).getFktable_db()); + Assert.assertEquals(table.getTableName(), fetched.get(0).getFktable_name()); + Assert.assertEquals("col1", fetched.get(0).getFkcolumn_name()); + Assert.assertEquals(parentTable.getDbName(), fetched.get(0).getPktable_db()); + Assert.assertEquals(parentTable.getTableName(), fetched.get(0).getPktable_name()); + Assert.assertEquals("col1", fetched.get(0).getFkcolumn_name()); + Assert.assertEquals(1, fetched.get(0).getKey_seq()); + Assert.assertEquals(parentTable.getTableName() + "_primary_key", fetched.get(0).getPk_name()); + Assert.assertEquals(constraintName, fetched.get(0).getFk_name()); + Assert.assertTrue(fetched.get(0).isEnable_cstr()); + Assert.assertFalse(fetched.get(0).isValidate_cstr()); + Assert.assertFalse(fetched.get(0).isRely_cstr()); + Assert.assertEquals(table.getCatName(), fetched.get(0).getCatName()); + } + + @Test + public void createTableWithConstraintsInOtherCatalog() throws TException { + String constraintName = "ctwcocfk"; + Table parentTable = testTables[2]; + Table table = new TableBuilder() + .setTableName("table_with_constraints") + .inDb(inOtherCatalog) + .addCol("col1", "int") + .addCol("col2", "varchar(32)") + .build(metaStore.getConf()); + + List<SQLPrimaryKey> pk = new SQLPrimaryKeyBuilder() + .onTable(parentTable) + .addColumn("col1") + .build(metaStore.getConf()); + client.addPrimaryKey(pk); + + List<SQLForeignKey> fk = new SQLForeignKeyBuilder() + .fromPrimaryKey(pk) + .onTable(table) + .addColumn("col1") + .setConstraintName(constraintName) + .build(metaStore.getConf()); + + client.createTableWithConstraints(table, null, fk, null, null, null, null); + + ForeignKeysRequest rqst = new ForeignKeysRequest(parentTable.getDbName(), parentTable + .getTableName(), + table.getDbName(), table.getTableName()); + rqst.setCatName(table.getCatName()); + List<SQLForeignKey> fetched = client.getForeignKeys(rqst); + Assert.assertEquals(1, fetched.size()); + Assert.assertEquals(table.getDbName(), fetched.get(0).getFktable_db()); + Assert.assertEquals(table.getTableName(), fetched.get(0).getFktable_name()); + Assert.assertEquals("col1", fetched.get(0).getFkcolumn_name()); + Assert.assertEquals(parentTable.getDbName(), fetched.get(0).getPktable_db()); + Assert.assertEquals(parentTable.getTableName(), fetched.get(0).getPktable_name()); + Assert.assertEquals("col1", fetched.get(0).getFkcolumn_name()); + Assert.assertEquals(1, fetched.get(0).getKey_seq()); + Assert.assertEquals(parentTable.getTableName() + "_primary_key", fetched.get(0).getPk_name()); + Assert.assertEquals(constraintName, fetched.get(0).getFk_name()); + Assert.assertTrue(fetched.get(0).isEnable_cstr()); + Assert.assertFalse(fetched.get(0).isValidate_cstr()); + Assert.assertFalse(fetched.get(0).isRely_cstr()); + Assert.assertEquals(table.getCatName(), fetched.get(0).getCatName()); + } + + @Test(expected = MetaException.class) + public void noSuchPk() throws TException { + List<SQLPrimaryKey> pk = new SQLPrimaryKeyBuilder() + .onTable(testTables[1]) + .addColumn("col1") + .build(metaStore.getConf()); + // Don't actually create the key + List<SQLForeignKey> fk = new SQLForeignKeyBuilder() + .onTable(testTables[0]) + .fromPrimaryKey(pk) + .addColumn("col2") + .build(metaStore.getConf()); + client.addForeignKey(fk); + Assert.fail(); + } + + @Test + public void addNoSuchTable() throws TException { + Table parentTable = testTables[0]; + + List<SQLPrimaryKey> pk = new SQLPrimaryKeyBuilder() + .onTable(parentTable) + .addColumn("col1") + .build(metaStore.getConf()); + client.addPrimaryKey(pk); + + try { + List<SQLForeignKey> fk = new SQLForeignKeyBuilder() + .setTableName("nosuch") + .fromPrimaryKey(pk) + .addColumn("col2") + .build(metaStore.getConf()); + client.addForeignKey(fk); + Assert.fail(); + } catch (InvalidObjectException |TApplicationException e) { + // NOP + } + } + + @Test + public void addNoSuchDb() throws TException { + Table parentTable = testTables[0]; + + List<SQLPrimaryKey> pk = new SQLPrimaryKeyBuilder() + .onTable(parentTable) + .addColumn("col1") + .build(metaStore.getConf()); + client.addPrimaryKey(pk); + + try { + List<SQLForeignKey> fk = new SQLForeignKeyBuilder() + .setTableName(testTables[0].getTableName()) + .setDbName("nosuch") + .fromPrimaryKey(pk) + .addColumn("col2") + .build(metaStore.getConf()); + client.addForeignKey(fk); + Assert.fail(); + } catch (InvalidObjectException |TApplicationException e) { + // NOP + } + } + + @Test + public void addNoSuchCatalog() throws TException { + Table parentTable = testTables[0]; + + List<SQLPrimaryKey> pk = new SQLPrimaryKeyBuilder() + .onTable(parentTable) + .addColumn("col1") + .build(metaStore.getConf()); + client.addPrimaryKey(pk); + + try { + List<SQLForeignKey> fk = new SQLForeignKeyBuilder() + .setTableName(testTables[0].getTableName()) + .setDbName(testTables[0].getDbName()) + .setCatName("nosuch") + .fromPrimaryKey(pk) + .addColumn("col2") + .build(metaStore.getConf()); + client.addForeignKey(fk); + Assert.fail(); + } catch (InvalidObjectException |TApplicationException e) { + // NOP + } + } + + @Test + public void foreignKeyAcrossCatalogs() throws TException { + Table parentTable = testTables[2]; + Table table = testTables[0]; + + // Single column unnamed primary key in default catalog and database + List<SQLPrimaryKey> pk = new SQLPrimaryKeyBuilder() + .onTable(parentTable) + .addColumn("col1") + .build(metaStore.getConf()); + client.addPrimaryKey(pk); + + try { + List<SQLForeignKey> fk = new SQLForeignKeyBuilder() + .fromPrimaryKey(pk) + .onTable(table) + .addColumn("col1") + .build(metaStore.getConf()); + client.addForeignKey(fk); + Assert.fail(); + } catch (InvalidObjectException |TApplicationException e) { + // NOP + } + } + +}
