@Test
  public void testToAcidConversionMultiBucket() throws Exception {
    //need to disable these so that automatic merge doesn't merge the files
    hiveConf.setBoolVar(HiveConf.ConfVars.HIVE_MERGE_MAPFILES, false);
    hiveConf.setBoolVar(HiveConf.ConfVars.HIVE_MERGE_MAPRED_FILES, false);
    hiveConf.setBoolVar(HiveConf.ConfVars.HIVE_MERGE_TEZ_FILES, false);
    d.close();
    d = new Driver(hiveConf);

    int[][] values = {{1,2},{2,4},{5,6},{6,8},{9,10}};
    runStatementOnDriver("insert into " + Table.ACIDTBL + makeValuesClause(values));
    dropTables("T");
    runStatementOnDriver("create table T (a int, b int) stored as ORC  TBLPROPERTIES ('transactional'='false')");
    runStatementOnDriver("insert into T(a,b) select a, b from " + Table.ACIDTBL +
      " where a between 1 and 3 group by a, b union all select a, b from " + Table.ACIDTBL +
      " where a between 5 and 7 union all select a, b from " + Table.ACIDTBL + " where a >= 9");
    runStatementOnDriver("insert into T values(12,12)");

    List<String> rs = runStatementOnDriver("select a, b, INPUT__FILE__NAME from T order by a, b, INPUT__FILE__NAME");
    //previous insert+union creates 3 data files (0-3)
    //insert (12,12) creates 000000_0
    String expected[][] = {
        {"1\t2",  "warehouse/t/HIVE_UNION_SUBDIR_1/000000_0"},
        {"2\t4",  "warehouse/t/HIVE_UNION_SUBDIR_1/000000_0"},
        {"5\t6",  "warehouse/t/HIVE_UNION_SUBDIR_2/000000_0"},
        {"6\t8",  "warehouse/t/HIVE_UNION_SUBDIR_2/000001_0"},
        {"9\t10", "warehouse/t/HIVE_UNION_SUBDIR_3/000000_0"},
        {"12\t12", "warehouse/t/000000_0"}
    };
    checkExpected(rs, expected,"before converting to acid");

    //now do Insert from Union here to create data files in sub dirs
    hiveConf.setBoolVar(HiveConf.ConfVars.HIVE_OPTIMIZE_UNION_REMOVE, true);
    hiveConf.setVar(HiveConf.ConfVars.HIVE_FETCH_TASK_CONVERSION, "none");
    d.close();
    d = new Driver(hiveConf);
    runStatementOnDriver("insert into T(a,b) select a * 10, b * 10 from " + Table.ACIDTBL +
        " where a between 1 and 3 group by a, b union all select a * 10, b * 10 from " + Table.ACIDTBL +
        " where a between 5 and 7");
    //now we have a table with data files at multiple different levels.
    String expected1[][] = {
        {"1\t2",  "warehouse/t/HIVE_UNION_SUBDIR_1/000000_0"},
        {"2\t4",  "warehouse/t/HIVE_UNION_SUBDIR_1/000000_0"},
        {"5\t6",  "warehouse/t/HIVE_UNION_SUBDIR_2/000000_0"},
        {"6\t8",  "warehouse/t/HIVE_UNION_SUBDIR_2/000001_0"},
        {"9\t10", "warehouse/t/HIVE_UNION_SUBDIR_3/000000_0"},
        {"10\t20", "warehouse/t/HIVE_UNION_SUBDIR_15/000000_0"},
        {"12\t12", "warehouse/t/000000_0"},
        {"20\t40", "warehouse/t/HIVE_UNION_SUBDIR_15/000000_0"},
        {"50\t60", "warehouse/t/HIVE_UNION_SUBDIR_16/000000_0"},
        {"60\t80", "warehouse/t/HIVE_UNION_SUBDIR_16/000001_0"}
    };
    rs = runStatementOnDriver("select a, b, INPUT__FILE__NAME from T order by a, b, INPUT__FILE__NAME");
    checkExpected(rs, expected1,"before converting to acid (with multi level data layout)");

    //make it an Acid table and make sure we assign ROW__IDs correctly
    runStatementOnDriver("alter table T SET TBLPROPERTIES ('transactional'='true')");
    rs = runStatementOnDriver("select ROW__ID, a, b, INPUT__FILE__NAME from T order by a, b, INPUT__FILE__NAME");
    /**
    now that T is Acid, data for each writerId is treated like a logical bucket (though T is not
    bucketed), so rowid are assigned per logical bucket (e.g. 000000_0 + 000000_0_copy_1 + subdirs).
     {@link AcidUtils.Directory#getOriginalFiles()} ensures consistent ordering of files within
     logical bucket (tranche)
     */
    String expected2[][] = {
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":1}\t1\t2",  "warehouse/t/HIVE_UNION_SUBDIR_1/000000_0"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":2}\t2\t4",  "warehouse/t/HIVE_UNION_SUBDIR_1/000000_0"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":6}\t5\t6",  "warehouse/t/HIVE_UNION_SUBDIR_2/000000_0"},
        {"{\"writeid\":0,\"bucketid\":536936448,\"rowid\":1}\t6\t8",  "warehouse/t/HIVE_UNION_SUBDIR_2/000001_0"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":7}\t9\t10", "warehouse/t/HIVE_UNION_SUBDIR_3/000000_0"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":3}\t10\t20", "warehouse/t/HIVE_UNION_SUBDIR_15/000000_0"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":0}\t12\t12", "warehouse/t/000000_0"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":4}\t20\t40", "warehouse/t/HIVE_UNION_SUBDIR_15/000000_0"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":5}\t50\t60", "warehouse/t/HIVE_UNION_SUBDIR_16/000000_0"},
        {"{\"writeid\":0,\"bucketid\":536936448,\"rowid\":0}\t60\t80", "warehouse/t/HIVE_UNION_SUBDIR_16/000001_0"},
    };
    checkExpected(rs, expected2,"after converting to acid (no compaction)");
    Assert.assertEquals(0, BucketCodec.determineVersion(536870912).decodeWriterId(536870912));
    Assert.assertEquals(2, BucketCodec.determineVersion(537001984).decodeWriterId(537001984));
    Assert.assertEquals(1, BucketCodec.determineVersion(536936448).decodeWriterId(536936448));

    assertMappersAreVectorized("update T set b = 88 where b = 80 or b = 60");
    runStatementOnDriver("update T set b = 88 where b = 80 or b = 60");
    assertMappersAreVectorized("delete from T where b = 8");
    runStatementOnDriver("delete from T where b = 8");
    String expected3[][] = {
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":1}\t1\t2",  "warehouse/t/HIVE_UNION_SUBDIR_1/000000_0"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":2}\t2\t4",  "warehouse/t/HIVE_UNION_SUBDIR_1/000000_0"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":6}\t5\t6",  "warehouse/t/HIVE_UNION_SUBDIR_2/000000_0"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":7}\t9\t10", "warehouse/t/HIVE_UNION_SUBDIR_3/000000_0"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":3}\t10\t20", "warehouse/t/HIVE_UNION_SUBDIR_15/000000_0"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":0}\t12\t12", "warehouse/t/000000_0"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":4}\t20\t40", "warehouse/t/HIVE_UNION_SUBDIR_15/000000_0"},
        {"{\"writeid\":10000001,\"bucketid\":537067521,\"rowid\":0}\t50\t88", "warehouse/t/delta_10000001_10000001_0001/bucket_00003_0"},
        {"{\"writeid\":10000001,\"bucketid\":536870913,\"rowid\":0}\t60\t88", "warehouse/t/delta_10000001_10000001_0001/bucket_00000_0"},
    };
    rs = runStatementOnDriver("select ROW__ID, a, b, INPUT__FILE__NAME from T order by a, b, INPUT__FILE__NAME");
    checkExpected(rs, expected3,"after converting to acid (no compaction with updates)");

    //major compaction + check data + files
    runStatementOnDriver("alter table T compact 'major'");
    TestTxnCommands2.runWorker(hiveConf);
    rs = runStatementOnDriver("select ROW__ID, a, b, INPUT__FILE__NAME from T order by a, b, INPUT__FILE__NAME");

    /*Compaction preserves location of rows wrt buckets/tranches (for now)*/
    String expected4[][] = {
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":1}\t1\t2",
            "warehouse/t/base_10000002_v0000015/bucket_00000"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":2}\t2\t4",
            "warehouse/t/base_10000002_v0000015/bucket_00000"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":6}\t5\t6",
            "warehouse/t/base_10000002_v0000015/bucket_00000"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":7}\t9\t10",
            "warehouse/t/base_10000002_v0000015/bucket_00000"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":3}\t10\t20",
            "warehouse/t/base_10000002_v0000015/bucket_00000"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":0}\t12\t12",
            "warehouse/t/base_10000002_v0000015/bucket_00000"},
        {"{\"writeid\":0,\"bucketid\":536870912,\"rowid\":4}\t20\t40",
            "warehouse/t/base_10000002_v0000015/bucket_00000"},
        {"{\"writeid\":10000001,\"bucketid\":537067521,\"rowid\":0}\t50\t88",
            "warehouse/t/base_10000002_v0000015/bucket_00003"},
        {"{\"writeid\":10000001,\"bucketid\":536870913,\"rowid\":0}\t60\t88",
            "warehouse/t/base_10000002_v0000015/bucket_00000"},
    };
    checkExpected(rs, expected4,"after major compact");
  }
The idea here is to create a non acid table that was written by multiple writers, i.e.
unbucketed table that has 000000_0 & 000001_0, for example.
Also, checks that we can handle a case when data files can be at multiple levels (subdirs)
of the table.
ql/src/test/org/apache/hadoop/hive/ql/TestTxnNoBuckets.java