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
+    }
+  }
+
+}

Reply via email to