blob: 6844c5df1129e00a536920915ae0db6b6f754ce6 [file] [log] [blame]
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.ql.metadata;
import com.google.common.collect.Lists;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.Warehouse;
import org.apache.hadoop.hive.metastore.annotation.MetastoreCheckinTest;
import org.apache.hadoop.hive.metastore.api.FieldSchema;
import org.apache.hadoop.hive.metastore.api.MetaException;
import org.apache.hadoop.hive.metastore.api.Partition;
import org.apache.hadoop.hive.metastore.api.Table;
import org.apache.hadoop.hive.metastore.client.TestExchangePartitions;
import org.apache.hadoop.hive.metastore.client.builder.TableBuilder;
import org.apache.hadoop.hive.metastore.minihms.AbstractMetaStoreService;
import org.apache.hadoop.hive.ql.session.SessionState;
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.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Test class for exchange partitions related methods on temporary tables.
*/
@RunWith(Parameterized.class)
@Category(MetastoreCheckinTest.class)
public class TestSessionHiveMetastoreClientExchangePartitionsTempTable extends TestExchangePartitions {
private HiveConf conf;
private Warehouse wh;
public TestSessionHiveMetastoreClientExchangePartitionsTempTable(String name, AbstractMetaStoreService metaStore) {
super(name, metaStore);
}
@Before
@Override
public void setUp() throws Exception {
initHiveConf();
wh = new Warehouse(conf);
SessionState.start(conf);
setClient(Hive.get(conf).getMSC());
getClient().dropDatabase(DB_NAME, true, true, true);
getMetaStore().cleanWarehouseDirs();
createTestTables();
}
private void initHiveConf() throws Exception{
conf = Hive.get().getConf();
conf.setBoolVar(HiveConf.ConfVars.METASTORE_FASTPATH, true);
}
@Override
protected Table createTable(String dbName, String tableName, List<FieldSchema> partCols,
List<FieldSchema> cols, String location) throws Exception {
new TableBuilder()
.setDbName(dbName)
.setTableName(tableName)
.setCols(cols)
.setPartCols(partCols)
.setLocation(location)
.setTemporary(true)
.create(getClient(), getMetaStore().getConf());
return getClient().getTable(dbName, tableName);
}
@Override
@Test(expected = MetaException.class)
public void testExchangePartitionsNonExistingPartLocation() throws Exception {
Map<String, String> partitionSpecs = getPartitionSpec(getPartitions()[1]);
getMetaStore().cleanWarehouseDirs();
cleanTempTableDir(getSourceTable());
cleanTempTableDir(getDestTable());
getClient().exchange_partitions(partitionSpecs, getSourceTable().getDbName(),
getSourceTable().getTableName(), getDestTable().getDbName(), getDestTable().getTableName());
}
@Override
@Test
public void testExchangePartitionsCustomTableAndPartLocation() throws Exception {
Table source = createTable(DB_NAME, "test_source_table_cust_loc",
getYearMonthAndDayPartCols(), getMetaStore().getWarehouseRoot() + "/sourceTable");
Table dest = createTable(DB_NAME, "test_dest_table_cust_loc", getYearMonthAndDayPartCols(),
getMetaStore().getWarehouseRoot() + "/destTable");
org.apache.hadoop.hive.metastore.api.Partition[] parts = new Partition[2];
parts[0] = createPartition(source, Lists.newArrayList("2019", "may", "11"),
source.getSd().getLocation() + "/2019m11");
parts[1] = createPartition(source, Lists.newArrayList("2019", "july", "23"),
source.getSd().getLocation() + "/2019j23");
Map<String, String> partitionSpecs = getPartitionSpec(parts[1]);
getClient().exchange_partitions(partitionSpecs, source.getDbName(),
source.getTableName(), dest.getDbName(), dest.getTableName());
checkRemainingPartitions(source, dest, Lists.newArrayList(parts[0]));
List<Partition> destTablePartitions = getClient().listPartitions(dest.getDbName(), dest.getTableName(), (short) -1);
Assert.assertEquals(1, destTablePartitions.size());
checkExchangedPartitions(source, dest, Lists.newArrayList(parts[1]));
}
@Override
@Test
public void testExchangePartitionsCustomPartLocation() throws Exception {
Table source = createTable(DB_NAME, "test_source_table", getYearMonthAndDayPartCols(), null);
Table dest = createTable(DB_NAME, "test_dest_table", getYearMonthAndDayPartCols(), null);
Partition[] parts = new Partition[2];
parts[0] = createPartition(source, Lists.newArrayList("2019", "march", "15"),
source.getSd().getLocation() + "/2019m15");
parts[1] = createPartition(source, Lists.newArrayList("2019", "march", "22"),
source.getSd().getLocation() + "/2019m22");
Map<String, String> partitionSpecs = getPartitionSpec(parts[1]);
getClient().exchange_partitions(partitionSpecs, source.getDbName(),
source.getTableName(), dest.getDbName(), dest.getTableName());
checkRemainingPartitions(source, dest, Lists.newArrayList(parts[0]));
List<Partition> destTablePartitions = getClient().listPartitions(dest.getDbName(), dest.getTableName(), (short) -1);
Assert.assertEquals(1, destTablePartitions.size());
checkExchangedPartitions(source, dest, Lists.newArrayList(parts[1]));
}
@Override
@Test
public void testExchangePartitionsOnlyMonthSetInPartSpec() throws Exception {
Map<String, String> partitionSpecs = new HashMap<>();
partitionSpecs.put(YEAR_COL_NAME, "");
partitionSpecs.put(MONTH_COL_NAME, "march");
partitionSpecs.put(DAY_COL_NAME, "");
getClient().exchange_partitions(partitionSpecs, getSourceTable().getDbName(),
getSourceTable().getTableName(), getDestTable().getDbName(), getDestTable().getTableName());
checkRemainingPartitions(getSourceTable(), getDestTable(), Lists.newArrayList(getPartitions()[2],
getPartitions()[3], getPartitions()[4]));
List<Partition> exchangedPartitions = getClient().listPartitions(getDestTable().getDbName(),
getDestTable().getTableName(), MAX);
Assert.assertEquals(2, exchangedPartitions.size());
checkExchangedPartitions(getSourceTable(), getDestTable(), Lists.newArrayList(getPartitions()[0],
getPartitions()[1]));
}
@Override
@Test
public void testExchangePartitionsYearAndDaySetInPartSpec() throws Exception {
Map<String, String> partitionSpecs = new HashMap<>();
partitionSpecs.put(YEAR_COL_NAME, "2017");
partitionSpecs.put(MONTH_COL_NAME, "");
partitionSpecs.put(DAY_COL_NAME, "22");
getClient().exchange_partitions(partitionSpecs, getSourceTable().getDbName(),
getSourceTable().getTableName(), getDestTable().getDbName(), getDestTable().getTableName());
checkRemainingPartitions(getSourceTable(), getDestTable(), Lists.newArrayList(getPartitions()[0],
getPartitions()[2], getPartitions()[3], getPartitions()[4]));
List<Partition> exchangedPartitions = getClient().listPartitions(getDestTable().getDbName(),
getDestTable().getTableName(), MAX);
Assert.assertEquals(1, exchangedPartitions.size());
checkExchangedPartitions(getSourceTable(), getDestTable(), Lists.newArrayList(getPartitions()[1]));
}
@Override
@Test
public void testExchangePartition() throws Exception {
Map<String, String> partitionSpecs = getPartitionSpec(getPartitions()[1]);
Partition exchangedPartition =
getClient().exchange_partition(partitionSpecs, getSourceTable().getDbName(),
getSourceTable().getTableName(), getDestTable().getDbName(), getDestTable().getTableName());
Assert.assertNotNull(exchangedPartition);
checkExchangedPartitions(getSourceTable(), getDestTable(), Lists.newArrayList(getPartitions()[1]));
checkRemainingPartitions(getSourceTable(), getDestTable(),
Lists.newArrayList(getPartitions()[0], getPartitions()[2], getPartitions()[3], getPartitions()[4]));
}
@Override
@Test
public void testExchangePartitionYearSet() throws Exception {
Map<String, String> partitionSpecs = getPartitionSpec(Lists.newArrayList("2017", "", ""));
Partition exchangedPartition =
getClient().exchange_partition(partitionSpecs, getSourceTable().getDbName(),
getSourceTable().getTableName(), getDestTable().getDbName(), getDestTable().getTableName());
Assert.assertNotNull(exchangedPartition);
checkExchangedPartitions(getSourceTable(), getDestTable(),
Lists.newArrayList(getPartitions()[0], getPartitions()[1], getPartitions()[2], getPartitions()[3]));
checkRemainingPartitions(getSourceTable(), getDestTable(), Lists.newArrayList(getPartitions()[4]));
}
@Override
@Test
public void testExchangePartitionCustomTableAndPartLocation() throws Exception {
Table source = createTable(DB_NAME, "test_source_table_cust_loc",
getYearMonthAndDayPartCols(), getMetaStore().getWarehouseRoot() + "/sourceTable");
Table dest = createTable(DB_NAME, "test_dest_table_cust_loc", getYearMonthAndDayPartCols(),
getMetaStore().getWarehouseRoot() + "/destTable");
Partition[] parts = new Partition[2];
parts[0] = createPartition(source, Lists.newArrayList("2019", "may", "11"),
source.getSd().getLocation() + "/2019m11");
parts[1] = createPartition(source, Lists.newArrayList("2019", "july", "23"),
source.getSd().getLocation() + "/2019j23");
Map<String, String> partitionSpecs = getPartitionSpec(parts[1]);
getClient().exchange_partition(partitionSpecs, source.getDbName(),
source.getTableName(), dest.getDbName(), dest.getTableName());
checkRemainingPartitions(source, dest, Lists.newArrayList(parts[0]));
List<Partition> destTablePartitions =
getClient().listPartitions(dest.getDbName(), dest.getTableName(), (short) -1);
Assert.assertEquals(1, destTablePartitions.size());
checkExchangedPartitions(source, dest, Lists.newArrayList(parts[1]));
}
@Override
@Test
public void testExchangePartitionCustomPartLocation() throws Exception {
Table source = createTable(DB_NAME, "test_source_table", getYearMonthAndDayPartCols(), null);
Table dest = createTable(DB_NAME, "test_dest_table", getYearMonthAndDayPartCols(), null);
Partition[] parts = new Partition[2];
parts[0] = createPartition(source, Lists.newArrayList("2019", "march", "15"),
source.getSd().getLocation() + "/2019m15");
parts[1] = createPartition(source, Lists.newArrayList("2019", "march", "22"),
source.getSd().getLocation() + "/2019m22");
Map<String, String> partitionSpecs = getPartitionSpec(parts[1]);
getClient().exchange_partition(partitionSpecs, source.getDbName(),
source.getTableName(), dest.getDbName(), dest.getTableName());
checkRemainingPartitions(source, dest, Lists.newArrayList(parts[0]));
List<Partition> destTablePartitions =
getClient().listPartitions(dest.getDbName(), dest.getTableName(), (short) -1);
Assert.assertEquals(1, destTablePartitions.size());
checkExchangedPartitions(source, dest, Lists.newArrayList(parts[1]));
}
@Override
@Test(expected = MetaException.class)
public void testExchangePartitionNonExistingPartLocation() throws Exception {
Map<String, String> partitionSpecs = getPartitionSpec(getPartitions()[1]);
cleanTempTableDir(getSourceTable());
cleanTempTableDir(getDestTable());
getClient().exchange_partition(partitionSpecs, getSourceTable().getDbName(),
getSourceTable().getTableName(), getDestTable().getDbName(), getDestTable().getTableName());
}
@Override
@Test
public void testExchangePartitionOnlyMonthSetInPartSpec() throws Exception {
Map<String, String> partitionSpecs = new HashMap<>();
partitionSpecs.put(YEAR_COL_NAME, "");
partitionSpecs.put(MONTH_COL_NAME, "march");
partitionSpecs.put(DAY_COL_NAME, "");
getClient().exchange_partitions(partitionSpecs, getSourceTable().getDbName(),
getSourceTable().getTableName(), getDestTable().getDbName(), getDestTable().getTableName());
checkRemainingPartitions(getSourceTable(), getDestTable(),
Lists.newArrayList(getPartitions()[2], getPartitions()[3], getPartitions()[4]));
List<Partition> exchangedPartitions = getClient().listPartitions(getDestTable().getDbName(),
getDestTable().getTableName(), MAX);
Assert.assertEquals(2, exchangedPartitions.size());
checkExchangedPartitions(getSourceTable(), getDestTable(),
Lists.newArrayList(getPartitions()[0], getPartitions()[1]));
}
@Override
@Test
public void testExchangePartitionYearAndDaySetInPartSpec() throws Exception {
Map<String, String> partitionSpecs = new HashMap<>();
partitionSpecs.put(YEAR_COL_NAME, "2017");
partitionSpecs.put(MONTH_COL_NAME, "");
partitionSpecs.put(DAY_COL_NAME, "22");
getClient().exchange_partition(partitionSpecs, getSourceTable().getDbName(),
getSourceTable().getTableName(), getDestTable().getDbName(), getDestTable().getTableName());
checkRemainingPartitions(getSourceTable(), getDestTable(),
Lists.newArrayList(getPartitions()[0], getPartitions()[2], getPartitions()[3], getPartitions()[4]));
List<Partition> exchangedPartitions = getClient().listPartitions(getDestTable().getDbName(),
getDestTable().getTableName(), MAX);
Assert.assertEquals(1, exchangedPartitions.size());
checkExchangedPartitions(getSourceTable(), getDestTable(), Lists.newArrayList(getPartitions()[1]));
}
@Test(expected = MetaException.class)
public void testExchangePartitionBetweenTempAndNonTemp() throws Exception {
Table nonTempTable = createNonTempTable(DB_NAME, "nonTempTable", getYearMonthAndDayPartCols(), null);
Map<String, String> partitionSpecs = new HashMap<>();
partitionSpecs.put(YEAR_COL_NAME, "2017");
partitionSpecs.put(MONTH_COL_NAME, "march");
partitionSpecs.put(DAY_COL_NAME, "22");
getClient().exchange_partition(partitionSpecs, getSourceTable().getDbName(), getSourceTable().getTableName(),
nonTempTable.getDbName(), nonTempTable.getTableName());
}
@Test(expected = MetaException.class)
public void testExchangePartitionBetweenNonTempAndTemp() throws Exception {
Table nonTempTable = createNonTempTable(DB_NAME, "nonTempTable", getYearMonthAndDayPartCols(), null);
Map<String, String> partitionSpecs = new HashMap<>();
partitionSpecs.put(YEAR_COL_NAME, "2017");
partitionSpecs.put(MONTH_COL_NAME, "march");
partitionSpecs.put(DAY_COL_NAME, "22");
getClient().exchange_partition(partitionSpecs, nonTempTable.getDbName(), nonTempTable.getTableName(),
getDestTable().getDbName(), getDestTable().getTableName());
}
@Test(expected = MetaException.class)
public void testExchangePartitionsBetweenTempAndNonTemp() throws Exception {
Table nonTempTable = createNonTempTable(DB_NAME, "nonTempTable", getYearMonthAndDayPartCols(), null);
Map<String, String> partitionSpecs = new HashMap<>();
partitionSpecs.put(YEAR_COL_NAME, "2017");
partitionSpecs.put(MONTH_COL_NAME, "");
partitionSpecs.put(DAY_COL_NAME, "23");
getClient().exchange_partitions(partitionSpecs, getSourceTable().getDbName(), getSourceTable().getTableName(),
nonTempTable.getDbName(), nonTempTable.getTableName());
}
@Test(expected = MetaException.class)
public void testExchangePartitionsBetweenNonTempAndTemp() throws Exception {
Table nonTempTable = createNonTempTable(DB_NAME, "nonTempTable", getYearMonthAndDayPartCols(), null);
Map<String, String> partitionSpecs = new HashMap<>();
partitionSpecs.put(YEAR_COL_NAME, "2017");
partitionSpecs.put(MONTH_COL_NAME, "");
partitionSpecs.put(DAY_COL_NAME, "23");
getClient().exchange_partitions(partitionSpecs, nonTempTable.getDbName(), nonTempTable.getTableName(),
getDestTable().getDbName(), getDestTable().getTableName());
}
private Table createNonTempTable(String dbName, String tableName, List<FieldSchema> partCols,
String location) throws Exception {
List<FieldSchema> cols = new ArrayList<>();
cols.add(new FieldSchema("test_id", INT_COL_TYPE, "test col id"));
cols.add(new FieldSchema("test_value", "string", "test col value"));
new TableBuilder()
.setDbName(dbName)
.setTableName(tableName)
.setCols(cols)
.setPartCols(partCols)
.setLocation(location)
.setTemporary(false)
.create(getClient(), getMetaStore().getConf());
return getClient().getTable(dbName, tableName);
}
private void cleanTempTableDir(Table table) throws MetaException {
wh.deleteDir(new Path(table.getSd().getLocation()), true, false, false);
}
}