You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by hy...@apache.org on 2014/03/31 17:20:16 UTC

[1/2] TAJO-480: Umbrella Jira for adding ALTER TABLE statement. (Alvin Henrick via hyunsik)

Repository: tajo
Updated Branches:
  refs/heads/master 40851e565 -> bd418a5c3


http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
index 30d4c2e..35ad4c2 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
@@ -125,7 +125,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     Expr current = visitNon_join_query_primary(ctx.non_join_query_primary());
     Expr left;
 
-    for (int i = 1; i < ctx.getChildCount();) {
+    for (int i = 1; i < ctx.getChildCount(); ) {
       int idx = i;
       boolean distinct = true;
 
@@ -147,7 +147,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
         left = current;
         current = new SetOperation(OpType.Intersect, left, right, distinct);
 
-        i+=idx;
+        i += idx;
       }
     }
 
@@ -215,6 +215,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
    *   : select_sublist (COMMA select_sublist)*
    *   ;
    * </pre>
+   *
    * @param ctx
    * @return
    */
@@ -237,6 +238,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
    *   | asterisked_qualifier
    *   ;
    * </pre>
+   *
    * @param ctx
    * @return
    */
@@ -251,7 +253,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
 
   @Override
   public RelationList visitFrom_clause(SQLParser.From_clauseContext ctx) {
-    Expr [] relations = new Expr[ctx.table_reference_list().table_reference().size()];
+    Expr[] relations = new Expr[ctx.table_reference_list().table_reference().size()];
     for (int i = 0; i < relations.length; i++) {
       relations[i] = visitTable_reference(ctx.table_reference_list().table_reference(i));
     }
@@ -308,7 +310,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
   @Override
   public Sort visitOrderby_clause(SQLParser.Orderby_clauseContext ctx) {
     int size = ctx.sort_specifier_list().sort_specifier().size();
-    Sort.SortSpec specs [] = new Sort.SortSpec[size];
+    Sort.SortSpec specs[] = new Sort.SortSpec[size];
     for (int i = 0; i < size; i++) {
       SQLParser.Sort_specifierContext specContext = ctx.sort_specifier_list().sort_specifier(i);
       Expr column = visitRow_value_predicand(specContext.key);
@@ -381,7 +383,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
               join_condition().search_condition());
           join.setQual(searchCondition);
         } else if (ctx.join_specification().named_columns_join() != null) {
-          ColumnReferenceExpr [] columns = getColumnReferences(ctx.join_specification().
+          ColumnReferenceExpr[] columns = getColumnReferences(ctx.join_specification().
               named_columns_join().column_reference_list());
           join.setJoinColumns(columns);
         }
@@ -392,7 +394,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     return join;
   }
 
-  private Expr [] getRowValuePredicandsFromOrdinaryGroupingSetList(Ordinary_grouping_set_listContext ctx) {
+  private Expr[] getRowValuePredicandsFromOrdinaryGroupingSetList(Ordinary_grouping_set_listContext ctx) {
     ArrayList<Expr> rowValuePredicands = new ArrayList<Expr>();
     for (int i = 0; i < ctx.ordinary_grouping_set().size(); i++) {
       Collections.addAll(rowValuePredicands, getRowValuePredicandsFromOrdinaryGroupingSet(ctx.ordinary_grouping_set(i)));
@@ -400,7 +402,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     return rowValuePredicands.toArray(new Expr[rowValuePredicands.size()]);
   }
 
-  private Expr [] getRowValuePredicandsFromOrdinaryGroupingSet(Ordinary_grouping_setContext ctx) {
+  private Expr[] getRowValuePredicandsFromOrdinaryGroupingSet(Ordinary_grouping_setContext ctx) {
     ArrayList<Expr> rowValuePredicands = new ArrayList<Expr>();
     if (ctx.row_value_predicand() != null) {
       rowValuePredicands.add(visitRow_value_predicand(ctx.row_value_predicand()));
@@ -411,16 +413,16 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     return rowValuePredicands.toArray(new Expr[rowValuePredicands.size()]);
   }
 
-  private Expr [] getRowValuePredicands(Row_value_predicand_listContext ctx) {
-    Expr [] rowValuePredicands = new Expr[ctx.row_value_predicand().size()];
+  private Expr[] getRowValuePredicands(Row_value_predicand_listContext ctx) {
+    Expr[] rowValuePredicands = new Expr[ctx.row_value_predicand().size()];
     for (int i = 0; i < rowValuePredicands.length; i++) {
       rowValuePredicands[i] = visitRow_value_predicand(ctx.row_value_predicand(i));
     }
     return rowValuePredicands;
   }
 
-  private ColumnReferenceExpr [] getColumnReferences(Column_reference_listContext ctx) {
-    ColumnReferenceExpr [] columnRefs = new ColumnReferenceExpr[ctx.column_reference().size()];
+  private ColumnReferenceExpr[] getColumnReferences(Column_reference_listContext ctx) {
+    ColumnReferenceExpr[] columnRefs = new ColumnReferenceExpr[ctx.column_reference().size()];
     for (int i = 0; i < columnRefs.length; i++) {
       columnRefs[i] = visitColumn_reference(ctx.column_reference(i));
     }
@@ -482,7 +484,8 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     }
   }
 
-  @Override public CaseWhenPredicate visitSearched_case(SQLParser.Searched_caseContext ctx) {
+  @Override
+  public CaseWhenPredicate visitSearched_case(SQLParser.Searched_caseContext ctx) {
     CaseWhenPredicate caseWhen = new CaseWhenPredicate();
 
     for (int i = 0; i < ctx.searched_when_clause().size(); i++) {
@@ -497,7 +500,8 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     return caseWhen;
   }
 
-  @Override public Expr visitCommon_value_expression(SQLParser.Common_value_expressionContext ctx) {
+  @Override
+  public Expr visitCommon_value_expression(SQLParser.Common_value_expressionContext ctx) {
     if (checkIfExist(ctx.NULL())) {
       return new NullLiteral();
     } else {
@@ -671,7 +675,8 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     return current;
   }
 
-  @Override public Expr visitFactor(SQLParser.FactorContext ctx) {
+  @Override
+  public Expr visitFactor(SQLParser.FactorContext ctx) {
     Expr current = visitNumeric_primary(ctx.numeric_primary());
     if (checkIfExist(ctx.sign()) && checkIfExist(ctx.sign().MINUS())) {
       current = new SignedExpr(true, current);
@@ -696,27 +701,44 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
 
   public static OpType tokenToExprType(int tokenId) {
     switch (tokenId) {
-      case SQLParser.UNION: return OpType.Union;
-      case SQLParser.EXCEPT: return OpType.Except;
-      case SQLParser.INTERSECT: return OpType.Intersect;
-
-      case SQLParser.AND: return OpType.And;
-      case SQLParser.OR: return OpType.Or;
-
-      case SQLParser.EQUAL: return OpType.Equals;
-      case SQLParser.NOT_EQUAL: return OpType.NotEquals;
-      case SQLParser.LTH: return OpType.LessThan;
-      case SQLParser.LEQ: return OpType.LessThanOrEquals;
-      case SQLParser.GTH: return OpType.GreaterThan;
-      case SQLParser.GEQ: return OpType.GreaterThanOrEquals;
-
-      case SQLParser.MULTIPLY: return OpType.Multiply;
-      case SQLParser.DIVIDE: return OpType.Divide;
-      case SQLParser.MODULAR: return OpType.Modular;
-      case SQLParser.PLUS: return OpType.Plus;
-      case SQLParser.MINUS: return OpType.Minus;
-
-      default: throw new RuntimeException("Unknown Token Id: " + tokenId);
+      case SQLParser.UNION:
+        return OpType.Union;
+      case SQLParser.EXCEPT:
+        return OpType.Except;
+      case SQLParser.INTERSECT:
+        return OpType.Intersect;
+
+      case SQLParser.AND:
+        return OpType.And;
+      case SQLParser.OR:
+        return OpType.Or;
+
+      case SQLParser.EQUAL:
+        return OpType.Equals;
+      case SQLParser.NOT_EQUAL:
+        return OpType.NotEquals;
+      case SQLParser.LTH:
+        return OpType.LessThan;
+      case SQLParser.LEQ:
+        return OpType.LessThanOrEquals;
+      case SQLParser.GTH:
+        return OpType.GreaterThan;
+      case SQLParser.GEQ:
+        return OpType.GreaterThanOrEquals;
+
+      case SQLParser.MULTIPLY:
+        return OpType.Multiply;
+      case SQLParser.DIVIDE:
+        return OpType.Divide;
+      case SQLParser.MODULAR:
+        return OpType.Modular;
+      case SQLParser.PLUS:
+        return OpType.Plus;
+      case SQLParser.MINUS:
+        return OpType.Minus;
+
+      default:
+        throw new RuntimeException("Unknown Token Id: " + tokenId);
     }
   }
 
@@ -730,7 +752,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
   public Expr visitIn_predicate_value(SQLParser.In_predicate_valueContext ctx) {
     if (checkIfExist(ctx.in_value_list())) {
       int size = ctx.in_value_list().row_value_expression().size();
-      Expr [] exprs = new Expr[size];
+      Expr[] exprs = new Expr[size];
       for (int i = 0; i < size; i++) {
         exprs[i] = visitRow_value_expression(ctx.in_value_list().row_value_expression(i));
       }
@@ -743,7 +765,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
   @Override
   public Expr visitArray(SQLParser.ArrayContext ctx) {
     int size = ctx.numeric_value_expression().size();
-    Expr [] exprs = new Expr[size];
+    Expr[] exprs = new Expr[size];
     for (int i = 0; i < size; i++) {
       exprs[i] = visit(ctx.numeric_value_expression(i));
     }
@@ -825,7 +847,8 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     }
   }
 
-  @Override public FunctionExpr visitAggregate_function( SQLParser.Aggregate_functionContext ctx) {
+  @Override
+  public FunctionExpr visitAggregate_function(SQLParser.Aggregate_functionContext ctx) {
     if (ctx.COUNT() != null && ctx.MULTIPLY() != null) {
       return new CountRowsFunctionExpr();
     } else {
@@ -833,7 +856,8 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     }
   }
 
-  @Override public FunctionExpr visitGeneral_set_function(SQLParser.General_set_functionContext ctx) {
+  @Override
+  public FunctionExpr visitGeneral_set_function(SQLParser.General_set_functionContext ctx) {
     String signature = ctx.set_function_type().getText();
     boolean distinct = checkIfExist(ctx.set_qualifier()) && checkIfExist(ctx.set_qualifier().DISTINCT());
     Expr param = visitValue_expression(ctx.value_expression());
@@ -847,7 +871,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     FunctionExpr function = new FunctionExpr(signature);
     if (ctx.sql_argument_list() != null) {
       int numArgs = ctx.sql_argument_list().value_expression().size();
-      Expr [] argument_list = new Expr[numArgs];
+      Expr[] argument_list = new Expr[numArgs];
       for (int i = 0; i < numArgs; i++) {
         argument_list[i] = visitValue_expression(ctx.sql_argument_list().
             value_expression().get(i));
@@ -894,7 +918,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
       right = visitCharacter_factor((Character_factorContext) ctx.getChild(i));
 
       if (left.getType() == OpType.Literal && right.getType() == OpType.Literal) {
-        current = new LiteralValue(((LiteralValue)left).getValue() + ((LiteralValue)right).getValue(),
+        current = new LiteralValue(((LiteralValue) left).getValue() + ((LiteralValue) right).getValue(),
             LiteralType.String);
       } else {
         current = new BinaryOperator(OpType.Concatenate, left, right);
@@ -927,7 +951,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     }
 
     String functionName = "date_part";
-    Expr [] params = new Expr[] {extractTarget, extractSource};
+    Expr[] params = new Expr[]{extractTarget, extractSource};
 
     return new FunctionExpr(functionName, params);
   }
@@ -954,11 +978,11 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
       trimCharacters = visitCharacter_value_expression(ctx.trim_operands().trim_character);
     }
 
-    Expr [] params;
+    Expr[] params;
     if (trimCharacters != null) {
-      params = new Expr[] {trimSource, trimCharacters};
+      params = new Expr[]{trimSource, trimCharacters};
     } else {
-      params = new Expr[] {trimSource};
+      params = new Expr[]{trimSource};
     }
 
     return new FunctionExpr(functionName, params);
@@ -982,7 +1006,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     if (checkIfExist(ctx.EXTERNAL())) {
       createTable.setExternal();
 
-      CreateTable.ColumnDefinition [] elements = getDefinitions(ctx.table_elements());
+      ColumnDefinition[] elements = getDefinitions(ctx.table_elements());
       String fileType = ctx.file_type.getText();
       String path = stripQuote(ctx.path.getText());
 
@@ -991,7 +1015,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
       createTable.setLocation(path);
     } else {
       if (checkIfExist(ctx.table_elements())) {
-        CreateTable.ColumnDefinition [] elements = getDefinitions(ctx.table_elements());
+        ColumnDefinition[] elements = getDefinitions(ctx.table_elements());
         createTable.setTableElements(elements);
       }
 
@@ -1019,13 +1043,13 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     return createTable;
   }
 
-  private CreateTable.ColumnDefinition [] getDefinitions(SQLParser.Table_elementsContext ctx) {
+  private ColumnDefinition[] getDefinitions(SQLParser.Table_elementsContext ctx) {
     int size = ctx.field_element().size();
-    CreateTable.ColumnDefinition [] elements = new CreateTable.ColumnDefinition[size];
+    ColumnDefinition[] elements = new ColumnDefinition[size];
     for (int i = 0; i < size; i++) {
       String name = ctx.field_element(i).name.getText();
       DataTypeExpr typeDef = visitData_type(ctx.field_element(i).field_type().data_type());
-      elements[i] = new CreateTable.ColumnDefinition(name, typeDef);
+      elements[i] = new ColumnDefinition(name, typeDef);
     }
 
     return elements;
@@ -1074,7 +1098,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
 
       for (List_value_partitionContext listValuePartition : partitions) {
         int size = listValuePartition.in_value_list().row_value_expression().size();
-        Expr [] exprs = new Expr[size];
+        Expr[] exprs = new Expr[size];
         for (int i = 0; i < size; i++) {
           exprs[i] = visitRow_value_expression(listValuePartition.in_value_list().row_value_expression(i));
         }
@@ -1120,7 +1144,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
         }
 
       } else if (character_string_type.TEXT() != null) {
-        typeDefinition =  new DataTypeExpr(Type.TEXT.name());
+        typeDefinition = new DataTypeExpr(Type.TEXT.name());
       }
 
     } else if (predefined_type.national_character_string_type() != null) {
@@ -1187,7 +1211,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
           typeDefinition = new DataTypeExpr(Type.FLOAT8.name());
         }
       }
-    } else if (predefined_type.boolean_type() != null)  {
+    } else if (predefined_type.boolean_type() != null) {
       typeDefinition = new DataTypeExpr(Type.BOOLEAN.name());
     } else if (predefined_type.datetime_type() != null) {
       SQLParser.Datetime_typeContext dateTimeType = predefined_type.datetime_type();
@@ -1246,7 +1270,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
       insertExpr.setTableName(ctx.table_name().getText());
 
       if (ctx.column_name_list() != null) {
-        String [] targetColumns = new String[ctx.column_name_list().identifier().size()];
+        String[] targetColumns = new String[ctx.column_name_list().identifier().size()];
         for (int i = 0; i < targetColumns.length; i++) {
           targetColumns[i] = ctx.column_name_list().identifier().get(i).getText();
         }
@@ -1296,7 +1320,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     for (Map.Entry<String, String> entry : map.entrySet()) {
       if (entry.getKey().equals(CatalogConstants.CSVFILE_DELIMITER)) {
         params.put(entry.getKey(), escapeDelimiter(entry.getValue()));
-      }  else {
+      } else {
         params.put(entry.getKey(), entry.getValue());
       }
     }
@@ -1317,13 +1341,15 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     return str.substring(1, str.length() - 1);
   }
 
-  @Override public Expr visitCast_specification(SQLParser.Cast_specificationContext ctx) {
+  @Override
+  public Expr visitCast_specification(SQLParser.Cast_specificationContext ctx) {
     Expr operand = visitChildren(ctx.cast_operand());
     DataTypeExpr castTarget = visitData_type(ctx.cast_target().data_type());
     return new CastExpr(operand, castTarget);
   }
 
-  @Override public Expr visitUnsigned_value_specification(@NotNull SQLParser.Unsigned_value_specificationContext ctx) {
+  @Override
+  public Expr visitUnsigned_value_specification(@NotNull SQLParser.Unsigned_value_specificationContext ctx) {
     return visitChildren(ctx);
   }
 
@@ -1351,7 +1377,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
   public Expr visitDatetime_literal(@NotNull SQLParser.Datetime_literalContext ctx) {
     if (checkIfExist(ctx.time_literal())) {
       return visitTime_literal(ctx.time_literal());
-    } else if(checkIfExist(ctx.date_literal())) {
+    } else if (checkIfExist(ctx.date_literal())) {
       return visitDate_literal(ctx.date_literal());
     } else {
       return visitTimestamp_literal(ctx.timestamp_literal());
@@ -1373,7 +1399,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
   @Override
   public Expr visitTimestamp_literal(SQLParser.Timestamp_literalContext ctx) {
     String timestampStr = stripQuote(ctx.timestamp_string.getText());
-    String [] parts = timestampStr.split(" ");
+    String[] parts = timestampStr.split(" ");
     String datePart = parts[0];
     String timePart = parts[1];
     return new TimestampLiteral(parseDate(datePart), parseTime(timePart));
@@ -1381,18 +1407,18 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
 
   private DateValue parseDate(String datePart) {
     // e.g., 1980-04-01
-    String [] parts = datePart.split("-");
+    String[] parts = datePart.split("-");
     return new DateValue(parts[0], parts[1], parts[2]);
   }
 
   private TimeValue parseTime(String timePart) {
     // e.g., 12:01:50.399
-    String [] parts = timePart.split(":");
+    String[] parts = timePart.split(":");
 
     TimeValue time;
     boolean hasFractionOfSeconds = parts[2].indexOf('.') > 0;
     if (hasFractionOfSeconds) {
-      String [] secondsParts = parts[2].split("\\.");
+      String[] secondsParts = parts[2].split("\\.");
       time = new TimeValue(parts[0], parts[1], secondsParts[0]);
       if (secondsParts.length == 2) {
         time.setSecondsFraction(secondsParts[1]);
@@ -1402,4 +1428,77 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     }
     return time;
   }
+
+  @Override
+  public Expr visitAlter_table_statement(SQLParser.Alter_table_statementContext ctx) {
+
+    final List<Table_nameContext> tables = ctx.table_name();
+
+    final AlterTable alterTable = new AlterTable(tables.get(0).getText());
+
+    if (tables.size() == 2) {
+      alterTable.setNewTableName(tables.get(1).getText());
+    }
+
+    if (checkIfExist(ctx.column_name()) && ctx.column_name().size() == 2) {
+      final List<Column_nameContext> columns = ctx.column_name();
+      alterTable.setColumnName(columns.get(0).getText());
+      alterTable.setNewColumnName(columns.get(1).getText());
+    }
+
+    Field_elementContext field_elementContext = ctx.field_element();
+    if (checkIfExist(field_elementContext)) {
+      final String name = field_elementContext.name.getText();
+      final DataTypeExpr typeDef = visitData_type(field_elementContext.field_type().data_type());
+      final ColumnDefinition columnDefinition = new ColumnDefinition(name, typeDef);
+      alterTable.setAddNewColumn(columnDefinition);
+    }
+
+    alterTable.setAlterTableOpType(determineAlterTableType(ctx));
+
+    return alterTable;
+  }
+
+  private AlterTableOpType determineAlterTableType(SQLParser.Alter_table_statementContext ctx) {
+
+    final int RENAME_MASK = 00000001;
+    final int COLUMN_MASK = 00000010;
+    final int TO_MASK = 00000100;
+    final int ADD_MASK = 00001000;
+
+    int val = 00000000;
+
+    for (int idx = 1; idx < ctx.getChildCount(); idx++) {
+
+      if (ctx.getChild(idx) instanceof TerminalNode) {
+        if (((TerminalNode) ctx.getChild(idx)).getSymbol().getType() == RENAME) {
+          val = val | RENAME_MASK;
+        }
+        if (((TerminalNode) ctx.getChild(idx)).getSymbol().getType() == COLUMN) {
+          val = val | COLUMN_MASK;
+        }
+        if (((TerminalNode) ctx.getChild(idx)).getSymbol().getType() == TO) {
+          val = val | TO_MASK;
+        }
+        if (((TerminalNode) ctx.getChild(idx)).getSymbol().getType() == ADD) {
+          val = val | ADD_MASK;
+        }
+      }
+    }
+    return evaluateAlterTableOperationTye(val);
+  }
+
+  private AlterTableOpType evaluateAlterTableOperationTye(final int value) {
+
+    switch (value) {
+      case 65:
+        return AlterTableOpType.RENAME_TABLE;
+      case 73:
+        return AlterTableOpType.RENAME_COLUMN;
+      case 520:
+        return AlterTableOpType.ADD_COLUMN;
+      default:
+        return null;
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
index 84cdc08..0ea2c77 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
@@ -45,8 +45,9 @@ public interface AlgebraVisitor<CONTEXT, RESULT> {
   RESULT visitDropDatabase(CONTEXT ctx, Stack<Expr> stack, DropDatabase expr) throws PlanningException;
   RESULT visitCreateTable(CONTEXT ctx, Stack<Expr> stack, CreateTable expr) throws PlanningException;
   RESULT visitDropTable(CONTEXT ctx, Stack<Expr> stack, DropTable expr) throws PlanningException;
+  RESULT visitAlterTable(CONTEXT ctx, Stack<Expr> stack, AlterTable expr) throws PlanningException;
 
-  // Insert or Update
+    // Insert or Update
   RESULT visitInsert(CONTEXT ctx, Stack<Expr> stack, Insert expr) throws PlanningException;
 
   // Logical operators

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
index 62cee57..6f217a7 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
@@ -109,6 +109,9 @@ public class BaseAlgebraVisitor<CONTEXT, RESULT> implements AlgebraVisitor<CONTE
     case DropTable:
       current = visitDropTable(ctx, stack, (DropTable) expr);
       break;
+    case AlterTable:
+      current = visitAlterTable(ctx, stack, (AlterTable) expr);
+      break;
 
     case Insert:
       current = visitInsert(ctx, stack, (Insert) expr);
@@ -434,6 +437,11 @@ public class BaseAlgebraVisitor<CONTEXT, RESULT> implements AlgebraVisitor<CONTE
     return null;
   }
 
+  @Override
+  public RESULT visitAlterTable(CONTEXT ctx, Stack<Expr> stack, AlterTable expr) throws PlanningException {
+        return null;
+    }
+
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////
   // Insert or Update Section
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java
index 772e5fb..d569758 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java
@@ -116,6 +116,9 @@ public class BasicLogicalPlanVisitor<CONTEXT, RESULT> implements LogicalPlanVisi
       case DROP_TABLE:
         current = visitDropTable(context, plan, block, (DropTableNode) node, stack);
         break;
+      case ALTER_TABLE:
+        current = visitAlterTable(context, plan, block, (AlterTableNode) node, stack);
+        break;
       default:
         throw new PlanningException("Unknown logical node type: " + node.getType());
     }
@@ -298,4 +301,9 @@ public class BasicLogicalPlanVisitor<CONTEXT, RESULT> implements LogicalPlanVisi
                                Stack<LogicalNode> stack) {
     return null;
   }
+  @Override
+  public RESULT visitAlterTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, AlterTableNode node,
+                                 Stack<LogicalNode> stack) {
+        return null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
index 1ac416f..540d45b 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
@@ -413,6 +413,13 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
     return dropTable;
   }
 
+  @Override
+  public LogicalNode visitAlterTable(PreprocessContext ctx, Stack<Expr> stack, AlterTable expr)
+      throws PlanningException {
+    AlterTableNode alterTableNode = ctx.plan.createNode(AlterTableNode.class);
+    return alterTableNode;
+  }
+
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////
   // Insert or Update Section
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanVisitor.java
index 76454b9..7f38026 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanVisitor.java
@@ -82,4 +82,7 @@ public interface LogicalPlanVisitor<CONTEXT, RESULT> {
 
   RESULT visitDropTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, DropTableNode node,
                         Stack<LogicalNode> stack) throws PlanningException;
+
+  RESULT visitAlterTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, AlterTableNode node,
+                          Stack<LogicalNode> stack) throws PlanningException;
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
index 15fe6c0..317c05b 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
@@ -30,7 +30,6 @@ import org.apache.hadoop.fs.FileStatus;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.tajo.algebra.*;
-import org.apache.tajo.algebra.CreateTable.ColumnDefinition;
 import org.apache.tajo.catalog.*;
 import org.apache.tajo.catalog.partition.PartitionMethodDesc;
 import org.apache.tajo.catalog.proto.CatalogProtos;
@@ -1412,10 +1411,10 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
    * @param elements to be transformed
    * @return schema transformed from table definition elements
    */
-  private Schema convertColumnsToSchema(CreateTable.ColumnDefinition[] elements) {
+  private Schema convertColumnsToSchema(ColumnDefinition[] elements) {
     Schema schema = new Schema();
 
-    for (CreateTable.ColumnDefinition columnDefinition: elements) {
+    for (ColumnDefinition columnDefinition: elements) {
       schema.addColumn(convertColumn(columnDefinition));
     }
 
@@ -1428,10 +1427,10 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
    * @param elements to be transformed
    * @return schema transformed from table definition elements
    */
-  private Schema convertTableElementsSchema(CreateTable.ColumnDefinition[] elements) {
+  private Schema convertTableElementsSchema(ColumnDefinition[] elements) {
     Schema schema = new Schema();
 
-    for (CreateTable.ColumnDefinition columnDefinition: elements) {
+    for (ColumnDefinition columnDefinition: elements) {
       schema.addColumn(convertColumn(columnDefinition));
     }
 
@@ -1467,6 +1466,21 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
     return dropTableNode;
   }
 
+  @Override
+  public LogicalNode visitAlterTable(PlanContext context, Stack<Expr> stack, AlterTable alterTable) {
+    AlterTableNode alterTableNode = context.queryBlock.getNodeFromExpr(alterTable);
+    alterTableNode.setTableName(alterTable.getTableName());
+    alterTableNode.setNewTableName(alterTable.getNewTableName());
+    alterTableNode.setColumnName(alterTable.getColumnName());
+    alterTableNode.setNewColumnName(alterTable.getNewColumnName());
+
+    if (null != alterTable.getAddNewColumn()) {
+      alterTableNode.setAddNewColumn(convertColumn(alterTable.getAddNewColumn()));
+    }
+    alterTableNode.setAlterTableOpType(alterTable.getAlterTableOpType());
+    return alterTableNode;
+  }
+
   /*===============================================================================================
     Util SECTION
   ===============================================================================================*/

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
index fbd65a9..ccd9847 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
@@ -49,9 +49,9 @@ public class PlannerUtil {
 
     return
         type == NodeType.CREATE_DATABASE ||
-        type == NodeType.DROP_DATABASE ||
-        (type == NodeType.CREATE_TABLE && !((CreateTableNode)baseNode).hasSubQuery()) ||
-        baseNode.getType() == NodeType.DROP_TABLE;
+            type == NodeType.DROP_DATABASE ||
+            (type == NodeType.CREATE_TABLE && !((CreateTableNode) baseNode).hasSubQuery()) ||
+            baseNode.getType() == NodeType.DROP_TABLE || baseNode.getType() == NodeType.ALTER_TABLE;
   }
 
   /**
@@ -60,9 +60,9 @@ public class PlannerUtil {
    * @param from The LogicalNode to start visiting LogicalNodes.
    * @return an array of all descendant RelationNode of LogicalNode.
    */
-  public static String [] getRelationLineage(LogicalNode from) {
-    LogicalNode [] scans = findAllNodes(from, NodeType.SCAN, NodeType.PARTITIONS_SCAN);
-    String [] tableNames = new String[scans.length];
+  public static String[] getRelationLineage(LogicalNode from) {
+    LogicalNode[] scans = findAllNodes(from, NodeType.SCAN, NodeType.PARTITIONS_SCAN);
+    String[] tableNames = new String[scans.length];
     ScanNode scan;
     for (int i = 0; i < scans.length; i++) {
       scan = (ScanNode) scans[i];
@@ -106,11 +106,11 @@ public class PlannerUtil {
       return node;
     }
   }
-  
+
   /**
    * Delete the logical node from a plan.
    *
-   * @param parent this node must be a parent node of one node to be removed.
+   * @param parent      this node must be a parent node of one node to be removed.
    * @param tobeRemoved this node must be a child node of the parent.
    */
   public static LogicalNode deleteNode(LogicalNode parent, LogicalNode tobeRemoved) {
@@ -137,7 +137,7 @@ public class PlannerUtil {
       }
     } else {
       throw new InvalidQueryException("Unexpected logical plan: " + parent);
-    }    
+    }
     return child;
   }
 
@@ -233,13 +233,13 @@ public class PlannerUtil {
 
     @Override
     public LogicalNode visitPartitionedTableScan(ReplacerContext context, LogicalPlan plan, LogicalPlan.
-        QueryBlock block,PartitionedTableScanNode node, Stack<LogicalNode> stack)
+        QueryBlock block, PartitionedTableScanNode node, Stack<LogicalNode> stack)
 
         throws PlanningException {
       return node;
     }
   }
-  
+
   public static void replaceNode(LogicalNode plan, LogicalNode newNode, NodeType type) {
     LogicalNode parent = findTopParentNode(plan, type);
     Preconditions.checkArgument(parent instanceof UnaryNode);
@@ -254,7 +254,7 @@ public class PlannerUtil {
 
   /**
    * Find the top logical node matched to type from the given node
-   * 
+   *
    * @param node start node
    * @param type to find
    * @return a found logical node
@@ -262,10 +262,10 @@ public class PlannerUtil {
   public static <T extends LogicalNode> T findTopNode(LogicalNode node, NodeType type) {
     Preconditions.checkNotNull(node);
     Preconditions.checkNotNull(type);
-    
+
     LogicalNodeFinder finder = new LogicalNodeFinder(type);
     node.preOrder(finder);
-    
+
     if (finder.getFoundNodes().size() == 0) {
       return null;
     }
@@ -299,7 +299,7 @@ public class PlannerUtil {
    * @param type to find
    * @return a found logical node
    */
-  public static LogicalNode [] findAllNodes(LogicalNode node, NodeType...type) {
+  public static LogicalNode[] findAllNodes(LogicalNode node, NodeType... type) {
     Preconditions.checkNotNull(node);
     Preconditions.checkNotNull(type);
 
@@ -307,15 +307,15 @@ public class PlannerUtil {
     node.postOrder(finder);
 
     if (finder.getFoundNodes().size() == 0) {
-      return new LogicalNode[] {};
+      return new LogicalNode[]{};
     }
     List<LogicalNode> founds = finder.getFoundNodes();
     return founds.toArray(new LogicalNode[founds.size()]);
   }
-  
+
   /**
    * Find a parent node of a given-typed operator.
-   * 
+   *
    * @param node start node
    * @param type to find
    * @return the parent node of a found logical node
@@ -323,10 +323,10 @@ public class PlannerUtil {
   public static <T extends LogicalNode> T findTopParentNode(LogicalNode node, NodeType type) {
     Preconditions.checkNotNull(node);
     Preconditions.checkNotNull(type);
-    
+
     ParentNodeFinder finder = new ParentNodeFinder(type);
     node.postOrder(finder);
-    
+
     if (finder.getFoundNodes().size() == 0) {
       return null;
     }
@@ -339,7 +339,7 @@ public class PlannerUtil {
     private boolean topmost = false;
     private boolean finished = false;
 
-    public LogicalNodeFinder(NodeType...type) {
+    public LogicalNodeFinder(NodeType... type) {
       this.tofind = type;
     }
 
@@ -366,11 +366,11 @@ public class PlannerUtil {
       return list;
     }
 
-    public LogicalNode [] getFoundNodeArray() {
+    public LogicalNode[] getFoundNodeArray() {
       return list.toArray(new LogicalNode[list.size()]);
     }
   }
-  
+
   private static class ParentNodeFinder implements LogicalNodeVisitor {
     private List<LogicalNode> list = new ArrayList<LogicalNode>();
     private NodeType tofind;
@@ -386,7 +386,7 @@ public class PlannerUtil {
         if (unary.getChild().getType() == tofind) {
           list.add(node);
         }
-      } else if (node instanceof BinaryNode){
+      } else if (node instanceof BinaryNode) {
         BinaryNode bin = (BinaryNode) node;
         if (bin.getLeftChild().getType() == tofind ||
             bin.getRightChild().getType() == tofind) {
@@ -403,10 +403,10 @@ public class PlannerUtil {
   /**
    * fill targets with FieldEvals from a given schema
    *
-   * @param schema to be transformed to targets
+   * @param schema  to be transformed to targets
    * @param targets to be filled
    */
-  public static void schemaToTargets(Schema schema, Target [] targets) {
+  public static void schemaToTargets(Schema schema, Target[] targets) {
     FieldEval eval;
     for (int i = 0; i < schema.size(); i++) {
       eval = new FieldEval(schema.getColumn(i));
@@ -440,7 +440,7 @@ public class PlannerUtil {
     return schemaToSortSpecs(schema.toArray());
   }
 
-  public static SortSpec[] schemaToSortSpecs(Column [] columns) {
+  public static SortSpec[] schemaToSortSpecs(Column[] columns) {
     SortSpec[] specs = new SortSpec[columns.length];
 
     for (int i = 0; i < columns.length; i++) {
@@ -450,7 +450,7 @@ public class PlannerUtil {
     return specs;
   }
 
-  public static SortSpec [] columnsToSortSpec(Collection<Column> columns) {
+  public static SortSpec[] columnsToSortSpec(Collection<Column> columns) {
     SortSpec[] specs = new SortSpec[columns.size()];
     int i = 0;
     for (Column column : columns) {
@@ -472,7 +472,7 @@ public class PlannerUtil {
   /**
    * is it join qual or not?
    *
-   * @param qual  The condition to be checked
+   * @param qual The condition to be checked
    * @return true if two operands refers to columns and the operator is comparison,
    */
   public static boolean isJoinQual(EvalNode qual) {
@@ -489,7 +489,7 @@ public class PlannerUtil {
   }
 
   public static SortSpec[][] getSortKeysFromJoinQual(EvalNode joinQual, Schema outer, Schema inner) {
-    List<Column []> joinKeyPairs = getJoinKeyPairs(joinQual, outer, inner);
+    List<Column[]> joinKeyPairs = getJoinKeyPairs(joinQual, outer, inner);
     SortSpec[] outerSortSpec = new SortSpec[joinKeyPairs.size()];
     SortSpec[] innerSortSpec = new SortSpec[joinKeyPairs.size()];
 
@@ -498,12 +498,12 @@ public class PlannerUtil {
       innerSortSpec[i] = new SortSpec(joinKeyPairs.get(i)[1]);
     }
 
-    return new SortSpec[][] {outerSortSpec, innerSortSpec};
+    return new SortSpec[][]{outerSortSpec, innerSortSpec};
   }
 
   public static TupleComparator[] getComparatorsFromJoinQual(EvalNode joinQual, Schema leftSchema, Schema rightSchema) {
     SortSpec[][] sortSpecs = getSortKeysFromJoinQual(joinQual, leftSchema, rightSchema);
-    TupleComparator [] comparators = new TupleComparator[2];
+    TupleComparator[] comparators = new TupleComparator[2];
     comparators[0] = new TupleComparator(leftSchema, sortSpecs[0]);
     comparators[1] = new TupleComparator(rightSchema, sortSpecs[1]);
     return comparators;
@@ -512,27 +512,27 @@ public class PlannerUtil {
   /**
    * @return the first array contains left table's columns, and the second array contains right table's columns.
    */
-  public static Column [][] joinJoinKeyForEachTable(EvalNode joinQual, Schema leftSchema, Schema rightSchema) {
-    List<Column []> joinKeys = getJoinKeyPairs(joinQual, leftSchema, rightSchema);
-    Column [] leftColumns = new Column[joinKeys.size()];
-    Column [] rightColumns = new Column[joinKeys.size()];
+  public static Column[][] joinJoinKeyForEachTable(EvalNode joinQual, Schema leftSchema, Schema rightSchema) {
+    List<Column[]> joinKeys = getJoinKeyPairs(joinQual, leftSchema, rightSchema);
+    Column[] leftColumns = new Column[joinKeys.size()];
+    Column[] rightColumns = new Column[joinKeys.size()];
     for (int i = 0; i < joinKeys.size(); i++) {
       leftColumns[i] = joinKeys.get(i)[0];
       rightColumns[i] = joinKeys.get(i)[1];
     }
 
-    return new Column[][] {leftColumns, rightColumns};
+    return new Column[][]{leftColumns, rightColumns};
   }
 
-  public static List<Column []> getJoinKeyPairs(EvalNode joinQual, Schema leftSchema, Schema rightSchema) {
+  public static List<Column[]> getJoinKeyPairs(EvalNode joinQual, Schema leftSchema, Schema rightSchema) {
     JoinKeyPairFinder finder = new JoinKeyPairFinder(leftSchema, rightSchema);
     joinQual.preOrder(finder);
     return finder.getPairs();
   }
 
   public static class JoinKeyPairFinder implements EvalNodeVisitor {
-    private final List<Column []> pairs = Lists.newArrayList();
-    private Schema [] schemas = new Schema[2];
+    private final List<Column[]> pairs = Lists.newArrayList();
+    private Schema[] schemas = new Schema[2];
 
     public JoinKeyPairFinder(Schema outer, Schema inner) {
       schemas[0] = outer;
@@ -542,13 +542,13 @@ public class PlannerUtil {
     @Override
     public void visit(EvalNode node) {
       if (EvalTreeUtil.isJoinQual(node)) {
-        Column [] pair = new Column[2];
+        Column[] pair = new Column[2];
 
         for (int i = 0; i <= 1; i++) { // access left, right sub expression
           Column column = EvalTreeUtil.findAllColumnRefs(node.getExpr(i)).get(0);
           for (int j = 0; j < schemas.length; j++) {
-          // check whether the column is for either outer or inner
-          // 0 is outer, and 1 is inner
+            // check whether the column is for either outer or inner
+            // 0 is outer, and 1 is inner
             if (schemas[j].containsByQualifiedName(column.getQualifiedName())) {
               pair[j] = column;
             }
@@ -562,7 +562,7 @@ public class PlannerUtil {
       }
     }
 
-    public List<Column []> getPairs() {
+    public List<Column[]> getPairs() {
       return this.pairs;
     }
   }
@@ -573,7 +573,7 @@ public class PlannerUtil {
 
   public static Schema targetToSchema(Target[] targets) {
     Schema schema = new Schema();
-    for(Target t : targets) {
+    for (Target t : targets) {
       DataType type = t.getEvalTree().getValueType();
       String name;
       if (t.hasAlias()) {
@@ -595,9 +595,9 @@ public class PlannerUtil {
    * @param sourceTargets The targets to be stripped
    * @return The stripped targets
    */
-  public static Target [] stripTarget(Target [] sourceTargets) {
-    Target [] copy = new Target[sourceTargets.length];
-    for(int i = 0; i < sourceTargets.length; i++) {
+  public static Target[] stripTarget(Target[] sourceTargets) {
+    Target[] copy = new Target[sourceTargets.length];
+    for (int i = 0; i < sourceTargets.length; i++) {
       try {
         copy[i] = (Target) sourceTargets[i].clone();
       } catch (CloneNotSupportedException e) {
@@ -650,6 +650,7 @@ public class PlannerUtil {
     boolean generalSetFunction;
     boolean distinctSetFunction;
   }
+
   static class AggregationFunctionFinder extends SimpleAlgebraVisitor<AggFunctionFoundResult, Object> {
     @Override
     public Object visitCountRowsFunction(AggFunctionFoundResult ctx, Stack<Expr> stack, CountRowsFunctionExpr expr)
@@ -670,7 +671,7 @@ public class PlannerUtil {
   public static Collection<String> toQualifiedFieldNames(Collection<String> fieldNames, String qualifier) {
     List<String> names = TUtil.newList();
     for (String n : fieldNames) {
-      String [] parts = n.split("\\.");
+      String[] parts = n.split("\\.");
       if (parts.length == 1) {
         names.add(qualifier + "." + parts[0]);
       } else {
@@ -680,8 +681,8 @@ public class PlannerUtil {
     return names;
   }
 
-  public static SortSpec [] convertSortSpecs(Collection<CatalogProtos.SortSpecProto> sortSpecProtos) {
-    SortSpec [] sortSpecs = new SortSpec[sortSpecProtos.size()];
+  public static SortSpec[] convertSortSpecs(Collection<CatalogProtos.SortSpecProto> sortSpecProtos) {
+    SortSpec[] sortSpecs = new SortSpec[sortSpecProtos.size()];
     int i = 0;
     for (CatalogProtos.SortSpecProto proto : sortSpecProtos) {
       sortSpecs[i++] = new SortSpec(proto);
@@ -701,7 +702,7 @@ public class PlannerUtil {
     StringBuilder explains = new StringBuilder();
     try {
       ExplainLogicalPlanVisitor.Context explainContext = explain.getBlockPlanStrings(null, node);
-      while(!explainContext.explains.empty()) {
+      while (!explainContext.explains.empty()) {
         explains.append(
             ExplainLogicalPlanVisitor.printDepthString(explainContext.getMaxDepth(), explainContext.explains.pop()));
       }

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/SimpleAlgebraVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/SimpleAlgebraVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/SimpleAlgebraVisitor.java
index dc7b7a2..bae6e4a 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/SimpleAlgebraVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/SimpleAlgebraVisitor.java
@@ -121,10 +121,15 @@ public abstract class SimpleAlgebraVisitor<CONTEXT, RESULT> extends BaseAlgebraV
     return super.visitDropTable(ctx, stack, expr);
   }
 
+  @Override
+  public RESULT visitAlterTable(CONTEXT ctx, Stack<Expr> stack, AlterTable expr) throws PlanningException {
+    return super.visitAlterTable(ctx, stack, expr);
+  }
+
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////
   // Insert or Update Section
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+  @Override
   public RESULT visitInsert(CONTEXT ctx, Stack<Expr> stack, Insert expr) throws PlanningException {
     return super.visitInsert(ctx, stack, expr);
   }

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/AlterTableNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/AlterTableNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/AlterTableNode.java
new file mode 100644
index 0000000..76a47d0
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/AlterTableNode.java
@@ -0,0 +1,134 @@
+/**
+ * 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.tajo.engine.planner.logical;
+
+
+import com.google.gson.annotations.Expose;
+import org.apache.tajo.algebra.AlterTableOpType;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.engine.planner.PlanString;
+
+public class AlterTableNode extends LogicalNode {
+
+  @Expose
+  private String tableName;
+  @Expose
+  private String newTableName;
+  @Expose
+  private String columnName;
+  @Expose
+  private String newColumnName;
+  @Expose
+  private Column addNewColumn;
+  @Expose
+  private AlterTableOpType alterTableOpType;
+
+  public AlterTableNode(int pid) {
+    super(pid, NodeType.ALTER_TABLE);
+  }
+
+  public String getTableName() {
+    return tableName;
+  }
+
+  public void setTableName(String tableName) {
+    this.tableName = tableName;
+  }
+
+  public String getNewTableName() {
+    return newTableName;
+  }
+
+  public void setNewTableName(String newTableName) {
+    this.newTableName = newTableName;
+  }
+
+  public String getColumnName() {
+    return columnName;
+  }
+
+  public void setColumnName(String columnName) {
+    this.columnName = columnName;
+  }
+
+  public String getNewColumnName() {
+    return newColumnName;
+  }
+
+  public void setNewColumnName(String newColumnName) {
+    this.newColumnName = newColumnName;
+  }
+
+  public Column getAddNewColumn() {
+    return addNewColumn;
+  }
+
+  public void setAddNewColumn(Column addNewColumn) {
+    this.addNewColumn = addNewColumn;
+  }
+
+  public AlterTableOpType getAlterTableOpType() {
+    return alterTableOpType;
+  }
+
+  public void setAlterTableOpType(AlterTableOpType alterTableOpType) {
+    this.alterTableOpType = alterTableOpType;
+  }
+
+  @Override
+  public PlanString getPlanString() {
+    return new PlanString(this);
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof AlterTableNode) {
+      AlterTableNode other = (AlterTableNode) obj;
+      return super.equals(other);
+    } else {
+      return false;
+    }
+  }
+
+    /*@Override
+    public Object clone() throws CloneNotSupportedException {
+        AlterTableNode alterTableNode = (AlterTableNode) super.clone();
+        alterTableNode.tableName = tableName;
+        alterTableNode.newTableName = newTableName;
+        alterTableNode.columnName = columnName;
+        alterTableNode.newColumnName=newColumnName;
+        alterTableNode.addNewColumn =(Column) addNewColumn.clone();
+        return alterTableNode;
+    }*/
+
+  @Override
+  public String toString() {
+    return "AlterTable (table=" + tableName + ")";
+  }
+
+  @Override
+  public void preOrder(LogicalNodeVisitor visitor) {
+    visitor.visit(this);
+  }
+
+  @Override
+  public void postOrder(LogicalNodeVisitor visitor) {
+    visitor.visit(this);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java
index 2b453fb..375926e 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java
@@ -21,6 +21,7 @@
  */
 package org.apache.tajo.engine.planner.logical;
 
+
 /**
  * This indicates a logical node type.
  */
@@ -47,8 +48,8 @@ public enum NodeType {
   CREATE_DATABASE(CreateDatabaseNode.class),
   DROP_DATABASE(DropDatabaseNode.class),
   CREATE_TABLE(CreateTableNode.class),
-  DROP_TABLE(DropTableNode.class)
-  ;
+  DROP_TABLE(DropTableNode.class),
+  ALTER_TABLE (AlterTableNode.class);
 
   private final Class<? extends LogicalNode> baseClass;
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
index fe3caeb..b0c0614 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
@@ -235,7 +235,10 @@ public class GlobalEngine extends AbstractService {
         DropTableNode dropTable = (DropTableNode) root;
         dropTable(session, dropTable.getTableName(), dropTable.isIfExists(), dropTable.isPurge());
         return true;
-
+      case ALTER_TABLE:
+         AlterTableNode alterTable = (AlterTableNode) root;
+         alterTable(session,alterTable);
+         return true;
       default:
         throw new InternalError("updateQuery cannot handle such query: \n" + root.toJson());
     }
@@ -275,6 +278,82 @@ public class GlobalEngine extends AbstractService {
     return plan;
   }
 
+  /**
+   * Alter a given table
+   */
+  public void alterTable(final Session session, final AlterTableNode alterTable) throws IOException {
+
+    final CatalogService catalog = context.getCatalog();
+    final String tableName = alterTable.getTableName();
+
+    String databaseName;
+    String simpleTableName;
+    if (CatalogUtil.isFQTableName(tableName)) {
+      String[] split = CatalogUtil.splitFQTableName(tableName);
+      databaseName = split[0];
+      simpleTableName = split[1];
+    } else {
+      databaseName = session.getCurrentDatabase();
+      simpleTableName = tableName;
+    }
+    final String qualifiedName = CatalogUtil.buildFQName(databaseName, simpleTableName);
+
+    if (!catalog.existsTable(databaseName, simpleTableName)) {
+      throw new NoSuchTableException(qualifiedName);
+    }
+
+    switch (alterTable.getAlterTableOpType()) {
+      case RENAME_TABLE:
+        if (!catalog.existsTable(databaseName, simpleTableName)) {
+          throw new NoSuchTableException(alterTable.getTableName());
+        }
+        if (catalog.existsTable(databaseName, alterTable.getNewTableName())) {
+          throw new AlreadyExistsTableException(alterTable.getNewTableName());
+        }
+
+        TableDesc desc = catalog.getTableDesc(databaseName, simpleTableName);
+
+        if (!desc.isExternal()) { // if the table is the managed table
+          Path oldPath = StorageUtil.concatPath(context.getConf().getVar(TajoConf.ConfVars.WAREHOUSE_DIR),
+              databaseName, simpleTableName);
+          Path newPath = StorageUtil.concatPath(context.getConf().getVar(TajoConf.ConfVars.WAREHOUSE_DIR),
+              databaseName, alterTable.getNewTableName());
+          FileSystem fs = oldPath.getFileSystem(context.getConf());
+
+          if (!fs.exists(oldPath)) {
+            throw new IOException("No such a table directory: " + oldPath);
+          }
+          if (fs.exists(newPath)) {
+            throw new IOException("Already table directory exists: " + newPath);
+          }
+
+          fs.rename(oldPath, newPath);
+        }
+        catalog.alterTable(CatalogUtil.renameTable(qualifiedName, alterTable.getNewTableName(),
+            AlterTableType.RENAME_TABLE));
+        break;
+      case RENAME_COLUMN:
+        if (existColumnName(qualifiedName, alterTable.getNewColumnName())) {
+          throw new ColumnNameAlreadyExistException(alterTable.getNewColumnName());
+        }
+        catalog.alterTable(CatalogUtil.renameColumn(qualifiedName, alterTable.getColumnName(), alterTable.getNewColumnName(), AlterTableType.RENAME_COLUMN));
+        break;
+      case ADD_COLUMN:
+        if (existColumnName(qualifiedName, alterTable.getAddNewColumn().getSimpleName())) {
+          throw new ColumnNameAlreadyExistException(alterTable.getAddNewColumn().getSimpleName());
+        }
+        catalog.alterTable(CatalogUtil.addNewColumn(qualifiedName, alterTable.getAddNewColumn(), AlterTableType.ADD_COLUMN));
+        break;
+      default:
+        //TODO
+    }
+  }
+
+  private boolean existColumnName(String tableName, String columnName) {
+    final TableDesc tableDesc = catalog.getTableDesc(tableName);
+    return tableDesc.getSchema().containsByName(columnName) ? true : false;
+  }
+
   private TableDesc createTable(Session session, CreateTableNode createTable, boolean ifNotExists) throws IOException {
     TableMeta meta;
 
@@ -287,7 +366,18 @@ public class GlobalEngine extends AbstractService {
     if(createTable.isExternal()){
       Preconditions.checkState(createTable.hasPath(), "ERROR: LOCATION must be given.");
     } else {
-      Path tablePath = new Path(sm.getWarehouseDir(), createTable.getTableName());
+      String databaseName;
+      String tableName;
+      if (CatalogUtil.isFQTableName(createTable.getTableName())) {
+        databaseName = CatalogUtil.extractQualifier(createTable.getTableName());
+        tableName = CatalogUtil.extractSimpleName(createTable.getTableName());
+      } else {
+        databaseName = session.getCurrentDatabase();
+        tableName = createTable.getTableName();
+      }
+
+      // create a table directory (i.e., ${WAREHOUSE_DIR}/${DATABASE_NAME}/${TABLE_NAME} )
+      Path tablePath = StorageUtil.concatPath(sm.getWarehouseDir(), databaseName, tableName);
       createTable.setPath(tablePath);
     }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java
index 65a0d47..784fea5 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java
@@ -23,10 +23,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
-import org.apache.tajo.algebra.CreateTable;
-import org.apache.tajo.algebra.DropTable;
-import org.apache.tajo.algebra.Expr;
-import org.apache.tajo.algebra.OpType;
+import org.apache.tajo.algebra.*;
 import org.apache.tajo.annotation.Nullable;
 import org.apache.tajo.catalog.CatalogService;
 import org.apache.tajo.catalog.CatalogUtil;
@@ -321,6 +318,15 @@ public class QueryTestCaseBase {
     assertTrue(client.existTable(tableName));
   }
 
+  public void assertColumnExists(String tableName,String columnName) throws ServiceException {
+    TableDesc tableDesc = fetchTableMetaData(tableName);
+    assertTrue(tableDesc.getSchema().containsByName(columnName));
+  }
+
+  private TableDesc fetchTableMetaData(String tableName) throws ServiceException {
+    return client.getTableDesc(tableName);
+  }
+
   public void assertTableNotExists(String tableName) throws ServiceException {
     assertTrue(!client.existTable(tableName));
   }
@@ -403,7 +409,7 @@ public class QueryTestCaseBase {
   }
 
   private List<String> executeDDL(String ddlFileName, @Nullable String dataFileName, boolean isLocalTable,
-                            @Nullable String [] args) throws Exception {
+                                  @Nullable String[] args) throws Exception {
 
     Path ddlFilePath = new Path(currentQueryPath, ddlFileName);
     FileSystem fs = ddlFilePath.getFileSystem(conf);
@@ -431,7 +437,7 @@ public class QueryTestCaseBase {
         TableDesc createdTable = client.getTableDesc(tableName);
         String createdTableName = createdTable.getName();
 
-        assertTrue("table '" + createdTableName  + "' creation check", client.existTable(createdTableName));
+        assertTrue("table '" + createdTableName + "' creation check", client.existTable(createdTableName));
         if (isLocalTable) {
           createdTableGlobalSet.add(createdTableName);
           createdTableNames.add(tableName);
@@ -447,6 +453,14 @@ public class QueryTestCaseBase {
         if (isLocalTable) {
           createdTableGlobalSet.remove(tableName);
         }
+      } else if (expr.getType() == OpType.AlterTable) {
+        AlterTable alterTable = (AlterTable) expr;
+        String tableName = alterTable.getTableName();
+        assertTrue("table '" + tableName + "' existence check", client.existTable(tableName));
+        client.updateQuery(compiled);
+        if (isLocalTable) {
+          createdTableGlobalSet.remove(tableName);
+        }
       } else {
         assertTrue(ddlFilePath + " is not a Create or Drop Table statement", false);
       }

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java
new file mode 100644
index 0000000..5779347
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java
@@ -0,0 +1,53 @@
+/**
+ * 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.tajo.engine.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.util.List;
+
+@Category(IntegrationTest.class)
+public class TestAlterTable extends QueryTestCaseBase {
+  @Test
+  public final void testAlterTableName() throws Exception {
+    List<String> createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "ABC");
+    assertTableExists(createdNames.get(0));
+    executeDDL("alter_table_rename_table_ddl.sql", null);
+    assertTableExists("DEF");
+
+  }
+
+  @Test
+  public final void testAlterTableColumnName() throws Exception {
+    List<String> createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "XYZ");
+    executeDDL("alter_table_rename_column_ddl.sql", null);
+    assertColumnExists(createdNames.get(0),"renum");
+  }
+
+  @Test
+  public final void testAlterTableAddNewColumn() throws Exception {
+    List<String> createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "EFG");
+    executeDDL("alter_table_add_new_column_ddl.sql", null);
+    assertColumnExists(createdNames.get(0),"cool");
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
index e6840f6..72e92d2 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
@@ -212,13 +212,15 @@ public class TestCTASQuery extends QueryTestCaseBase {
 
   @Test
   public final void testCtasWithManagedTable() throws Exception {
-    ResultSet res = executeFile("CtasWithManagedTable.sql");
-    res.close();
-
-    assertFalse(client.existTable("MANAGED_TABLE1"));
-    assertTrue(client.existTable("\"MANAGED_TABLE1\""));
-    TableDesc desc =  client.getTableDesc("\"MANAGED_TABLE1\"");
-    assertNotNull(desc);
-    assertEquals("MANAGED_TABLE1", desc.getPath().getName());
+    if (!testingCluster.isHCatalogStoreRunning()) {
+      ResultSet res = executeFile("CtasWithManagedTable.sql");
+      res.close();
+
+      assertFalse(client.existTable("MANAGED_TABLE1"));
+      assertTrue(client.existTable("\"MANAGED_TABLE1\""));
+      TableDesc desc =  client.getTableDesc("\"MANAGED_TABLE1\"");
+      assertNotNull(desc);
+      assertEquals("MANAGED_TABLE1", desc.getPath().getName());
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCreateTable.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCreateTable.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCreateTable.java
index a5b57b2..a6bb467 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCreateTable.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCreateTable.java
@@ -18,14 +18,23 @@
 
 package org.apache.tajo.engine.query;
 
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
 import org.apache.tajo.IntegrationTest;
 import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.storage.StorageUtil;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import java.sql.ResultSet;
 import java.util.List;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
 @Category(IntegrationTest.class)
 public class TestCreateTable extends QueryTestCaseBase {
 
@@ -79,6 +88,56 @@ public class TestCreateTable extends QueryTestCaseBase {
     assertDatabaseNotExists("D2");
   }
 
+  private final void assertPathOfCreatedTable(final String databaseName,
+                                              final String originalTableName,
+                                              final String newTableName,
+                                              String createTableStmt) throws Exception {
+    // create one table
+    executeString("CREATE DATABASE " + CatalogUtil.denormalizeIdentifier(databaseName)).close();
+    getClient().existDatabase(CatalogUtil.denormalizeIdentifier(databaseName));
+    final String oldFQTableName = CatalogUtil.buildFQName(databaseName, originalTableName);
+
+    ResultSet res = executeString(createTableStmt);
+    res.close();
+    assertTableExists(CatalogUtil.denormalizeIdentifier(oldFQTableName));
+    TableDesc oldTableDesc = client.getTableDesc(CatalogUtil.denormalizeIdentifier(oldFQTableName));
+
+
+    // checking the existence of the table directory and validating the path
+    FileSystem fs = testingCluster.getMaster().getStorageManager().getFileSystem();
+    Path warehouseDir = TajoConf.getWarehouseDir(testingCluster.getConfiguration());
+    assertTrue(fs.exists(oldTableDesc.getPath()));
+    assertEquals(StorageUtil.concatPath(warehouseDir, databaseName, originalTableName), oldTableDesc.getPath());
+
+    // Rename
+    client.executeQuery("ALTER TABLE " + CatalogUtil.denormalizeIdentifier(oldFQTableName)
+        + " RENAME to " + CatalogUtil.denormalizeIdentifier(newTableName));
+
+    // checking the existence of the new table directory and validating the path
+    final String newFQTableName = CatalogUtil.buildFQName(databaseName, newTableName);
+    TableDesc newTableDesc = client.getTableDesc(CatalogUtil.denormalizeIdentifier(newFQTableName));
+    assertTrue(fs.exists(newTableDesc.getPath()));
+    assertEquals(StorageUtil.concatPath(warehouseDir, databaseName, newTableName), newTableDesc.getPath());
+  }
+
+  @Test
+  public final void testCreatedTableViaCTASAndVerifyPath() throws Exception {
+    assertPathOfCreatedTable("d4", "old_table", "new_mgmt_table",
+        "CREATE TABLE d4.old_table AS SELECT * FROM default.lineitem;");
+  }
+
+  @Test
+  public final void testCreatedTableJustCreatedAndVerifyPath() throws Exception {
+    assertPathOfCreatedTable("d5", "old_table", "new_mgmt_table", "CREATE TABLE d5.old_table (age integer);");
+  }
+
+  @Test
+  public final void testCreatedTableWithQuotedIdentifierAndVerifyPath() throws Exception {
+    if (!testingCluster.isHCatalogStoreRunning()) {
+      assertPathOfCreatedTable("D6", "OldTable", "NewMgmtTable", "CREATE TABLE \"D6\".\"OldTable\" (age integer);");
+    }
+  }
+
   @Test
   public final void testCreateTableIfNotExists() throws Exception {
     executeString("CREATE DATABASE D3;").close();

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestDropTable.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestDropTable.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestDropTable.java
new file mode 100644
index 0000000..e362eef
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestDropTable.java
@@ -0,0 +1,39 @@
+/**
+ * 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.tajo.engine.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.util.List;
+
+@Category(IntegrationTest.class)
+public class TestDropTable extends QueryTestCaseBase {
+
+  @Test
+  public final void testDropManagedTable() throws Exception {
+    List<String> createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "ABC");
+    assertTableExists(createdNames.get(0));
+    executeDDL("drop_table_ddl.sql", null);
+    assertTableNotExists("ABC");
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/dataset/TestAlterTable/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/dataset/TestAlterTable/table1.tbl b/tajo-core/tajo-core-backend/src/test/resources/dataset/TestAlterTable/table1.tbl
new file mode 100644
index 0000000..340fe85
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/dataset/TestAlterTable/table1.tbl
@@ -0,0 +1,3 @@
+1|abc|2
+2|def|5
+3|ghi|8

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/dataset/TestDropTable/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/dataset/TestDropTable/table1.tbl b/tajo-core/tajo-core-backend/src/test/resources/dataset/TestDropTable/table1.tbl
new file mode 100644
index 0000000..340fe85
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/dataset/TestDropTable/table1.tbl
@@ -0,0 +1,3 @@
+1|abc|2
+2|def|5
+3|ghi|8

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_add_new_column_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_add_new_column_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_add_new_column_ddl.sql
new file mode 100644
index 0000000..567aed8
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_add_new_column_ddl.sql
@@ -0,0 +1 @@
+ALTER TABLE EFG ADD COLUMN cool text;

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_column_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_column_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_column_ddl.sql
new file mode 100644
index 0000000..7c326ff
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_column_ddl.sql
@@ -0,0 +1 @@
+ALTER TABLE XYZ RENAME COLUMN num TO renum;

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_table_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_table_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_table_ddl.sql
new file mode 100644
index 0000000..eeab457
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_table_ddl.sql
@@ -0,0 +1 @@
+ ALTER TABLE ABC RENAME TO DEF;

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/table1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/table1_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/table1_ddl.sql
new file mode 100644
index 0000000..8d7fba0
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/table1_ddl.sql
@@ -0,0 +1 @@
+CREATE EXTERNAL TABLE ${0} (id int, str text, num int) using csv location ${table.path};

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/drop_table_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/drop_table_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/drop_table_ddl.sql
new file mode 100644
index 0000000..c770b43
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/drop_table_ddl.sql
@@ -0,0 +1 @@
+DROP TABLE ABC PURGE
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/table1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/table1_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/table1_ddl.sql
new file mode 100644
index 0000000..0d56ec8
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/table1_ddl.sql
@@ -0,0 +1 @@
+CREATE TABLE ${0} (id int, str text, num int);

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-docs/src/main/sphinx/functions/datetime_func_and_operators.rst
----------------------------------------------------------------------
diff --git a/tajo-docs/src/main/sphinx/functions/datetime_func_and_operators.rst b/tajo-docs/src/main/sphinx/functions/datetime_func_and_operators.rst
index 51156fa..e31caba 100644
--- a/tajo-docs/src/main/sphinx/functions/datetime_func_and_operators.rst
+++ b/tajo-docs/src/main/sphinx/functions/datetime_func_and_operators.rst
@@ -2,4 +2,41 @@
 DateTime Functions and Operators
 ********************************
 
-.. todo::
\ No newline at end of file
+.. function:: utc_usec_to (string text , long timestamp , int dayOfWeek)
+
+  * If the **first parameter** is 'day'.
+
+    Shifts and return a UNIX timestamp in microseconds to the beginning of the day it occurs in.
+    For example, if unix_timestamp occurs on May 19th at 08:58, this function returns a UNIX timestamp for May 19th at 00:00 (midnight).
+
+  * If the **first parameter** is 'hour'.
+
+    Shifts and return a UNIX timestamp in microseconds to the beginning of the hour it occurs in.
+    For example, if unix_timestamp occurs at 08:58, this function returns a UNIX timestamp for 08:00 on the same day.
+
+  * If the **first parameter** is 'month'.
+
+    Shifts and return a UNIX timestamp in microseconds to the beginning of the month it occurs in.
+    For example, if unix_timestamp occurs on March 19th, this function returns a UNIX timestamp for March 1st of the same year.
+
+  * If the **first parameter** is 'year'.
+
+    Returns a UNIX timestamp in microseconds that represents the year of the unix_timestamp argument.
+    For example, if unix_timestamp occurs in 2010, the function returns 1274259481071200, the microsecond representation of 2010-01-01 00:00.
+
+  * If the **first parameter** is 'week' and **third parameter** is 2 i.e (TUESDAY)
+
+    Returns a UNIX timestamp in microseconds that represents a day in the week of the
+    For example, if unix_timestamp occurs on Friday, 2008-04-11, and you set day_of_week to 2 (Tuesday), the function returns a UNIX timestamp for Tuesday, 2008-04-08.
+
+  :param string: could be 'day' 'hour' 'month' 'year' 'week'
+  :param long: unix timestamp in microseconds
+  :param int: day of the week from 0 (Sunday) to 6 (Saturday).Optional parameter required only if first parameter is 'week'
+  :rtype: long
+  :alias: utc_usec_to
+  :example:
+
+  .. code-block:: sql
+
+    SELECT utc_usec_to('day', 1274259481071200);
+    > 1274227200000000
\ No newline at end of file


[2/2] git commit: TAJO-480: Umbrella Jira for adding ALTER TABLE statement. (Alvin Henrick via hyunsik)

Posted by hy...@apache.org.
TAJO-480: Umbrella Jira for adding ALTER TABLE statement. (Alvin Henrick via hyunsik)


Project: http://git-wip-us.apache.org/repos/asf/tajo/repo
Commit: http://git-wip-us.apache.org/repos/asf/tajo/commit/bd418a5c
Tree: http://git-wip-us.apache.org/repos/asf/tajo/tree/bd418a5c
Diff: http://git-wip-us.apache.org/repos/asf/tajo/diff/bd418a5c

Branch: refs/heads/master
Commit: bd418a5c3edb8bb8df4be31866a5d3ec9b407f88
Parents: 40851e5
Author: Hyunsik Choi <hy...@apache.org>
Authored: Tue Apr 1 00:12:39 2014 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Tue Apr 1 00:12:39 2014 +0900

----------------------------------------------------------------------
 CHANGES.txt                                     |   5 +-
 .../org/apache/tajo/algebra/AlterTable.java     | 111 ++++++++
 .../apache/tajo/algebra/AlterTableOpType.java   |  22 ++
 .../apache/tajo/algebra/ColumnDefinition.java   |  59 ++++
 .../org/apache/tajo/algebra/CreateTable.java    |  41 ---
 .../java/org/apache/tajo/algebra/OpType.java    |   1 +
 .../tajo/catalog/AbstractCatalogClient.java     |  18 +-
 .../org/apache/tajo/catalog/CatalogService.java |   7 +
 .../src/main/proto/CatalogProtocol.proto        |   2 +
 .../org/apache/tajo/catalog/AlterTableDesc.java | 150 ++++++++++
 .../org/apache/tajo/catalog/AlterTableType.java |  22 ++
 .../org/apache/tajo/catalog/CatalogUtil.java    |  25 ++
 .../ColumnNameAlreadyExistException.java        |  31 +++
 .../src/main/proto/CatalogProtos.proto          |  18 ++
 .../tajo/catalog/store/HCatalogStore.java       | 147 +++++++++-
 .../org/apache/tajo/catalog/CatalogServer.java  |  25 +-
 .../tajo/catalog/store/AbstractDBStore.java     | 277 ++++++++++++++++---
 .../apache/tajo/catalog/store/CatalogStore.java |   3 +-
 .../org/apache/tajo/catalog/store/MemStore.java |  74 ++++-
 .../org/apache/tajo/catalog/TestCatalog.java    |  49 ++++
 .../org/apache/tajo/engine/parser/SQLLexer.g4   |   4 +
 .../org/apache/tajo/engine/parser/SQLParser.g4  |  17 ++
 .../tajo/engine/parser/HiveQLAnalyzer.java      |   4 +-
 .../apache/tajo/engine/parser/SQLAnalyzer.java  | 223 ++++++++++-----
 .../tajo/engine/planner/AlgebraVisitor.java     |   3 +-
 .../tajo/engine/planner/BaseAlgebraVisitor.java |   8 +
 .../engine/planner/BasicLogicalPlanVisitor.java |   8 +
 .../engine/planner/LogicalPlanPreprocessor.java |   7 +
 .../tajo/engine/planner/LogicalPlanVisitor.java |   3 +
 .../tajo/engine/planner/LogicalPlanner.java     |  24 +-
 .../apache/tajo/engine/planner/PlannerUtil.java | 105 +++----
 .../engine/planner/SimpleAlgebraVisitor.java    |   7 +-
 .../engine/planner/logical/AlterTableNode.java  | 134 +++++++++
 .../tajo/engine/planner/logical/NodeType.java   |   5 +-
 .../org/apache/tajo/master/GlobalEngine.java    |  94 ++++++-
 .../java/org/apache/tajo/QueryTestCaseBase.java |  26 +-
 .../tajo/engine/query/TestAlterTable.java       |  53 ++++
 .../apache/tajo/engine/query/TestCTASQuery.java |  18 +-
 .../tajo/engine/query/TestCreateTable.java      |  59 ++++
 .../apache/tajo/engine/query/TestDropTable.java |  39 +++
 .../resources/dataset/TestAlterTable/table1.tbl |   3 +
 .../resources/dataset/TestDropTable/table1.tbl  |   3 +
 .../alter_table_add_new_column_ddl.sql          |   1 +
 .../alter_table_rename_column_ddl.sql           |   1 +
 .../alter_table_rename_table_ddl.sql            |   1 +
 .../queries/TestAlterTable/table1_ddl.sql       |   1 +
 .../queries/TestDropTable/drop_table_ddl.sql    |   1 +
 .../queries/TestDropTable/table1_ddl.sql        |   1 +
 .../functions/datetime_func_and_operators.rst   |  39 ++-
 49 files changed, 1743 insertions(+), 236 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 50fa593..d4b8452 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,7 +4,10 @@ Release 0.8.0 - unreleased
 
   NEW FEATURES
 
-    TAJO-378: Implement concat_ws function. (Seungun Choe via jaehwa) 
+    TAJO-480: Umbrella Jira for adding ALTER TABLE statement.
+    (Alvin Henrick via hyunsik)
+
+    TAJO-378: Implement concat_ws function. (Seungun Choe via jaehwa)
 
     TAJO-377: Implement concat function (Seungun Choe via jaehwa)
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTable.java
----------------------------------------------------------------------
diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTable.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTable.java
new file mode 100644
index 0000000..4bb0ed2
--- /dev/null
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTable.java
@@ -0,0 +1,111 @@
+/**
+ * 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.tajo.algebra;
+
+
+import com.google.common.base.Objects;
+import org.apache.tajo.util.TUtil;
+
+public class AlterTable extends Expr {
+
+  private String tableName;
+  private String newTableName;
+  private String columnName;
+  private String newColumnName;
+  private ColumnDefinition addNewColumn;
+  private AlterTableOpType alterTableOpType;
+
+  public AlterTable(final String tableName) {
+    super(OpType.AlterTable);
+    this.tableName = tableName;
+  }
+
+
+  public String getTableName() {
+    return tableName;
+  }
+
+  public void setTableName(String tableName) {
+    this.tableName = tableName;
+  }
+
+  public String getNewTableName() {
+    return newTableName;
+  }
+
+  public void setNewTableName(String newTableName) {
+    this.newTableName = newTableName;
+  }
+
+  public String getColumnName() {
+    return columnName;
+  }
+
+  public void setColumnName(String columnName) {
+    this.columnName = columnName;
+  }
+
+  public String getNewColumnName() {
+    return newColumnName;
+  }
+
+  public void setNewColumnName(String newColumnName) {
+    this.newColumnName = newColumnName;
+  }
+
+  public ColumnDefinition getAddNewColumn() {
+    return addNewColumn;
+  }
+
+  public void setAddNewColumn(ColumnDefinition addNewColumn) {
+    this.addNewColumn = addNewColumn;
+  }
+
+  public AlterTableOpType getAlterTableOpType() {
+    return alterTableOpType;
+  }
+
+  public void setAlterTableOpType(AlterTableOpType alterTableOpType) {
+    this.alterTableOpType = alterTableOpType;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hashCode(tableName,
+        null != newTableName ? Objects.hashCode(newTableName) : newTableName,
+        null != columnName ? Objects.hashCode(columnName) : columnName,
+        null != newColumnName ? Objects.hashCode(newColumnName) : newColumnName,
+        null != addNewColumn ? Objects.hashCode(addNewColumn) : addNewColumn,
+        null != alterTableOpType ? Objects.hashCode(alterTableOpType) : alterTableOpType);
+
+  }
+
+  @Override
+  boolean equalsTo(Expr expr) {
+    AlterTable another = (AlterTable) expr;
+    return tableName.equals(another.tableName) &&
+        TUtil.checkEquals(newTableName, another.newTableName) &&
+        TUtil.checkEquals(columnName, another.columnName) &&
+        TUtil.checkEquals(newColumnName, another.newColumnName) &&
+        TUtil.checkEquals(addNewColumn, another.addNewColumn) &&
+        TUtil.checkEquals(alterTableOpType, another.alterTableOpType);
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTableOpType.java
----------------------------------------------------------------------
diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTableOpType.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTableOpType.java
new file mode 100644
index 0000000..67b28a2
--- /dev/null
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTableOpType.java
@@ -0,0 +1,22 @@
+/**
+ * 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.tajo.algebra;
+
+public enum AlterTableOpType {
+  RENAME_TABLE, RENAME_COLUMN, ADD_COLUMN
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-algebra/src/main/java/org/apache/tajo/algebra/ColumnDefinition.java
----------------------------------------------------------------------
diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/ColumnDefinition.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/ColumnDefinition.java
new file mode 100644
index 0000000..ce935dd
--- /dev/null
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/ColumnDefinition.java
@@ -0,0 +1,59 @@
+/**
+ * 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.tajo.algebra;
+
+public  class ColumnDefinition extends DataTypeExpr {
+  String col_name;
+
+  public ColumnDefinition(String columnName, String dataType) {
+    super(dataType);
+    this.col_name = columnName;
+  }
+
+  public ColumnDefinition(String columnName, DataTypeExpr dataType) {
+    super(dataType.getTypeName());
+    if (dataType.hasLengthOrPrecision()) {
+      setLengthOrPrecision(dataType.lengthOrPrecision);
+      if (dataType.hasScale()) {
+        setScale(dataType.scale);
+      }
+    }
+    this.col_name = columnName;
+  }
+
+  public String getColumnName() {
+    return this.col_name;
+  }
+
+  @Override
+  public int hashCode() {
+    int hash = super.hashCode();
+    return hash * 89 * col_name.hashCode();
+
+  }
+
+  @Override
+  public boolean equalsTo(Expr expr) {
+    if (expr instanceof ColumnDefinition) {
+      ColumnDefinition another = (ColumnDefinition) expr;
+      return col_name.equals(another.col_name) && super.equalsTo(another);
+    }
+
+    return false;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java
----------------------------------------------------------------------
diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java
index eb11ed0..63ca364 100644
--- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java
@@ -155,47 +155,6 @@ public class CreateTable extends Expr {
         ifNotExists == another.ifNotExists;
   }
 
-  public static class ColumnDefinition extends DataTypeExpr {
-    String col_name;
-
-    public ColumnDefinition(String columnName, String dataType) {
-      super(dataType);
-      this.col_name = columnName;
-    }
-
-    public ColumnDefinition(String columnName, DataTypeExpr dataType) {
-      super(dataType.getTypeName());
-      if (dataType.hasLengthOrPrecision()) {
-        setLengthOrPrecision(dataType.lengthOrPrecision);
-        if (dataType.hasScale()) {
-          setScale(dataType.scale);
-        }
-      }
-      this.col_name = columnName;
-    }
-
-    public String getColumnName() {
-      return this.col_name;
-    }
-
-    @Override
-    public int hashCode() {
-      int hash = super.hashCode();
-      return hash * 89 * col_name.hashCode();
-
-    }
-
-    @Override
-    public boolean equalsTo(Expr expr) {
-      if (expr instanceof ColumnDefinition) {
-        ColumnDefinition another = (ColumnDefinition) expr;
-        return col_name.equals(another.col_name) && super.equalsTo(another);
-      }
-
-      return false;
-    }
-  }
-
   public static enum PartitionType {
     RANGE,
     HASH,

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java
----------------------------------------------------------------------
diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java
index c4a007a..a4fb617 100644
--- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java
@@ -46,6 +46,7 @@ public enum OpType {
   DropDatabase(DropDatabase.class),
   CreateTable(CreateTable.class),
   DropTable(DropTable.class),
+  AlterTable(AlterTable.class),
 
   // Insert or Update
   Insert(Insert.class),

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java
index 6fb385e..60cce9a 100644
--- a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java
+++ b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java
@@ -360,7 +360,7 @@ public abstract class AbstractCatalogClient implements CatalogService {
       return false;
     }
   }
-
+  @Override
   public final boolean existsTable(final String tableName) {
     String [] splitted = CatalogUtil.splitFQTableName(tableName);
     return existsTable(splitted[0], splitted[1]);
@@ -595,4 +595,20 @@ public abstract class AbstractCatalogClient implements CatalogService {
       return false;
     }
   }
+
+  @Override
+  public final boolean alterTable(final AlterTableDesc desc) {
+    try {
+      return new ServerCallable<Boolean>(this.pool, catalogServerAddr, CatalogProtocol.class, false) {
+        public Boolean call(NettyClientBase client) throws ServiceException {
+          CatalogProtocolService.BlockingInterface stub = getStub(client);
+          return stub.alterTable(null, desc.getProto()).getValue();
+        }
+      }.withRetries();
+    } catch (ServiceException e) {
+      LOG.error(e.getMessage(), e);
+      return false;
+    }
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/CatalogService.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/CatalogService.java b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/CatalogService.java
index d69ed7e..f68f11a 100644
--- a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/CatalogService.java
+++ b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/CatalogService.java
@@ -157,4 +157,11 @@ public interface CatalogService {
   boolean containFunction(String signature, DataType... paramTypes);
 
   boolean containFunction(String signature, FunctionType funcType, DataType... paramTypes);
+
+  /**
+  * Add a table via table description
+  * @see AlterTableDesc
+  * @throws Throwable
+  */
+  boolean alterTable(AlterTableDesc desc);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto b/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto
index 06b69c1..0f34f7c 100644
--- a/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto
+++ b/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto
@@ -30,6 +30,8 @@ service CatalogProtocolService {
   rpc dropTablespace(StringProto) returns (BoolProto);
   rpc existTablespace(StringProto) returns (BoolProto);
   rpc getAllTablespaceNames(NullProto) returns (StringListProto);
+  rpc alterTable(AlterTableDescProto) returns (BoolProto);
+
 
   rpc createDatabase(CreateDatabaseRequest) returns (BoolProto);
   rpc dropDatabase(StringProto) returns (BoolProto);

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableDesc.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableDesc.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableDesc.java
new file mode 100644
index 0000000..d69330d
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableDesc.java
@@ -0,0 +1,150 @@
+/**
+ * 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.tajo.catalog;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.annotations.Expose;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tajo.catalog.json.CatalogGsonHelper;
+import org.apache.tajo.catalog.proto.CatalogProtos;
+import org.apache.tajo.common.ProtoObject;
+import org.apache.tajo.json.GsonObject;
+
+
+public class AlterTableDesc implements ProtoObject<CatalogProtos.AlterTableDescProto>, GsonObject, Cloneable {
+  private final Log LOG = LogFactory.getLog(AlterTableDesc.class);
+
+  protected CatalogProtos.AlterTableDescProto.Builder builder = null;
+
+  @Expose
+  protected String tableName;  // required
+  @Expose
+  protected String newTableName;  // optional
+  @Expose
+  protected String columnName;   //optional
+  @Expose
+  protected String newColumnName; //optional
+  @Expose
+  protected Column addColumn = null; //optiona
+  @Expose
+  protected AlterTableType alterTableType; //required
+
+  public AlterTableDesc() {
+    builder = CatalogProtos.AlterTableDescProto.newBuilder();
+  }
+
+
+  public String getTableName() {
+    return tableName;
+  }
+
+  public void setTableName(String tableName) {
+    this.tableName = tableName;
+  }
+
+  public String getNewTableName() {
+    return newTableName;
+  }
+
+  public void setNewTableName(String newTableName) {
+    this.newTableName = newTableName;
+  }
+
+  public String getColumnName() {
+    return columnName;
+  }
+
+  public void setColumnName(String columnName) {
+    this.columnName = columnName;
+  }
+
+  public String getNewColumnName() {
+    return newColumnName;
+  }
+
+  public void setNewColumnName(String newColumnName) {
+    this.newColumnName = newColumnName;
+  }
+
+  public Column getAddColumn() {
+    return addColumn;
+  }
+
+  public void setAddColumn(Column addColumn) {
+    this.addColumn = addColumn;
+  }
+
+  public AlterTableType getAlterTableType() {
+    return alterTableType;
+  }
+
+  public void setAlterTableType(AlterTableType alterTableType) {
+    this.alterTableType = alterTableType;
+  }
+
+  @Override
+  public String toString() {
+    Gson gson = new GsonBuilder().setPrettyPrinting().
+        excludeFieldsWithoutExposeAnnotation().create();
+    return gson.toJson(this);
+  }
+
+  @Override
+  public String toJson() {
+    return CatalogGsonHelper.toJson(this, AlterTableDesc.class);
+  }
+
+  @Override
+  public CatalogProtos.AlterTableDescProto getProto() {
+    if (null == builder) {
+      builder = CatalogProtos.AlterTableDescProto.newBuilder();
+    }
+    if (null != this.tableName) {
+      builder.setTableName(this.tableName);
+    }
+    if (null != this.newTableName) {
+      builder.setNewTableName(this.newTableName);
+    }
+    if (null != this.columnName && null != this.newColumnName) {
+      final CatalogProtos.AlterColumnProto.Builder alterColumnBuilder = CatalogProtos.AlterColumnProto.newBuilder();
+      alterColumnBuilder.setOldColumnName(this.columnName);
+      alterColumnBuilder.setNewColumnName(this.newColumnName);
+      builder.setAlterColumnName(alterColumnBuilder.build());
+    }
+    if (null != this.addColumn) {
+      builder.setAddColumn(addColumn.getProto());
+    }
+
+    switch (alterTableType) {
+      case RENAME_TABLE:
+        builder.setAlterTableType(CatalogProtos.AlterTableType.RENAME_TABLE);
+        break;
+      case RENAME_COLUMN:
+        builder.setAlterTableType(CatalogProtos.AlterTableType.RENAME_COLUMN);
+        break;
+      case ADD_COLUMN:
+        builder.setAlterTableType(CatalogProtos.AlterTableType.ADD_COLUMN);
+        break;
+      default:
+    }
+    return builder.build();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableType.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableType.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableType.java
new file mode 100644
index 0000000..0b7639c
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableType.java
@@ -0,0 +1,22 @@
+/**
+ * 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.tajo.catalog;
+
+public enum AlterTableType {
+    RENAME_TABLE, RENAME_COLUMN, ADD_COLUMN
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java
index 9078e60..22f54ca 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java
@@ -441,4 +441,29 @@ public class CatalogUtil {
       RESERVED_KEYWORDS_SET.add(keyword);
     }
   }
+
+  public static AlterTableDesc renameColumn(String tableName, String oldColumName, String newColumName, AlterTableType alterTableType) {
+    final AlterTableDesc alterTableDesc = new AlterTableDesc();
+    alterTableDesc.setTableName(tableName);
+    alterTableDesc.setColumnName(oldColumName);
+    alterTableDesc.setNewColumnName(newColumName);
+    alterTableDesc.setAlterTableType(alterTableType);
+    return alterTableDesc;
+  }
+
+  public static AlterTableDesc renameTable(String tableName, String newTableName, AlterTableType alterTableType) {
+    final AlterTableDesc alterTableDesc = new AlterTableDesc();
+    alterTableDesc.setTableName(tableName);
+    alterTableDesc.setNewTableName(newTableName);
+    alterTableDesc.setAlterTableType(alterTableType);
+    return alterTableDesc;
+  }
+
+  public static AlterTableDesc addNewColumn(String tableName, Column column, AlterTableType alterTableType) {
+    final AlterTableDesc alterTableDesc = new AlterTableDesc();
+    alterTableDesc.setTableName(tableName);
+    alterTableDesc.setAddColumn(column);
+    alterTableDesc.setAlterTableType(alterTableType);
+    return alterTableDesc;
+  }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/ColumnNameAlreadyExistException.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/ColumnNameAlreadyExistException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/ColumnNameAlreadyExistException.java
new file mode 100644
index 0000000..1c026d7
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/ColumnNameAlreadyExistException.java
@@ -0,0 +1,31 @@
+/**
+ * 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.tajo.catalog.exception;
+
+
+public class ColumnNameAlreadyExistException extends CatalogException {
+
+  private static final long serialVersionUID = -4863862140874083282L;
+
+  public ColumnNameAlreadyExistException() {
+  }
+
+  public ColumnNameAlreadyExistException(String columnName) {
+    super("Column already exists : " + columnName);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto b/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto
index 06ffcfd..d3abc70 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto
+++ b/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto
@@ -48,6 +48,12 @@ enum PartitionType {
     COLUMN = 3;
 }
 
+enum AlterTableType {
+  RENAME_TABLE = 0;
+  RENAME_COLUMN = 1;
+  ADD_COLUMN = 2;
+}
+
 message ColumnProto {
 	required string name = 1;
 	required DataType dataType = 3;
@@ -263,3 +269,15 @@ message PartitionDescProto {
   optional string path = 5;
 }
 
+message AlterTableDescProto {
+  required string tableName = 1;
+  optional string newTableName = 2 ;
+  optional ColumnProto addColumn = 3;
+  optional AlterColumnProto alterColumnName = 4;
+  required AlterTableType alterTableType = 5;
+}
+
+message AlterColumnProto {
+  required string oldColumnName = 1;
+  required string newColumnName = 2;
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-drivers/tajo-hcatalog/src/main/java/org/apache/tajo/catalog/store/HCatalogStore.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-drivers/tajo-hcatalog/src/main/java/org/apache/tajo/catalog/store/HCatalogStore.java b/tajo-catalog/tajo-catalog-drivers/tajo-hcatalog/src/main/java/org/apache/tajo/catalog/store/HCatalogStore.java
index 6ef255f..a4bdb28 100644
--- a/tajo-catalog/tajo-catalog-drivers/tajo-hcatalog/src/main/java/org/apache/tajo/catalog/store/HCatalogStore.java
+++ b/tajo-catalog/tajo-catalog-drivers/tajo-hcatalog/src/main/java/org/apache/tajo/catalog/store/HCatalogStore.java
@@ -36,9 +36,7 @@ import org.apache.hcatalog.data.schema.HCatSchema;
 import org.apache.tajo.TajoConstants;
 import org.apache.tajo.catalog.*;
 import org.apache.tajo.catalog.Schema;
-import org.apache.tajo.catalog.exception.AlreadyExistsDatabaseException;
-import org.apache.tajo.catalog.exception.CatalogException;
-import org.apache.tajo.catalog.exception.NoSuchDatabaseException;
+import org.apache.tajo.catalog.exception.*;
 import org.apache.tajo.catalog.partition.PartitionMethodDesc;
 import org.apache.tajo.catalog.proto.CatalogProtos;
 import org.apache.tajo.catalog.statistics.TableStats;
@@ -135,7 +133,7 @@ public class HCatalogStore extends CatalogConstants implements CatalogStore {
         isPartitionKey = false;
 
         if (table.getPartitionKeys() != null) {
-          for(FieldSchema partitionKey: table.getPartitionKeys()) {
+          for (FieldSchema partitionKey : table.getPartitionKeys()) {
             if (partitionKey.getName().equals(eachField.getName())) {
               isPartitionKey = true;
             }
@@ -198,7 +196,7 @@ public class HCatalogStore extends CatalogConstants implements CatalogStore {
 
         // set data size
         long totalSize = 0;
-        if(properties.getProperty("totalSize") != null) {
+        if (properties.getProperty("totalSize") != null) {
           totalSize = Long.parseLong(properties.getProperty("totalSize"));
         } else {
           try {
@@ -219,7 +217,7 @@ public class HCatalogStore extends CatalogConstants implements CatalogStore {
         StringBuilder sb = new StringBuilder();
         if (table.getPartitionKeys().size() > 0) {
           List<FieldSchema> partitionKeys = table.getPartitionKeys();
-          for(int i = 0; i < partitionKeys.size(); i++) {
+          for (int i = 0; i < partitionKeys.size(); i++) {
             FieldSchema fieldSchema = partitionKeys.get(i);
             TajoDataTypes.Type dataType = HCatalogUtil.getTajoFieldType(fieldSchema.getType().toString());
             String fieldName = databaseName + CatalogUtil.IDENTIFIER_DELIMITER + tableName +
@@ -377,7 +375,7 @@ public class HCatalogStore extends CatalogConstants implements CatalogStore {
     HCatalogStoreClientPool.HCatalogStoreClient client = null;
 
     TableDesc tableDesc = new TableDesc(tableDescProto);
-    String [] splitted = CatalogUtil.splitFQTableName(tableDesc.getName());
+    String[] splitted = CatalogUtil.splitFQTableName(tableDesc.getName());
     String databaseName = splitted[0];
     String tableName = splitted[1];
 
@@ -425,8 +423,8 @@ public class HCatalogStore extends CatalogConstants implements CatalogStore {
       // set partition keys
       if (tableDesc.hasPartition() && tableDesc.getPartitionMethod().getPartitionType().equals(PartitionType.COLUMN)) {
         List<FieldSchema> partitionKeys = new ArrayList<FieldSchema>();
-        for(Column eachPartitionKey: tableDesc.getPartitionMethod().getExpressionSchema().getColumns()) {
-          partitionKeys.add(new FieldSchema( eachPartitionKey.getSimpleName(),
+        for (Column eachPartitionKey : tableDesc.getPartitionMethod().getExpressionSchema().getColumns()) {
+          partitionKeys.add(new FieldSchema(eachPartitionKey.getSimpleName(),
               HCatalogUtil.getHiveFieldType(eachPartitionKey.getDataType()), ""));
         }
         table.setPartitionKeys(partitionKeys);
@@ -500,6 +498,110 @@ public class HCatalogStore extends CatalogConstants implements CatalogStore {
     }
   }
 
+
+  @Override
+  public void alterTable(final CatalogProtos.AlterTableDescProto alterTableDescProto) throws CatalogException {
+
+    HCatalogStoreClientPool.HCatalogStoreClient client = clientPool.getClient();
+
+    final String[] split = CatalogUtil.splitFQTableName(alterTableDescProto.getTableName());
+
+    if (split.length == 1) {
+      throw new IllegalArgumentException("alterTable() requires a qualified table name, but it is \""
+          + alterTableDescProto.getTableName() + "\".");
+    }
+
+    final String databaseName = split[0];
+    final String tableName = split[1];
+
+
+    switch (alterTableDescProto.getAlterTableType()) {
+      case RENAME_TABLE:
+        if (existTable(databaseName,alterTableDescProto.getNewTableName().toLowerCase())) {
+          throw new AlreadyExistsTableException(alterTableDescProto.getNewTableName());
+        }
+        renameTable(databaseName, tableName, alterTableDescProto.getNewTableName().toLowerCase());
+        break;
+      case RENAME_COLUMN:
+        if (existColumn(databaseName,tableName, alterTableDescProto.getAlterColumnName().getNewColumnName())) {
+          throw new ColumnNameAlreadyExistException(alterTableDescProto.getAlterColumnName().getNewColumnName());
+        }
+        renameColumn(databaseName, tableName, alterTableDescProto.getAlterColumnName());
+        break;
+      case ADD_COLUMN:
+        if (existColumn(databaseName,tableName, alterTableDescProto.getAddColumn().getName())) {
+          throw new ColumnNameAlreadyExistException(alterTableDescProto.getAddColumn().getName());
+        }
+        addNewColumn(databaseName, tableName, alterTableDescProto.getAddColumn());
+        break;
+      default:
+        //TODO
+    }
+
+
+  }
+
+
+  private void renameTable(String databaseName, String tableName, String newTableName) {
+    HCatalogStoreClientPool.HCatalogStoreClient client = null;
+    try {
+      client = clientPool.getClient();
+      Table newTable = client.getHiveClient().getTable(databaseName, tableName);
+      newTable.setTableName(newTableName);
+      client.getHiveClient().alter_table(databaseName, tableName, newTable);
+
+    } catch (NoSuchObjectException nsoe) {
+    } catch (Exception e) {
+      throw new CatalogException(e);
+    } finally {
+      client.release();
+    }
+  }
+
+  private void renameColumn(String databaseName, String tableName, CatalogProtos.AlterColumnProto alterColumnProto) {
+    HCatalogStoreClientPool.HCatalogStoreClient client = null;
+    try {
+
+      client = clientPool.getClient();
+      Table table = client.getHiveClient().getTable(databaseName, tableName);
+      List<FieldSchema> columns = table.getSd().getCols();
+
+      for (final FieldSchema currentColumn : columns) {
+        if (currentColumn.getName().equalsIgnoreCase(alterColumnProto.getOldColumnName())) {
+          currentColumn.setName(alterColumnProto.getNewColumnName());
+        }
+      }
+      client.getHiveClient().alter_table(databaseName, tableName, table);
+
+    } catch (NoSuchObjectException nsoe) {
+    } catch (Exception e) {
+      throw new CatalogException(e);
+    } finally {
+      client.release();
+    }
+  }
+
+
+  private void addNewColumn(String databaseName, String tableName, CatalogProtos.ColumnProto columnProto) {
+    HCatalogStoreClientPool.HCatalogStoreClient client = null;
+    try {
+
+      client = clientPool.getClient();
+      Table table = client.getHiveClient().getTable(databaseName, tableName);
+      List<FieldSchema> columns = table.getSd().getCols();
+      columns.add(new FieldSchema(columnProto.getName(),
+          HCatalogUtil.getHiveFieldType(columnProto.getDataType()), ""));
+      client.getHiveClient().alter_table(databaseName, tableName, table);
+
+
+    } catch (NoSuchObjectException nsoe) {
+    } catch (Exception e) {
+      throw new CatalogException(e);
+    } finally {
+      client.release();
+    }
+  }
+
   @Override
   public void addPartitionMethod(CatalogProtos.PartitionMethodProto partitionMethodProto) throws CatalogException {
     // TODO - not implemented yet
@@ -618,4 +720,31 @@ public class HCatalogStore extends CatalogConstants implements CatalogStore {
   public final void close() {
     clientPool.close();
   }
+
+  private boolean existColumn(final String databaseName ,final String tableName , final String columnName) throws CatalogException {
+    boolean exist = false;
+    HCatalogStoreClientPool.HCatalogStoreClient client = null;
+
+    try {
+
+      client = clientPool.getClient();
+      Table table = client.getHiveClient().getTable(databaseName, tableName);
+      List<FieldSchema> columns = table.getSd().getCols();
+
+      for (final FieldSchema currentColumn : columns) {
+        if (currentColumn.getName().equalsIgnoreCase(columnName)) {
+          exist = true;
+        }
+      }
+      client.getHiveClient().alter_table(databaseName, tableName, table);
+
+    } catch (NoSuchObjectException nsoe) {
+    } catch (Exception e) {
+      throw new CatalogException(e);
+    } finally {
+      client.release();
+    }
+
+    return exist;
+  }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java
index a171fb4..b6f7f08 100644
--- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java
+++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java
@@ -102,7 +102,7 @@ public class CatalogServer extends AbstractService {
     this.builtingFuncs = sqlFuncs;
   }
 
-  @Override
+  
   public void serviceInit(Configuration conf) throws Exception {
 
     Constructor<?> cons;
@@ -306,6 +306,26 @@ public class CatalogServer extends AbstractService {
     }
 
     @Override
+    public BoolProto alterTable(RpcController controller, AlterTableDescProto proto) throws ServiceException {
+      wlock.lock();
+      try {
+        String [] split = CatalogUtil.splitTableName(proto.getTableName());
+        if (!store.existTable(split[0], split[1])) {
+          throw new NoSuchTableException(proto.getTableName());
+        }
+        store.alterTable(proto);
+      } catch (Exception e) {
+        LOG.error(e.getMessage(), e);
+        return BOOL_FALSE;
+      } finally {
+        wlock.unlock();
+        LOG.info("Table " + proto.getTableName() + " is altered in the catalog ("
+            + bindAddressStr + ")");
+      }
+      return BOOL_TRUE;
+    }
+
+    @Override
     public BoolProto dropDatabase(RpcController controller, StringProto request) throws ServiceException {
       String databaseName = request.getValue();
 
@@ -593,7 +613,6 @@ public class CatalogServer extends AbstractService {
 
     @Override
     public BoolProto addPartitions(RpcController controller, PartitionsProto request) throws ServiceException {
-
       return ProtoUtil.TRUE;
     }
 
@@ -814,7 +833,7 @@ public class CatalogServer extends AbstractService {
       return BOOL_TRUE;
     }
 
-    @Override
+     @Override
     public BoolProto dropFunction(RpcController controller, UnregisterFunctionRequest request)
         throws ServiceException {
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java
index d10f545..b1efc7f 100644
--- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java
+++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java
@@ -29,10 +29,7 @@ import org.apache.tajo.annotation.Nullable;
 import org.apache.tajo.catalog.CatalogConstants;
 import org.apache.tajo.catalog.CatalogUtil;
 import org.apache.tajo.catalog.FunctionDesc;
-import org.apache.tajo.catalog.exception.CatalogException;
-import org.apache.tajo.catalog.exception.NoSuchDatabaseException;
-import org.apache.tajo.catalog.exception.NoSuchTableException;
-import org.apache.tajo.catalog.exception.NoSuchTablespaceException;
+import org.apache.tajo.catalog.exception.*;
 import org.apache.tajo.catalog.proto.CatalogProtos;
 import org.apache.tajo.catalog.proto.CatalogProtos.*;
 import org.apache.tajo.common.TajoDataTypes.Type;
@@ -73,7 +70,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
 
     this.conf = conf;
 
-    if(conf.get(CatalogConstants.DEPRECATED_CATALOG_URI) != null) {
+    if (conf.get(CatalogConstants.DEPRECATED_CATALOG_URI) != null) {
       LOG.warn("Configuration parameter " + CatalogConstants.DEPRECATED_CATALOG_URI + " " +
           "is deprecated. Use " + CatalogConstants.CATALOG_URI + " instead.");
       this.catalogUri = conf.get(CatalogConstants.DEPRECATED_CATALOG_URI);
@@ -81,7 +78,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
       this.catalogUri = conf.get(CatalogConstants.CATALOG_URI);
     }
 
-    if(conf.get(CatalogConstants.DEPRECATED_CONNECTION_ID) != null) {
+    if (conf.get(CatalogConstants.DEPRECATED_CONNECTION_ID) != null) {
       LOG.warn("Configuration parameter " + CatalogConstants.DEPRECATED_CONNECTION_ID + " " +
           "is deprecated. Use " + CatalogConstants.CONNECTION_ID + " instead.");
       this.connectionId = conf.get(CatalogConstants.DEPRECATED_CONNECTION_ID);
@@ -89,7 +86,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
       this.connectionId = conf.get(CatalogConstants.CONNECTION_ID);
     }
 
-    if(conf.get(CatalogConstants.DEPRECATED_CONNECTION_PASSWORD) != null) {
+    if (conf.get(CatalogConstants.DEPRECATED_CONNECTION_PASSWORD) != null) {
       LOG.warn("Configuration parameter " + CatalogConstants.DEPRECATED_CONNECTION_PASSWORD + " " +
           "is deprecated. Use " + CatalogConstants.CONNECTION_PASSWORD + " instead.");
       this.connectionPassword = conf.get(CatalogConstants.DEPRECATED_CONNECTION_PASSWORD);
@@ -146,7 +143,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
     }
   }
 
-  protected String getCatalogUri(){
+  protected String getCatalogUri() {
     return catalogUri;
   }
 
@@ -180,7 +177,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
 
       boolean noVersion = !result.next();
 
-      int schemaVersion =  result.getInt(1);
+      int schemaVersion = result.getInt(1);
       if (noVersion || schemaVersion != getDriverVersion()) {
         LOG.error(String.format("Catalog version (%d) and current driver version (%d) are mismatch to each other",
             schemaVersion, getDriverVersion()));
@@ -266,7 +263,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
 
     try {
       StringBuilder sql = new StringBuilder();
-      sql.append("SELECT SPACE_NAME FROM " + TB_SPACES +" WHERE SPACE_NAME = ?");
+      sql.append("SELECT SPACE_NAME FROM " + TB_SPACES + " WHERE SPACE_NAME = ?");
       if (LOG.isDebugEnabled()) {
         LOG.debug(sql.toString());
       }
@@ -302,7 +299,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
         dropDatabase(databaseName);
       }
 
-      String sql = "DELETE FROM " + TB_SPACES + " WHERE " + COL_TABLESPACE_PK +"= ?";
+      String sql = "DELETE FROM " + TB_SPACES + " WHERE " + COL_TABLESPACE_PK + "= ?";
       pstmt = conn.prepareStatement(sql);
       pstmt.setInt(1, tableSpace.getSpaceId());
       pstmt.executeUpdate();
@@ -326,7 +323,6 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
     return getAllTablespaceNamesInternal(null);
   }
 
-
   private Collection<String> getAllTablespaceNamesInternal(@Nullable String whereCondition) throws CatalogException {
     Connection conn = null;
     PreparedStatement pstmt = null;
@@ -344,7 +340,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
       conn = getConnection();
       pstmt = conn.prepareStatement(sql);
       resultSet = pstmt.executeQuery();
-      while(resultSet.next()) {
+      while (resultSet.next()) {
         tablespaceNames.add(resultSet.getString(1));
       }
     } catch (SQLException se) {
@@ -476,7 +472,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
       conn = getConnection();
       pstmt = conn.prepareStatement(sql);
       resultSet = pstmt.executeQuery();
-      while(resultSet.next()) {
+      while (resultSet.next()) {
         databaseNames.add(resultSet.getString(1));
       }
     } catch (SQLException se) {
@@ -572,7 +568,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
       conn = getConnection();
       conn.setAutoCommit(false);
 
-      String [] splitted = CatalogUtil.splitTableName(table.getTableName());
+      String[] splitted = CatalogUtil.splitTableName(table.getTableName());
       if (splitted.length == 1) {
         throw new IllegalArgumentException("createTable() requires a qualified table name, but it is \""
             + table.getTableName() + "\".");
@@ -636,7 +632,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
       }
 
       pstmt = conn.prepareStatement(colSql);
-      for(int i = 0; i < table.getSchema().getFieldsCount(); i++) {
+      for (int i = 0; i < table.getSchema().getFieldsCount(); i++) {
         ColumnProto col = table.getSchema().getFields(i);
         pstmt.setInt(1, tableId);
         pstmt.setString(2, CatalogUtil.extractSimpleName(col.getName()));
@@ -649,7 +645,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
       pstmt.executeBatch();
       pstmt.close();
 
-      if(table.getMeta().hasParams()) {
+      if (table.getMeta().hasParams()) {
         String propSQL = "INSERT INTO " + TB_OPTIONS + "(TID, KEY_, VALUE_) VALUES(?, ?, ?)";
 
         if (LOG.isDebugEnabled()) {
@@ -684,7 +680,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
         pstmt.close();
       }
 
-      if(table.hasPartition()) {
+      if (table.hasPartition()) {
         String partSql =
             "INSERT INTO PARTITION_METHODS (TID, PARTITION_TYPE, EXPRESSION, EXPRESSION_SCHEMA) VALUES(?, ?, ?, ?)";
 
@@ -716,6 +712,183 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
     }
   }
 
+  @Override
+  public void alterTable(CatalogProtos.AlterTableDescProto alterTableDescProto) throws CatalogException {
+
+    String[] splitted = CatalogUtil.splitTableName(alterTableDescProto.getTableName());
+    if (splitted.length == 1) {
+      throw new IllegalArgumentException("alterTable() requires a qualified table name, but it is \""
+          + alterTableDescProto.getTableName() + "\".");
+    }
+    String databaseName = splitted[0];
+    String tableName = splitted[1];
+
+    try {
+
+      int databaseId = getDatabaseId(databaseName);
+      int tableId = getTableId(databaseId, databaseName, tableName);
+
+      switch (alterTableDescProto.getAlterTableType()) {
+        case RENAME_TABLE:
+          if (existTable(databaseName,alterTableDescProto.getNewTableName())) {
+            throw new AlreadyExistsTableException(alterTableDescProto.getNewTableName());
+          }
+          renameTable(tableId, alterTableDescProto.getNewTableName());
+          break;
+        case RENAME_COLUMN:
+          if (existColumn(tableId, alterTableDescProto.getAlterColumnName().getNewColumnName())) {
+            throw new ColumnNameAlreadyExistException(alterTableDescProto.getAlterColumnName().getNewColumnName());
+          }
+          renameColumn(tableId, alterTableDescProto.getAlterColumnName());
+          break;
+        case ADD_COLUMN:
+          if (existColumn(tableId, alterTableDescProto.getAddColumn().getName())) {
+            throw new ColumnNameAlreadyExistException(alterTableDescProto.getAddColumn().getName());
+          }
+          addNewColumn(tableId, alterTableDescProto.getAddColumn());
+          break;
+        default:
+      }
+    } catch (SQLException sqlException) {
+      throw new CatalogException(sqlException);
+    }
+
+  }
+
+  private void renameTable(final int tableId, final String tableName) throws CatalogException {
+
+    final String updtaeRenameTableSql = "UPDATE " + TB_TABLES + " SET " + COL_TABLES_NAME + " = ? " + " WHERE TID = ?";
+
+    if (LOG.isDebugEnabled()) {
+      LOG.debug(updtaeRenameTableSql);
+    }
+
+    Connection conn;
+    PreparedStatement pstmt = null;
+
+    try {
+
+      conn = getConnection();
+      pstmt = conn.prepareStatement(updtaeRenameTableSql);
+      pstmt.setString(1, tableName);
+      pstmt.setInt(2, tableId);
+      pstmt.executeUpdate();
+
+    } catch (SQLException sqlException) {
+      throw new CatalogException(sqlException);
+    } finally {
+      CatalogUtil.closeQuietly(pstmt);
+    }
+  }
+
+  private void renameColumn(final int tableId, final CatalogProtos.AlterColumnProto alterColumnProto) throws CatalogException {
+
+    final String selectColumnSql = "SELECT COLUMN_NAME, DATA_TYPE, TYPE_LENGTH, ORDINAL_POSITION from " + TB_COLUMNS +" WHERE " + COL_TABLES_PK + " = ?" + " AND COLUMN_NAME = ?" ;
+    final String deleteColumnNameSql = "DELETE FROM " + TB_COLUMNS + " WHERE TID = ? AND COLUMN_NAME = ?";
+    final String insertNewColumnSql = "INSERT INTO " + TB_COLUMNS + " (TID, COLUMN_NAME, ORDINAL_POSITION, DATA_TYPE, TYPE_LENGTH) VALUES(?, ?, ?, ?, ?) ";
+
+    if (LOG.isDebugEnabled()) {
+      LOG.debug(selectColumnSql);
+      LOG.debug(deleteColumnNameSql);
+      LOG.debug(insertNewColumnSql);
+    }
+
+    Connection conn;
+    PreparedStatement pstmt = null;
+    ResultSet resultSet = null;
+
+    try {
+
+      conn = getConnection();
+      conn.setAutoCommit(false);
+
+      //SELECT COLUMN
+      pstmt = conn.prepareStatement(selectColumnSql);
+      pstmt.setInt(1, tableId);
+      pstmt.setString(2, alterColumnProto.getOldColumnName());
+      resultSet = pstmt.executeQuery();
+
+      CatalogProtos.ColumnProto columnProto = null;
+      int ordinalPostion = -1;
+
+      if (resultSet.next()) {
+        columnProto = resultToColumnProto(resultSet);
+        //NOTE ==> Setting new column Name
+        columnProto = columnProto.toBuilder().setName(alterColumnProto.getNewColumnName()).build();
+        ordinalPostion = resultSet.getInt("ORDINAL_POSITION");
+      }
+
+      resultSet.close();
+      pstmt.close();
+      resultSet = null;
+
+      //DELETE COLUMN
+      pstmt = conn.prepareStatement(deleteColumnNameSql);
+      pstmt.setInt(1, tableId);
+      pstmt.setString(2, alterColumnProto.getOldColumnName());
+      pstmt.executeUpdate();
+      pstmt.close();
+
+      //INSERT COLUMN
+      pstmt = conn.prepareStatement(insertNewColumnSql);
+      pstmt.setInt(1, tableId);
+      pstmt.setString(2, CatalogUtil.extractSimpleName(columnProto.getName()));
+      pstmt.setInt(3, ordinalPostion);
+      pstmt.setString(4, columnProto.getDataType().getType().name());
+      pstmt.setInt(5, (columnProto.getDataType().hasLength() ? columnProto.getDataType().getLength() : 0));
+      pstmt.executeUpdate();
+
+      conn.commit();
+
+
+    } catch (SQLException sqlException) {
+      throw new CatalogException(sqlException);
+    } finally {
+      CatalogUtil.closeQuietly(pstmt,resultSet);
+    }
+  }
+
+  private void addNewColumn(int tableId, CatalogProtos.ColumnProto columnProto) throws CatalogException {
+
+    final String insertNewColumnSql = "INSERT INTO " + TB_COLUMNS + " (TID, COLUMN_NAME, ORDINAL_POSITION, DATA_TYPE, TYPE_LENGTH) VALUES(?, ?, ?, ?, ?) ";
+    final String columnCountSql = "SELECT COLUMN_NAME, MAX(ORDINAL_POSITION) AS POSITION FROM " + TB_COLUMNS + " WHERE TID = ? GROUP BY COLUMN_NAME";
+
+    if (LOG.isDebugEnabled()) {
+      LOG.debug(insertNewColumnSql);
+      LOG.debug(columnCountSql);
+    }
+
+    Connection conn;
+    PreparedStatement pstmt = null;
+    ResultSet resultSet = null;
+
+    try {
+      conn = getConnection();
+      pstmt = conn.prepareStatement(columnCountSql);
+      pstmt.setInt(1 , tableId);
+      resultSet =  pstmt.executeQuery();
+
+      int position = resultSet.next() ? resultSet.getInt("POSITION") : 0;
+
+      resultSet.close();
+      pstmt.close();
+      resultSet = null;
+
+      pstmt = conn.prepareStatement(insertNewColumnSql);
+      pstmt.setInt(1, tableId);
+      pstmt.setString(2, CatalogUtil.extractSimpleName(columnProto.getName()));
+      pstmt.setInt(3, position + 1);
+      pstmt.setString(4, columnProto.getDataType().getType().name());
+      pstmt.setInt(5, (columnProto.getDataType().hasLength() ? columnProto.getDataType().getLength() : 0));
+      pstmt.executeUpdate();
+
+    } catch (SQLException sqlException) {
+      throw new CatalogException(sqlException);
+    } finally {
+      CatalogUtil.closeQuietly(pstmt,resultSet);
+    }
+  }
+
   private int getDatabaseId(String databaseName) throws SQLException {
     String sql = String.format("SELECT DB_ID from %s WHERE DB_NAME = ?", TB_DATABASES);
 
@@ -986,7 +1159,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
       //////////////////////////////////////////
       CatalogProtos.TableProto.Builder metaBuilder = CatalogProtos.TableProto.newBuilder();
       metaBuilder.setStoreType(storeType);
-      sql = "SELECT key_, value_ FROM " + TB_OPTIONS +" WHERE " + COL_TABLES_PK + " = ?";
+      sql = "SELECT key_, value_ FROM " + TB_OPTIONS + " WHERE " + COL_TABLES_PK + " = ?";
 
       if (LOG.isDebugEnabled()) {
         LOG.debug(sql);
@@ -1136,12 +1309,12 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
 
   private static void addPartitionInternal(PreparedStatement pstmt, int tableId, PartitionDescProto partition) throws
       SQLException {
-      pstmt.setInt(1, tableId);
-      pstmt.setString(2, partition.getPartitionName());
-      pstmt.setInt(3, partition.getOrdinalPosition());
-      pstmt.setString(4, partition.getPath());
-      pstmt.addBatch();
-      pstmt.clearParameters();
+    pstmt.setInt(1, tableId);
+    pstmt.setString(2, partition.getPartitionName());
+    pstmt.setInt(3, partition.getOrdinalPosition());
+    pstmt.setString(4, partition.getPath());
+    pstmt.addBatch();
+    pstmt.clearParameters();
   }
 
   @Override
@@ -1151,7 +1324,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
 
     try {
       String sql = "INSERT INTO " + TB_PARTITION_METHODS + " (TID, PARTITION_TYPE,  EXPRESSION, EXPRESSION_SCHEMA) " +
-              "VALUES (?,?,?,?)";
+          "VALUES (?,?,?,?)";
 
       if (LOG.isDebugEnabled()) {
         LOG.debug(sql);
@@ -1209,7 +1382,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
 
     try {
       String sql = "SELECT partition_type, expression, expression_schema FROM " + TB_PARTITION_METHODS +
-      " WHERE " + COL_TABLES_NAME + " = ? ";
+          " WHERE " + COL_TABLES_NAME + " = ? ";
 
       if (LOG.isDebugEnabled()) {
         LOG.debug(sql);
@@ -1242,7 +1415,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
 
     try {
       String sql = "SELECT partition_type, expression, expression_schema FROM " + TB_PARTITION_METHODS +
-      " WHERE " + COL_TABLES_NAME + "= ?";
+          " WHERE " + COL_TABLES_NAME + "= ?";
 
       if (LOG.isDebugEnabled()) {
         LOG.debug(sql);
@@ -1256,7 +1429,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
       exist = res.next();
     } catch (SQLException se) {
       throw new CatalogException(se);
-    } finally {                           
+    } finally {
       CatalogUtil.closeQuietly(pstmt, res);
     }
     return exist;
@@ -1362,7 +1535,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
       int tableId = getTableId(databaseId, databaseName, tableName);
 
       String sql = "INSERT INTO " + TB_INDEXES +
-        " (" + COL_DATABASES_PK + ", " + COL_TABLES_PK + ", INDEX_NAME, " +
+          " (" + COL_DATABASES_PK + ", " + COL_TABLES_PK + ", INDEX_NAME, " +
           "COLUMN_NAME, DATA_TYPE, INDEX_TYPE, IS_UNIQUE, IS_CLUSTERED, IS_ASCENDING) VALUES (?,?,?,?,?,?,?,?,?)";
 
       if (LOG.isDebugEnabled()) {
@@ -1422,7 +1595,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
 
     try {
       pstmt =
-          conn.prepareStatement("SELECT " + COL_TABLES_NAME + " FROM " + TB_TABLES + " WHERE " + COL_TABLES_PK +"=?");
+          conn.prepareStatement("SELECT " + COL_TABLES_NAME + " FROM " + TB_TABLES + " WHERE " + COL_TABLES_PK + "=?");
       pstmt.setInt(1, tableId);
       res = pstmt.executeQuery();
       if (!res.next()) {
@@ -1435,9 +1608,10 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
   }
 
   final static String GET_INDEXES_SQL =
-      "SELECT " + COL_TABLES_PK + ", INDEX_NAME, COLUMN_NAME, DATA_TYPE, INDEX_TYPE, IS_UNIQUE, "+
+      "SELECT " + COL_TABLES_PK + ", INDEX_NAME, COLUMN_NAME, DATA_TYPE, INDEX_TYPE, IS_UNIQUE, " +
           "IS_CLUSTERED, IS_ASCENDING FROM " + TB_INDEXES;
 
+
   @Override
   public IndexDescProto getIndexByName(String databaseName, final String indexName)
       throws CatalogException {
@@ -1497,7 +1671,8 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
 
       conn = getConnection();
       pstmt = conn.prepareStatement(sql);
-      pstmt.setInt(1, databaseId);;
+      pstmt.setInt(1, databaseId);
+      ;
       pstmt.setString(2, columnName);
       res = pstmt.executeQuery();
       if (!res.next()) {
@@ -1625,7 +1800,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
   }
 
   private void resultToIndexDescProtoBuilder(IndexDescProto.Builder builder,
-                                                final ResultSet res) throws SQLException {
+                                             final ResultSet res) throws SQLException {
     builder.setIndexName(res.getString("index_name"));
     builder.setColumn(indexResultToColumnProto(res));
     builder.setIndexMethod(getIndexMethod(res.getString("index_type").trim()));
@@ -1653,7 +1828,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
 
     Type type = getDataType(res.getString("data_type").trim());
     int typeLength = res.getInt("type_length");
-    if(typeLength > 0 ) {
+    if (typeLength > 0) {
       builder.setDataType(CatalogUtil.newDataTypeWithLen(type, typeLength));
     } else {
       builder.setDataType(CatalogUtil.newSimpleDataType(type));
@@ -1696,7 +1871,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
     return partBuilder.build();
   }
 
-  @Override
+
   public void close() {
     CatalogUtil.closeQuietly(conn);
     LOG.info("Shutdown database (" + catalogUri + ")");
@@ -1722,4 +1897,34 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
     // TODO - not implemented yet
     return null;
   }
+
+  private boolean existColumn(final int tableId, final String columnName) throws CatalogException {
+    Connection conn ;
+    PreparedStatement pstmt = null;
+    ResultSet res = null;
+    boolean exist = false;
+
+    try {
+
+      String sql = "SELECT COLUMN_NAME FROM " + TB_COLUMNS + " WHERE TID = ? AND COLUMN_NAME = ?";
+
+      if (LOG.isDebugEnabled()) {
+        LOG.debug(sql.toString());
+      }
+
+      conn = getConnection();
+      pstmt = conn.prepareStatement(sql.toString());
+
+      pstmt.setInt(1, tableId);
+      pstmt.setString(2, columnName);
+      res = pstmt.executeQuery();
+      exist = res.next();
+    } catch (SQLException se) {
+      throw new CatalogException(se);
+    } finally {
+      CatalogUtil.closeQuietly(pstmt, res);
+    }
+
+    return exist;
+  }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/CatalogStore.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/CatalogStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/CatalogStore.java
index 3f8686d..e0c5a9d 100644
--- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/CatalogStore.java
+++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/CatalogStore.java
@@ -60,8 +60,9 @@ public interface CatalogStore extends Closeable {
   
   List<String> getAllTableNames(String databaseName) throws CatalogException;
 
+  void alterTable(CatalogProtos.AlterTableDescProto alterTableDescProto) throws CatalogException;
 
-  /************************ PARTITION METHOD **************************/
+    /************************ PARTITION METHOD **************************/
   void addPartitionMethod(PartitionMethodProto partitionMethodProto) throws CatalogException;
 
   PartitionMethodProto getPartitionMethod(String databaseName, String tableName)

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java
index ef98ee2..ca29a6b 100644
--- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java
+++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java
@@ -23,6 +23,8 @@ package org.apache.tajo.catalog.store;
 
 import com.google.common.collect.Maps;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.TajoConstants;
 import org.apache.tajo.catalog.CatalogUtil;
 import org.apache.tajo.catalog.FunctionDesc;
 import org.apache.tajo.catalog.exception.*;
@@ -42,11 +44,11 @@ public class MemStore implements CatalogStore {
   private final Map<String, CatalogProtos.FunctionDescProto> functions = Maps.newHashMap();
   private final Map<String, Map<String, IndexDescProto>> indexes = Maps.newHashMap();
   private final Map<String, Map<String, IndexDescProto>> indexesByColumn = Maps.newHashMap();
-  
+
   public MemStore(Configuration conf) {
   }
 
-  @Override
+  
   public void close() throws IOException {
     databases.clear();
     functions.clear();
@@ -157,6 +159,74 @@ public class MemStore implements CatalogStore {
   }
 
   /* (non-Javadoc)
+   * @see CatalogStore#alterTable(AlterTableDesc)
+   */
+  @Override
+  public void alterTable(CatalogProtos.AlterTableDescProto alterTableDescProto) throws CatalogException {
+
+    String[] split = CatalogUtil.splitTableName(alterTableDescProto.getTableName());
+    if (split.length == 1) {
+      throw new IllegalArgumentException("alterTable() requires a qualified table name, but it is \""
+          + alterTableDescProto.getTableName() + "\".");
+    }
+    String databaseName = split[0];
+    String tableName = split[1];
+
+    final Map<String, CatalogProtos.TableDescProto> database = checkAndGetDatabaseNS(databases, databaseName);
+
+    final CatalogProtos.TableDescProto tableDescProto = database.get(tableName);
+    CatalogProtos.TableDescProto newTableDescProto;
+    CatalogProtos.SchemaProto schemaProto;
+
+    switch (alterTableDescProto.getAlterTableType()) {
+      case RENAME_TABLE:
+        if (database.containsKey(alterTableDescProto.getNewTableName())) {
+          throw new AlreadyExistsTableException(alterTableDescProto.getNewTableName());
+        }
+        // Currently, we only use the default table space (i.e., WAREHOUSE directory).
+        String spaceUri = tablespaces.get(TajoConstants.DEFAULT_TABLESPACE_NAME);
+        // Create a new table directory.
+        String newPath = new Path(spaceUri, new Path(databaseName, alterTableDescProto.getNewTableName())).toString();
+        newTableDescProto = tableDescProto.toBuilder()
+            .setTableName(alterTableDescProto.getNewTableName())
+            .setPath(newPath).build();
+        database.remove(tableName);
+        database.put(alterTableDescProto.getNewTableName(), newTableDescProto);
+        break;
+      case RENAME_COLUMN:
+        schemaProto = tableDescProto.getSchema();
+        final int index = getIndexOfColumnToBeRenamed(schemaProto.getFieldsList(),
+            alterTableDescProto.getAlterColumnName().getOldColumnName());
+        final CatalogProtos.ColumnProto columnProto = schemaProto.getFields(index);
+        final CatalogProtos.ColumnProto newcolumnProto =
+            columnProto.toBuilder().setName(alterTableDescProto.getAlterColumnName().getNewColumnName()).build();
+        newTableDescProto = tableDescProto.toBuilder().setSchema(schemaProto.toBuilder().
+            setFields(index, newcolumnProto).build()).build();
+        database.put(tableName, newTableDescProto);
+        break;
+      case ADD_COLUMN:
+        schemaProto = tableDescProto.getSchema();
+        CatalogProtos.SchemaProto newSchemaProto =
+            schemaProto.toBuilder().addFields(alterTableDescProto.getAddColumn()).build();
+        newTableDescProto = tableDescProto.toBuilder().setSchema(newSchemaProto).build();
+        database.put(tableName, newTableDescProto);
+        break;
+      default:
+        //TODO
+    }
+  }
+
+  private int getIndexOfColumnToBeRenamed(List<CatalogProtos.ColumnProto> fieldList, String columnName) {
+    int fieldCount = fieldList.size();
+    for (int index = 0; index < fieldCount; index++) {
+      CatalogProtos.ColumnProto columnProto = fieldList.get(index);
+      if (null != columnProto && columnProto.getName().equalsIgnoreCase(columnName)) {
+        return index;
+      }
+    }
+    return -1;
+  }
+  /* (non-Javadoc)
    * @see CatalogStore#getTable(java.lang.String)
    */
   @Override

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java
index 36c6b6b..22ab552 100644
--- a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java
+++ b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java
@@ -667,4 +667,53 @@ public class TestCatalog {
     catalog.dropTable(tableName);
     assertFalse(catalog.existsTable(tableName));
   }
+
+  @Test
+  public void testAlterTableName () throws Exception {
+
+    //CREATE_TABLE
+    TableDesc tableRenameTestDesc = createMockupTable("default", "mycooltable") ;
+    catalog.createTable(tableRenameTestDesc);
+
+    //RENAME_TABLE
+    catalog.alterTable(createMockAlterTableName());
+    assertTrue(catalog.existsTable("default", "mynewcooltable"));
+
+    //RENAME_COLUMN
+    catalog.alterTable(createMockAlterTableRenameColumn());
+    TableDesc columnRenameDesc = catalog.getTableDesc("default","mynewcooltable");
+    assertTrue(columnRenameDesc.getSchema().containsByName("ren"+FieldName1));
+
+    //ADD_COLUMN
+    catalog.alterTable(createMockAlterTableAddColumn());
+    TableDesc addColumnDesc = catalog.getTableDesc("default","mynewcooltable");
+    assertTrue(addColumnDesc.getSchema().containsByName("mynewcol"));
+
+  }
+
+  private AlterTableDesc createMockAlterTableName(){
+    AlterTableDesc alterTableDesc = new AlterTableDesc();
+    alterTableDesc.setTableName("default.mycooltable");
+    alterTableDesc.setNewTableName("mynewcooltable");
+    alterTableDesc.setAlterTableType(AlterTableType.RENAME_TABLE);
+    return alterTableDesc;
+  }
+
+  private AlterTableDesc createMockAlterTableRenameColumn(){
+    AlterTableDesc alterTableDesc = new AlterTableDesc();
+    alterTableDesc.setTableName("default.mynewcooltable");
+    alterTableDesc.setColumnName(FieldName1);
+    alterTableDesc.setNewColumnName("ren" + FieldName1);
+    alterTableDesc.setAlterTableType(AlterTableType.RENAME_COLUMN);
+    return alterTableDesc;
+  }
+
+  private AlterTableDesc createMockAlterTableAddColumn(){
+    AlterTableDesc alterTableDesc = new AlterTableDesc();
+    alterTableDesc.setTableName("default.mynewcooltable");
+    alterTableDesc.setAddColumn(new Column("mynewcol", Type.TEXT));
+    alterTableDesc.setAlterTableType(AlterTableType.ADD_COLUMN);
+    return alterTableDesc;
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
index 6eccd12..3b8f9cf 100644
--- a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
+++ b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
@@ -121,6 +121,7 @@ ANY : A N Y;
 ASYMMETRIC : A S Y M M E T R I C;
 ASC : A S C;
 
+
 BOTH : B O T H;
 
 CASE : C A S E;
@@ -189,6 +190,8 @@ WITH : W I T H;
 ===============================================================================
 */
 AVG : A V G;
+ADD: A D D;
+ALTER : A L T E R;
 
 BETWEEN : B E T W E E N;
 BY : B Y;
@@ -263,6 +266,7 @@ RANGE : R A N G E;
 REGEXP : R E G E X P;
 RLIKE : R L I K E;
 ROLLUP : R O L L U P;
+RENAME : R E N A M E;
 
 SECOND : S E C O N D;
 SET : S E T;

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
index c0edf09..825969a 100644
--- a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
+++ b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
@@ -58,6 +58,7 @@ schema_statement
   | drop_database_statement
   | create_table_statement
   | drop_table_statement
+  | alter_table_statement
   ;
 
 index_statement
@@ -1059,6 +1060,10 @@ table_name
   : identifier (DOT identifier ( DOT identifier)? )?
   ;
 
+column_name
+  : identifier
+  ;
+
 query_specification
   : SELECT set_qualifier? select_list table_expression?
   ;
@@ -1366,3 +1371,15 @@ insert_statement
   : INSERT (OVERWRITE)? INTO table_name (LEFT_PAREN column_name_list RIGHT_PAREN)? query_expression
   | INSERT (OVERWRITE)? INTO LOCATION path=Character_String_Literal (USING file_type=identifier (param_clause)?)? query_expression
   ;
+
+/*
+===============================================================================
+  <alter table>
+===============================================================================
+*/
+
+alter_table_statement
+  : ALTER TABLE table_name RENAME TO table_name
+  | ALTER TABLE table_name RENAME COLUMN column_name TO column_name
+  | ALTER TABLE table_name ADD COLUMN field_element
+  ;

http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java
index afd0ce9..c734583 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java
@@ -1450,7 +1450,7 @@ public class HiveQLAnalyzer extends HiveQLParserBaseVisitor<Expr> {
       if (ctx.columnNameTypeList() != null) {
         List<HiveQLParser.ColumnNameTypeContext> list = ctx.columnNameTypeList().columnNameType();
 
-        CreateTable.ColumnDefinition[] columns = new CreateTable.ColumnDefinition[list.size()];
+        ColumnDefinition[] columns = new ColumnDefinition[list.size()];
 
         for (int i = 0; i < list.size(); i++) {
           HiveQLParser.ColumnNameTypeContext eachColumn = list.get(i);
@@ -1459,7 +1459,7 @@ public class HiveQLAnalyzer extends HiveQLParserBaseVisitor<Expr> {
             if (eachColumn.colType().type().primitiveType() != null) {
               HiveQLParser.PrimitiveTypeContext primitiveType = eachColumn.colType().type().primitiveType();
               type = getDataTypeExpr(primitiveType).getTypeName();
-              columns[i] = new CreateTable.ColumnDefinition(eachColumn.colName.Identifier().getText(), type);
+              columns[i] = new ColumnDefinition(eachColumn.colName.Identifier().getText(), type);
             }
           }
         }