@Test
  public void testB() throws Throwable {
    declareBaseTable();
    conn.execute("using container testcont (global)");
    conn.execute("insert into bt values (1, 'one')");
    conn.assertResults(
        "show container_tenants", br(nr, "testcont", "id:1,junk:'one'", getIgnore()));
    conn.execute("insert into bt values (2, 'two')");
    conn.assertResults(
        "show container_tenants like '%two%'", br(nr, "testcont", "id:2,junk:'two'", getIgnore()));
    conn.execute("using container testcont (1, 'one')");
    String errorMessage =
        "Internal error: Inserts into base table `bt` for container testcont must be done when in the global container context";

    // should not be able to insert into base table as a nonglobal container tenant
    new ExpectedSqlErrorTester() {
      @Override
      public void test() throws Throwable {
        conn.execute("insert into bt values (3, 'three')");
      }
    }.assertError(SchemaException.class, MySQLErrors.internalFormatter, errorMessage);
    conn.disconnect();
    conn.connect();
    conn.execute("use " + testDDL.getDatabaseName());

    // should not be able to insert into base table in the null container tenant
    new ExpectedSqlErrorTester() {
      @Override
      public void test() throws Throwable {
        conn.execute("insert into bt values (3, 'three')");
      }
    }.assertError(SchemaException.class, MySQLErrors.internalFormatter, errorMessage);
  }
  @Test
  public void testPE469() throws Throwable {
    declareBaseTable();
    conn.execute("using container testcont (global)");
    conn.execute("insert into bt values (1, 'global')");
    conn.execute("using container testcont (1, 'global')");
    conn.execute(
        "create table A (`id` int, `junk` varchar(32), primary key (id)) container distribute testcont");
    conn.execute("insert into A values (1, 'global')");
    conn.execute("using container testcont (junk='global', id=1)");
    conn.assertResults("select * from A where id = 1", br(nr, new Integer(1), "global"));

    // cannot specify GLOBAL context and discriminators
    new ExpectedSqlErrorTester() {
      @Override
      public void test() throws Throwable {
        conn.execute("using container testcont (global, junk='global', id=1)");
      }
    }.assertError(
        SchemaException.class,
        MySQLErrors.internalFormatter,
        "Internal error: GLOBAL context cannot be specified with container discriminant.");

    // cannot specify GLOBAL context and discriminators
    new ExpectedSqlErrorTester() {
      @Override
      public void test() throws Throwable {
        conn.execute("using container testcont (global, junk='global', null, id=1)");
      }
    }.assertError(
        SchemaException.class,
        MySQLErrors.internalFormatter,
        "Internal error: GLOBAL context cannot be specified with container discriminant.");

    // cannot specify NULL context and discriminators
    new ExpectedSqlErrorTester() {
      @Override
      public void test() throws Throwable {
        conn.execute("using container testcont (null, junk='global', id=1)");
      }
    }.assertError(
        SchemaException.class,
        MySQLErrors.internalFormatter,
        "Internal error: NULL context cannot be specified with container discriminant.");

    // cannot specify NULL context and discriminators
    new ExpectedSqlErrorTester() {
      @Override
      public void test() throws Throwable {
        conn.execute("using container testcont (junk='global', null, global, id=1)");
      }
    }.assertError(
        SchemaException.class,
        MySQLErrors.internalFormatter,
        "Internal error: NULL context cannot be specified with container discriminant.");
  }
  @Test
  public void testF() throws Throwable {
    declareBaseTable();
    conn.execute("using container testcont (global)");
    conn.execute("insert into bt values (1, 'one')");
    conn.execute("insert into bt values (2, 'two')");

    // should not be able to drop disc column
    new ExpectedSqlErrorTester() {
      @Override
      public void test() throws Throwable {
        conn.execute("alter table bt drop junk");
      }
    }.assertError(
        SchemaException.class,
        MySQLErrors.internalFormatter,
        "Internal error: Illegal alter on container base table `bt` discriminant column `junk`");
    conn.execute("alter table bt alter column `unused` set default 'deadbeef'");

    // should not be able to update disc columns
    new ExpectedSqlErrorTester() {
      @Override
      public void test() throws Throwable {
        conn.execute("update bt set id = 20 where unused = 'whatever'");
      }
    }.assertError(
        SchemaException.class, MySQLErrors.invalidDiscriminantUpdateFormatter, "id", "bt");
    // this should work
    conn.execute("update bt set unused = 'whatever' where id = 1");

    // should also do change def, but will have to pull that in
    // should not be able to range delete from base table
    new ExpectedSqlErrorTester() {
      @Override
      public void test() throws Throwable {
        conn.execute("delete from bt where unused = 'whatever'");
      }
    }.assertError(SchemaException.class, MySQLErrors.invalidContainerDeleteFormatter, "bt");
    // this does work, however
    conn.execute("delete from bt where id = 2 and junk = 'two'");
    conn.assertResults(
        "show container_tenants", br(nr, "testcont", "id:1,junk:'one'", getIgnore()));
  }
 @Test
 public void testA() throws Throwable {
   declareBaseTable();
   conn.execute("using container testcont (global)");
   conn.execute("insert into bt values (1,'one'),(2,'two')");
   conn.assertResults(
       "show container_tenants",
       br(
           nr,
           "testcont",
           "id:1,junk:'one'",
           getIgnore(),
           nr,
           "testcont",
           "id:2,junk:'two'",
           getIgnore()));
   conn.execute(
       "create table A (`id` int, `junk` varchar(32), primary key (`id`)) container distribute testcont");
   conn.assertResults(
       "describe A",
       br(
           nr,
           "id",
           "int(11)",
           "NO",
           "PRI",
           null,
           "",
           nr,
           "junk",
           "varchar(32)",
           "YES",
           "",
           null,
           ""));
   conn.execute("set @@dve_metadata_extensions = 1");
   conn.assertResults(
       "describe A",
       br(
           nr,
           "id",
           "int(11)",
           "NO",
           "PRI",
           null,
           "",
           nr,
           "junk",
           "varchar(32)",
           "YES",
           "",
           null,
           "",
           nr,
           "___mtid",
           "int(10) unsigned",
           "NO",
           "",
           null,
           ""));
   conn.execute("drop database " + testDDL.getDatabaseName());
   conn.execute("drop container testcont");
 }
  // containers and fks
  @Test
  public void testFKs() throws Throwable {
    declareBaseTable();
    conn.execute("using container testcont (global)");
    conn.execute("insert into bt values (1, 'one')");
    conn.execute("insert into bt values (2, 'two')");
    conn.execute(
        "create table A (`id` int, `junk` varchar(32), primary key (id)) container distribute testcont");
    conn.execute(
        "create table B (`id` int, `junk` varchar(32), `fid` int, primary key (id), foreign key (fid) references A (id)) container distribute testcont");
    conn.assertResults(
        "select * from information_schema.table_constraints where table_name != 'bt'",
        br(
            nr,
            "def",
            "checkdb",
            "PRIMARY",
            "checkdb",
            "A",
            "PRIMARY KEY",
            nr,
            "def",
            "checkdb",
            "PRIMARY",
            "checkdb",
            "B",
            "PRIMARY KEY",
            nr,
            "def",
            "checkdb",
            "B_ibfk_1",
            "checkdb",
            "B",
            "FOREIGN KEY"));
    String dbn = testDDL.getDatabaseName();
    conn.assertResults(
        "select * from information_schema.referential_constraints",
        br(nr, "def", dbn, "def", dbn, "RESTRICT", "RESTRICT", "B", "A"));

    // should not be able to create a table with a noncolocated fk
    new ExpectedSqlErrorTester() {
      @Override
      public void test() throws Throwable {
        conn.execute(
            "create table C (`id` int, `sid` int, primary key (id), foreign key (sid) references B (id)) random distribute");
      }
    }.assertError(
        SchemaException.class,
        MySQLErrors.internalFormatter,
        "Internal error: Invalid foreign key C.C_ibfk_1: table C is not colocated with B");
    conn.execute("set foreign_key_checks = 0");
    conn.execute(
        "create table D (`id` int, `sid` int, primary key (id), foreign key tfk (sid) references E (id)) container distribute testcont");
    Object[] results =
        br(
            nr,
            "def",
            dbn,
            "def",
            dbn,
            "RESTRICT",
            "RESTRICT",
            "B",
            "A",
            nr,
            "def",
            dbn,
            "def",
            dbn,
            "RESTRICT",
            "RESTRICT",
            "D",
            "E");
    conn.assertResults("select * from information_schema.referential_constraints", results);
    Object one = new Integer(1);
    //		System.out.println(conn.printResults("select * from information_schema.key_column_usage"));
    conn.assertResults(
        "select * from information_schema.key_column_usage",
        br(
            nr, "def", "def", "checkdb", "bt", "id", one, null, null, null, nr, "def", "def",
            "checkdb", "A", "id", one, null, null, null, nr, "def", "def", "checkdb", "B", "id",
            one, null, null, null, nr, "def", "def", "checkdb", "B", "fid", one, "checkdb", "A",
            "id", nr, "def", "def", "checkdb", "D", "id", one, null, null, null, nr, "def", "def",
            "checkdb", "D", "sid", one, "checkdb", "E", "id"));

    // should not be able to create a table which is the target of a noncolocated fk
    new ExpectedSqlErrorTester() {
      @Override
      public void test() throws Throwable {
        conn.execute(
            "create table E (`id` int, `junk` varchar(32), primary key (`id`)) random distribute");
      }
    }.assertError(
        SchemaException.class,
        MySQLErrors.internalFormatter,
        "Internal error: Invalid foreign key D.D_ibfk_1: table D is not colocated with E");
    conn.execute(
        "create table E (`id` int, `junk` varchar(32), primary key (`id`)) container distribute testcont");
    conn.assertResults("select * from information_schema.referential_constraints", results);
    conn.assertResults(
        "select * from information_schema.key_column_usage",
        br(
            nr, "def", "def", "checkdb", "bt", "id", one, null, null, null, nr, "def", "def",
            "checkdb", "A", "id", one, null, null, null, nr, "def", "def", "checkdb", "B", "id",
            one, null, null, null, nr, "def", "def", "checkdb", "B", "fid", one, "checkdb", "A",
            "id", nr, "def", "def", "checkdb", "D", "id", one, null, null, null, nr, "def", "def",
            "checkdb", "D", "sid", one, "checkdb", "E", "id", nr, "def", "def", "checkdb", "E",
            "id", one, null, null, null));
  }
  @Test
  public void testC() throws Throwable {
    // conn.execute("alter dve set plan_cache_limit = 0");
    declareBaseTable();
    conn.execute("using container testcont (global)");
    conn.execute("insert into bt values (1, 'one')");
    conn.execute("insert into bt values (2, 'two')");
    conn.execute("using container testcont (1, 'one')");
    conn.execute(
        "create table A (`id` int, `junk` varchar(32), primary key (id)) container distribute testcont");
    conn.execute(
        "create table B (`id` int, `junk` varchar(32), primary key (id)) container distribute testcont");
    conn.execute("insert into A values (1, 'one')");
    conn.assertResults("select * from A where id = 1", br(nr, new Integer(1), "one"));
    conn.execute("insert into B values (1, 'uno')");
    conn.assertResults("select * from B where id = 1", br(nr, new Integer(1), "uno"));
    conn.assertResults(
        "select a.junk, b.junk from A a, B b where a.id = b.id", br(nr, "one", "uno"));
    conn.execute("using container testcont (junk='two', id=2)");
    conn.execute("insert into A values (2, 'two')");
    conn.assertResults("select * from A where id = 2", br(nr, new Integer(2), "two"));
    conn.execute("using container testcont (global)");
    conn.assertResults(
        "select * from A order by id", br(nr, new Integer(1), "one", nr, new Integer(2), "two"));

    // should not be able to drop nonempty container
    new ExpectedSqlErrorTester() {
      @Override
      public void test() throws Throwable {
        conn.execute("drop container testcont");
      }
    }.assertError(
        SchemaException.class,
        MySQLErrors.internalFormatter,
        "Internal error: Unable to drop container testcont due to existing tables");
    // I shouldn't be able to drop the base table out of the container if the container has other
    // nonbase tables
    // this is because if I could, then I could no longer access those tables.
    new ExpectedSqlErrorTester() {
      @Override
      public void test() throws Throwable {
        conn.execute("drop table bt");
      }
    }.assertError(
        SchemaException.class,
        MySQLErrors.internalFormatter,
        "Internal error: Unable to drop table `bt` because it is the base table to container testcont which is not empty");
    conn.execute("drop table A");
    conn.execute("drop table B");
    conn.assertResults(
        "show container_tenants",
        br(
            nr,
            "testcont",
            "id:1,junk:'one'",
            getIgnore(),
            nr,
            "testcont",
            "id:2,junk:'two'",
            getIgnore()));
    conn.execute("drop table bt");
    conn.assertResults("show container_tenants", br());

    // should not be able to drop range for container in use
    new ExpectedSqlErrorTester() {
      @Override
      public void test() throws Throwable {
        conn.execute("drop range cont_range");
      }
    }.assertError(
        SchemaException.class,
        MySQLErrors.internalFormatter,
        "Internal error: Unable to drop range cont_range because used by container testcont");
  }