You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by ji...@apache.org on 2016/07/11 13:08:16 UTC

tajo git commit: TAJO-2165: Add 'ALTER TABLE UNSET PROPERTY' statement to Tajo DDL.

Repository: tajo
Updated Branches:
  refs/heads/master 9cf9f7516 -> fab36f97e


TAJO-2165: Add 'ALTER TABLE UNSET PROPERTY' statement to Tajo DDL.

Closes #1036

Signed-off-by: Jihoon Son <ji...@apache.org>


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

Branch: refs/heads/master
Commit: fab36f97eff330ec2f655536bb00d2ca2cc557e9
Parents: 9cf9f75
Author: Lee Dongjin <do...@apache.org>
Authored: Mon Jul 11 22:05:59 2016 +0900
Committer: Jihoon Son <ji...@apache.org>
Committed: Mon Jul 11 22:08:00 2016 +0900

----------------------------------------------------------------------
 CHANGES                                         |  3 ++
 .../org/apache/tajo/algebra/AlterTable.java     | 11 ++++++
 .../apache/tajo/algebra/AlterTableOpType.java   |  2 +-
 .../org/apache/tajo/catalog/AlterTableDesc.java | 21 ++++++++++++
 .../org/apache/tajo/catalog/AlterTableType.java |  2 +-
 .../org/apache/tajo/catalog/CatalogUtil.java    |  9 +++++
 .../src/main/proto/CatalogProtos.proto          |  2 ++
 .../tajo/catalog/store/HiveCatalogStore.java    |  3 ++
 .../tajo/catalog/store/AbstractDBStore.java     | 36 ++++++++++++++++++++
 .../org/apache/tajo/catalog/TestCatalog.java    | 16 ++++++++-
 .../tajo/engine/query/TestAlterTable.java       | 33 ++++++++++++++++++
 .../alter_table_unset_not_exists_property.sql   |  1 +
 .../alter_table_unset_property_delimiter.sql    |  1 +
 .../apache/tajo/master/exec/DDLExecutor.java    |  3 ++
 .../org/apache/tajo/parser/sql/SQLAnalyzer.java | 18 ++++++++++
 .../org/apache/tajo/plan/LogicalPlanner.java    |  4 +++
 .../tajo/plan/logical/AlterTableNode.java       | 12 ++++++-
 .../plan/serder/LogicalNodeDeserializer.java    |  5 +++
 .../tajo/plan/serder/LogicalNodeSerializer.java |  9 ++---
 tajo-plan/src/main/proto/Plan.proto             |  4 ++-
 .../org/apache/tajo/parser/sql/SQLLexer.g4      |  1 +
 .../org/apache/tajo/parser/sql/SQLParser.g4     |  9 +++++
 22 files changed, 196 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 71fc12e..f2bd964 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,9 @@ Release 0.12.0 - unreleased
 
   NEW FEATURES
 
+    TAJO-2165: Add 'ALTER TABLE UNSET PROPERTY' statement to Tajo DDL.
+    (Lee Dongjin via jihoon)
+
     TAJO-2160: Implement string_agg function. (Byunghwa Yun via jinho)
 
     TAJO-2148: Implement an example HTTP tablespace. (jihoon)

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/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
index af6e902..d65c87c 100644
--- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTable.java
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTable.java
@@ -25,6 +25,7 @@ import com.google.gson.annotations.SerializedName;
 import org.apache.tajo.util.TUtil;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 public class AlterTable extends Expr {
@@ -43,6 +44,8 @@ public class AlterTable extends Expr {
   private AlterTableOpType alterTableOpType;
   @Expose @SerializedName("TableProperties")
   private Map<String, String> params;
+  @Expose @SerializedName("UnsetPropertyKeys")
+  private List<String> unsetPropertyKeys;
 
   @Expose @SerializedName("Columns")
   ColumnReferenceExpr [] columns;
@@ -137,6 +140,14 @@ public class AlterTable extends Expr {
     this.params = params;
   }
 
+  public List<String> getUnsetPropertyKeys() {
+    return unsetPropertyKeys;
+  }
+
+  public void setUnsetPropertyKeys(List<String> unsetPropertyKeys) {
+    this.unsetPropertyKeys = unsetPropertyKeys;
+  }
+
   public boolean isPurge() {
     return purge;
   }

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/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
index 89daef0..b9f39af 100644
--- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTableOpType.java
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTableOpType.java
@@ -18,5 +18,5 @@
 package org.apache.tajo.algebra;
 
 public enum AlterTableOpType {
-  RENAME_TABLE, RENAME_COLUMN, ADD_COLUMN, ADD_PARTITION, DROP_PARTITION, SET_PROPERTY, REPAIR_PARTITION
+  RENAME_TABLE, RENAME_COLUMN, ADD_COLUMN, ADD_PARTITION, DROP_PARTITION, SET_PROPERTY, UNSET_PROPERTY, REPAIR_PARTITION
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/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
index a9dccbc..b25dac9 100644
--- 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
@@ -17,6 +17,7 @@
  */
 package org.apache.tajo.catalog;
 
+import com.google.common.collect.Sets;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.annotations.Expose;
@@ -27,8 +28,10 @@ import org.apache.tajo.catalog.proto.CatalogProtos;
 import org.apache.tajo.common.ProtoObject;
 import org.apache.tajo.json.GsonObject;
 import org.apache.tajo.util.KeyValueSet;
+import org.apache.tajo.util.ProtoUtil;
 
 import java.net.URI;
+import java.util.Set;
 
 import static org.apache.tajo.catalog.proto.CatalogProtos.AlterTableDescProto;
 
@@ -51,6 +54,8 @@ public class AlterTableDesc implements ProtoObject<AlterTableDescProto>, GsonObj
   @Expose
   protected KeyValueSet properties;
   @Expose
+  protected Set<String> unsetPropertyKeys;
+  @Expose
   protected URI newTablePath; // optional
 
   public AlterTableDesc() {
@@ -59,6 +64,7 @@ public class AlterTableDesc implements ProtoObject<AlterTableDescProto>, GsonObj
 
   private void init() {
     this.properties = new KeyValueSet();
+    this.unsetPropertyKeys = Sets.newHashSet();
   }
 
   public String getTableName() {
@@ -125,6 +131,14 @@ public class AlterTableDesc implements ProtoObject<AlterTableDescProto>, GsonObj
     this.properties.set(key, value);
   }
 
+  public Set<String> getUnsetPropertyKeys() {
+    return unsetPropertyKeys;
+  }
+
+  public void setUnsetPropertyKey(Set<String> unsetPropertyKeys) {
+    this.unsetPropertyKeys = unsetPropertyKeys;
+  }
+
   public String getProperty(String key) {
     return this.properties.get(key);
   }
@@ -154,6 +168,7 @@ public class AlterTableDesc implements ProtoObject<AlterTableDescProto>, GsonObj
     newAlter.addColumn = addColumn;
     newAlter.partitionDesc = partitionDesc;
     newAlter.properties = (KeyValueSet)properties.clone();
+    newAlter.unsetPropertyKeys = Sets.newHashSet(unsetPropertyKeys);
     newAlter.newTablePath = URI.create(newTablePath.toString());
     return newAlter;
   }
@@ -185,6 +200,9 @@ public class AlterTableDesc implements ProtoObject<AlterTableDescProto>, GsonObj
     if (null != this.properties) {
       builder.setParams(properties.getProto());
     }
+    if (null != this.unsetPropertyKeys) {
+      builder.setUnsetPropertyKeys(ProtoUtil.convertStrings(unsetPropertyKeys));
+    }
 
     switch (alterTableType) {
       case RENAME_TABLE:
@@ -199,6 +217,9 @@ public class AlterTableDesc implements ProtoObject<AlterTableDescProto>, GsonObj
       case SET_PROPERTY:
         builder.setAlterTableType(CatalogProtos.AlterTableType.SET_PROPERTY);
         break;
+      case UNSET_PROPERTY:
+        builder.setAlterTableType(CatalogProtos.AlterTableType.UNSET_PROPERTY);
+        break;
       case ADD_PARTITION:
         builder.setAlterTableType(CatalogProtos.AlterTableType.ADD_PARTITION);
         break;

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/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
index a562d9f..f395763 100644
--- 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
@@ -18,5 +18,5 @@
 package org.apache.tajo.catalog;
 
 public enum AlterTableType {
-    RENAME_TABLE, RENAME_COLUMN, ADD_COLUMN, ADD_PARTITION, DROP_PARTITION, SET_PROPERTY
+    RENAME_TABLE, RENAME_COLUMN, ADD_COLUMN, ADD_PARTITION, DROP_PARTITION, SET_PROPERTY, UNSET_PROPERTY
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/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 0a81eac..892e5c0 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
@@ -19,6 +19,7 @@
 package org.apache.tajo.catalog;
 
 import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import org.apache.hadoop.fs.Path;
 import org.apache.tajo.BuiltinStorages;
 import org.apache.tajo.DataTypeUtil;
@@ -525,6 +526,14 @@ public class CatalogUtil {
     return alterTableDesc;
   }
 
+  public static AlterTableDesc unsetProperty(String tableName, String[] propertyKeys) {
+    final AlterTableDesc alterTableDesc = new AlterTableDesc();
+    alterTableDesc.setTableName(tableName);
+    alterTableDesc.setUnsetPropertyKey(Sets.newHashSet(propertyKeys));
+    alterTableDesc.setAlterTableType(AlterTableType.UNSET_PROPERTY);
+    return alterTableDesc;
+  }
+
   /**
    * Converts passed parameters to a AlterTableDesc. This method would be called when adding a partition or dropping
    * a table. This creates AlterTableDesc that is a wrapper class for protocol buffer.

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/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 ea5f933..f02bfbf 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto
+++ b/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto
@@ -45,6 +45,7 @@ enum AlterTableType {
   ADD_PARTITION = 3;
   DROP_PARTITION = 4;
   SET_PROPERTY = 5;
+  UNSET_PROPERTY = 6;
 }
 
 message ColumnProto {
@@ -305,6 +306,7 @@ message AlterTableDescProto {
   optional PartitionDescProto partition_desc = 6;
   optional KeyValueSetProto params = 7;
   optional string new_table_path = 8;
+  optional StringListProto unset_property_keys = 9;
 }
 
 message AlterColumnProto {

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java
index 1a154d6..9d6b369 100644
--- a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java
+++ b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java
@@ -657,6 +657,9 @@ public class HiveCatalogStore extends CatalogConstants implements CatalogStore {
       case SET_PROPERTY:
         // TODO - not implemented yet
         break;
+      case UNSET_PROPERTY:
+        // TODO - not implemented yet
+        break;
       default:
         //TODO
     }

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/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 2e2db6f..c37889a 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
@@ -36,6 +36,7 @@ import org.apache.tajo.conf.TajoConf;
 import org.apache.tajo.exception.*;
 import org.apache.tajo.plan.expr.AlgebraicUtil;
 import org.apache.tajo.plan.util.PartitionFilterAlgebraVisitor;
+import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos;
 import org.apache.tajo.schema.IdentifierUtil;
 import org.apache.tajo.type.TypeProtobufEncoder;
 import org.apache.tajo.type.TypeStringEncoder;
@@ -1037,6 +1038,9 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
     case SET_PROPERTY:
       setProperties(tableId, alterTableDescProto.getParams());
       break;
+    case UNSET_PROPERTY:
+      unsetProperties(tableId, alterTableDescProto.getUnsetPropertyKeys());
+      break;
     default:
     }
   }
@@ -1106,6 +1110,38 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
     }
   }
 
+  private void unsetProperties(final int tableId, final PrimitiveProtos.StringListProto propertyKeys) {
+    final String deleteSql = "DELETE FROM " + TB_OPTIONS + " WHERE TID=? AND KEY_=?";
+
+    Connection conn;
+    PreparedStatement pstmt = null;
+
+    Map<String, String> oldProperties = getTableOptions(tableId);
+
+    try {
+      conn = getConnection();
+      conn.setAutoCommit(false);
+
+      for (String key : propertyKeys.getValuesList()) {
+        if (oldProperties.containsKey(key)) {
+          // unset property
+          pstmt = conn.prepareStatement(deleteSql);
+
+          pstmt.setInt(1, tableId);
+          pstmt.setString(2, key);
+          pstmt.executeUpdate();
+          pstmt.close();
+        }
+      }
+
+      conn.commit();
+    } catch (Throwable sqlException) {
+      throw new TajoInternalError(sqlException);
+    } finally {
+      CatalogUtil.closeQuietly(pstmt);
+    }
+  }
+
   private void renameExternalTable(final int tableId, final String tableName) {
 
     final String updtaeRenameTableSql = "UPDATE " + TB_TABLES + " SET " + COL_TABLES_NAME + " = ? " + " WHERE TID = ?";

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/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 f0cb208..e385765 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
@@ -970,7 +970,7 @@ public class TestCatalog {
   }
 
   @Test
-  public void testAlterTableName () throws Exception {
+  public void testAlterTable() throws Exception {
 
     //CREATE_TABLE
     TableDesc tableRenameTestDesc = createMockupTable("default", "mycooltable") ;
@@ -1001,6 +1001,12 @@ public class TestCatalog {
     setPropertyDesc = catalog.getTableDesc("default","mynewcooltable");
     assertNotEquals(prevTimeZone, setPropertyDesc.getMeta().getProperty("timezone"));
     assertEquals(newTimeZone, setPropertyDesc.getMeta().getProperty("timezone"));
+
+    //UNSET_PROPERTY
+    catalog.alterTable(createMockAlterTableUnsetProperty(Sets.newHashSet("timezone", "dummy")));
+    setPropertyDesc = catalog.getTableDesc("default","mynewcooltable");
+    assertFalse(setPropertyDesc.getMeta().getPropertySet().containsKey("timezone"));
+    assertFalse(setPropertyDesc.getMeta().getPropertySet().containsKey("dummy"));
   }
 
   private AlterTableDesc createMockAlterTableName(){
@@ -1036,6 +1042,14 @@ public class TestCatalog {
     return alterTableDesc;
   }
 
+  private AlterTableDesc createMockAlterTableUnsetProperty(Set<String> keys) {
+    AlterTableDesc alterTableDesc = new AlterTableDesc();
+    alterTableDesc.setTableName("default.mynewcooltable");
+    alterTableDesc.setUnsetPropertyKey(keys);
+    alterTableDesc.setAlterTableType(AlterTableType.UNSET_PROPERTY);
+    return alterTableDesc;
+  }
+
   public static class TestIntFunc extends Function {
     public TestIntFunc() {
       super(

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java
index 30490f4..48e055e 100644
--- a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java
@@ -24,6 +24,7 @@ import org.apache.tajo.IntegrationTest;
 import org.apache.tajo.QueryTestCaseBase;
 import org.apache.tajo.catalog.Column;
 import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.catalog.TableMeta;
 import org.apache.tajo.catalog.proto.CatalogProtos;
 import org.apache.tajo.exception.*;
 import org.apache.tajo.schema.IdentifierUtil;
@@ -88,6 +89,38 @@ public class TestAlterTable extends QueryTestCaseBase {
     cleanupQuery(after_res);
   }
 
+  @Test
+  public final void testAlterTableUnsetProperty() throws Exception {
+    executeDDL("table2_ddl.sql", "table2.tbl", "ALTY");
+    String tableName = IdentifierUtil.buildFQName(getCurrentDatabase(), "alty");
+    assertTrue(catalog.existsTable(tableName));
+
+    TableDesc tableDesc = catalog.getTableDesc(tableName);
+    TableMeta tableMeta = tableDesc.getMeta();
+    assertEquals(tableMeta.getPropertySet().size(), 3);
+    assertNotNull(tableMeta.getProperty("timezone"));
+    assertNotNull(tableMeta.getProperty("text.null"));
+    assertEquals(tableMeta.getProperty("text.delimiter"), "\\u002b");
+
+    executeDDL("alter_table_unset_property_delimiter.sql", null);
+
+    tableDesc = catalog.getTableDesc(tableName);
+    tableMeta = tableDesc.getMeta();
+    assertEquals(tableMeta.getPropertySet().size(), 2);
+    assertNotNull(tableMeta.getProperty("timezone"));
+    assertNotNull(tableMeta.getProperty("text.null"));
+    assertFalse(tableMeta.getPropertySet().containsKey("text.delimiter"));
+
+    executeDDL("alter_table_unset_not_exists_property.sql", null);
+
+    tableDesc = catalog.getTableDesc(tableName);
+    tableMeta = tableDesc.getMeta();
+    assertEquals(tableMeta.getPropertySet().size(), 2);
+    assertNotNull(tableMeta.getProperty("timezone"));
+    assertNotNull(tableMeta.getProperty("text.null"));
+    assertFalse(tableMeta.getPropertySet().containsKey("text.delimiter"));
+  }
+
   // TODO: This should be added at TAJO-1891
   public final void testAlterTableAddPartition() throws Exception {
     executeDDL("create_partitioned_table.sql", null);

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_unset_not_exists_property.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_unset_not_exists_property.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_unset_not_exists_property.sql
new file mode 100644
index 0000000..e86ca77
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_unset_not_exists_property.sql
@@ -0,0 +1 @@
+ALTER TABLE ALTY UNSET PROPERTY 'csv.delimiter';

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_unset_property_delimiter.sql
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_unset_property_delimiter.sql b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_unset_property_delimiter.sql
new file mode 100644
index 0000000..791e806
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/queries/TestAlterTable/alter_table_unset_property_delimiter.sql
@@ -0,0 +1 @@
+ALTER TABLE ALTY UNSET PROPERTY 'text.delimiter';

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java
index c480d04..458a0c8 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java
@@ -477,6 +477,9 @@ public class DDLExecutor {
       catalog.alterTable(CatalogUtil.setProperty(qualifiedName, alterTable.getProperties(), AlterTableType
           .SET_PROPERTY));
       break;
+    case UNSET_PROPERTY:
+      catalog.alterTable(CatalogUtil.unsetProperty(qualifiedName, alterTable.getUnsetPropertyKeys()));
+      break;
     case ADD_PARTITION:
       pair = CatalogUtil.getPartitionKeyNamePair(alterTable.getPartitionColumns(), alterTable.getPartitionValues());
       ensureColumnPartitionKeys(qualifiedName, alterTable.getPartitionColumns());

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java b/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java
index 6ffe65b..fdb4c0b 100644
--- a/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java
+++ b/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java
@@ -1931,6 +1931,10 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
       alterTable.setParams(getProperties(ctx.property_list()));
     }
 
+    if (checkIfExist(ctx.property_key_list())) {
+      alterTable.setUnsetPropertyKeys(getPropertyKeys(ctx.property_key_list()));
+    }
+
     alterTable.setAlterTableOpType(determineAlterTableType(ctx));
 
     return alterTable;
@@ -1945,6 +1949,14 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     return params;
   }
 
+  private List<String> getPropertyKeys(Property_key_listContext ctx) {
+    List<String> keys = Lists.newArrayList();
+    for (int i = 0; i < ctx.property_key().size(); i++) {
+      keys.add(stripQuote(ctx.property_key(i).key.getText()));
+    }
+    return keys;
+  }
+
   private AlterTableOpType determineAlterTableType(Alter_table_statementContext ctx) {
 
     final int RENAME_MASK = 00000001;
@@ -1954,6 +1966,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     final int DROP_MASK = 00001001;
     final int PARTITION_MASK = 00000020;
     final int SET_MASK = 00000002;
+    final int UNSET_MASK = 00000200;
     final int PROPERTY_MASK = 00010000;
     final int REPAIR_MASK = 00000003;
 
@@ -1984,6 +1997,9 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
           case SET:
             val = val | SET_MASK;
             break;
+          case UNSET:
+            val = val | UNSET_MASK;
+            break;
           case PROPERTY:
             val = val | PROPERTY_MASK;
             break;
@@ -2015,6 +2031,8 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
         return AlterTableOpType.DROP_PARTITION;
       case 4098:
         return AlterTableOpType.SET_PROPERTY;
+      case 4224:
+        return AlterTableOpType.UNSET_PROPERTY;
       default:
         return null;
     }

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
index 51b2568..3721556 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
@@ -2171,6 +2171,10 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
     alterTableNode.setColumnName(alterTable.getColumnName());
     alterTableNode.setNewColumnName(alterTable.getNewColumnName());
     alterTableNode.setProperties(new KeyValueSet(alterTable.getParams()));
+    List<String> propertyKeys = alterTable.getUnsetPropertyKeys();
+    if (null != propertyKeys) {
+      alterTableNode.setUnsetPropertyKeys(propertyKeys.toArray(new String[propertyKeys.size()]));
+    }
 
     if (null != alterTable.getAddNewColumn()) {
       alterTableNode.setAddNewColumn(convertColumn(alterTable.getAddNewColumn()));

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/tajo-plan/src/main/java/org/apache/tajo/plan/logical/AlterTableNode.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/AlterTableNode.java b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/AlterTableNode.java
index 4e25baa..c144dc4 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/AlterTableNode.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/AlterTableNode.java
@@ -42,6 +42,8 @@ public class AlterTableNode extends LogicalNode {
   @Expose
   private KeyValueSet properties = new KeyValueSet();
   @Expose
+  private String[] unsetPropertyKeys;
+  @Expose
   private AlterTableOpType alterTableOpType;
   @Expose
   private String[] partitionColumns;
@@ -130,6 +132,14 @@ public class AlterTableNode extends LogicalNode {
     this.properties = properties;
   }
 
+  public String[] getUnsetPropertyKeys() {
+    return unsetPropertyKeys;
+  }
+
+  public void setUnsetPropertyKeys(String[] unsetPropertyKeys) {
+    this.unsetPropertyKeys = unsetPropertyKeys;
+  }
+
   public String[] getPartitionColumns() {
     return partitionColumns;
   }
@@ -186,7 +196,7 @@ public class AlterTableNode extends LogicalNode {
   @Override
   public int hashCode() {
     return Objects.hashCode(tableName, addNewColumn, alterTableOpType, columnName, newColumnName, newTableName,
-      tableName, properties, partitionColumns, partitionValues, location, isPurge, ifNotExists, ifExists);
+      tableName, properties, unsetPropertyKeys, partitionColumns, partitionValues, location, isPurge, ifNotExists, ifExists);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java
index 4b47e4a..02b2ad9 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java
@@ -34,6 +34,7 @@ import org.apache.tajo.plan.expr.*;
 import org.apache.tajo.plan.logical.*;
 import org.apache.tajo.plan.rewrite.rules.IndexScanInfo.SimplePredicate;
 import org.apache.tajo.util.KeyValueSet;
+import org.apache.tajo.util.ProtoUtil;
 import org.apache.tajo.util.TUtil;
 
 import java.net.URI;
@@ -624,6 +625,10 @@ public class LogicalNodeDeserializer {
     case SET_PROPERTY:
       alterTable.setProperties(new KeyValueSet(alterTableProto.getProperties()));
       break;
+    case UNSET_PROPERTY:
+      Collection<String> strings = ProtoUtil.convertStrings(alterTableProto.getUnsetPropertyKeys());
+      alterTable.setUnsetPropertyKeys(strings.toArray(new String[strings.size()]));
+      break;
     case ADD_PARTITION:
       alterPartition = alterTableProto.getAlterPartition();
       alterTable.setPartitionColumns(alterPartition.getColumnNamesList().toArray(new String[alterPartition

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java
index e724768..a536b02 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java
@@ -41,10 +41,7 @@ import org.apache.tajo.plan.serder.PlanProto.LogicalNodeTree;
 import org.apache.tajo.plan.visitor.BasicLogicalPlanVisitor;
 import org.apache.tajo.util.ProtoUtil;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
+import java.util.*;
 
 /**
  * It serializes a logical plan into a protobuf-based serialized bytes.
@@ -607,6 +604,10 @@ public class LogicalNodeSerializer extends BasicLogicalPlanVisitor<LogicalNodeSe
       alterTableBuilder.setSetType(PlanProto.AlterTableNode.Type.SET_PROPERTY);
       alterTableBuilder.setProperties(node.getProperties().getProto());
       break;
+    case UNSET_PROPERTY:
+      alterTableBuilder.setSetType(PlanProto.AlterTableNode.Type.UNSET_PROPERTY);
+      alterTableBuilder.setUnsetPropertyKeys(ProtoUtil.convertStrings(Arrays.asList(node.getUnsetPropertyKeys())));
+      break;
     case ADD_PARTITION:
       alterTableBuilder.setSetType(PlanProto.AlterTableNode.Type.ADD_PARTITION);
       partitionBuilder = PlanProto.AlterTableNode.AlterPartition.newBuilder();

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/tajo-plan/src/main/proto/Plan.proto
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/proto/Plan.proto b/tajo-plan/src/main/proto/Plan.proto
index 99a0914..da9501c 100644
--- a/tajo-plan/src/main/proto/Plan.proto
+++ b/tajo-plan/src/main/proto/Plan.proto
@@ -302,7 +302,8 @@ message AlterTableNode {
     SET_PROPERTY = 3;
     ADD_PARTITION = 4;
     DROP_PARTITION = 5;
-    REPAIR_PARTITION = 6;    
+    REPAIR_PARTITION = 6;
+    UNSET_PROPERTY = 7;
   }
 
   message RenameTable {
@@ -334,6 +335,7 @@ message AlterTableNode {
   optional AddColumn addColumn = 5;
   optional KeyValueSetProto properties = 6;
   optional AlterPartition alterPartition = 7;
+  optional StringListProto unsetPropertyKeys = 8;
 }
 
 message CreateIndexNode {

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/tajo-sql-parser/src/main/antlr4/org/apache/tajo/parser/sql/SQLLexer.g4
----------------------------------------------------------------------
diff --git a/tajo-sql-parser/src/main/antlr4/org/apache/tajo/parser/sql/SQLLexer.g4 b/tajo-sql-parser/src/main/antlr4/org/apache/tajo/parser/sql/SQLLexer.g4
index 93601cc..e67b435 100644
--- a/tajo-sql-parser/src/main/antlr4/org/apache/tajo/parser/sql/SQLLexer.g4
+++ b/tajo-sql-parser/src/main/antlr4/org/apache/tajo/parser/sql/SQLLexer.g4
@@ -318,6 +318,7 @@ TRUNCATE : T R U N C A T E;
 
 UNBOUNDED : U N B O U N D E D;
 UNKNOWN : U N K N O W N;
+UNSET : U N S E T;
 
 VALUES : V A L U E S;
 VAR_SAMP : V A R UNDERLINE S A M P;

http://git-wip-us.apache.org/repos/asf/tajo/blob/fab36f97/tajo-sql-parser/src/main/antlr4/org/apache/tajo/parser/sql/SQLParser.g4
----------------------------------------------------------------------
diff --git a/tajo-sql-parser/src/main/antlr4/org/apache/tajo/parser/sql/SQLParser.g4 b/tajo-sql-parser/src/main/antlr4/org/apache/tajo/parser/sql/SQLParser.g4
index 213024c..8b5d36e 100644
--- a/tajo-sql-parser/src/main/antlr4/org/apache/tajo/parser/sql/SQLParser.g4
+++ b/tajo-sql-parser/src/main/antlr4/org/apache/tajo/parser/sql/SQLParser.g4
@@ -1628,6 +1628,7 @@ alter_table_statement
   | ALTER TABLE table_name ADD (if_not_exists)? PARTITION LEFT_PAREN partition_column_value_list RIGHT_PAREN (LOCATION path=Character_String_Literal)?
   | ALTER TABLE table_name DROP (if_exists)? PARTITION LEFT_PAREN partition_column_value_list RIGHT_PAREN (PURGE)?
   | ALTER TABLE table_name SET PROPERTY property_list
+  | ALTER TABLE table_name UNSET PROPERTY property_key_list
   | ALTER TABLE table_name REPAIR PARTITION
   ;
 
@@ -1646,3 +1647,11 @@ property_list
 property
   : key=Character_String_Literal EQUAL value=Character_String_Literal
   ;
+
+property_key_list
+  : property_key (COMMA property_key)*
+  ;
+
+property_key
+  : key=Character_String_Literal
+  ;