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 2013/10/31 13:37:43 UTC

git commit: TAJO-285: Add CREATE TABLE... BY PARTITION statement to parser. (hyunsik)

Updated Branches:
  refs/heads/master 8e6fec0fc -> 06b1e0e70


TAJO-285: Add CREATE TABLE... BY PARTITION statement to parser. (hyunsik)


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

Branch: refs/heads/master
Commit: 06b1e0e70c52c17b68a2cd726985149d5430bd78
Parents: 8e6fec0
Author: Hyunsik Choi <hy...@apache.org>
Authored: Thu Oct 31 21:31:29 2013 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Thu Oct 31 21:37:26 2013 +0900

----------------------------------------------------------------------
 CHANGES.txt                                     |   2 +
 .../org/apache/tajo/algebra/CreateTable.java    | 170 +++++++++++++++++++
 .../org/apache/tajo/engine/parser/SQLLexer.g4   |  81 +++++++--
 .../org/apache/tajo/engine/parser/SQLParser.g4  |  72 +++++++-
 .../apache/tajo/engine/parser/SQLAnalyzer.java  |  78 ++++++++-
 .../tajo/engine/parser/TestSQLAnalyzer.java     |  87 ++++++++++
 .../create_table_partition_by_column.sql        |   4 +
 .../create_table_partition_by_hash_1.sql        |   3 +
 .../create_table_partition_by_hash_2.sql        |   7 +
 .../queries/create_table_partition_by_list.sql  |   8 +
 .../queries/create_table_partition_by_range.sql |   9 +
 11 files changed, 496 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/06b1e0e7/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index b7f131e..c0d9084 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,6 +4,8 @@ Release 0.2.0 - unreleased
 
   NEW FEATURES
 
+    TAJO-285: Add CREATE TABLE... BY PARTITION statement to parser. (hyunsik)
+
     TAJO-267: Implement equals() and deepEquals() functions at LogicalNode. 
     (jihoon)
 

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/06b1e0e7/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 5f96d00..6e36f3a 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
@@ -20,6 +20,7 @@ package org.apache.tajo.algebra;
 
 import org.apache.tajo.util.TUtil;
 
+import java.util.List;
 import java.util.Map;
 
 public class CreateTable extends Expr {
@@ -30,6 +31,7 @@ public class CreateTable extends Expr {
   private String location;
   private Expr subquery;
   private Map<String, String> params;
+  private PartitionOption partition;
 
   public CreateTable(final String tableName) {
     super(OpType.CreateTable);
@@ -101,6 +103,18 @@ public class CreateTable extends Expr {
     this.params = params;
   }
 
+  public boolean hasPartition() {
+    return partition != null;
+  }
+
+  public void setPartition(PartitionOption partition) {
+    this.partition = partition;
+  }
+
+  public <T extends PartitionOption> T getPartition() {
+    return (T) this.partition;
+  }
+
   public boolean hasSubQuery() {
     return subquery != null;
   }
@@ -156,4 +170,160 @@ public class CreateTable extends Expr {
       return false;
     }
   }
+
+  public static enum PartitionType {
+    RANGE,
+    HASH,
+    LIST,
+    COLUMN
+  }
+
+  public static abstract class PartitionOption {
+    PartitionType type;
+
+    public PartitionOption(PartitionType type) {
+      this.type = type;
+    }
+
+    public PartitionType getPartitionType() {
+      return type;
+    }
+  }
+
+  public static class RangePartition extends PartitionOption {
+    ColumnReferenceExpr [] columns;
+    List<RangePartitionSpecifier> specifiers;
+
+    public RangePartition(ColumnReferenceExpr [] columns, List<RangePartitionSpecifier> specifiers) {
+      super(PartitionType.RANGE);
+      this.columns = columns;
+      this.specifiers = specifiers;
+    }
+
+    public ColumnReferenceExpr [] getColumns() {
+      return columns;
+    }
+
+    public List<RangePartitionSpecifier> getSpecifiers() {
+      return specifiers;
+    }
+  }
+
+  public static class HashPartition extends PartitionOption {
+    ColumnReferenceExpr [] columns;
+    Expr quantity;
+    List<PartitionSpecifier> specifiers;
+    public HashPartition(ColumnReferenceExpr [] columns, Expr quantity) {
+      super(PartitionType.HASH);
+      this.columns = columns;
+      this.quantity = quantity;
+    }
+
+    public HashPartition(ColumnReferenceExpr [] columns, List<PartitionSpecifier> specifier) {
+      super(PartitionType.HASH);
+      this.columns = columns;
+      this.specifiers = specifier;
+    }
+
+    public ColumnReferenceExpr [] getColumns() {
+      return columns;
+    }
+
+    public boolean hasQuantifier() {
+      return quantity != null;
+    }
+
+    public Expr getQuantifier() {
+      return quantity;
+    }
+
+    public boolean hasSpecifiers() {
+      return specifiers != null;
+    }
+
+    public List<PartitionSpecifier> getSpecifiers() {
+      return specifiers;
+    }
+  }
+
+  public static class ListPartition extends PartitionOption {
+    ColumnReferenceExpr [] columns;
+    List<ListPartitionSpecifier> specifiers;
+
+    public ListPartition(ColumnReferenceExpr [] columns, List<ListPartitionSpecifier> specifers) {
+      super(PartitionType.LIST);
+      this.columns = columns;
+      this.specifiers = specifers;
+    }
+
+    public ColumnReferenceExpr [] getColumns() {
+      return columns;
+    }
+
+    public List<ListPartitionSpecifier> getSpecifiers() {
+      return specifiers;
+    }
+  }
+
+  public static class ColumnPartition extends PartitionOption {
+    ColumnReferenceExpr [] columns;
+
+    public ColumnPartition(ColumnReferenceExpr [] columns) {
+      super(PartitionType.COLUMN);
+      this.columns = columns;
+    }
+
+    public ColumnReferenceExpr [] getColumns() {
+      return columns;
+    }
+  }
+
+  public static class RangePartitionSpecifier extends PartitionSpecifier {
+    String name;
+    Expr end;
+    boolean maxValue;
+
+    public RangePartitionSpecifier(String name, Expr end) {
+      super(name);
+      this.end = end;
+    }
+
+    public RangePartitionSpecifier(String name) {
+      super(name);
+      maxValue = true;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    public Expr getEnd() {
+      return end;
+    }
+
+    public boolean isEndMaxValue() {
+      return this.maxValue;
+    }
+  }
+
+  public static class ListPartitionSpecifier extends PartitionSpecifier {
+    ValueListExpr valueList;
+
+    public ListPartitionSpecifier(String name, ValueListExpr valueList) {
+      super(name);
+      this.valueList = valueList;
+    }
+
+    public ValueListExpr getValueList() {
+      return valueList;
+    }
+  }
+
+  public static class PartitionSpecifier {
+    String name;
+
+    public PartitionSpecifier(String name) {
+      this.name = name;
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/06b1e0e7/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 f0992ef..dc5bff3 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
@@ -120,32 +120,20 @@ AND : A N D;
 ANY : A N Y;
 ASYMMETRIC : A S Y M M E T R I C;
 ASC : A S C;
-AVG : A V G;
 
-BETWEEN : B E T W E E N;
 BOTH : B O T H;
-BY : B Y;
 
 CASE : C A S E;
 CAST : C A S T;
-CHARACTER : C H A R A C T E R;
-COALESCE : C O A L E S C E;
-COUNT : C O U N T;
 CREATE : C R E A T E;
 CROSS : C R O S S;
-CUBE : C U B E;
 
-DEC : D E C;
 DESC : D E S C;
 DISTINCT : D I S T I N C T;
-DROP : D R O P;
 
 END : E N D;
 ELSE : E L S E;
-EVERY : E V E R Y;
 EXCEPT : E X C E P T;
-EXISTS : E X I S T S;
-EXTERNAL : E X T E R N A L;
 
 FALSE : F A L S E;
 FILTER : F I L T E R;
@@ -158,6 +146,7 @@ GROUP : G R O U P;
 GROUPING : G R O U P I N G;
 
 HAVING : H A V I N G;
+HASH : H A S H;
 
 ILIKE : I L I K E;
 IN : I N;
@@ -175,6 +164,7 @@ LEADING : L E A D I N G;
 LEFT : L E F T;
 LIKE : L I K E;
 LIMIT : L I M I T;
+LIST : L I S T;
 LOCATION : L O C A T I O N;
 
 NATIONAL : N A T I O N A L;
@@ -194,15 +184,15 @@ OVERWRITE : O V E R W R I T E;
 
 PRECISION : P R E C I S I ON;
 
+RANGE : R A N G E;
 REGEXP : R E G E X P;
 RIGHT : R I G H T;
 RLIKE : R L I K E;
-ROLLUP : R O L L U P;
 
-SYMMETRIC : S Y M M E T R I C;
 SET : S E T;
 SELECT : S E L E C T;
 SOME : S O M E;
+SYMMETRIC : S Y M M E T R I C;
 
 TABLE : T A B L E;
 THEN : T H E N;
@@ -214,7 +204,6 @@ UNIQUE : U N I Q U E;
 UNKNOWN : U N K N O W N;
 USING : U S I N G;
 
-VALUES : V A L U E S;
 VAR_SAMP : V A R UNDERLINE S A M P;
 VAR_POP : V A R UNDERLINE P O P;
 VARYING : V A R Y I N G;
@@ -230,29 +219,89 @@ ZONE : Z O N E;
   Non Reserved Keywords
 ===============================================================================
 */
+AVG : A V G;
 
+BETWEEN : B E T W E E N;
+BY : B Y;
+
+CHARACTER : C H A R A C T E R;
 COLLECT : C O L L E C T;
+COALESCE : C O A L E S C E;
+COLUMN : C O L U M N;
+COUNT : C O U N T;
+CUBE : C U B E;
+
+DEC : D E C;
+DROP : D R O P;
+
+EVERY : E V E R Y;
+EXISTS : E X I S T S;
+EXTERNAL : E X T E R N A L;
+
+LESS : L E S S;
 
 FUSION : F U S I O N;
 
 INTERSECTION : I N T E R S E C T I O N;
 
+MAXVALUE : M A X V A L U E;
+
+PARTITION : P A R T I T I O N;
+PARTITIONS : P A R T I T I O N S;
+
+ROLLUP : R O L L U P;
+
 SIMILAR : S I M I L A R;
 STDDEV_POP : S T D D E V UNDERLINE P O P;
 STDDEV_SAMP : S T D D E V UNDERLINE S A M P;
+SUBPARTITION : S U B P A R T I T I O N;
 SUM : S U M;
 
+TABLESPACE : T A B L E S P A C E;
+THAN : T H A N;
 TRIM : T R I M;
 TO : T O;
 
+VALUES : V A L U E S;
+
 Nonreserved_keywords
-  : COLLECT
+  : AVG
+  | BETWEEN
+  | BY
+
+  | CHARACTER
+  | COALESCE
+  | COLLECT
+  | COLUMN
+  | COUNT
+  | CUBE
+  | DEC
+  | DROP
+  | EVERY
+  | EXISTS
+  | EXTERNAL
   | FUSION
+  | HASH
   | INTERSECTION
+
+  | LESS
+  | LIST
+
+  | MAXVALUE
+
+  | VALUES
+  | PARTITION
+  | PARTITIONS
+  | ROLLUP
+
   | SIMILAR
   | STDDEV_POP
   | STDDEV_SAMP
+  | SUBPARTITION
   | SUM
+
+  | TABLESPACE
+  | THAN
   | TRIM
   | TO
   ;

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/06b1e0e7/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 7d48834..b071b82 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
@@ -65,9 +65,9 @@ index_statement
 
 create_table_statement
   : CREATE EXTERNAL TABLE table_name table_elements USING file_type=Identifier
-    (param_clause)? (LOCATION path=Character_String_Literal)
+    (param_clause)? (table_partitioning_clauses)? (LOCATION path=Character_String_Literal)
   | CREATE TABLE table_name (table_elements)? (USING file_type=Identifier)?
-    (param_clause)? (AS query_expression)?
+    (param_clause)? (table_partitioning_clauses)? (AS query_expression)?
   ;
 
 table_elements
@@ -94,6 +94,71 @@ method_specifier
   : USING m=Identifier
   ;
 
+table_space_specifier
+  : TABLESPACE table_space_name
+  ;
+
+table_space_name
+  : Identifier
+  ;
+
+table_partitioning_clauses
+  : range_partitions
+  | hash_partitions
+  | list_partitions
+  | column_partitions
+  ;
+
+range_partitions
+  : PARTITION BY RANGE LEFT_PAREN column_reference_list RIGHT_PAREN
+    LEFT_PAREN range_value_clause_list RIGHT_PAREN
+  ;
+
+range_value_clause_list
+  : range_value_clause (COMMA range_value_clause)*
+  ;
+
+range_value_clause
+  : PARTITION partition_name VALUES LESS THAN (LEFT_PAREN value_expression RIGHT_PAREN | LEFT_PAREN? MAXVALUE RIGHT_PAREN?)
+  ;
+
+hash_partitions
+  : PARTITION BY HASH LEFT_PAREN column_reference_list RIGHT_PAREN
+    (LEFT_PAREN individual_hash_partitions RIGHT_PAREN | hash_partitions_by_quantity)
+  ;
+
+individual_hash_partitions
+  : individual_hash_partition (COMMA individual_hash_partition)*
+  ;
+
+individual_hash_partition
+  : PARTITION partition_name
+  ;
+
+hash_partitions_by_quantity
+  : PARTITIONS quantity = numeric_value_expression
+  ;
+
+list_partitions
+  : PARTITION BY LIST LEFT_PAREN column_reference_list RIGHT_PAREN LEFT_PAREN  list_value_clause_list RIGHT_PAREN
+  ;
+
+list_value_clause_list
+  : list_value_partition (COMMA list_value_partition)*
+  ;
+
+list_value_partition
+  : PARTITION partition_name VALUES (IN)? LEFT_PAREN in_value_list RIGHT_PAREN
+  ;
+
+column_partitions
+  : PARTITION BY COLUMN LEFT_PAREN column_reference_list RIGHT_PAREN
+  ;
+
+partition_name
+  : Identifier
+  ;
+
 /*
 ===============================================================================
   11.21 <data types>
@@ -880,10 +945,9 @@ in_predicate
   : predicand=numeric_value_expression  NOT? IN in_predicate_value
   ;
 
-
 in_predicate_value
   : table_subquery
-  | LEFT_PAREN in_value_list  RIGHT_PAREN
+  | LEFT_PAREN in_value_list RIGHT_PAREN
   ;
 
 in_value_list

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/06b1e0e7/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 3fa303a..2b641cb 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
@@ -19,6 +19,7 @@
 package org.apache.tajo.engine.parser;
 
 import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
 import org.antlr.v4.runtime.ANTLRInputStream;
 import org.antlr.v4.runtime.CommonTokenStream;
 import org.antlr.v4.runtime.misc.NotNull;
@@ -31,9 +32,11 @@ import org.apache.tajo.engine.parser.SQLParser.*;
 import org.apache.tajo.storage.CSVFile;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import static org.apache.tajo.algebra.Aggregation.GroupElement;
+import static org.apache.tajo.algebra.CreateTable.*;
 import static org.apache.tajo.common.TajoDataTypes.Type;
 import static org.apache.tajo.engine.parser.SQLParser.*;
 
@@ -849,7 +852,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     String tableName = ctx.table_name().getText();
     CreateTable createTable = new CreateTable(tableName);
 
-    if (ctx.EXTERNAL() != null) {
+    if (checkIfExist(ctx.EXTERNAL())) {
       createTable.setExternal();
 
       CreateTable.ColumnDefinition [] elements = getDefinitions(ctx.table_elements());
@@ -860,26 +863,32 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
       createTable.setStorageType(fileType);
       createTable.setLocation(path);
     } else {
-      if (ctx.table_elements() != null) {
+      if (checkIfExist(ctx.table_elements())) {
         CreateTable.ColumnDefinition [] elements = getDefinitions(ctx.table_elements());
         createTable.setTableElements(elements);
       }
 
-      if (ctx.USING() != null) {
+      if (checkIfExist(ctx.USING())) {
         String fileType = ctx.file_type.getText();
         createTable.setStorageType(fileType);
       }
 
-      if (ctx.query_expression() != null) {
+      if (checkIfExist(ctx.query_expression())) {
         Expr subquery = visitQuery_expression(ctx.query_expression());
         createTable.setSubQuery(subquery);
       }
     }
 
-    if (ctx.param_clause() != null) {
+    if (checkIfExist(ctx.param_clause())) {
       Map<String, String> params = escapeTableMeta(getParams(ctx.param_clause()));
       createTable.setParams(params);
     }
+
+    if (checkIfExist(ctx.table_partitioning_clauses())) {
+      CreateTable.PartitionOption partitionOption =
+          parseTablePartitioningClause(ctx.table_partitioning_clauses());
+      createTable.setPartition(partitionOption);
+    }
     return createTable;
   }
 
@@ -895,6 +904,65 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     return elements;
   }
 
+  public CreateTable.PartitionOption parseTablePartitioningClause(SQLParser.Table_partitioning_clausesContext ctx) {
+
+    if (checkIfExist(ctx.range_partitions())) { // For Range Partition
+      Range_partitionsContext rangePartitionsContext = ctx.range_partitions();
+      List<Range_value_clauseContext> rangeValueClause = rangePartitionsContext.
+          range_value_clause_list().range_value_clause();
+
+      List<RangePartitionSpecifier> specifiers = Lists.newArrayList();
+
+      for (Range_value_clauseContext rangeValue : rangeValueClause) {
+        if (checkIfExist(rangeValue.MAXVALUE())) { // LESS THAN (MAXVALUE)
+          specifiers.add(new RangePartitionSpecifier(rangeValue.partition_name().getText()));
+        } else { // LESS THAN (expr)
+          specifiers.add(new RangePartitionSpecifier(rangeValue.partition_name().getText(),
+              visitValue_expression(rangeValue.value_expression())));
+        }
+      }
+      return new CreateTable.RangePartition(getColumnReferences(ctx.range_partitions().column_reference_list()),
+          specifiers);
+
+    } else if (checkIfExist(ctx.hash_partitions())) { // For Hash Partition
+      Hash_partitionsContext hashPartitions = ctx.hash_partitions();
+
+      if (checkIfExist(hashPartitions.hash_partitions_by_quantity())) { // PARTITIONS (num)
+        return new HashPartition(getColumnReferences(hashPartitions.column_reference_list()),
+            visitNumeric_value_expression(hashPartitions.hash_partitions_by_quantity().quantity));
+
+      } else { // ( PARTITION part_name , ...)
+        List<CreateTable.PartitionSpecifier> specifiers = Lists.newArrayList();
+        for (Individual_hash_partitionContext partition :
+            hashPartitions.individual_hash_partitions().individual_hash_partition()) {
+          specifiers.add(new CreateTable.PartitionSpecifier(partition.partition_name().getText()));
+        }
+        return new HashPartition(getColumnReferences(hashPartitions.column_reference_list()), specifiers);
+      }
+
+    } else if (checkIfExist(ctx.list_partitions())) { // For List Partition
+      List_partitionsContext listPartitions = ctx.list_partitions();
+      List<List_value_partitionContext> partitions = listPartitions.list_value_clause_list().list_value_partition();
+      List<ListPartitionSpecifier> specifiers = Lists.newArrayList();
+
+      for (List_value_partitionContext listValuePartition : partitions) {
+        int size = listValuePartition.in_value_list().row_value_expression().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));
+        }
+        specifiers.add(new ListPartitionSpecifier(listValuePartition.partition_name().getText(),
+            new ValueListExpr(exprs)));
+      }
+      return new ListPartition(getColumnReferences(ctx.list_partitions().column_reference_list()), specifiers);
+
+    } else if (checkIfExist(ctx.column_partitions())) { // For Column Partition (Hive Style)
+      return new CreateTable.ColumnPartition(getColumnReferences(ctx.column_partitions().column_reference_list()));
+    } else {
+      throw new SQLSyntaxError("Wrong partition option");
+    }
+  }
+
   @Override
   public DataType visitData_type(SQLParser.Data_typeContext ctx) {
     SQLParser.Predefined_typeContext predefined_type = ctx.predefined_type();

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/06b1e0e7/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java
index 894d9ea..6775aa9 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java
@@ -20,7 +20,10 @@ package org.apache.tajo.engine.parser;
 
 import org.antlr.v4.runtime.ANTLRInputStream;
 import org.antlr.v4.runtime.CommonTokenStream;
+import org.apache.tajo.algebra.CreateTable;
 import org.apache.tajo.algebra.Expr;
+import org.apache.tajo.algebra.LiteralValue;
+import org.apache.tajo.algebra.OpType;
 import org.apache.tajo.engine.parser.SQLParser.Boolean_value_expressionContext;
 import org.apache.tajo.engine.parser.SQLParser.SqlContext;
 import org.apache.tajo.util.FileUtil;
@@ -28,6 +31,10 @@ import org.junit.Test;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Iterator;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 /**
  * This unit tests uses a number of query files located in tajo/tajo-core/tajo-core-backend/test/queries.
@@ -240,6 +247,86 @@ public class TestSQLAnalyzer {
   }
 
   @Test
+  public void testCreateTablePartitionByHash1() throws IOException {
+    String sql = FileUtil.readTextFile(new File("src/test/queries/create_table_partition_by_hash_1.sql"));
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.CreateTable, expr.getType());
+    CreateTable createTable = (CreateTable) expr;
+    assertTrue(createTable.hasPartition());
+    assertEquals(CreateTable.PartitionType.HASH, createTable.getPartition().getPartitionType());
+    CreateTable.HashPartition hashPartition = createTable.getPartition();
+    assertEquals("col1", hashPartition.getColumns()[0].getCanonicalName());
+    assertTrue(hashPartition.hasQuantifier());
+  }
+
+  @Test
+  public void testCreateTablePartitionByHash2() throws IOException {
+    String sql = FileUtil.readTextFile(new File("src/test/queries/create_table_partition_by_hash_2.sql"));
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.CreateTable, expr.getType());
+    CreateTable createTable = (CreateTable) expr;
+    assertTrue(createTable.hasPartition());
+    assertEquals(CreateTable.PartitionType.HASH, createTable.getPartition().getPartitionType());
+    CreateTable.HashPartition hashPartition = createTable.getPartition();
+    assertEquals("col1", hashPartition.getColumns()[0].getCanonicalName());
+    assertTrue(hashPartition.hasSpecifiers());
+    assertEquals(3, hashPartition.getSpecifiers().size());
+  }
+
+  @Test
+  public void testCreateTablePartitionByRange() throws IOException {
+    String sql = FileUtil.readTextFile(new File("src/test/queries/create_table_partition_by_range.sql"));
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.CreateTable, expr.getType());
+    CreateTable createTable = (CreateTable) expr;
+    assertTrue(createTable.hasPartition());
+    assertEquals(CreateTable.PartitionType.RANGE, createTable.getPartition().getPartitionType());
+    CreateTable.RangePartition rangePartition = createTable.getPartition();
+    assertEquals("col1", rangePartition.getColumns()[0].getCanonicalName());
+    assertEquals(3, rangePartition.getSpecifiers().size());
+  }
+
+  @Test
+  public void testCreateTablePartitionByList() throws IOException {
+    String sql = FileUtil.readTextFile(new File("src/test/queries/create_table_partition_by_list.sql"));
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.CreateTable, expr.getType());
+    CreateTable createTable = (CreateTable) expr;
+    assertTrue(createTable.hasPartition());
+    assertEquals(CreateTable.PartitionType.LIST, createTable.getPartition().getPartitionType());
+    CreateTable.ListPartition listPartition = createTable.getPartition();
+    assertEquals("col1", listPartition.getColumns()[0].getCanonicalName());
+    assertEquals(2, listPartition.getSpecifiers().size());
+    Iterator<CreateTable.ListPartitionSpecifier> iterator = listPartition.getSpecifiers().iterator();
+    CreateTable.ListPartitionSpecifier specifier = iterator.next();
+    LiteralValue value1 = (LiteralValue) specifier.getValueList().getValues()[0];
+    LiteralValue value2 = (LiteralValue) specifier.getValueList().getValues()[1];
+    assertEquals("Seoul", value1.getValue());
+    assertEquals("서울", value2.getValue());
+
+    specifier = iterator.next();
+    value1 = (LiteralValue) specifier.getValueList().getValues()[0];
+    value2 = (LiteralValue) specifier.getValueList().getValues()[1];
+    assertEquals("Busan", value1.getValue());
+    assertEquals("부산", value2.getValue());
+  }
+
+  @Test
+  public void testCreateTablePartitionByColumn() throws IOException {
+    String sql = FileUtil.readTextFile(new File("src/test/queries/create_table_partition_by_column.sql"));
+    Expr expr = parseQuery(sql);
+    assertEquals(OpType.CreateTable, expr.getType());
+    CreateTable createTable = (CreateTable) expr;
+    assertTrue(createTable.hasPartition());
+    assertEquals(CreateTable.PartitionType.COLUMN, createTable.getPartition().getPartitionType());
+    CreateTable.ColumnPartition columnPartition = createTable.getPartition();
+    assertEquals(3, columnPartition.getColumns().length);
+    assertEquals("col1", columnPartition.getColumns()[0].getCanonicalName());
+    assertEquals("col2", columnPartition.getColumns()[1].getCanonicalName());
+    assertEquals("col3", columnPartition.getColumns()[2].getCanonicalName());
+  }
+
+  @Test
   public void testTableSubQuery1() throws IOException {
     String sql = FileUtil.readTextFile(new File("src/test/queries/table_subquery1.sql"));
     parseQuery(sql);

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/06b1e0e7/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_column.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_column.sql b/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_column.sql
new file mode 100644
index 0000000..65493a2
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_column.sql
@@ -0,0 +1,4 @@
+CREATE TABLE sales ( col1 int, col2 int)
+PARTITION BY COLUMN (col1, col2, col3);
+
+

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/06b1e0e7/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_hash_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_hash_1.sql b/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_hash_1.sql
new file mode 100644
index 0000000..f13225a
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_hash_1.sql
@@ -0,0 +1,3 @@
+CREATE TABLE sales ( col1 int, col2 int)
+PARTITION BY HASH (col1)
+PARTITIONS 2;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/06b1e0e7/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_hash_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_hash_2.sql b/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_hash_2.sql
new file mode 100644
index 0000000..c8fe3c5
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_hash_2.sql
@@ -0,0 +1,7 @@
+CREATE TABLE sales ( col1 int, col2 int)
+PARTITION BY HASH (col1)
+(
+  PARTITION part1,
+  PARTITION part2,
+  PARTITION part3
+);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/06b1e0e7/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_list.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_list.sql b/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_list.sql
new file mode 100644
index 0000000..9461e01
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_list.sql
@@ -0,0 +1,8 @@
+CREATE TABLE sales ( col1 int, col2 int)
+PARTITION BY LIST (col1)
+ (
+  PARTITION col1 VALUES ('Seoul', '서울'),
+  PARTITION col2 VALUES ('Busan', '부산')
+ );
+
+

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/06b1e0e7/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_range.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_range.sql b/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_range.sql
new file mode 100644
index 0000000..65c4fdd
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/queries/create_table_partition_by_range.sql
@@ -0,0 +1,9 @@
+CREATE TABLE sales ( col1 int, col2 int)
+PARTITION BY RANGE (col1)
+ (
+  PARTITION col1 VALUES LESS THAN (2),
+  PARTITION col1 VALUES LESS THAN (5),
+  PARTITION col1 VALUES LESS THAN (MAXVALUE)
+ );
+
+