@Test
  public void testColumnStatistics() throws Throwable {

    String dbName = "columnstatstestdb";
    String tblName = "tbl";
    String typeName = "Person";
    String tblOwner = "testowner";
    int lastAccessed = 6796;

    try {
      cleanUp(dbName, tblName, typeName);
      new DatabaseBuilder()
          .setName(dbName)
          .create(client, conf);
      createTableForTestFilter(dbName, tblName, tblOwner, lastAccessed, true);

      // Create a ColumnStatistics Obj
      String[] colName = new String[]{"income", "name"};
      double lowValue = 50000.21;
      double highValue = 1200000.4525;
      long numNulls = 3;
      long numDVs = 22;
      double avgColLen = 50.30;
      long maxColLen = 102;
      String[] colType = new String[] {"double", "string"};
      boolean isTblLevel = true;
      String partName = null;
      List<ColumnStatisticsObj> statsObjs = new ArrayList<>();

      ColumnStatisticsDesc statsDesc = new ColumnStatisticsDesc();
      statsDesc.setDbName(dbName);
      statsDesc.setTableName(tblName);
      statsDesc.setIsTblLevel(isTblLevel);
      statsDesc.setPartName(partName);

      ColumnStatisticsObj statsObj = new ColumnStatisticsObj();
      statsObj.setColName(colName[0]);
      statsObj.setColType(colType[0]);

      ColumnStatisticsData statsData = new ColumnStatisticsData();
      DoubleColumnStatsData numericStats = new DoubleColumnStatsData();
      statsData.setDoubleStats(numericStats);

      statsData.getDoubleStats().setHighValue(highValue);
      statsData.getDoubleStats().setLowValue(lowValue);
      statsData.getDoubleStats().setNumDVs(numDVs);
      statsData.getDoubleStats().setNumNulls(numNulls);

      statsObj.setStatsData(statsData);
      statsObjs.add(statsObj);

      statsObj = new ColumnStatisticsObj();
      statsObj.setColName(colName[1]);
      statsObj.setColType(colType[1]);

      statsData = new ColumnStatisticsData();
      StringColumnStatsData stringStats = new StringColumnStatsData();
      statsData.setStringStats(stringStats);
      statsData.getStringStats().setAvgColLen(avgColLen);
      statsData.getStringStats().setMaxColLen(maxColLen);
      statsData.getStringStats().setNumDVs(numDVs);
      statsData.getStringStats().setNumNulls(numNulls);

      statsObj.setStatsData(statsData);
      statsObjs.add(statsObj);

      ColumnStatistics colStats = new ColumnStatistics();
      colStats.setStatsDesc(statsDesc);
      colStats.setStatsObj(statsObjs);
      colStats.setEngine(ENGINE);

      // write stats objs persistently
      client.updateTableColumnStatistics(colStats);

      // retrieve the stats obj that was just written
      ColumnStatisticsObj colStats2 = client.getTableColumnStatistics(
          dbName, tblName, Lists.newArrayList(colName[0]), ENGINE).get(0);

     // compare stats obj to ensure what we get is what we wrote
      assertNotNull(colStats2);
      assertEquals(colStats2.getColName(), colName[0]);
      assertEquals(colStats2.getStatsData().getDoubleStats().getLowValue(), lowValue, 0.01);
      assertEquals(colStats2.getStatsData().getDoubleStats().getHighValue(), highValue, 0.01);
      assertEquals(colStats2.getStatsData().getDoubleStats().getNumNulls(), numNulls);
      assertEquals(colStats2.getStatsData().getDoubleStats().getNumDVs(), numDVs);

      // test delete column stats; if no col name is passed all column stats associated with the
      // table is deleted
      boolean status = client.deleteTableColumnStatistics(dbName, tblName, null, ENGINE);
      assertTrue(status);
      // try to query stats for a column for which stats doesn't exist
      List<ColumnStatisticsObj> stats = client.getTableColumnStatistics(
          dbName, tblName, Lists.newArrayList(colName[1]), ENGINE);
      assertTrue("stats are not empty: " + stats, stats.isEmpty());

      colStats.setStatsDesc(statsDesc);
      colStats.setStatsObj(statsObjs);

      // update table level column stats
      client.updateTableColumnStatistics(colStats);

      // query column stats for column whose stats were updated in the previous call
      List<ColumnStatisticsObj> colStats3 = client.getTableColumnStatistics(
          dbName, tblName, Lists.newArrayList(colName), ENGINE);
      assertEquals(2, colStats3.size());
      DeleteColumnStatisticsRequest request = new DeleteColumnStatisticsRequest(dbName, tblName);
      request.setTableLevel(true);
      request.setEngine(ENGINE);
      // multiple columns
      request.setCol_names(Arrays.asList(colName));
      assertTrue(client.deleteColumnStatistics(request));
      colStats3 = client.getTableColumnStatistics(
          dbName, tblName, Lists.newArrayList(colName), ENGINE);
      assertTrue("stats are not empty: " + colStats3, colStats3.isEmpty());

      // partition level column statistics test
      // create a table with multiple partitions
      cleanUp(dbName, tblName, typeName);

      List<List<String>> values = new ArrayList<>();
      values.add(makeVals("2008-07-01 14:13:12", "14"));
      values.add(makeVals("2008-07-01 14:13:12", "15"));
      values.add(makeVals("2008-07-02 14:13:12", "15"));
      values.add(makeVals("2008-07-03 14:13:12", "151"));

      createMultiPartitionTableSchema(dbName, tblName, typeName, values);

      List<String> partitions = client.listPartitionNames(dbName, tblName, (short)-1);

      partName = partitions.get(0);
      isTblLevel = false;

      // create a new columnstatistics desc to represent partition level column stats
      statsDesc = new ColumnStatisticsDesc();
      statsDesc.setDbName(dbName);
      statsDesc.setTableName(tblName);
      statsDesc.setPartName(partName);
      statsDesc.setIsTblLevel(isTblLevel);

      colStats = new ColumnStatistics();
      colStats.setStatsDesc(statsDesc);
      colStats.setStatsObj(statsObjs);
      colStats.setEngine(ENGINE);

     client.updatePartitionColumnStatistics(colStats);

     colStats2 = client.getPartitionColumnStatistics(dbName, tblName,
         Lists.newArrayList(partName), Lists.newArrayList(colName[1]), ENGINE).get(partName).get(0);

     // compare stats obj to ensure what we get is what we wrote
     assertNotNull(colStats2);
     assertEquals(colStats.getStatsDesc().getPartName(), partName);
     assertEquals(colStats2.getColName(), colName[1]);
     assertEquals(colStats2.getStatsData().getStringStats().getMaxColLen(), maxColLen);
     assertEquals(colStats2.getStatsData().getStringStats().getAvgColLen(), avgColLen, 0.01);
     assertEquals(colStats2.getStatsData().getStringStats().getNumNulls(), numNulls);
     assertEquals(colStats2.getStatsData().getStringStats().getNumDVs(), numDVs);

     // test stats deletion at partition level
     client.deletePartitionColumnStatistics(dbName, tblName, partName, colName[1], ENGINE);

     colStats2 = client.getPartitionColumnStatistics(dbName, tblName,
         Lists.newArrayList(partName), Lists.newArrayList(colName[0]), ENGINE).get(partName).get(0);

     // test get stats on a column for which stats doesn't exist
     Map<String, List<ColumnStatisticsObj>> stats2 = client.getPartitionColumnStatistics(dbName, tblName,
         Lists.newArrayList(partName), Lists.newArrayList(colName[1]), ENGINE);
     assertTrue("stats are not empty: " + stats2, stats2.isEmpty());

     request.setTableLevel(false);
     request.setCol_names(Arrays.asList(colName));
     request.addToPart_names(partName);
     // no column name set
     request.unsetCol_names();
     assertTrue(client.deleteColumnStatistics(request));
     stats2 = client.getPartitionColumnStatistics(dbName, tblName,
          Lists.newArrayList(partName), Lists.newArrayList(colName), ENGINE);
     assertTrue("stats are not empty: " + stats2, stats2.isEmpty());

     client.updatePartitionColumnStatistics(colStats);
     ColumnStatistics colStats1 = new ColumnStatistics(colStats);
     colStats1.getStatsDesc().setPartName(partitions.get(1));
     client.updatePartitionColumnStatistics(colStats1);
     colStats1 = new ColumnStatistics(colStats);
     colStats1.getStatsDesc().setPartName(partitions.get(2));
     client.updatePartitionColumnStatistics(colStats1);

     request.unsetPart_names();
     request.setPart_names(Arrays.asList(partitions.get(0), partitions.get(1)));
     request.setCol_names(Arrays.asList(colName[0]));
     assertTrue(client.deleteColumnStatistics(request));
     stats2 = client.getPartitionColumnStatistics(dbName, tblName,
         Lists.newArrayList(partitions.get(0), partitions.get(1), partitions.get(2)), Lists.newArrayList(colName), ENGINE);
     assertEquals(1, stats2.get(partitions.get(0)).size());
     assertEquals(colName[1], stats2.get(partitions.get(0)).get(0).getColName());
     assertEquals(1, stats2.get(partitions.get(1)).size());
     assertEquals(colName[1], stats2.get(partitions.get(1)).get(0).getColName());
     assertEquals(2, stats2.get(partitions.get(2)).size());

     // no column
     request.unsetCol_names();
     assertTrue(client.deleteColumnStatistics(request));
     stats2 = client.getPartitionColumnStatistics(dbName, tblName,
          Lists.newArrayList(partitions.get(0), partitions.get(1), partitions.get(2)), Lists.newArrayList(colName), ENGINE);
     assertEquals(1, stats2.size());
     assertEquals(2, stats2.get(partitions.get(2)).size());

     // no partition or column name is set
     request.unsetPart_names();
     client.updatePartitionColumnStatistics(colStats);
     assertTrue(client.deleteColumnStatistics(request));
     stats2 = client.getPartitionColumnStatistics(dbName, tblName,
          Lists.newArrayList(partitions), Lists.newArrayList(colName), ENGINE);
     assertTrue("stats are not empty: " + stats2, stats2.isEmpty());
    } catch (Exception e) {
      System.err.println(StringUtils.stringifyException(e));
      System.err.println("testColumnStatistics() failed.");
      throw e;
    } finally {
      cleanUp(dbName, tblName, typeName);
    }
  }
tests create table and partition and tries to drop the table without
droppping the partition
standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestHiveMetaStore.java