blob: 20a36c5bf5600a9996d4c3ef93b936645545fa70 [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.hcatalog.cli;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.hive.cli.CliSessionState;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.MetaStoreUtils;
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.ql.CommandNeedRetryException;
import org.apache.hadoop.hive.ql.Driver;
import org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat;
import org.apache.hadoop.hive.ql.io.RCFileInputFormat;
import org.apache.hadoop.hive.ql.io.RCFileOutputFormat;
import org.apache.hadoop.hive.ql.processors.CommandProcessorResponse;
import org.apache.hadoop.hive.ql.session.SessionState;
import org.apache.hadoop.mapred.TextInputFormat;
import org.apache.hcatalog.cli.SemanticAnalysis.HCatSemanticAnalyzer;
import org.apache.hcatalog.mapreduce.HCatBaseTest;
import org.apache.thrift.TException;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestSemanticAnalysis extends HCatBaseTest {
private static final Logger LOG = LoggerFactory.getLogger(TestSemanticAnalysis.class);
private static final String TBL_NAME = "junit_sem_analysis";
private Driver hcatDriver = null;
private String query;
@Before
public void setUpHCatDriver() throws IOException {
if (hcatDriver == null) {
HiveConf hcatConf = new HiveConf(hiveConf);
hcatConf.set(HiveConf.ConfVars.SEMANTIC_ANALYZER_HOOK.varname,
HCatSemanticAnalyzer.class.getName());
hcatDriver = new Driver(hcatConf);
SessionState.start(new CliSessionState(hcatConf));
}
}
@Test
public void testDescDB() throws CommandNeedRetryException, IOException {
hcatDriver.run("drop database mydb cascade");
assertEquals(0, hcatDriver.run("create database mydb").getResponseCode());
CommandProcessorResponse resp = hcatDriver.run("describe database mydb");
assertEquals(0, resp.getResponseCode());
ArrayList<String> result = new ArrayList<String>();
hcatDriver.getResults(result);
assertTrue(result.get(0).contains("mydb.db"));
hcatDriver.run("drop database mydb cascade");
}
@Test
public void testCreateTblWithLowerCasePartNames() throws CommandNeedRetryException, MetaException, TException, NoSuchObjectException {
driver.run("drop table junit_sem_analysis");
CommandProcessorResponse resp = driver.run("create table junit_sem_analysis (a int) partitioned by (B string) stored as TEXTFILE");
assertEquals(resp.getResponseCode(), 0);
assertEquals(null, resp.getErrorMessage());
Table tbl = client.getTable(MetaStoreUtils.DEFAULT_DATABASE_NAME, TBL_NAME);
assertEquals("Partition key name case problem", "b", tbl.getPartitionKeys().get(0).getName());
driver.run("drop table junit_sem_analysis");
}
@Test
public void testAlterTblFFpart() throws MetaException, TException, NoSuchObjectException, CommandNeedRetryException {
driver.run("drop table junit_sem_analysis");
driver.run("create table junit_sem_analysis (a int) partitioned by (b string) stored as TEXTFILE");
driver.run("alter table junit_sem_analysis add partition (b='2010-10-10')");
hcatDriver.run("alter table junit_sem_analysis partition (b='2010-10-10') set fileformat RCFILE");
Table tbl = client.getTable(MetaStoreUtils.DEFAULT_DATABASE_NAME, TBL_NAME);
assertEquals(TextInputFormat.class.getName(), tbl.getSd().getInputFormat());
assertEquals(HiveIgnoreKeyTextOutputFormat.class.getName(), tbl.getSd().getOutputFormat());
List<String> partVals = new ArrayList<String>(1);
partVals.add("2010-10-10");
Partition part = client.getPartition(MetaStoreUtils.DEFAULT_DATABASE_NAME, TBL_NAME, partVals);
assertEquals(RCFileInputFormat.class.getName(), part.getSd().getInputFormat());
assertEquals(RCFileOutputFormat.class.getName(), part.getSd().getOutputFormat());
hcatDriver.run("drop table junit_sem_analysis");
}
@Test
public void testUsNonExistentDB() throws CommandNeedRetryException {
CommandProcessorResponse resp = hcatDriver.run("use no_such_db");
assertEquals(1, resp.getResponseCode());
}
@Test
public void testDatabaseOperations() throws MetaException, CommandNeedRetryException {
List<String> dbs = client.getAllDatabases();
String testDb1 = "testdatabaseoperatons1";
String testDb2 = "testdatabaseoperatons2";
if (dbs.contains(testDb1.toLowerCase())) {
assertEquals(0, hcatDriver.run("drop database " + testDb1).getResponseCode());
}
if (dbs.contains(testDb2.toLowerCase())) {
assertEquals(0, hcatDriver.run("drop database " + testDb2).getResponseCode());
}
assertEquals(0, hcatDriver.run("create database " + testDb1).getResponseCode());
assertTrue(client.getAllDatabases().contains(testDb1));
assertEquals(0, hcatDriver.run("create database if not exists " + testDb1).getResponseCode());
assertTrue(client.getAllDatabases().contains(testDb1));
assertEquals(0, hcatDriver.run("create database if not exists " + testDb2).getResponseCode());
assertTrue(client.getAllDatabases().contains(testDb2));
assertEquals(0, hcatDriver.run("drop database " + testDb1).getResponseCode());
assertEquals(0, hcatDriver.run("drop database " + testDb2).getResponseCode());
assertFalse(client.getAllDatabases().contains(testDb1));
assertFalse(client.getAllDatabases().contains(testDb2));
}
@Test
public void testCreateTableIfNotExists() throws MetaException, TException, NoSuchObjectException, CommandNeedRetryException {
hcatDriver.run("drop table " + TBL_NAME);
hcatDriver.run("create table junit_sem_analysis (a int) stored as RCFILE");
Table tbl = client.getTable(MetaStoreUtils.DEFAULT_DATABASE_NAME, TBL_NAME);
List<FieldSchema> cols = tbl.getSd().getCols();
assertEquals(1, cols.size());
assertTrue(cols.get(0).equals(new FieldSchema("a", "int", null)));
assertEquals(RCFileInputFormat.class.getName(), tbl.getSd().getInputFormat());
assertEquals(RCFileOutputFormat.class.getName(), tbl.getSd().getOutputFormat());
CommandProcessorResponse resp = hcatDriver.run("create table if not exists junit_sem_analysis (a int) stored as RCFILE");
assertEquals(0, resp.getResponseCode());
assertNull(resp.getErrorMessage());
tbl = client.getTable(MetaStoreUtils.DEFAULT_DATABASE_NAME, TBL_NAME);
cols = tbl.getSd().getCols();
assertEquals(1, cols.size());
assertTrue(cols.get(0).equals(new FieldSchema("a", "int", null)));
assertEquals(RCFileInputFormat.class.getName(), tbl.getSd().getInputFormat());
assertEquals(RCFileOutputFormat.class.getName(), tbl.getSd().getOutputFormat());
hcatDriver.run("drop table junit_sem_analysis");
}
@Test
public void testAlterTblTouch() throws CommandNeedRetryException {
hcatDriver.run("drop table junit_sem_analysis");
hcatDriver.run("create table junit_sem_analysis (a int) partitioned by (b string) stored as RCFILE");
CommandProcessorResponse response = hcatDriver.run("alter table junit_sem_analysis touch");
assertEquals(0, response.getResponseCode());
hcatDriver.run("alter table junit_sem_analysis touch partition (b='12')");
assertEquals(0, response.getResponseCode());
hcatDriver.run("drop table junit_sem_analysis");
}
@Test
public void testChangeColumns() throws CommandNeedRetryException {
hcatDriver.run("drop table junit_sem_analysis");
hcatDriver.run("create table junit_sem_analysis (a int, c string) partitioned by (b string) stored as RCFILE");
CommandProcessorResponse response = hcatDriver.run("alter table junit_sem_analysis change a a1 int");
assertEquals(0, response.getResponseCode());
response = hcatDriver.run("alter table junit_sem_analysis change a1 a string");
assertEquals(0, response.getResponseCode());
response = hcatDriver.run("alter table junit_sem_analysis change a a int after c");
assertEquals(0, response.getResponseCode());
hcatDriver.run("drop table junit_sem_analysis");
}
@Test
public void testAddReplaceCols() throws IOException, MetaException, TException, NoSuchObjectException, CommandNeedRetryException {
hcatDriver.run("drop table junit_sem_analysis");
hcatDriver.run("create table junit_sem_analysis (a int, c string) partitioned by (b string) stored as RCFILE");
CommandProcessorResponse response = hcatDriver.run("alter table junit_sem_analysis replace columns (a1 tinyint)");
assertEquals(0, response.getResponseCode());
response = hcatDriver.run("alter table junit_sem_analysis add columns (d tinyint)");
assertEquals(0, response.getResponseCode());
assertNull(response.getErrorMessage());
response = hcatDriver.run("describe extended junit_sem_analysis");
assertEquals(0, response.getResponseCode());
Table tbl = client.getTable(MetaStoreUtils.DEFAULT_DATABASE_NAME, TBL_NAME);
List<FieldSchema> cols = tbl.getSd().getCols();
assertEquals(2, cols.size());
assertTrue(cols.get(0).equals(new FieldSchema("a1", "tinyint", null)));
assertTrue(cols.get(1).equals(new FieldSchema("d", "tinyint", null)));
hcatDriver.run("drop table junit_sem_analysis");
}
@Test
public void testAlterTblClusteredBy() throws CommandNeedRetryException {
hcatDriver.run("drop table junit_sem_analysis");
hcatDriver.run("create table junit_sem_analysis (a int) partitioned by (b string) stored as RCFILE");
CommandProcessorResponse response = hcatDriver.run("alter table junit_sem_analysis clustered by (a) into 7 buckets");
assertEquals(0, response.getResponseCode());
hcatDriver.run("drop table junit_sem_analysis");
}
@Test
public void testAlterTableSetFF() throws IOException, MetaException, TException, NoSuchObjectException, CommandNeedRetryException {
hcatDriver.run("drop table junit_sem_analysis");
hcatDriver.run("create table junit_sem_analysis (a int) partitioned by (b string) stored as RCFILE");
Table tbl = client.getTable(MetaStoreUtils.DEFAULT_DATABASE_NAME, TBL_NAME);
assertEquals(RCFileInputFormat.class.getName(), tbl.getSd().getInputFormat());
assertEquals(RCFileOutputFormat.class.getName(), tbl.getSd().getOutputFormat());
hcatDriver.run("alter table junit_sem_analysis set fileformat INPUTFORMAT 'org.apache.hadoop.hive.ql.io.RCFileInputFormat' OUTPUTFORMAT " +
"'org.apache.hadoop.hive.ql.io.RCFileOutputFormat' inputdriver 'mydriver' outputdriver 'yourdriver'");
hcatDriver.run("desc extended junit_sem_analysis");
tbl = client.getTable(MetaStoreUtils.DEFAULT_DATABASE_NAME, TBL_NAME);
assertEquals(RCFileInputFormat.class.getName(), tbl.getSd().getInputFormat());
assertEquals(RCFileOutputFormat.class.getName(), tbl.getSd().getOutputFormat());
hcatDriver.run("drop table junit_sem_analysis");
}
@Test
public void testAddPartFail() throws CommandNeedRetryException {
driver.run("drop table junit_sem_analysis");
driver.run("create table junit_sem_analysis (a int) partitioned by (b string) stored as RCFILE");
CommandProcessorResponse response = hcatDriver.run("alter table junit_sem_analysis add partition (b='2') location 'README.txt'");
assertEquals(0, response.getResponseCode());
driver.run("drop table junit_sem_analysis");
}
@Test
public void testAddPartPass() throws IOException, CommandNeedRetryException {
hcatDriver.run("drop table junit_sem_analysis");
hcatDriver.run("create table junit_sem_analysis (a int) partitioned by (b string) stored as RCFILE");
CommandProcessorResponse response = hcatDriver.run("alter table junit_sem_analysis add partition (b='2') location '" + TEST_DATA_DIR + "'");
assertEquals(0, response.getResponseCode());
assertNull(response.getErrorMessage());
hcatDriver.run("drop table junit_sem_analysis");
}
@Test
public void testCTAS() throws CommandNeedRetryException {
hcatDriver.run("drop table junit_sem_analysis");
query = "create table junit_sem_analysis (a int) as select * from tbl2";
CommandProcessorResponse response = hcatDriver.run(query);
assertEquals(40000, response.getResponseCode());
assertTrue(response.getErrorMessage().contains("FAILED: SemanticException Operation not supported. Create table as Select is not a valid operation."));
hcatDriver.run("drop table junit_sem_analysis");
}
@Test
public void testStoredAs() throws CommandNeedRetryException {
hcatDriver.run("drop table junit_sem_analysis");
query = "create table junit_sem_analysis (a int)";
CommandProcessorResponse response = hcatDriver.run(query);
assertEquals(0, response.getResponseCode());
hcatDriver.run("drop table junit_sem_analysis");
}
@Test
public void testAddDriverInfo() throws IOException, MetaException, TException, NoSuchObjectException, CommandNeedRetryException {
hcatDriver.run("drop table junit_sem_analysis");
query = "create table junit_sem_analysis (a int) partitioned by (b string) stored as " +
"INPUTFORMAT 'org.apache.hadoop.hive.ql.io.RCFileInputFormat' OUTPUTFORMAT " +
"'org.apache.hadoop.hive.ql.io.RCFileOutputFormat' inputdriver 'mydriver' outputdriver 'yourdriver' ";
assertEquals(0, hcatDriver.run(query).getResponseCode());
Table tbl = client.getTable(MetaStoreUtils.DEFAULT_DATABASE_NAME, TBL_NAME);
assertEquals(RCFileInputFormat.class.getName(), tbl.getSd().getInputFormat());
assertEquals(RCFileOutputFormat.class.getName(), tbl.getSd().getOutputFormat());
hcatDriver.run("drop table junit_sem_analysis");
}
@Test
public void testInvalidateNonStringPartition() throws IOException, CommandNeedRetryException {
hcatDriver.run("drop table junit_sem_analysis");
query = "create table junit_sem_analysis (a int) partitioned by (b int) stored as RCFILE";
CommandProcessorResponse response = hcatDriver.run(query);
assertEquals(40000, response.getResponseCode());
assertEquals("FAILED: SemanticException Operation not supported. HCatalog only supports partition columns of type string. For column: b Found type: int",
response.getErrorMessage());
}
@Test
public void testInvalidateSeqFileStoredAs() throws IOException, CommandNeedRetryException {
hcatDriver.run("drop table junit_sem_analysis");
query = "create table junit_sem_analysis (a int) partitioned by (b string) stored as SEQUENCEFILE";
CommandProcessorResponse response = hcatDriver.run(query);
assertEquals(0, response.getResponseCode());
}
@Test
public void testInvalidateTextFileStoredAs() throws IOException, CommandNeedRetryException {
hcatDriver.run("drop table junit_sem_analysis");
query = "create table junit_sem_analysis (a int) partitioned by (b string) stored as TEXTFILE";
CommandProcessorResponse response = hcatDriver.run(query);
assertEquals(0, response.getResponseCode());
}
@Test
public void testInvalidateClusteredBy() throws IOException, CommandNeedRetryException {
hcatDriver.run("drop table junit_sem_analysis");
query = "create table junit_sem_analysis (a int) partitioned by (b string) clustered by (a) into 10 buckets stored as TEXTFILE";
CommandProcessorResponse response = hcatDriver.run(query);
assertEquals(0, response.getResponseCode());
}
@Test
public void testCTLFail() throws IOException, CommandNeedRetryException {
driver.run("drop table junit_sem_analysis");
driver.run("drop table like_table");
query = "create table junit_sem_analysis (a int) partitioned by (b string) stored as RCFILE";
driver.run(query);
query = "create table like_table like junit_sem_analysis";
CommandProcessorResponse response = hcatDriver.run(query);
assertEquals(0, response.getResponseCode());
}
@Test
public void testCTLPass() throws IOException, MetaException, TException, NoSuchObjectException, CommandNeedRetryException {
try {
hcatDriver.run("drop table junit_sem_analysis");
} catch (Exception e) {
LOG.error("Error in drop table.", e);
}
query = "create table junit_sem_analysis (a int) partitioned by (b string) stored as RCFILE";
hcatDriver.run(query);
String likeTbl = "like_table";
hcatDriver.run("drop table " + likeTbl);
query = "create table like_table like junit_sem_analysis";
CommandProcessorResponse resp = hcatDriver.run(query);
assertEquals(0, resp.getResponseCode());
// Table tbl = client.getTable(MetaStoreUtils.DEFAULT_DATABASE_NAME, likeTbl);
// assertEquals(likeTbl,tbl.getTableName());
// List<FieldSchema> cols = tbl.getSd().getCols();
// assertEquals(1, cols.size());
// assertEquals(new FieldSchema("a", "int", null), cols.get(0));
// assertEquals("org.apache.hadoop.hive.ql.io.RCFileInputFormat",tbl.getSd().getInputFormat());
// assertEquals("org.apache.hadoop.hive.ql.io.RCFileOutputFormat",tbl.getSd().getOutputFormat());
// Map<String, String> tblParams = tbl.getParameters();
// assertEquals("org.apache.hadoop.hive.hcat.rcfile.RCFileInputStorageDriver", tblParams.get("hcat.isd"));
// assertEquals("org.apache.hadoop.hive.hcat.rcfile.RCFileOutputStorageDriver", tblParams.get("hcat.osd"));
//
// hcatDriver.run("drop table junit_sem_analysis");
// hcatDriver.run("drop table "+likeTbl);
}
// This test case currently fails, since add partitions don't inherit anything from tables.
// public void testAddPartInheritDrivers() throws MetaException, TException, NoSuchObjectException{
//
// hcatDriver.run("drop table "+TBL_NAME);
// hcatDriver.run("create table junit_sem_analysis (a int) partitioned by (b string) stored as RCFILE");
// hcatDriver.run("alter table "+TBL_NAME+" add partition (b='2010-10-10')");
//
// List<String> partVals = new ArrayList<String>(1);
// partVals.add("2010-10-10");
//
// Map<String,String> map = client.getPartition(MetaStoreUtils.DEFAULT_DATABASE_NAME, TBL_NAME, partVals).getParameters();
// assertEquals(map.get(InitializeInput.HOWL_ISD_CLASS), RCFileInputStorageDriver.class.getName());
// assertEquals(map.get(InitializeInput.HOWL_OSD_CLASS), RCFileOutputStorageDriver.class.getName());
// }
}