You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by zs...@apache.org on 2010/01/21 08:31:27 UTC

svn commit: r901581 [7/10] - in /hadoop/hive/trunk: ./ cli/src/java/org/apache/hadoop/hive/cli/ common/src/java/org/apache/hadoop/hive/common/ common/src/java/org/apache/hadoop/hive/common/io/ contrib/src/java/org/apache/hadoop/hive/contrib/fileformat/...

Modified: hadoop/hive/trunk/jdbc/src/test/org/apache/hadoop/hive/jdbc/TestJdbcDriver.java
URL: http://svn.apache.org/viewvc/hadoop/hive/trunk/jdbc/src/test/org/apache/hadoop/hive/jdbc/TestJdbcDriver.java?rev=901581&r1=901580&r2=901581&view=diff
==============================================================================
--- hadoop/hive/trunk/jdbc/src/test/org/apache/hadoop/hive/jdbc/TestJdbcDriver.java (original)
+++ hadoop/hive/trunk/jdbc/src/test/org/apache/hadoop/hive/jdbc/TestJdbcDriver.java Thu Jan 21 07:29:29 2010
@@ -18,16 +18,18 @@
 
 package org.apache.hadoop.hive.jdbc;
 
-import java.sql.SQLException;
 import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.Statement;
-import java.sql.DriverManager;
 import java.sql.DatabaseMetaData;
+import java.sql.DriverManager;
 import java.sql.DriverPropertyInfo;
+import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
 import java.sql.Types;
+
 import junit.framework.TestCase;
+
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hive.conf.HiveConf;
 
@@ -35,17 +37,19 @@
   private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";
   private static String tableName = "testHiveDriverTable";
   private static String partitionedTableName = "testHiveDriverPartitionedTable";
-  private HiveConf conf;
-  private Path dataFilePath;
+  private final HiveConf conf;
+  private final Path dataFilePath;
   private Connection con;
   private boolean standAloneServer = false;
 
   public TestJdbcDriver(String name) {
     super(name);
     conf = new HiveConf(TestJdbcDriver.class);
-    String dataFileDir = conf.get("test.data.files").replace('\\', '/').replace("c:", "");
+    String dataFileDir = conf.get("test.data.files").replace('\\', '/')
+        .replace("c:", "");
     dataFilePath = new Path(dataFileDir, "kv1.txt");
-    standAloneServer = "true".equals(System.getProperty("test.service.standalone.server"));
+    standAloneServer = "true".equals(System
+        .getProperty("test.service.standalone.server"));
   }
 
   protected void setUp() throws Exception {
@@ -53,9 +57,9 @@
     Class.forName(driverName);
     if (standAloneServer) {
       // get connection
-      con = DriverManager.getConnection("jdbc:hive://localhost:10000/default", "", "");
-    }
-    else {
+      con = DriverManager.getConnection("jdbc:hive://localhost:10000/default",
+          "", "");
+    } else {
       con = DriverManager.getConnection("jdbc:hive://", "", "");
     }
     assertNotNull("Connection is null", con);
@@ -70,11 +74,13 @@
     }
 
     // create table
-    ResultSet res = stmt.executeQuery("create table " + tableName + " (key int, value string)");
+    ResultSet res = stmt.executeQuery("create table " + tableName
+        + " (key int, value string)");
     assertFalse(res.next());
 
     // load data
-    res = stmt.executeQuery("load data local inpath '" + dataFilePath.toString() + "' into table " + tableName);
+    res = stmt.executeQuery("load data local inpath '"
+        + dataFilePath.toString() + "' into table " + tableName);
     assertFalse(res.next());
 
     // also initialize a paritioned table to test against.
@@ -85,14 +91,14 @@
     } catch (Exception ex) {
     }
 
-    res = stmt.executeQuery("create table " + partitionedTableName +
-                            " (key int, value string) partitioned by (dt STRING)");
+    res = stmt.executeQuery("create table " + partitionedTableName
+        + " (key int, value string) partitioned by (dt STRING)");
     assertFalse(res.next());
 
     // load data
-    res = stmt.executeQuery("load data local inpath '" + dataFilePath.toString() +
-                            "' into table " + partitionedTableName +
-                            " PARTITION (dt='20090619')");
+    res = stmt.executeQuery("load data local inpath '"
+        + dataFilePath.toString() + "' into table " + partitionedTableName
+        + " PARTITION (dt='20090619')");
     assertFalse(res.next());
 
   }
@@ -114,38 +120,44 @@
     Exception expectedException = null;
     try {
       con.createStatement();
-    }
-    catch(Exception e) {
+    } catch (Exception e) {
       expectedException = e;
     }
-    
-    assertNotNull("createStatement() on closed connection should throw exception",
-                  expectedException);
+
+    assertNotNull(
+        "createStatement() on closed connection should throw exception",
+        expectedException);
   }
 
   public final void testSelectAll() throws Exception {
-    doTestSelectAll(this.tableName, -1); // tests not setting maxRows  (return all)
-    doTestSelectAll(this.tableName, 0);  // tests setting maxRows to 0 (return all)
+    doTestSelectAll(tableName, -1); // tests not setting maxRows (return all)
+    doTestSelectAll(tableName, 0); // tests setting maxRows to 0 (return all)
   }
 
   public final void testSelectAllPartioned() throws Exception {
-    doTestSelectAll(this.partitionedTableName, -1); // tests not setting maxRows  (return all)
-    doTestSelectAll(this.partitionedTableName, 0);  // tests setting maxRows to 0 (return all)
+    doTestSelectAll(partitionedTableName, -1); // tests not setting maxRows
+                                               // (return all)
+    doTestSelectAll(partitionedTableName, 0); // tests setting maxRows to 0
+                                              // (return all)
   }
 
   public final void testSelectAllMaxRows() throws Exception {
-    doTestSelectAll(this.tableName, 100);
+    doTestSelectAll(tableName, 100);
   }
 
-  private final void doTestSelectAll(String tableName, int maxRows) throws Exception {
+  private final void doTestSelectAll(String tableName, int maxRows)
+      throws Exception {
     Statement stmt = con.createStatement();
-    if (maxRows >= 0) stmt.setMaxRows(maxRows);
+    if (maxRows >= 0) {
+      stmt.setMaxRows(maxRows);
+    }
 
-    //JDBC says that 0 means return all, which is the default
+    // JDBC says that 0 means return all, which is the default
     int expectedMaxRows = maxRows < 1 ? 0 : maxRows;
 
     assertNotNull("Statement is null", stmt);
-    assertEquals("Statement max rows not as expected", expectedMaxRows, stmt.getMaxRows());
+    assertEquals("Statement max rows not as expected", expectedMaxRows, stmt
+        .getMaxRows());
     assertFalse("Statement should not be closed", stmt.isClosed());
 
     ResultSet res;
@@ -153,7 +165,8 @@
     // run some queries
     res = stmt.executeQuery("select * from " + tableName);
     assertNotNull("ResultSet is null", res);
-    assertTrue("getResultSet() not returning expected ResultSet", res == stmt.getResultSet());
+    assertTrue("getResultSet() not returning expected ResultSet", res == stmt
+        .getResultSet());
     assertEquals("get update count not as expected", 0, stmt.getUpdateCount());
     int i = 0;
 
@@ -165,17 +178,18 @@
         res.getString(1);
         res.getString(2);
         assertFalse("Last result value was not null", res.wasNull());
-        assertNull("No warnings should be found on ResultSet", res.getWarnings());
-        res.clearWarnings(); //verifying that method is supported
-        
-        //System.out.println(res.getString(1) + " " + res.getString(2));
-        assertEquals("getInt and getString don't align for the same result value",
-                String.valueOf(res.getInt(1)), res.getString(1));
-        assertEquals("Unexpected result found",
-                "val_" + res.getString(1), res.getString(2));
+        assertNull("No warnings should be found on ResultSet", res
+            .getWarnings());
+        res.clearWarnings(); // verifying that method is supported
+
+        // System.out.println(res.getString(1) + " " + res.getString(2));
+        assertEquals(
+            "getInt and getString don't align for the same result value",
+            String.valueOf(res.getInt(1)), res.getString(1));
+        assertEquals("Unexpected result found", "val_" + res.getString(1), res
+            .getString(2));
         moreRow = res.next();
-      }
-      catch (SQLException e) {
+      } catch (SQLException e) {
         System.out.println(e.toString());
         e.printStackTrace();
         throw new Exception(e.toString());
@@ -190,10 +204,10 @@
     assertEquals(false, moreRow);
 
     assertNull("No warnings should be found on statement", stmt.getWarnings());
-    stmt.clearWarnings(); //verifying that method is supported
+    stmt.clearWarnings(); // verifying that method is supported
 
     assertNull("No warnings should be found on connection", con.getWarnings());
-    con.clearWarnings(); //verifying that method is supported
+    con.clearWarnings(); // verifying that method is supported
 
     stmt.close();
     assertTrue("Statement should be closed", stmt.isClosed());
@@ -203,51 +217,52 @@
     String invalidSyntaxSQLState = "42000";
     int parseErrorCode = 10;
 
-    //These tests inherently cause exceptions to be written to the test output
-    //logs. This is undesirable, since you it might appear to someone looking
-    //at the test output logs as if something is failing when it isn't. Not sure
-    //how to get around that.
+    // These tests inherently cause exceptions to be written to the test output
+    // logs. This is undesirable, since you it might appear to someone looking
+    // at the test output logs as if something is failing when it isn't. Not
+    // sure
+    // how to get around that.
     doTestErrorCase("SELECTT * FROM " + tableName,
-            "cannot recognize input 'SELECTT'",
-            invalidSyntaxSQLState, 11);
+        "cannot recognize input 'SELECTT'", invalidSyntaxSQLState, 11);
     doTestErrorCase("SELECT * FROM some_table_that_does_not_exist",
-            "Table not found", "42S02", parseErrorCode);
+        "Table not found", "42S02", parseErrorCode);
     doTestErrorCase("drop table some_table_that_does_not_exist",
-            "Table not found", "42S02", parseErrorCode);
+        "Table not found", "42S02", parseErrorCode);
     doTestErrorCase("SELECT invalid_column FROM " + tableName,
-            "Invalid Table Alias or Column Reference",
-            invalidSyntaxSQLState, parseErrorCode);
+        "Invalid Table Alias or Column Reference", invalidSyntaxSQLState,
+        parseErrorCode);
     doTestErrorCase("SELECT invalid_function(key) FROM " + tableName,
-            "Invalid Function", invalidSyntaxSQLState, parseErrorCode);
+        "Invalid Function", invalidSyntaxSQLState, parseErrorCode);
 
-    //TODO: execute errors like this currently don't return good messages (i.e.
-    //'Table already exists'). This is because the Driver class calls
-    //Task.executeTask() which swallows meaningful exceptions and returns a status
-    //code. This should be refactored.
-    doTestErrorCase("create table " + tableName + " (key int, value string)",
-            "Query returned non-zero code: 9, cause: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask",
-            "08S01", 9);
+    // TODO: execute errors like this currently don't return good messages (i.e.
+    // 'Table already exists'). This is because the Driver class calls
+    // Task.executeTask() which swallows meaningful exceptions and returns a
+    // status
+    // code. This should be refactored.
+    doTestErrorCase(
+        "create table " + tableName + " (key int, value string)",
+        "Query returned non-zero code: 9, cause: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask",
+        "08S01", 9);
   }
 
   private void doTestErrorCase(String sql, String expectedMessage,
-                                           String expectedSQLState,
-                                           int expectedErrorCode) throws SQLException {
+      String expectedSQLState, int expectedErrorCode) throws SQLException {
     Statement stmt = con.createStatement();
     boolean exceptionFound = false;
     try {
       stmt.executeQuery(sql);
-    }
-    catch(SQLException e) {
-      assertTrue("Adequate error messaging not found for '" + sql + "': " +
-              e.getMessage(), e.getMessage().contains(expectedMessage));
+    } catch (SQLException e) {
+      assertTrue("Adequate error messaging not found for '" + sql + "': "
+          + e.getMessage(), e.getMessage().contains(expectedMessage));
       assertEquals("Expected SQLState not found for '" + sql + "'",
-              expectedSQLState, e.getSQLState());
+          expectedSQLState, e.getSQLState());
       assertEquals("Expected error code not found for '" + sql + "'",
-              expectedErrorCode, e.getErrorCode());
+          expectedErrorCode, e.getErrorCode());
       exceptionFound = true;
     }
 
-    assertNotNull("Exception should have been thrown for query: " + sql, exceptionFound);
+    assertNotNull("Exception should have been thrown for query: " + sql,
+        exceptionFound);
   }
 
   public void testShowTables() throws SQLException {
@@ -259,11 +274,13 @@
     boolean testTableExists = false;
     while (res.next()) {
       assertNotNull("table name is null in result set", res.getString(1));
-      if (tableName.equalsIgnoreCase(res.getString(1))) testTableExists = true;
+      if (tableName.equalsIgnoreCase(res.getString(1))) {
+        testTableExists = true;
+      }
     }
 
-    assertTrue("table name " + tableName + " not found in SHOW TABLES result set",
-               testTableExists);
+    assertTrue("table name " + tableName
+        + " not found in SHOW TABLES result set", testTableExists);
   }
 
   public void testDescribeTable() throws SQLException {
@@ -274,12 +291,12 @@
 
     res.next();
     assertEquals("Column name 'key' not found", "key", res.getString(1));
-    assertEquals("Column type 'int' for column key not found",
-                "int", res.getString(2));
+    assertEquals("Column type 'int' for column key not found", "int", res
+        .getString(2));
     res.next();
     assertEquals("Column name 'value' not found", "value", res.getString(1));
-    assertEquals("Column type 'string' for column key not found",
-                "string", res.getString(2));
+    assertEquals("Column type 'string' for column key not found", "string", res
+        .getString(2));
 
     assertFalse("More results found than expected", res.next());
 
@@ -303,26 +320,37 @@
     Statement stmt = con.createStatement();
     ResultSet res = stmt.executeQuery("drop table " + tableName);
 
-    //creating a table with tinyint is failing currently so not including
-    res = stmt.executeQuery("create table " + tableName + " (a string, b boolean, c bigint, d int, f double)");
+    // creating a table with tinyint is failing currently so not including
+    res = stmt.executeQuery("create table " + tableName
+        + " (a string, b boolean, c bigint, d int, f double)");
     res = stmt.executeQuery("select * from " + tableName + " limit 1");
 
     ResultSetMetaData meta = res.getMetaData();
     assertEquals("Unexpected column type", Types.VARCHAR, meta.getColumnType(1));
     assertEquals("Unexpected column type", Types.BOOLEAN, meta.getColumnType(2));
-    assertEquals("Unexpected column type", Types.BIGINT,  meta.getColumnType(3));
+    assertEquals("Unexpected column type", Types.BIGINT, meta.getColumnType(3));
     assertEquals("Unexpected column type", Types.INTEGER, meta.getColumnType(4));
-    assertEquals("Unexpected column type", Types.DOUBLE,  meta.getColumnType(5));
-    assertEquals("Unexpected column type name", "string", meta.getColumnTypeName(1));
-    assertEquals("Unexpected column type name", "boolean",   meta.getColumnTypeName(2));
-    assertEquals("Unexpected column type name", "bigint",    meta.getColumnTypeName(3));
-    assertEquals("Unexpected column type name", "int",    meta.getColumnTypeName(4));
-    assertEquals("Unexpected column type name", "double", meta.getColumnTypeName(5));
-    assertEquals("Unexpected column display size", 32, meta.getColumnDisplaySize(1));
-    assertEquals("Unexpected column display size", 8,  meta.getColumnDisplaySize(2));
-    assertEquals("Unexpected column display size", 32, meta.getColumnDisplaySize(3));
-    assertEquals("Unexpected column display size", 16, meta.getColumnDisplaySize(4));
-    assertEquals("Unexpected column display size", 16, meta.getColumnDisplaySize(5));
+    assertEquals("Unexpected column type", Types.DOUBLE, meta.getColumnType(5));
+    assertEquals("Unexpected column type name", "string", meta
+        .getColumnTypeName(1));
+    assertEquals("Unexpected column type name", "boolean", meta
+        .getColumnTypeName(2));
+    assertEquals("Unexpected column type name", "bigint", meta
+        .getColumnTypeName(3));
+    assertEquals("Unexpected column type name", "int", meta
+        .getColumnTypeName(4));
+    assertEquals("Unexpected column type name", "double", meta
+        .getColumnTypeName(5));
+    assertEquals("Unexpected column display size", 32, meta
+        .getColumnDisplaySize(1));
+    assertEquals("Unexpected column display size", 8, meta
+        .getColumnDisplaySize(2));
+    assertEquals("Unexpected column display size", 32, meta
+        .getColumnDisplaySize(3));
+    assertEquals("Unexpected column display size", 16, meta
+        .getColumnDisplaySize(4));
+    assertEquals("Unexpected column display size", 16, meta
+        .getColumnDisplaySize(5));
 
     for (int i = 1; i <= 5; i++) {
       assertFalse(meta.isAutoIncrement(i));
@@ -330,20 +358,20 @@
       assertEquals(ResultSetMetaData.columnNullable, meta.isNullable(i));
 
       int expectedPrecision = i == 5 ? -1 : 0;
-      int expectedScale     = i == 5 ? -1 : 0;
-      assertEquals("Unexpected precision", expectedPrecision, meta.getPrecision(i));
+      int expectedScale = i == 5 ? -1 : 0;
+      assertEquals("Unexpected precision", expectedPrecision, meta
+          .getPrecision(i));
       assertEquals("Unexpected scale", expectedScale, meta.getScale(i));
     }
   }
 
   // [url] [host] [port] [db]
   private static final String[][] URL_PROPERTIES = new String[][] {
-          {"jdbc:hive://", "", "", "default"},
-          {"jdbc:hive://localhost:10001/default", "localhost", "10001", "default"},
-          {"jdbc:hive://localhost/notdefault", "localhost", "10000", "notdefault"},
-          {"jdbc:hive://foo:1243", "foo", "1243", "default"}
-  };
-  
+      { "jdbc:hive://", "", "", "default" },
+      { "jdbc:hive://localhost:10001/default", "localhost", "10001", "default" },
+      { "jdbc:hive://localhost/notdefault", "localhost", "10000", "notdefault" },
+      { "jdbc:hive://foo:1243", "foo", "1243", "default" } };
+
   public void testDriverProperties() throws SQLException {
     HiveDriver driver = new HiveDriver();
 
@@ -357,7 +385,8 @@
 
   }
 
-  private static void assertDpi(DriverPropertyInfo dpi, String name, String value) {
+  private static void assertDpi(DriverPropertyInfo dpi, String name,
+      String value) {
     assertEquals("Invalid DriverPropertyInfo name", name, dpi.name);
     assertEquals("Invalid DriverPropertyInfo value", value, dpi.value);
     assertEquals("Invalid DriverPropertyInfo required", false, dpi.required);

Modified: hadoop/hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/AlterHandler.java
URL: http://svn.apache.org/viewvc/hadoop/hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/AlterHandler.java?rev=901581&r1=901580&r2=901581&view=diff
==============================================================================
--- hadoop/hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/AlterHandler.java (original)
+++ hadoop/hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/AlterHandler.java Thu Jan 21 07:29:29 2010
@@ -23,22 +23,30 @@
 import org.apache.hadoop.hive.metastore.api.Table;
 
 /**
- * Interface for Alter Table and Alter Partition code 
+ * Interface for Alter Table and Alter Partition code
  */
 public interface AlterHandler extends Configurable {
 
   /**
    * handles alter table
-   * @param msdb      object to get metadata
-   * @param wh TODO
-   * @param dbname    database of the table being altered
-   * @param name      original name of the table being altered. same as 
-   *                  <i>newTable.tableName</i> if alter op is not a rename.
-   * @param newTable  new table object
-   * @throws InvalidOperationException  thrown if the newTable object is invalid
-   * @throws MetaException              thrown if there is any other erro 
+   * 
+   * @param msdb
+   *          object to get metadata
+   * @param wh
+   *          TODO
+   * @param dbname
+   *          database of the table being altered
+   * @param name
+   *          original name of the table being altered. same as
+   *          <i>newTable.tableName</i> if alter op is not a rename.
+   * @param newTable
+   *          new table object
+   * @throws InvalidOperationException
+   *           thrown if the newTable object is invalid
+   * @throws MetaException
+   *           thrown if there is any other erro
    */
-   public abstract void alterTable(RawStore msdb,
-        Warehouse wh, String dbname,
-        String name, Table newTable) throws InvalidOperationException, MetaException;
+  public abstract void alterTable(RawStore msdb, Warehouse wh, String dbname,
+      String name, Table newTable) throws InvalidOperationException,
+      MetaException;
 }

Modified: hadoop/hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java
URL: http://svn.apache.org/viewvc/hadoop/hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java?rev=901581&r1=901580&r2=901581&view=diff
==============================================================================
--- hadoop/hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java (original)
+++ hadoop/hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java Thu Jan 21 07:29:29 2010
@@ -33,39 +33,40 @@
 import org.apache.hadoop.hive.metastore.api.Table;
 
 /**
- * Hive specific implementation of alter 
+ * Hive specific implementation of alter
  */
-public class HiveAlterHandler  implements AlterHandler {
+public class HiveAlterHandler implements AlterHandler {
 
   private Configuration hiveConf;
-  private static final Log LOG = LogFactory.getLog(HiveAlterHandler.class.getName());
+  private static final Log LOG = LogFactory.getLog(HiveAlterHandler.class
+      .getName());
 
-  public Configuration getConf() { 
+  public Configuration getConf() {
     return hiveConf;
   }
 
   @SuppressWarnings("nls")
   public void setConf(Configuration conf) {
-    this.hiveConf = conf;
+    hiveConf = conf;
   }
 
-  public void alterTable(RawStore msdb, Warehouse wh, String dbname, String name, Table newt)
-  throws InvalidOperationException, MetaException {
+  public void alterTable(RawStore msdb, Warehouse wh, String dbname,
+      String name, Table newt) throws InvalidOperationException, MetaException {
     if (newt == null) {
       throw new InvalidOperationException("New table is invalid: " + newt);
     }
-    
-    if(!MetaStoreUtils.validateName(newt.getTableName()) ||
-        !MetaStoreUtils.validateColNames(newt.getSd().getCols())) {
-      throw new InvalidOperationException(newt.getTableName() + " is not a valid object name");
+
+    if (!MetaStoreUtils.validateName(newt.getTableName())
+        || !MetaStoreUtils.validateColNames(newt.getSd().getCols())) {
+      throw new InvalidOperationException(newt.getTableName()
+          + " is not a valid object name");
     }
 
     if (newt.getViewExpandedText() != null) {
-      throw new InvalidOperationException(
-        newt.getTableName()
-        + " is a view, so it cannot be modified via ALTER TABLE");
+      throw new InvalidOperationException(newt.getTableName()
+          + " is a view, so it cannot be modified via ALTER TABLE");
     }
-    
+
     Path srcPath = null;
     FileSystem srcFs = null;
     Path destPath = null;
@@ -84,63 +85,80 @@
       // check if table with the new name already exists
       if (!newt.getTableName().equalsIgnoreCase(name)
           || !newt.getDbName().equalsIgnoreCase(dbname)) {
-        if(msdb.getTable(newt.getDbName(), newt.getTableName()) != null) {
-          throw new InvalidOperationException("new table " + newt.getDbName() 
+        if (msdb.getTable(newt.getDbName(), newt.getTableName()) != null) {
+          throw new InvalidOperationException("new table " + newt.getDbName()
               + "." + newt.getTableName() + " already exists");
         }
-        rename = true; 
+        rename = true;
       }
 
       // get old table
       Table oldt = msdb.getTable(dbname, name);
-      if(oldt == null) {
-        throw new InvalidOperationException("table " + newt.getDbName() 
-            + "." + newt.getTableName() + " doesn't exist");
+      if (oldt == null) {
+        throw new InvalidOperationException("table " + newt.getDbName() + "."
+            + newt.getTableName() + " doesn't exist");
       }
-      
+
       // check that partition keys have not changed
-      if( oldt.getPartitionKeys().size() != newt.getPartitionKeys().size()
+      if (oldt.getPartitionKeys().size() != newt.getPartitionKeys().size()
           || !oldt.getPartitionKeys().containsAll(newt.getPartitionKeys())) {
-        throw new InvalidOperationException("partition keys can not be changed.");
+        throw new InvalidOperationException(
+            "partition keys can not be changed.");
       }
-      
-      if (rename  // if this alter is a rename
-          && (oldt.getSd().getLocation().compareTo(newt.getSd().getLocation()) == 0 // and user didn't change the default location
-              || StringUtils.isEmpty(newt.getSd().getLocation())) // or new location is empty
-          && !oldt.getParameters().containsKey("EXTERNAL")) { // and table is not an external table
-        // that means user is asking metastore to move data to new location corresponding to the new name
+
+      if (rename // if this alter is a rename
+          && (oldt.getSd().getLocation().compareTo(newt.getSd().getLocation()) == 0 // and
+                                                                                    // user
+                                                                                    // didn't
+                                                                                    // change
+                                                                                    // the
+                                                                                    // default
+                                                                                    // location
+          || StringUtils.isEmpty(newt.getSd().getLocation())) // or new location
+                                                              // is empty
+          && !oldt.getParameters().containsKey("EXTERNAL")) { // and table is
+                                                              // not an external
+                                                              // table
+        // that means user is asking metastore to move data to new location
+        // corresponding to the new name
         // get new location
-        newTblLoc = wh.getDefaultTablePath(newt.getDbName(), newt.getTableName()).toString();
+        newTblLoc = wh.getDefaultTablePath(newt.getDbName(),
+            newt.getTableName()).toString();
         newt.getSd().setLocation(newTblLoc);
         oldTblLoc = oldt.getSd().getLocation();
         moveData = true;
-        // check that destination does not exist otherwise we will be overwriting data
+        // check that destination does not exist otherwise we will be
+        // overwriting data
         srcPath = new Path(oldTblLoc);
         srcFs = wh.getFs(srcPath);
         destPath = new Path(newTblLoc);
         destFs = wh.getFs(destPath);
         // check that src and dest are on the same file system
         if (srcFs != destFs) {
-          throw new InvalidOperationException("table new location " + destPath 
-              + " is on a different file system than the old location " + srcPath
-              + ". This operation is not supported");
+          throw new InvalidOperationException("table new location " + destPath
+              + " is on a different file system than the old location "
+              + srcPath + ". This operation is not supported");
         }
         try {
-          srcFs.exists(srcPath); // check that src exists and also checks permissions necessary
-          if(destFs.exists(destPath)) {
-            throw new InvalidOperationException("New location for this table "+ newt.getDbName() 
-                + "." + newt.getTableName() + " already exists : " +  destPath); 
+          srcFs.exists(srcPath); // check that src exists and also checks
+                                 // permissions necessary
+          if (destFs.exists(destPath)) {
+            throw new InvalidOperationException("New location for this table "
+                + newt.getDbName() + "." + newt.getTableName()
+                + " already exists : " + destPath);
           }
         } catch (IOException e) {
-          throw new InvalidOperationException("Unable to access new location " + destPath + " for table "
-              + newt.getDbName() + "." + newt.getTableName() );
+          throw new InvalidOperationException("Unable to access new location "
+              + destPath + " for table " + newt.getDbName() + "."
+              + newt.getTableName());
         }
         // also the location field in partition
         List<Partition> parts = msdb.getPartitions(dbname, name, 0);
         for (Partition part : parts) {
           String oldPartLoc = part.getSd().getLocation();
           if (oldPartLoc.contains(oldTblLoc)) {
-            part.getSd().setLocation(part.getSd().getLocation().replace(oldTblLoc, newTblLoc));
+            part.getSd().setLocation(
+                part.getSd().getLocation().replace(oldTblLoc, newTblLoc));
             msdb.alterPartition(dbname, name, part);
           }
         }
@@ -151,13 +169,14 @@
       success = msdb.commitTransaction();
     } catch (InvalidObjectException e) {
       LOG.debug(e);
-      throw new InvalidOperationException("Unable to change partition or table." +
-      		" Check metastore logs for detailed stack." + e.getMessage());
+      throw new InvalidOperationException(
+          "Unable to change partition or table."
+              + " Check metastore logs for detailed stack." + e.getMessage());
     } finally {
-      if(!success) {
+      if (!success) {
         msdb.rollbackTransaction();
       }
-      if(success && moveData) {
+      if (success && moveData) {
         // change the file name in hdfs
         // check that src exists otherwise there is no need to copy the data
         try {
@@ -166,8 +185,8 @@
             srcFs.rename(srcPath, destPath);
           }
         } catch (IOException e) {
-          throw new InvalidOperationException("Unable to access old location " + srcPath + " for table "
-              + dbname + "." + name );
+          throw new InvalidOperationException("Unable to access old location "
+              + srcPath + " for table " + dbname + "." + name);
         }
       }
     }

Modified: hadoop/hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
URL: http://svn.apache.org/viewvc/hadoop/hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java?rev=901581&r1=901580&r2=901581&view=diff
==============================================================================
--- hadoop/hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java (original)
+++ hadoop/hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java Thu Jan 21 07:29:29 2010
@@ -18,10 +18,8 @@
 
 package org.apache.hadoop.hive.metastore;
 
-
 import java.util.List;
 import java.util.Map;
-import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.commons.logging.Log;
@@ -31,6 +29,7 @@
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.metastore.api.AlreadyExistsException;
 import org.apache.hadoop.hive.metastore.api.ConfigValSecurityException;
+import org.apache.hadoop.hive.metastore.api.Constants;
 import org.apache.hadoop.hive.metastore.api.Database;
 import org.apache.hadoop.hive.metastore.api.FieldSchema;
 import org.apache.hadoop.hive.metastore.api.Index;
@@ -50,11 +49,6 @@
 import org.apache.hadoop.hive.serde2.SerDeUtils;
 import org.apache.hadoop.util.ReflectionUtils;
 import org.apache.hadoop.util.StringUtils;
-import org.apache.hadoop.hive.metastore.api.Constants;
-
-import com.facebook.fb303.FacebookBase;
-import com.facebook.fb303.FacebookService;
-import com.facebook.fb303.fb_status;
 import org.apache.thrift.TException;
 import org.apache.thrift.protocol.TBinaryProtocol;
 import org.apache.thrift.server.TServer;
@@ -63,690 +57,744 @@
 import org.apache.thrift.transport.TServerTransport;
 import org.apache.thrift.transport.TTransportFactory;
 
+import com.facebook.fb303.FacebookBase;
+import com.facebook.fb303.FacebookService;
+import com.facebook.fb303.fb_status;
+
 /**
  * TODO:pc remove application logic to a separate interface.
  */
 public class HiveMetaStore extends ThriftHiveMetastore {
 
-    public static class HMSHandler extends FacebookBase implements ThriftHiveMetastore.Iface {
-      public static final Log LOG = LogFactory.getLog(HiveMetaStore.class.getName());
-      private static boolean createDefaultDB = false;
-      private String rawStoreClassName;
-      private HiveConf hiveConf; // stores datastore (jpox) properties, right now they come from jpox.properties
-      private Warehouse wh; // hdfs warehouse
-      private ThreadLocal<RawStore> threadLocalMS = new ThreadLocal() {
-        protected synchronized Object initialValue() {
-            return null;
-        }
-      };
-
-      // The next serial number to be assigned
-      private boolean checkForDefaultDb;
-      private static int nextSerialNum = 0;
-      private static ThreadLocal<Integer> threadLocalId = new ThreadLocal() {
-        protected synchronized Object initialValue() {
-          return new Integer(nextSerialNum++);
-        }
-      };
-      public static Integer get() {
-        return threadLocalId.get();
-      }
-
-      public HMSHandler(String name) throws MetaException {
-        super(name);
-        hiveConf = new HiveConf(this.getClass());
-        init();
-      }
-
-      public HMSHandler(String name, HiveConf conf) throws MetaException {
-        super(name);
-        hiveConf = conf;
-        init();
-      }
-
-      private ClassLoader classLoader;
-      private AlterHandler alterHandler;
-      {
-        classLoader = Thread.currentThread().getContextClassLoader();
-        if (classLoader == null) {
-          classLoader = Configuration.class.getClassLoader();
-        }
-      }
-
-      private boolean init() throws MetaException {
-        rawStoreClassName = hiveConf.get("hive.metastore.rawstore.impl");
-        checkForDefaultDb = hiveConf.getBoolean("hive.metastore.checkForDefaultDb", true);
-        String alterHandlerName = hiveConf.get("hive.metastore.alter.impl", HiveAlterHandler.class.getName());
-        alterHandler = (AlterHandler) ReflectionUtils.newInstance(getClass(alterHandlerName, AlterHandler.class), hiveConf);
-        wh = new Warehouse(hiveConf);
-        createDefaultDB();
-        return true;
-      }
-
-      /**
-       * @return
-       * @throws MetaException
-       */
-      private RawStore getMS() throws MetaException {
-        RawStore ms = threadLocalMS.get();
-        if(ms == null) {
-          LOG.info(threadLocalId.get() + ": Opening raw store with implemenation class:" + rawStoreClassName);
-          ms = (RawStore) ReflectionUtils.newInstance(getClass(rawStoreClassName, RawStore.class), hiveConf);
-          threadLocalMS.set(ms);
-          ms = threadLocalMS.get();
-        }
-        return ms;
-      }
-
-      /**
-       * create default database if it doesn't exist
-       * @throws MetaException
-       */
-      private void createDefaultDB() throws MetaException {
-        if(HMSHandler.createDefaultDB || !checkForDefaultDb) {
-          return;
-        }
-        try {
-          getMS().getDatabase(MetaStoreUtils.DEFAULT_DATABASE_NAME);
-        } catch (NoSuchObjectException e) {
-          getMS().createDatabase(new Database(MetaStoreUtils.DEFAULT_DATABASE_NAME,
-                    wh.getDefaultDatabasePath(MetaStoreUtils.DEFAULT_DATABASE_NAME).toString()));
-        }
-        HMSHandler.createDefaultDB = true;
+  public static class HMSHandler extends FacebookBase implements
+      ThriftHiveMetastore.Iface {
+    public static final Log LOG = LogFactory.getLog(HiveMetaStore.class
+        .getName());
+    private static boolean createDefaultDB = false;
+    private String rawStoreClassName;
+    private final HiveConf hiveConf; // stores datastore (jpox) properties,
+                                     // right now they come from jpox.properties
+    private Warehouse wh; // hdfs warehouse
+    private final ThreadLocal<RawStore> threadLocalMS = new ThreadLocal() {
+      @Override
+      protected synchronized Object initialValue() {
+        return null;
       }
+    };
 
-      private Class<?> getClass(String rawStoreClassName, Class<?> class1) throws MetaException {
-        try {
-          return Class.forName(rawStoreClassName, true, classLoader);
-        } catch (ClassNotFoundException e) {
-          throw new MetaException(rawStoreClassName + " class not found");
-        }
+    // The next serial number to be assigned
+    private boolean checkForDefaultDb;
+    private static int nextSerialNum = 0;
+    private static ThreadLocal<Integer> threadLocalId = new ThreadLocal() {
+      @Override
+      protected synchronized Object initialValue() {
+        return new Integer(nextSerialNum++);
       }
+    };
 
-      private void logStartFunction(String m) {
-        LOG.info(threadLocalId.get().toString() + ": " + m);
-      }
+    public static Integer get() {
+      return threadLocalId.get();
+    }
 
-      private void logStartFunction(String f, String db, String tbl) {
-        LOG.info(threadLocalId.get().toString() + ": " + f + " : db=" + db + " tbl=" + tbl);
-      }
+    public HMSHandler(String name) throws MetaException {
+      super(name);
+      hiveConf = new HiveConf(this.getClass());
+      init();
+    }
 
-      @Override
-      public int getStatus() {
-        return fb_status.ALIVE;
-      }
+    public HMSHandler(String name, HiveConf conf) throws MetaException {
+      super(name);
+      hiveConf = conf;
+      init();
+    }
 
-      public void shutdown() {
-        logStartFunction("Shutting down the object store...");
-        try {
-          if(threadLocalMS.get() != null) {
-            getMS().shutdown();
-          }
-        } catch (MetaException e) {
-          LOG.error("unable to shutdown metastore", e);
-        }
-        System.exit(0);
+    private ClassLoader classLoader;
+    private AlterHandler alterHandler;
+    {
+      classLoader = Thread.currentThread().getContextClassLoader();
+      if (classLoader == null) {
+        classLoader = Configuration.class.getClassLoader();
       }
+    }
 
-      public boolean create_database(String name, String location_uri)
-      throws AlreadyExistsException, MetaException {
-        this.incrementCounter("create_database");
-        logStartFunction("create_database: " + name);
-        boolean success = false;
-        try {
-          getMS().openTransaction();
-          Database db = new Database(name, location_uri);
-          if(getMS().createDatabase(db) && wh.mkdirs(wh.getDefaultDatabasePath(name))) {
-            success = getMS().commitTransaction();
-          }
-        } finally {
-          if(!success) {
-            getMS().rollbackTransaction();
-          }
-        }
-        return success;
-      }
+    private boolean init() throws MetaException {
+      rawStoreClassName = hiveConf.get("hive.metastore.rawstore.impl");
+      checkForDefaultDb = hiveConf.getBoolean(
+          "hive.metastore.checkForDefaultDb", true);
+      String alterHandlerName = hiveConf.get("hive.metastore.alter.impl",
+          HiveAlterHandler.class.getName());
+      alterHandler = (AlterHandler) ReflectionUtils.newInstance(getClass(
+          alterHandlerName, AlterHandler.class), hiveConf);
+      wh = new Warehouse(hiveConf);
+      createDefaultDB();
+      return true;
+    }
 
-      public Database get_database(String name) throws NoSuchObjectException, MetaException {
-        this.incrementCounter("get_database");
-        logStartFunction("get_database: " + name);
-        return getMS().getDatabase(name);
+    /**
+     * @return
+     * @throws MetaException
+     */
+    private RawStore getMS() throws MetaException {
+      RawStore ms = threadLocalMS.get();
+      if (ms == null) {
+        LOG.info(threadLocalId.get()
+            + ": Opening raw store with implemenation class:"
+            + rawStoreClassName);
+        ms = (RawStore) ReflectionUtils.newInstance(getClass(rawStoreClassName,
+            RawStore.class), hiveConf);
+        threadLocalMS.set(ms);
+        ms = threadLocalMS.get();
       }
+      return ms;
+    }
 
-      public boolean drop_database(String name) throws MetaException {
-        this.incrementCounter("drop_database");
-        logStartFunction("drop_database: " + name);
-        if(name.equalsIgnoreCase(MetaStoreUtils.DEFAULT_DATABASE_NAME)) {
-          throw new MetaException("Can't drop default database");
-        }
-        boolean success = false;
-        try {
-          getMS().openTransaction();
-          if(getMS().dropDatabase(name)) {
-            success = getMS().commitTransaction();
-          }
-        } finally {
-          if(!success) {
-            getMS().rollbackTransaction();
-          } else {
-            wh.deleteDir(wh.getDefaultDatabasePath(name), true);
-            // it is not a terrible thing even if the data is not deleted
-          }
-        }
-        return success;
+    /**
+     * create default database if it doesn't exist
+     * 
+     * @throws MetaException
+     */
+    private void createDefaultDB() throws MetaException {
+      if (HMSHandler.createDefaultDB || !checkForDefaultDb) {
+        return;
+      }
+      try {
+        getMS().getDatabase(MetaStoreUtils.DEFAULT_DATABASE_NAME);
+      } catch (NoSuchObjectException e) {
+        getMS().createDatabase(
+            new Database(MetaStoreUtils.DEFAULT_DATABASE_NAME, wh
+                .getDefaultDatabasePath(MetaStoreUtils.DEFAULT_DATABASE_NAME)
+                .toString()));
       }
+      HMSHandler.createDefaultDB = true;
+    }
 
-      public List<String> get_databases() throws MetaException {
-        this.incrementCounter("get_databases");
-        logStartFunction("get_databases");
-        return getMS().getDatabases();
+    private Class<?> getClass(String rawStoreClassName, Class<?> class1)
+        throws MetaException {
+      try {
+        return Class.forName(rawStoreClassName, true, classLoader);
+      } catch (ClassNotFoundException e) {
+        throw new MetaException(rawStoreClassName + " class not found");
       }
+    }
 
-      public boolean create_type(Type type) throws AlreadyExistsException, MetaException, InvalidObjectException {
-        this.incrementCounter("create_type");
-        logStartFunction("create_type: " + type.getName());
-        // check whether type already exists
-        if(get_type(type.getName()) != null) {
-          throw new AlreadyExistsException("Type " + type.getName() + " already exists");
-        }
+    private void logStartFunction(String m) {
+      LOG.info(threadLocalId.get().toString() + ": " + m);
+    }
 
-        //TODO:pc Validation of types should be done by clients or here????
-        return getMS().createType(type);
-      }
+    private void logStartFunction(String f, String db, String tbl) {
+      LOG.info(threadLocalId.get().toString() + ": " + f + " : db=" + db
+          + " tbl=" + tbl);
+    }
 
-      public Type get_type(String name) throws MetaException {
-        this.incrementCounter("get_type");
-        logStartFunction("get_type: " + name);
-        return getMS().getType(name);
-      }
+    @Override
+    public int getStatus() {
+      return fb_status.ALIVE;
+    }
 
-      public boolean drop_type(String name) throws MetaException {
-        this.incrementCounter("drop_type");
-        logStartFunction("drop_type: " + name);
-        // TODO:pc validate that there are no types that refer to this
-        return getMS().dropType(name);
+    public void shutdown() {
+      logStartFunction("Shutting down the object store...");
+      try {
+        if (threadLocalMS.get() != null) {
+          getMS().shutdown();
+        }
+      } catch (MetaException e) {
+        LOG.error("unable to shutdown metastore", e);
       }
+      System.exit(0);
+    }
 
-      public Map<String, Type> get_type_all(String name) throws MetaException {
-        this.incrementCounter("get_type_all");
-        // TODO Auto-generated method stub
-        logStartFunction("get_type_all");
-        throw new MetaException("Not yet implemented");
+    public boolean create_database(String name, String location_uri)
+        throws AlreadyExistsException, MetaException {
+      incrementCounter("create_database");
+      logStartFunction("create_database: " + name);
+      boolean success = false;
+      try {
+        getMS().openTransaction();
+        Database db = new Database(name, location_uri);
+        if (getMS().createDatabase(db)
+            && wh.mkdirs(wh.getDefaultDatabasePath(name))) {
+          success = getMS().commitTransaction();
+        }
+      } finally {
+        if (!success) {
+          getMS().rollbackTransaction();
+        }
       }
+      return success;
+    }
 
-      public void create_table(Table tbl) throws AlreadyExistsException, MetaException, InvalidObjectException {
-        this.incrementCounter("create_table");
-        logStartFunction("create_table: db=" + tbl.getDbName() + " tbl=" + tbl.getTableName());
+    public Database get_database(String name) throws NoSuchObjectException,
+        MetaException {
+      incrementCounter("get_database");
+      logStartFunction("get_database: " + name);
+      return getMS().getDatabase(name);
+    }
 
-        if(!MetaStoreUtils.validateName(tbl.getTableName()) ||
-            !MetaStoreUtils.validateColNames(tbl.getSd().getCols()) ||
-             (tbl.getPartitionKeys() != null &&
-              !MetaStoreUtils.validateColNames(tbl.getPartitionKeys()))) {
-            throw new InvalidObjectException(tbl.getTableName() + " is not a valid object name");
+    public boolean drop_database(String name) throws MetaException {
+      incrementCounter("drop_database");
+      logStartFunction("drop_database: " + name);
+      if (name.equalsIgnoreCase(MetaStoreUtils.DEFAULT_DATABASE_NAME)) {
+        throw new MetaException("Can't drop default database");
+      }
+      boolean success = false;
+      try {
+        getMS().openTransaction();
+        if (getMS().dropDatabase(name)) {
+          success = getMS().commitTransaction();
+        }
+      } finally {
+        if (!success) {
+          getMS().rollbackTransaction();
+        } else {
+          wh.deleteDir(wh.getDefaultDatabasePath(name), true);
+          // it is not a terrible thing even if the data is not deleted
         }
+      }
+      return success;
+    }
 
-        Path tblPath = null;
-        boolean success = false, madeDir = false;
-        try {
-          getMS().openTransaction();
-          if(tbl.getSd().getLocation() == null || tbl.getSd().getLocation().isEmpty()) {
-            tblPath = wh.getDefaultTablePath(tbl.getDbName(), tbl.getTableName());
-          } else {
-            if (!isExternal(tbl)) {
-              LOG.warn("Location: " + tbl.getSd().getLocation() +
-                       "specified for non-external table:" + tbl.getTableName());
-            }
-            tblPath = wh.getDnsPath(new Path(tbl.getSd().getLocation()));
-          }
+    public List<String> get_databases() throws MetaException {
+      incrementCounter("get_databases");
+      logStartFunction("get_databases");
+      return getMS().getDatabases();
+    }
 
-          tbl.getSd().setLocation(tblPath.toString());
+    public boolean create_type(Type type) throws AlreadyExistsException,
+        MetaException, InvalidObjectException {
+      incrementCounter("create_type");
+      logStartFunction("create_type: " + type.getName());
+      // check whether type already exists
+      if (get_type(type.getName()) != null) {
+        throw new AlreadyExistsException("Type " + type.getName()
+            + " already exists");
+      }
 
-          // get_table checks whether database exists, it should be moved here
-          if(is_table_exists(tbl.getDbName(), tbl.getTableName())) {
-            throw new AlreadyExistsException("Table " + tbl.getTableName() + " already exists");
-          }
+      // TODO:pc Validation of types should be done by clients or here????
+      return getMS().createType(type);
+    }
 
-          if(!wh.isDir(tblPath)) {
-            if(!wh.mkdirs(tblPath)) {
-              throw new MetaException (tblPath + " is not a directory or unable to create one");
-            }
-            madeDir = true;
-          }
+    public Type get_type(String name) throws MetaException {
+      incrementCounter("get_type");
+      logStartFunction("get_type: " + name);
+      return getMS().getType(name);
+    }
 
-          // set create time
-          long time = System.currentTimeMillis() / 1000;
-          tbl.setCreateTime((int) time);
-          tbl.putToParameters(Constants.DDL_TIME, Long.toString(time));
+    public boolean drop_type(String name) throws MetaException {
+      incrementCounter("drop_type");
+      logStartFunction("drop_type: " + name);
+      // TODO:pc validate that there are no types that refer to this
+      return getMS().dropType(name);
+    }
 
-          getMS().createTable(tbl);
-          success = getMS().commitTransaction();
+    public Map<String, Type> get_type_all(String name) throws MetaException {
+      incrementCounter("get_type_all");
+      // TODO Auto-generated method stub
+      logStartFunction("get_type_all");
+      throw new MetaException("Not yet implemented");
+    }
 
-        } finally {
-          if(!success) {
-            getMS().rollbackTransaction();
-            if(madeDir) {
-              wh.deleteDir(tblPath, true);
-            }
+    public void create_table(Table tbl) throws AlreadyExistsException,
+        MetaException, InvalidObjectException {
+      incrementCounter("create_table");
+      logStartFunction("create_table: db=" + tbl.getDbName() + " tbl="
+          + tbl.getTableName());
+
+      if (!MetaStoreUtils.validateName(tbl.getTableName())
+          || !MetaStoreUtils.validateColNames(tbl.getSd().getCols())
+          || (tbl.getPartitionKeys() != null && !MetaStoreUtils
+              .validateColNames(tbl.getPartitionKeys()))) {
+        throw new InvalidObjectException(tbl.getTableName()
+            + " is not a valid object name");
+      }
+
+      Path tblPath = null;
+      boolean success = false, madeDir = false;
+      try {
+        getMS().openTransaction();
+        if (tbl.getSd().getLocation() == null
+            || tbl.getSd().getLocation().isEmpty()) {
+          tblPath = wh.getDefaultTablePath(tbl.getDbName(), tbl.getTableName());
+        } else {
+          if (!isExternal(tbl)) {
+            LOG.warn("Location: " + tbl.getSd().getLocation()
+                + "specified for non-external table:" + tbl.getTableName());
+          }
+          tblPath = wh.getDnsPath(new Path(tbl.getSd().getLocation()));
+        }
+
+        tbl.getSd().setLocation(tblPath.toString());
+
+        // get_table checks whether database exists, it should be moved here
+        if (is_table_exists(tbl.getDbName(), tbl.getTableName())) {
+          throw new AlreadyExistsException("Table " + tbl.getTableName()
+              + " already exists");
+        }
+
+        if (!wh.isDir(tblPath)) {
+          if (!wh.mkdirs(tblPath)) {
+            throw new MetaException(tblPath
+                + " is not a directory or unable to create one");
+          }
+          madeDir = true;
+        }
+
+        // set create time
+        long time = System.currentTimeMillis() / 1000;
+        tbl.setCreateTime((int) time);
+        tbl.putToParameters(Constants.DDL_TIME, Long.toString(time));
+
+        getMS().createTable(tbl);
+        success = getMS().commitTransaction();
+
+      } finally {
+        if (!success) {
+          getMS().rollbackTransaction();
+          if (madeDir) {
+            wh.deleteDir(tblPath, true);
           }
         }
       }
+    }
 
-      public boolean is_table_exists(String dbname, String name) throws MetaException {
-        try {
-          return (get_table(dbname, name) != null);
-        } catch (NoSuchObjectException e) {
-          return false;
-        }
+    public boolean is_table_exists(String dbname, String name)
+        throws MetaException {
+      try {
+        return (get_table(dbname, name) != null);
+      } catch (NoSuchObjectException e) {
+        return false;
       }
+    }
 
-      public void drop_table(String dbname, String name, boolean deleteData) throws NoSuchObjectException, MetaException {
-        this.incrementCounter("drop_table");
-        logStartFunction("drop_table", dbname, name);
-        boolean success = false;
-        boolean isExternal = false;
-        Path tblPath = null;
-        Table tbl = null;
-        isExternal = false;
-        try {
-          getMS().openTransaction();
-          // drop any partitions
-          tbl = get_table(dbname, name);
-          if (tbl == null) {
-            throw new NoSuchObjectException(name + " doesn't exist");
-          }
-          if(tbl.getSd() == null  || tbl.getSd().getLocation() == null) {
-            throw new MetaException("Table metadata is corrupted");
-          }
-          isExternal = isExternal(tbl);
-          tblPath = new Path(tbl.getSd().getLocation());
-          if(!getMS().dropTable(dbname, name)) {
-            throw new MetaException("Unable to drop table");
-          }
-          tbl = null; // table collections disappear after dropping
-          success  = getMS().commitTransaction();
-        } finally {
-          if(!success) {
-            getMS().rollbackTransaction();
-          } else if(deleteData && (tblPath != null) && !isExternal) {
-            wh.deleteDir(tblPath, true);
-            // ok even if the data is not deleted
-          }
+    public void drop_table(String dbname, String name, boolean deleteData)
+        throws NoSuchObjectException, MetaException {
+      incrementCounter("drop_table");
+      logStartFunction("drop_table", dbname, name);
+      boolean success = false;
+      boolean isExternal = false;
+      Path tblPath = null;
+      Table tbl = null;
+      isExternal = false;
+      try {
+        getMS().openTransaction();
+        // drop any partitions
+        tbl = get_table(dbname, name);
+        if (tbl == null) {
+          throw new NoSuchObjectException(name + " doesn't exist");
+        }
+        if (tbl.getSd() == null || tbl.getSd().getLocation() == null) {
+          throw new MetaException("Table metadata is corrupted");
+        }
+        isExternal = isExternal(tbl);
+        tblPath = new Path(tbl.getSd().getLocation());
+        if (!getMS().dropTable(dbname, name)) {
+          throw new MetaException("Unable to drop table");
+        }
+        tbl = null; // table collections disappear after dropping
+        success = getMS().commitTransaction();
+      } finally {
+        if (!success) {
+          getMS().rollbackTransaction();
+        } else if (deleteData && (tblPath != null) && !isExternal) {
+          wh.deleteDir(tblPath, true);
+          // ok even if the data is not deleted
         }
       }
+    }
 
-      /**
-       * Is this an external table?
-       * @param table Check if this table is external.
-       * @return True if the table is external, otherwise false.
-       */
-      private boolean isExternal(Table table) {
-        if(table == null) {
-          return false;
-        }
-        Map<String, String> params = table.getParameters();
-        if(params == null) {
-          return false;
-        }
-
-        return "TRUE".equalsIgnoreCase(params.get("EXTERNAL"));
-      }
-
-      public Table get_table(String dbname, String name) throws MetaException, NoSuchObjectException {
-        this.incrementCounter("get_table");
-        logStartFunction("get_table", dbname, name);
-        Table t = getMS().getTable(dbname, name);
-        if(t == null) {
-          throw new NoSuchObjectException(dbname + "." + name + " table not found");
-        }
-        return t;
-      }
-
-      public boolean set_table_parameters(String dbname, String name,
-          Map<String, String> params) throws NoSuchObjectException,
-          MetaException {
-        this.incrementCounter("set_table_parameters");
-        logStartFunction("set_table_parameters", dbname, name);
-        // TODO Auto-generated method stub
+    /**
+     * Is this an external table?
+     * 
+     * @param table
+     *          Check if this table is external.
+     * @return True if the table is external, otherwise false.
+     */
+    private boolean isExternal(Table table) {
+      if (table == null) {
+        return false;
+      }
+      Map<String, String> params = table.getParameters();
+      if (params == null) {
         return false;
       }
 
-      public Partition append_partition(String dbName, String tableName, List<String> part_vals)
-          throws InvalidObjectException, AlreadyExistsException, MetaException {
-        this.incrementCounter("append_partition");
-        logStartFunction("append_partition", dbName, tableName);
-        if(LOG.isDebugEnabled()) {
-          for (String part : part_vals) {
-            LOG.debug(part);
-          }
-        }
-        Partition part = new Partition();
-        boolean success = false, madeDir = false;
-        Path partLocation = null;
-        try {
-          getMS().openTransaction();
-          part = new Partition();
-          part.setDbName(dbName);
-          part.setTableName(tableName);
-          part.setValues(part_vals);
-
-          Table tbl = getMS().getTable(part.getDbName(), part.getTableName());
-          if(tbl == null) {
-            throw new InvalidObjectException("Unable to add partition because table or database do not exist");
-          }
+      return "TRUE".equalsIgnoreCase(params.get("EXTERNAL"));
+    }
 
-          part.setSd(tbl.getSd());
-          partLocation = new Path(tbl.getSd().getLocation(),
-                                  Warehouse.makePartName(tbl.getPartitionKeys(), part_vals));
-          part.getSd().setLocation(partLocation.toString());
-
-          Partition old_part = this.get_partition(part.getDbName(),
-                                                  part.getTableName(), part.getValues());
-          if( old_part != null) {
-            throw new AlreadyExistsException("Partition already exists:" + part);
-          }
+    public Table get_table(String dbname, String name) throws MetaException,
+        NoSuchObjectException {
+      incrementCounter("get_table");
+      logStartFunction("get_table", dbname, name);
+      Table t = getMS().getTable(dbname, name);
+      if (t == null) {
+        throw new NoSuchObjectException(dbname + "." + name
+            + " table not found");
+      }
+      return t;
+    }
 
-          if(!wh.isDir(partLocation)) {
-            if(!wh.mkdirs(partLocation)) {
-              throw new MetaException (partLocation + " is not a directory or unable to create one");
-            }
-            madeDir = true;
-          }
+    public boolean set_table_parameters(String dbname, String name,
+        Map<String, String> params) throws NoSuchObjectException, MetaException {
+      incrementCounter("set_table_parameters");
+      logStartFunction("set_table_parameters", dbname, name);
+      // TODO Auto-generated method stub
+      return false;
+    }
 
-          // set create time
-          long time = System.currentTimeMillis() / 1000;
-          part.setCreateTime((int) time);
-          part.putToParameters(Constants.DDL_TIME, Long.toString(time));
-
-          success = getMS().addPartition(part);
-          if(success) {
-            success = getMS().commitTransaction();
-          }
-        } finally {
-          if(!success) {
-            getMS().rollbackTransaction();
-            if(madeDir) {
-              wh.deleteDir(partLocation, true);
-            }
+    public Partition append_partition(String dbName, String tableName,
+        List<String> part_vals) throws InvalidObjectException,
+        AlreadyExistsException, MetaException {
+      incrementCounter("append_partition");
+      logStartFunction("append_partition", dbName, tableName);
+      if (LOG.isDebugEnabled()) {
+        for (String part : part_vals) {
+          LOG.debug(part);
+        }
+      }
+      Partition part = new Partition();
+      boolean success = false, madeDir = false;
+      Path partLocation = null;
+      try {
+        getMS().openTransaction();
+        part = new Partition();
+        part.setDbName(dbName);
+        part.setTableName(tableName);
+        part.setValues(part_vals);
+
+        Table tbl = getMS().getTable(part.getDbName(), part.getTableName());
+        if (tbl == null) {
+          throw new InvalidObjectException(
+              "Unable to add partition because table or database do not exist");
+        }
+
+        part.setSd(tbl.getSd());
+        partLocation = new Path(tbl.getSd().getLocation(), Warehouse
+            .makePartName(tbl.getPartitionKeys(), part_vals));
+        part.getSd().setLocation(partLocation.toString());
+
+        Partition old_part = get_partition(part.getDbName(), part
+            .getTableName(), part.getValues());
+        if (old_part != null) {
+          throw new AlreadyExistsException("Partition already exists:" + part);
+        }
+
+        if (!wh.isDir(partLocation)) {
+          if (!wh.mkdirs(partLocation)) {
+            throw new MetaException(partLocation
+                + " is not a directory or unable to create one");
+          }
+          madeDir = true;
+        }
+
+        // set create time
+        long time = System.currentTimeMillis() / 1000;
+        part.setCreateTime((int) time);
+        part.putToParameters(Constants.DDL_TIME, Long.toString(time));
+
+        success = getMS().addPartition(part);
+        if (success) {
+          success = getMS().commitTransaction();
+        }
+      } finally {
+        if (!success) {
+          getMS().rollbackTransaction();
+          if (madeDir) {
+            wh.deleteDir(partLocation, true);
           }
         }
-        return part;
       }
+      return part;
+    }
 
-      public int add_partitions(List<Partition> parts) throws MetaException, InvalidObjectException, AlreadyExistsException {
-        this.incrementCounter("add_partition");
-        if(parts.size() == 0) {
-          return 0;
-        }
-        String db = parts.get(0).getDbName();
-        String tbl = parts.get(0).getTableName();
-        logStartFunction("add_partitions", db, tbl);
-        boolean success = false;
-        try {
-          getMS().openTransaction();
-          for (Partition part : parts) {
-            this.add_partition(part);
-          }
-          success = true;
-          getMS().commitTransaction();
-        } finally {
-          if(!success) {
-            getMS().rollbackTransaction();
-          }
+    public int add_partitions(List<Partition> parts) throws MetaException,
+        InvalidObjectException, AlreadyExistsException {
+      incrementCounter("add_partition");
+      if (parts.size() == 0) {
+        return 0;
+      }
+      String db = parts.get(0).getDbName();
+      String tbl = parts.get(0).getTableName();
+      logStartFunction("add_partitions", db, tbl);
+      boolean success = false;
+      try {
+        getMS().openTransaction();
+        for (Partition part : parts) {
+          add_partition(part);
+        }
+        success = true;
+        getMS().commitTransaction();
+      } finally {
+        if (!success) {
+          getMS().rollbackTransaction();
         }
-        return parts.size();
       }
+      return parts.size();
+    }
 
-      public Partition add_partition(Partition part) throws InvalidObjectException,
-          AlreadyExistsException, MetaException {
-        this.incrementCounter("add_partition");
-        logStartFunction("add_partition", part.getDbName(), part.getTableName());
-        boolean success = false, madeDir = false;
-        Path partLocation = null;
-        try {
-          getMS().openTransaction();
-          Partition old_part = this.get_partition(part.getDbName(), part.getTableName(), part.getValues());
-          if( old_part != null) {
-            throw new AlreadyExistsException("Partition already exists:" + part);
-          }
-          Table tbl = getMS().getTable(part.getDbName(), part.getTableName());
-          if(tbl == null) {
-            throw new InvalidObjectException("Unable to add partition because table or database do not exist");
-          }
+    public Partition add_partition(Partition part)
+        throws InvalidObjectException, AlreadyExistsException, MetaException {
+      incrementCounter("add_partition");
+      logStartFunction("add_partition", part.getDbName(), part.getTableName());
+      boolean success = false, madeDir = false;
+      Path partLocation = null;
+      try {
+        getMS().openTransaction();
+        Partition old_part = get_partition(part.getDbName(), part
+            .getTableName(), part.getValues());
+        if (old_part != null) {
+          throw new AlreadyExistsException("Partition already exists:" + part);
+        }
+        Table tbl = getMS().getTable(part.getDbName(), part.getTableName());
+        if (tbl == null) {
+          throw new InvalidObjectException(
+              "Unable to add partition because table or database do not exist");
+        }
 
-          String partLocationStr = part.getSd().getLocation();
-          if (partLocationStr == null || partLocationStr.isEmpty()) {
-            // set default location if not specified
-            partLocation = new Path(tbl.getSd().getLocation(),
-                                    Warehouse.makePartName(tbl.getPartitionKeys(), part.getValues()));
+        String partLocationStr = part.getSd().getLocation();
+        if (partLocationStr == null || partLocationStr.isEmpty()) {
+          // set default location if not specified
+          partLocation = new Path(tbl.getSd().getLocation(), Warehouse
+              .makePartName(tbl.getPartitionKeys(), part.getValues()));
 
-          } else {
-            partLocation = wh.getDnsPath(new Path(partLocationStr));
-          }
+        } else {
+          partLocation = wh.getDnsPath(new Path(partLocationStr));
+        }
 
-          part.getSd().setLocation(partLocation.toString());
+        part.getSd().setLocation(partLocation.toString());
 
-          if(!wh.isDir(partLocation)) {
-            if(!wh.mkdirs(partLocation)) {
-              throw new MetaException (partLocation + " is not a directory or unable to create one");
-            }
-            madeDir = true;
+        if (!wh.isDir(partLocation)) {
+          if (!wh.mkdirs(partLocation)) {
+            throw new MetaException(partLocation
+                + " is not a directory or unable to create one");
           }
+          madeDir = true;
+        }
+
+        // set create time
+        long time = System.currentTimeMillis() / 1000;
+        part.setCreateTime((int) time);
+        part.putToParameters(Constants.DDL_TIME, Long.toString(time));
+
+        success = getMS().addPartition(part) && getMS().commitTransaction();
 
-          // set create time
-          long time = System.currentTimeMillis() / 1000;
-          part.setCreateTime((int) time);
-          part.putToParameters(Constants.DDL_TIME, Long.toString(time));
-
-          success = getMS().addPartition(part) && getMS().commitTransaction();
-
-        } finally {
-          if(!success) {
-            getMS().rollbackTransaction();
-            if(madeDir) {
-              wh.deleteDir(partLocation, true);
-            }
+      } finally {
+        if (!success) {
+          getMS().rollbackTransaction();
+          if (madeDir) {
+            wh.deleteDir(partLocation, true);
           }
         }
-        return part;
       }
+      return part;
+    }
 
-      public boolean drop_partition(String db_name, String tbl_name, List<String> part_vals, boolean deleteData) throws NoSuchObjectException, MetaException,
-          TException {
-        this.incrementCounter("drop_partition");
-        logStartFunction("drop_partition", db_name, tbl_name);
-        LOG.info("Partition values:" + part_vals);
-        boolean success = false;
-        Path partPath = null;
-        Table tbl = null;
-        try {
-          getMS().openTransaction();
-          Partition part = this.get_partition(db_name, tbl_name, part_vals);
-          if(part == null) {
-            throw new NoSuchObjectException("Partition doesn't exist. " + part_vals);
-          }
-          if(part.getSd() == null  || part.getSd().getLocation() == null) {
-            throw new MetaException("Partition metadata is corrupted");
-          }
-          if(!getMS().dropPartition(db_name, tbl_name, part_vals)) {
-            throw new MetaException("Unable to drop partition");
-          }
-          success  = getMS().commitTransaction();
-          partPath = new Path(part.getSd().getLocation());
-          tbl = get_table(db_name, tbl_name);
-        } finally {
-          if(!success) {
-            getMS().rollbackTransaction();
-          } else if(deleteData && (partPath != null)) {
-            if(tbl != null && !isExternal(tbl)) {
-              wh.deleteDir(partPath, true);
-              // ok even if the data is not deleted
-            }
+    public boolean drop_partition(String db_name, String tbl_name,
+        List<String> part_vals, boolean deleteData)
+        throws NoSuchObjectException, MetaException, TException {
+      incrementCounter("drop_partition");
+      logStartFunction("drop_partition", db_name, tbl_name);
+      LOG.info("Partition values:" + part_vals);
+      boolean success = false;
+      Path partPath = null;
+      Table tbl = null;
+      try {
+        getMS().openTransaction();
+        Partition part = get_partition(db_name, tbl_name, part_vals);
+        if (part == null) {
+          throw new NoSuchObjectException("Partition doesn't exist. "
+              + part_vals);
+        }
+        if (part.getSd() == null || part.getSd().getLocation() == null) {
+          throw new MetaException("Partition metadata is corrupted");
+        }
+        if (!getMS().dropPartition(db_name, tbl_name, part_vals)) {
+          throw new MetaException("Unable to drop partition");
+        }
+        success = getMS().commitTransaction();
+        partPath = new Path(part.getSd().getLocation());
+        tbl = get_table(db_name, tbl_name);
+      } finally {
+        if (!success) {
+          getMS().rollbackTransaction();
+        } else if (deleteData && (partPath != null)) {
+          if (tbl != null && !isExternal(tbl)) {
+            wh.deleteDir(partPath, true);
+            // ok even if the data is not deleted
           }
         }
-        return true;
-      }
-
-      public Partition get_partition(String db_name, String tbl_name, List<String> part_vals)
-          throws MetaException {
-        this.incrementCounter("get_partition");
-        logStartFunction("get_partition", db_name, tbl_name);
-        return getMS().getPartition(db_name, tbl_name, part_vals);
-      }
-
-      public List<Partition> get_partitions(String db_name, String tbl_name, short max_parts)
-          throws NoSuchObjectException, MetaException {
-        this.incrementCounter("get_partitions");
-        logStartFunction("get_partitions", db_name, tbl_name);
-        return getMS().getPartitions(db_name, tbl_name, max_parts);
       }
+      return true;
+    }
 
-      public List<String> get_partition_names(String db_name, String tbl_name, short max_parts) throws MetaException {
-        this.incrementCounter("get_partition_names");
-        logStartFunction("get_partition_names", db_name, tbl_name);
-        return getMS().listPartitionNames(db_name, tbl_name, max_parts);
-      }
+    public Partition get_partition(String db_name, String tbl_name,
+        List<String> part_vals) throws MetaException {
+      incrementCounter("get_partition");
+      logStartFunction("get_partition", db_name, tbl_name);
+      return getMS().getPartition(db_name, tbl_name, part_vals);
+    }
 
-      public void alter_partition(String db_name, String tbl_name,
-          Partition new_part) throws InvalidOperationException, MetaException,
-          TException {
-        this.incrementCounter("alter_partition");
-        logStartFunction("alter_partition", db_name, tbl_name);
-        LOG.info("Partition values:" + new_part.getValues());
-        try {
-          new_part.putToParameters(Constants.DDL_TIME, Long.toString(System.currentTimeMillis() / 1000));
-          getMS().alterPartition(db_name, tbl_name, new_part);
-        } catch(InvalidObjectException e) {
-          LOG.error(StringUtils.stringifyException(e));
-          throw new InvalidOperationException("alter is not possible");
-        }
-      }
+    public List<Partition> get_partitions(String db_name, String tbl_name,
+        short max_parts) throws NoSuchObjectException, MetaException {
+      incrementCounter("get_partitions");
+      logStartFunction("get_partitions", db_name, tbl_name);
+      return getMS().getPartitions(db_name, tbl_name, max_parts);
+    }
 
-      public boolean create_index(Index index_def)
-          throws IndexAlreadyExistsException, MetaException {
-        this.incrementCounter("create_index");
-        // TODO Auto-generated method stub
-        throw new MetaException("Not yet implemented");
-      }
+    public List<String> get_partition_names(String db_name, String tbl_name,
+        short max_parts) throws MetaException {
+      incrementCounter("get_partition_names");
+      logStartFunction("get_partition_names", db_name, tbl_name);
+      return getMS().listPartitionNames(db_name, tbl_name, max_parts);
+    }
 
-      public String getVersion() throws TException {
-        this.incrementCounter("getVersion");
-        logStartFunction("getVersion");
-        return "3.0";
+    public void alter_partition(String db_name, String tbl_name,
+        Partition new_part) throws InvalidOperationException, MetaException,
+        TException {
+      incrementCounter("alter_partition");
+      logStartFunction("alter_partition", db_name, tbl_name);
+      LOG.info("Partition values:" + new_part.getValues());
+      try {
+        new_part.putToParameters(Constants.DDL_TIME, Long.toString(System
+            .currentTimeMillis() / 1000));
+        getMS().alterPartition(db_name, tbl_name, new_part);
+      } catch (InvalidObjectException e) {
+        LOG.error(StringUtils.stringifyException(e));
+        throw new InvalidOperationException("alter is not possible");
       }
+    }
 
-      public void alter_table(String dbname, String name, Table newTable) throws InvalidOperationException,
-          MetaException {
-        this.incrementCounter("alter_table");
-        logStartFunction("truncate_table: db=" + dbname + " tbl=" + name + " newtbl=" + newTable.getTableName());
-        newTable.putToParameters(Constants.DDL_TIME, Long.toString(System.currentTimeMillis() / 1000));
-        alterHandler.alterTable(getMS(), wh, dbname, name, newTable);
-      }
+    public boolean create_index(Index index_def)
+        throws IndexAlreadyExistsException, MetaException {
+      incrementCounter("create_index");
+      // TODO Auto-generated method stub
+      throw new MetaException("Not yet implemented");
+    }
 
-      public List<String> get_tables(String dbname, String pattern) throws MetaException {
-        this.incrementCounter("get_tables");
-        logStartFunction("get_tables: db=" + dbname + " pat=" + pattern);
-        return getMS().getTables(dbname, pattern);
-      }
+    public String getVersion() throws TException {
+      incrementCounter("getVersion");
+      logStartFunction("getVersion");
+      return "3.0";
+    }
 
+    public void alter_table(String dbname, String name, Table newTable)
+        throws InvalidOperationException, MetaException {
+      incrementCounter("alter_table");
+      logStartFunction("truncate_table: db=" + dbname + " tbl=" + name
+          + " newtbl=" + newTable.getTableName());
+      newTable.putToParameters(Constants.DDL_TIME, Long.toString(System
+          .currentTimeMillis() / 1000));
+      alterHandler.alterTable(getMS(), wh, dbname, name, newTable);
+    }
 
-      public List<FieldSchema> get_fields(String db, String tableName)
-        throws MetaException,UnknownTableException, UnknownDBException {
-        this.incrementCounter("get_fields");
-        logStartFunction("get_fields: db=" + db + "tbl=" + tableName);
-        String [] names = tableName.split("\\.");
-        String base_table_name = names[0];
+    public List<String> get_tables(String dbname, String pattern)
+        throws MetaException {
+      incrementCounter("get_tables");
+      logStartFunction("get_tables: db=" + dbname + " pat=" + pattern);
+      return getMS().getTables(dbname, pattern);
+    }
 
-        Table tbl;
-        try {
-          tbl = this.get_table(db, base_table_name);
-        } catch (NoSuchObjectException e) {
-          throw new UnknownTableException(e.getMessage());
-        }
-        boolean isNative = SerDeUtils.isNativeSerDe(tbl.getSd().getSerdeInfo().getSerializationLib());
-        if (isNative)
-          return tbl.getSd().getCols();
-        else {
-          try {
-            Deserializer s = MetaStoreUtils.getDeserializer(this.hiveConf, tbl);
-            return MetaStoreUtils.getFieldsFromDeserializer(tableName, s);
-          } catch(SerDeException e) {
-            StringUtils.stringifyException(e);
-            throw new MetaException(e.getMessage());
-          }
+    public List<FieldSchema> get_fields(String db, String tableName)
+        throws MetaException, UnknownTableException, UnknownDBException {
+      incrementCounter("get_fields");
+      logStartFunction("get_fields: db=" + db + "tbl=" + tableName);
+      String[] names = tableName.split("\\.");
+      String base_table_name = names[0];
+
+      Table tbl;
+      try {
+        tbl = get_table(db, base_table_name);
+      } catch (NoSuchObjectException e) {
+        throw new UnknownTableException(e.getMessage());
+      }
+      boolean isNative = SerDeUtils.isNativeSerDe(tbl.getSd().getSerdeInfo()
+          .getSerializationLib());
+      if (isNative) {
+        return tbl.getSd().getCols();
+      } else {
+        try {
+          Deserializer s = MetaStoreUtils.getDeserializer(hiveConf, tbl);
+          return MetaStoreUtils.getFieldsFromDeserializer(tableName, s);
+        } catch (SerDeException e) {
+          StringUtils.stringifyException(e);
+          throw new MetaException(e.getMessage());
         }
       }
+    }
 
-      /**
-       * Return the schema of the table. This function includes partition columns
-       * in addition to the regular columns.
-       * @param db Name of the database
-       * @param tableName Name of the table
-       * @return List of columns, each column is a FieldSchema structure
-       * @throws MetaException
-       * @throws UnknownTableException
-       * @throws UnknownDBException
-       */
-      public List<FieldSchema> get_schema(String db, String tableName)
+    /**
+     * Return the schema of the table. This function includes partition columns
+     * in addition to the regular columns.
+     * 
+     * @param db
+     *          Name of the database
+     * @param tableName
+     *          Name of the table
+     * @return List of columns, each column is a FieldSchema structure
+     * @throws MetaException
+     * @throws UnknownTableException
+     * @throws UnknownDBException
+     */
+    public List<FieldSchema> get_schema(String db, String tableName)
         throws MetaException, UnknownTableException, UnknownDBException {
-        this.incrementCounter("get_schema");
-        logStartFunction("get_schema: db=" + db + "tbl=" + tableName);
-        String [] names = tableName.split("\\.");
-        String base_table_name = names[0];
+      incrementCounter("get_schema");
+      logStartFunction("get_schema: db=" + db + "tbl=" + tableName);
+      String[] names = tableName.split("\\.");
+      String base_table_name = names[0];
 
-        Table tbl;
-        try {
-          tbl = this.get_table(db, base_table_name);
-        } catch (NoSuchObjectException e) {
-          throw new UnknownTableException(e.getMessage());
-        }
-        List<FieldSchema> fieldSchemas = this.get_fields(db, base_table_name);
-
-        if (tbl == null || fieldSchemas == null) {
-          throw new UnknownTableException(tableName + " doesn't exist");
-        }
+      Table tbl;
+      try {
+        tbl = get_table(db, base_table_name);
+      } catch (NoSuchObjectException e) {
+        throw new UnknownTableException(e.getMessage());
+      }
+      List<FieldSchema> fieldSchemas = get_fields(db, base_table_name);
 
-        if (tbl.getPartitionKeys() != null) {
-          // Combine the column field schemas and the partition keys to create the whole schema
-          fieldSchemas.addAll(tbl.getPartitionKeys());
-        }
-        return fieldSchemas;
+      if (tbl == null || fieldSchemas == null) {
+        throw new UnknownTableException(tableName + " doesn't exist");
       }
 
-      public String getCpuProfile(int profileDurationInSec) throws TException {
-        return "";
+      if (tbl.getPartitionKeys() != null) {
+        // Combine the column field schemas and the partition keys to create the
+        // whole schema
+        fieldSchemas.addAll(tbl.getPartitionKeys());
       }
+      return fieldSchemas;
+    }
 
-      /**
-       * Returns the value of the given configuration variable name. If the
-       * configuration variable with the given name doesn't exist, or if there 
-       * were an exception thrown while retrieving the variable, or if name is 
-       * null, defaultValue is returned.
-       */
-      public String get_config_value(String name, String defaultValue) 
-      throws TException, ConfigValSecurityException {
-        this.incrementCounter("get_config_value");
-        logStartFunction("get_config_value: name=" + name + 
-            " defaultValue=" + defaultValue);
-        if(name == null) {
-          return defaultValue;
-        }
-        // Allow only keys that start with hive.*, hdfs.*, mapred.* for security
-        // i.e. don't allow access to db password
-        if(!Pattern.matches("(hive|hdfs|mapred).*", name)) {
-          throw new ConfigValSecurityException("For security reasons, the " + 
-              "config key " + name + " cannot be accessed");
-        }
-        
-        String toReturn = defaultValue;
-        try {
-          toReturn = hiveConf.get(name, defaultValue);
-        } catch(RuntimeException e) {
-          LOG.error(threadLocalId.get().toString() + ": " + 
-              "RuntimeException thrown in get_config_value - msg: " + 
-              e.getMessage() + " cause: " + e.getCause());
-        }
-        return toReturn;
+    public String getCpuProfile(int profileDurationInSec) throws TException {
+      return "";
+    }
+
+    /**
+     * Returns the value of the given configuration variable name. If the
+     * configuration variable with the given name doesn't exist, or if there
+     * were an exception thrown while retrieving the variable, or if name is
+     * null, defaultValue is returned.
+     */
+    public String get_config_value(String name, String defaultValue)
+        throws TException, ConfigValSecurityException {
+      incrementCounter("get_config_value");
+      logStartFunction("get_config_value: name=" + name + " defaultValue="
+          + defaultValue);
+      if (name == null) {
+        return defaultValue;
+      }
+      // Allow only keys that start with hive.*, hdfs.*, mapred.* for security
+      // i.e. don't allow access to db password
+      if (!Pattern.matches("(hive|hdfs|mapred).*", name)) {
+        throw new ConfigValSecurityException("For security reasons, the "
+            + "config key " + name + " cannot be accessed");
+      }
+
+      String toReturn = defaultValue;
+      try {
+        toReturn = hiveConf.get(name, defaultValue);
+      } catch (RuntimeException e) {
+        LOG.error(threadLocalId.get().toString() + ": "
+            + "RuntimeException thrown in get_config_value - msg: "
+            + e.getMessage() + " cause: " + e.getCause());
       }
+      return toReturn;
+    }
   }
 
   /**
@@ -755,28 +803,32 @@
   public static void main(String[] args) {
     int port = 9083;
 
-    if(args.length > 0) {
+    if (args.length > 0) {
       port = Integer.getInteger(args[0]);
     }
     try {
       TServerTransport serverTransport = new TServerSocket(port);
       Iface handler = new HMSHandler("new db based metaserver");
-      FacebookService.Processor processor = new ThriftHiveMetastore.Processor(handler);
+      FacebookService.Processor processor = new ThriftHiveMetastore.Processor(
+          handler);
       TThreadPoolServer.Options options = new TThreadPoolServer.Options();
       options.minWorkerThreads = 200;
       TServer server = new TThreadPoolServer(processor, serverTransport,
           new TTransportFactory(), new TTransportFactory(),
           new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), options);
-      HMSHandler.LOG.info("Started the new metaserver on port [" + port + "]...");
-      HMSHandler.LOG.info("Options.minWorkerThreads = " + options.minWorkerThreads);
-      HMSHandler.LOG.info("Options.maxWorkerThreads = " + options.maxWorkerThreads);
+      HMSHandler.LOG.info("Started the new metaserver on port [" + port
+          + "]...");
+      HMSHandler.LOG.info("Options.minWorkerThreads = "
+          + options.minWorkerThreads);
+      HMSHandler.LOG.info("Options.maxWorkerThreads = "
+          + options.maxWorkerThreads);
       server.serve();
     } catch (Throwable x) {
       x.printStackTrace();
-      HMSHandler.LOG.error("Metastore Thrift Server threw an exception. Exiting...");
+      HMSHandler.LOG
+          .error("Metastore Thrift Server threw an exception. Exiting...");
       HMSHandler.LOG.error(StringUtils.stringifyException(x));
       System.exit(1);
     }
   }
 }
-