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 2015/02/21 12:46:15 UTC
tajo git commit: TAJO-1353: CREATE TABLE should support the nested
record definition.
Repository: tajo
Updated Branches:
refs/heads/master 95d9cc455 -> 08f303450
TAJO-1353: CREATE TABLE should support the nested record definition.
Closes #385
Project: http://git-wip-us.apache.org/repos/asf/tajo/repo
Commit: http://git-wip-us.apache.org/repos/asf/tajo/commit/08f30345
Tree: http://git-wip-us.apache.org/repos/asf/tajo/tree/08f30345
Diff: http://git-wip-us.apache.org/repos/asf/tajo/diff/08f30345
Branch: refs/heads/master
Commit: 08f30345047ddf62dc51c33b9c350f08bf918a5c
Parents: 95d9cc4
Author: Hyunsik Choi <hy...@apache.org>
Authored: Sat Feb 21 03:40:39 2015 -0800
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Sat Feb 21 03:46:02 2015 -0800
----------------------------------------------------------------------
CHANGES | 20 +-
.../apache/tajo/algebra/ColumnDefinition.java | 10 +-
.../org/apache/tajo/algebra/DataTypeExpr.java | 20 +-
tajo-common/src/main/proto/DataTypes.proto | 8 +-
.../org/apache/tajo/engine/parser/SQLLexer.g4 | 1 +
.../org/apache/tajo/engine/parser/SQLParser.g4 | 14 +-
.../apache/tajo/engine/parser/SQLAnalyzer.java | 189 ++++++++++++-------
.../tajo/engine/parser/TestSQLAnalyzer.java | 10 +
.../TestSQLAnalyzer/create_table_nested_1.sql | 1 +
.../TestSQLAnalyzer/create_table_nested_2.sql | 1 +
.../create_table_nested_1.result | 40 ++++
.../create_table_nested_2.result | 57 ++++++
12 files changed, 292 insertions(+), 79 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tajo/blob/08f30345/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index b78b8b7..3f375a4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,7 +1,25 @@
Tajo Change Log
+Release 0.11.0 - unreleased
-Release 0.10.0 - unreleased
+ NEW FEATURES
+
+
+ IMPROVEMENT
+
+
+ BUG FIXES
+
+
+ TASKS
+
+
+ SUB TASKS
+
+ TAJO-1353: Nested record support in CREATE TABLE statement. (hyunsik)
+
+
+Release 0.10.0 - Released
NEW FEATURES
http://git-wip-us.apache.org/repos/asf/tajo/blob/08f30345/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
index e6e05d4..80ecac4 100644
--- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/ColumnDefinition.java
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/ColumnDefinition.java
@@ -31,13 +31,21 @@ public class ColumnDefinition extends DataTypeExpr {
public ColumnDefinition(String columnName, DataTypeExpr dataType) {
super(dataType.getTypeName());
+
+ this.columnName = columnName;
+
+ // precision and scale
if (dataType.hasLengthOrPrecision()) {
setLengthOrPrecision(dataType.lengthOrPrecision);
if (dataType.hasScale()) {
setScale(dataType.scale);
}
}
- this.columnName = columnName;
+
+ // nested records
+ if (dataType.isNestedRecordType()) {
+ this.nestedRecord = dataType.nestedRecord;
+ }
}
public String getColumnName() {
http://git-wip-us.apache.org/repos/asf/tajo/blob/08f30345/tajo-algebra/src/main/java/org/apache/tajo/algebra/DataTypeExpr.java
----------------------------------------------------------------------
diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/DataTypeExpr.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/DataTypeExpr.java
index 9dc795b..28f9a5e 100644
--- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/DataTypeExpr.java
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/DataTypeExpr.java
@@ -21,6 +21,8 @@ package org.apache.tajo.algebra;
import com.google.common.base.Objects;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.common.TajoDataTypes.Type;
import org.apache.tajo.util.TUtil;
public class DataTypeExpr extends Expr {
@@ -30,16 +32,30 @@ public class DataTypeExpr extends Expr {
Integer lengthOrPrecision;
@Expose @SerializedName("Scale")
Integer scale;
+ @Expose @SerializedName("Record")
+ DataTypeExpr [] nestedRecord;
public DataTypeExpr(String typeName) {
super(OpType.DataType);
this.typeName = typeName;
}
+ public DataTypeExpr(DataTypeExpr [] nestedRecordTypes) {
+ super(OpType.DataType);
+ // Please refer to DataTypes.proto. 'STRUCT' must be equivalent to Enum type in DataTypes.proto.
+ // STRUCT = 51;
+ this.typeName = Type.RECORD.name();
+ this.nestedRecord = nestedRecordTypes;
+ }
+
public String getTypeName() {
return this.typeName;
}
+ public boolean isNestedRecordType() {
+ return this.typeName.equals(Type.RECORD.name());
+ }
+
public boolean hasLengthOrPrecision() {
return lengthOrPrecision != null;
}
@@ -74,7 +90,8 @@ public class DataTypeExpr extends Expr {
DataTypeExpr another = (DataTypeExpr) expr;
return typeName.equals(another.typeName) &&
TUtil.checkEquals(lengthOrPrecision, another.lengthOrPrecision) &&
- TUtil.checkEquals(scale, another.scale);
+ TUtil.checkEquals(scale, another.scale) &&
+ TUtil.checkEquals(nestedRecord, another.nestedRecord);
}
@Override
@@ -83,6 +100,7 @@ public class DataTypeExpr extends Expr {
dataType.typeName = typeName;
dataType.lengthOrPrecision = lengthOrPrecision;
dataType.scale = scale;
+ dataType.nestedRecord = nestedRecord;
return dataType;
}
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/08f30345/tajo-common/src/main/proto/DataTypes.proto
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/proto/DataTypes.proto b/tajo-common/src/main/proto/DataTypes.proto
index fb9c957..04f1e12 100644
--- a/tajo-common/src/main/proto/DataTypes.proto
+++ b/tajo-common/src/main/proto/DataTypes.proto
@@ -59,9 +59,11 @@ enum Type {
VARBINARY = 44; // variable-width binary strings
BLOB = 45;
- ANY = 51; // Any type
- UDT = 52; // user-defined function
- PROTOBUF = 53; // protocol buffer type
+ RECORD = 51; // nested structure type
+
+ ANY = 61; // Any type
+ UDT = 62; // user-defined function
+ PROTOBUF = 63; // protocol buffer type
INET4 = 91;
INET6 = 92;
http://git-wip-us.apache.org/repos/asf/tajo/blob/08f30345/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
index 0c144f7..f42e114 100644
--- a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
+++ b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
@@ -284,6 +284,7 @@ QUARTER : Q U A R T E R;
RANGE : R A N G E;
RANK : R A N K;
+RECORD : R E C O R D;
REGEXP : R E G E X P;
RENAME : R E N A M E;
RESET : R E S E T;
http://git-wip-us.apache.org/repos/asf/tajo/blob/08f30345/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
index a236514..420bf46 100644
--- a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
+++ b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
@@ -295,6 +295,7 @@ nonreserved_keywords
| QUARTER
| RANGE
| RANK
+ | RECORD
| REGEXP
| RENAME
| RESET
@@ -430,10 +431,7 @@ predefined_type
| bit_type
| binary_type
| network_type
- ;
-
-network_type
- : INET4
+ | record_type
;
character_string_type
@@ -525,6 +523,14 @@ binary_type
| VARBINARY type_length?
;
+network_type
+ : INET4
+ ;
+
+record_type
+ : RECORD table_elements
+ ;
+
/*
===============================================================================
6.3 <value_expression_primary>
http://git-wip-us.apache.org/repos/asf/tajo/blob/08f30345/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
index ab8e647..5b4054f 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
@@ -1288,7 +1288,10 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
ColumnDefinition[] elements = new ColumnDefinition[size];
for (int i = 0; i < size; i++) {
String name = ctx.field_element(i).name.getText();
+
+ String dataTypeName = ctx.field_element(i).field_type().data_type().getText();
DataTypeExpr typeDef = visitData_type(ctx.field_element(i).field_type().data_type());
+ Preconditions.checkNotNull(typeDef, dataTypeName + " is not handled correctly");
elements[i] = new ColumnDefinition(name, typeDef);
}
@@ -1359,12 +1362,17 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
SQLParser.Predefined_typeContext predefined_type = ctx.predefined_type();
DataTypeExpr typeDefinition = null;
- if (predefined_type.character_string_type() != null) {
- SQLParser.Character_string_typeContext character_string_type =
- predefined_type.character_string_type();
- if ((character_string_type.CHARACTER() != null || character_string_type.CHAR() != null) &&
- character_string_type.VARYING() == null) {
+ // CHAR -> FIXED CHAR
+ // |- VARYING CHAR
+ // TEXT
+ if (checkIfExist(predefined_type.character_string_type())) {
+
+ SQLParser.Character_string_typeContext character_string_type = predefined_type.character_string_type();
+
+
+ if ((checkIfExist(character_string_type.CHARACTER()) || checkIfExist(character_string_type.CHAR())) &&
+ !checkIfExist(character_string_type.VARYING())) {
typeDefinition = new DataTypeExpr(Type.CHAR.name());
@@ -1373,8 +1381,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
Integer.parseInt(character_string_type.type_length().NUMBER().getText()));
}
- } else if (character_string_type.VARCHAR() != null
- || character_string_type.VARYING() != null) {
+ } else if (checkIfExist(character_string_type.VARCHAR()) || checkIfExist(character_string_type.VARYING())) {
typeDefinition = new DataTypeExpr(Type.VARCHAR.name());
@@ -1383,115 +1390,159 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
Integer.parseInt(character_string_type.type_length().NUMBER().getText()));
}
- } else if (character_string_type.TEXT() != null) {
+ } else if (checkIfExist(character_string_type.TEXT())) {
typeDefinition = new DataTypeExpr(Type.TEXT.name());
}
- } else if (predefined_type.national_character_string_type() != null) {
- SQLParser.National_character_string_typeContext nchar_type =
- predefined_type.national_character_string_type();
- if ((nchar_type.CHAR() != null || nchar_type.CHARACTER() != null
- || nchar_type.NCHAR() != null) && nchar_type.VARYING() == null) {
+ // NCHAR
+ } else if (checkIfExist(predefined_type.national_character_string_type())) {
+
+ National_character_string_typeContext nchar_type = predefined_type.national_character_string_type();
+
+ if ((checkIfExist(nchar_type.CHAR()) || checkIfExist(nchar_type.CHARACTER()) ||
+ checkIfExist(nchar_type.NCHAR()) && !checkIfExist(nchar_type.VARYING()))) {
+
typeDefinition = new DataTypeExpr(Type.NCHAR.name());
- } else if (nchar_type.NVARCHAR() != null || nchar_type.VARYING() != null) {
+
+ } else if (checkIfExist(nchar_type.NVARCHAR()) || checkIfExist(nchar_type.VARYING())) {
+
typeDefinition = new DataTypeExpr(Type.NVARCHAR.name());
}
- if (nchar_type.type_length() != null) {
- typeDefinition.setLengthOrPrecision(
- Integer.parseInt(nchar_type.type_length().NUMBER().getText()));
+ // if a length is given
+ if (checkIfExist(nchar_type.type_length())) {
+ typeDefinition.setLengthOrPrecision(Integer.parseInt(nchar_type.type_length().NUMBER().getText()));
}
- } else if (predefined_type.binary_large_object_string_type() != null) {
- SQLParser.Binary_large_object_string_typeContext blob_type =
- predefined_type.binary_large_object_string_type();
+ // BLOB types
+ } else if (checkIfExist(predefined_type.binary_large_object_string_type())) {
+
+ Binary_large_object_string_typeContext blob_type = predefined_type.binary_large_object_string_type();
+
typeDefinition = new DataTypeExpr(Type.BLOB.name());
- if (blob_type.type_length() != null) {
- typeDefinition.setLengthOrPrecision(
- Integer.parseInt(blob_type.type_length().NUMBER().getText()));
+
+ if (checkIfExist(blob_type.type_length())) {
+ typeDefinition.setLengthOrPrecision(Integer.parseInt(blob_type.type_length().NUMBER().getText()));
}
- } else if (predefined_type.numeric_type() != null) {
+
+ // NUMERIC types
+ } else if (checkIfExist(predefined_type.numeric_type())) {
// exact number
- if (predefined_type.numeric_type().exact_numeric_type() != null) {
- SQLParser.Exact_numeric_typeContext exactType =
- predefined_type.numeric_type().exact_numeric_type();
- if (exactType.TINYINT() != null || exactType.INT1() != null) {
+ if (checkIfExist(predefined_type.numeric_type().exact_numeric_type())) {
+
+ Exact_numeric_typeContext exactType = predefined_type.numeric_type().exact_numeric_type();
+
+ if (checkIfExist(exactType.TINYINT()) || checkIfExist(exactType.INT1())) {
typeDefinition = new DataTypeExpr(Type.INT1.name());
- } else if (exactType.INT2() != null || exactType.SMALLINT() != null) {
+
+ } else if (checkIfExist(exactType.INT2()) || checkIfExist(exactType.SMALLINT())) {
typeDefinition = new DataTypeExpr(Type.INT2.name());
- } else if (exactType.INT4() != null || exactType.INTEGER() != null ||
- exactType.INT() != null) {
+
+ } else if (checkIfExist(exactType.INT4()) ||
+ checkIfExist(exactType.INTEGER()) ||
+ checkIfExist(exactType.INT())) {
typeDefinition = new DataTypeExpr(Type.INT4.name());
- } else if (exactType.INT8() != null || exactType.BIGINT() != null) {
+
+ } else if (checkIfExist(exactType.INT8()) || checkIfExist(exactType.BIGINT()) ) {
typeDefinition = new DataTypeExpr(Type.INT8.name());
- } else if (exactType.NUMERIC() != null) {
- typeDefinition = new DataTypeExpr(Type.NUMERIC.name());
- } else if (exactType.DECIMAL() != null || exactType.DEC() != null) {
+
+ } else if (checkIfExist(exactType.NUMERIC()) ||
+ checkIfExist(exactType.DECIMAL()) ||
+ checkIfExist(exactType.DEC())) {
typeDefinition = new DataTypeExpr(Type.NUMERIC.name());
- }
- if (typeDefinition.getTypeName().equals(Type.NUMERIC.name())) {
- if (exactType.precision_param() != null) {
- if (exactType.precision_param().scale != null) {
- typeDefinition.setScale(
- Integer.parseInt(exactType.precision_param().scale.getText()));
+ if (checkIfExist(exactType.precision_param())) {
+ typeDefinition.setLengthOrPrecision(Integer.parseInt(exactType.precision_param().precision.getText()));
+
+ if (checkIfExist(exactType.precision_param().scale)) {
+ typeDefinition.setScale(Integer.parseInt(exactType.precision_param().scale.getText()));
}
- typeDefinition.setLengthOrPrecision(
- Integer.parseInt(exactType.precision_param().precision.getText()));
}
}
+
+
} else { // approximate number
- SQLParser.Approximate_numeric_typeContext approximateType =
- predefined_type.numeric_type().approximate_numeric_type();
- if (approximateType.FLOAT() != null || approximateType.FLOAT4() != null
- || approximateType.REAL() != null) {
+ Approximate_numeric_typeContext approximateType = predefined_type.numeric_type().approximate_numeric_type();
+ if (checkIfExist(approximateType.FLOAT()) ||
+ checkIfExist(approximateType.FLOAT4()) ||
+ checkIfExist(approximateType.REAL())) {
typeDefinition = new DataTypeExpr(Type.FLOAT4.name());
- } else if (approximateType.FLOAT8() != null || approximateType.DOUBLE() != null) {
+
+ } else if (checkIfExist(approximateType.FLOAT8()) || checkIfExist(approximateType.DOUBLE())) {
typeDefinition = new DataTypeExpr(Type.FLOAT8.name());
}
}
- } else if (predefined_type.boolean_type() != null) {
+
+ } else if (checkIfExist(predefined_type.boolean_type())) {
typeDefinition = new DataTypeExpr(Type.BOOLEAN.name());
- } else if (predefined_type.datetime_type() != null) {
- SQLParser.Datetime_typeContext dateTimeType = predefined_type.datetime_type();
- if (dateTimeType.DATE() != null) {
+
+ } else if (checkIfExist(predefined_type.datetime_type())) {
+
+ Datetime_typeContext dateTimeType = predefined_type.datetime_type();
+ if (checkIfExist(dateTimeType.DATE())) {
typeDefinition = new DataTypeExpr(Type.DATE.name());
- } else if (dateTimeType.TIME(0) != null && dateTimeType.ZONE() == null) {
- typeDefinition = new DataTypeExpr(Type.TIME.name());
- } else if ((dateTimeType.TIME(0) != null && dateTimeType.ZONE() != null) ||
- dateTimeType.TIMETZ() != null) {
+
+ } else if (checkIfExist(dateTimeType.TIME(0))) {
+ if (checkIfExist(dateTimeType.ZONE())) {
+ typeDefinition = new DataTypeExpr(Type.TIMEZ.name());
+ } else {
+ typeDefinition = new DataTypeExpr(Type.TIME.name());
+ }
+
+ } else if (checkIfExist(dateTimeType.TIMETZ())) {
typeDefinition = new DataTypeExpr(Type.TIMEZ.name());
- } else if (dateTimeType.TIMESTAMP() != null && dateTimeType.ZONE() == null) {
- typeDefinition = new DataTypeExpr(Type.TIMESTAMP.name());
- } else if ((dateTimeType.TIMESTAMP() != null && dateTimeType.ZONE() != null) ||
- dateTimeType.TIMESTAMPTZ() != null) {
+
+ } else if (checkIfExist(dateTimeType.TIMESTAMP())) {
+ if (checkIfExist(dateTimeType.ZONE())) {
+ typeDefinition = new DataTypeExpr(Type.TIMESTAMPZ.name());
+ } else {
+ typeDefinition = new DataTypeExpr(Type.TIMESTAMP.name());
+ }
+
+ } else if (checkIfExist(dateTimeType.TIMESTAMPTZ())) {
typeDefinition = new DataTypeExpr(Type.TIMESTAMPZ.name());
}
+
+ // bit data types
} else if (predefined_type.bit_type() != null) {
- SQLParser.Bit_typeContext bitType = predefined_type.bit_type();
- if (bitType.VARBIT() != null || bitType.VARYING() != null) {
+ Bit_typeContext bitType = predefined_type.bit_type();
+
+ if (checkIfExist(bitType.VARBIT()) || checkIfExist(bitType.VARYING())) {
typeDefinition = new DataTypeExpr(Type.VARBIT.name());
+
} else {
typeDefinition = new DataTypeExpr(Type.BIT.name());
}
- if (bitType.type_length() != null) {
+
+ if (checkIfExist(bitType.type_length())) {
typeDefinition.setLengthOrPrecision(
Integer.parseInt(bitType.type_length().NUMBER().getText()));
}
- } else if (predefined_type.binary_type() != null) {
+
+
+ // binary data types
+ } else if (checkIfExist(predefined_type.binary_type())) {
SQLParser.Binary_typeContext binaryType = predefined_type.binary_type();
- if (binaryType.VARBINARY() != null || binaryType.VARYING() != null) {
+
+ if (checkIfExist(binaryType.VARBINARY()) || checkIfExist(binaryType.VARYING())) {
typeDefinition = new DataTypeExpr(Type.VARBINARY.name());
} else {
typeDefinition = new DataTypeExpr(Type.BINARY.name());
}
- if (binaryType.type_length() != null) {
- typeDefinition.setLengthOrPrecision(
- Integer.parseInt(binaryType.type_length().NUMBER().getText()));
+
+ if (checkIfExist(binaryType.type_length())) {
+ typeDefinition.setLengthOrPrecision(Integer.parseInt(binaryType.type_length().NUMBER().getText()));
}
- } else if (predefined_type.network_type() != null) {
+
+ // inet
+ } else if (checkIfExist(predefined_type.network_type())) {
typeDefinition = new DataTypeExpr(Type.INET4.name());
+
+
+ } else if (checkIfExist(predefined_type.record_type())) {
+ ColumnDefinition [] nestedRecordDefines = getDefinitions(predefined_type.record_type().table_elements());
+ typeDefinition = new DataTypeExpr(nestedRecordDefines);
}
return typeDefinition;
http://git-wip-us.apache.org/repos/asf/tajo/blob/08f30345/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java b/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java
index 9dfe814..d223554 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java
@@ -710,4 +710,14 @@ public class TestSQLAnalyzer {
public void testSetSession7() throws IOException {
assertParseResult("setsession7.sql", "setsession7.result");
}
+
+ @Test
+ public void testCreateTableWithNested1() throws IOException {
+ assertParseResult("create_table_nested_1.sql", "create_table_nested_1.result");
+ }
+
+ @Test
+ public void testCreateTableWithNested2() throws IOException {
+ assertParseResult("create_table_nested_2.sql", "create_table_nested_2.result");
+ }
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/08f30345/tajo-core/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_1.sql b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_1.sql
new file mode 100644
index 0000000..bdf76eb
--- /dev/null
+++ b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_1.sql
@@ -0,0 +1 @@
+CREATE TABLE T1 (A TEXT, B INT4, C RECORD (D TEXT, E INT8), F FLOAT8);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/08f30345/tajo-core/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_2.sql
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_2.sql b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_2.sql
new file mode 100644
index 0000000..0bfdc11
--- /dev/null
+++ b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/create_table_nested_2.sql
@@ -0,0 +1 @@
+CREATE TABLE T1 (A TEXT, B INT4, C RECORD (D TEXT, E INT8, F RECORD (G INT1, H FLOAT4)), Z FLOAT8);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/08f30345/tajo-core/src/test/resources/results/TestSQLAnalyzer/create_table_nested_1.result
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/resources/results/TestSQLAnalyzer/create_table_nested_1.result b/tajo-core/src/test/resources/results/TestSQLAnalyzer/create_table_nested_1.result
new file mode 100644
index 0000000..d609790
--- /dev/null
+++ b/tajo-core/src/test/resources/results/TestSQLAnalyzer/create_table_nested_1.result
@@ -0,0 +1,40 @@
+{
+ "IsExternal": false,
+ "TableName": "t1",
+ "Attributes": [
+ {
+ "ColumnDefName": "a",
+ "DataTypeName": "TEXT",
+ "OpType": "DataType"
+ },
+ {
+ "ColumnDefName": "b",
+ "DataTypeName": "INT4",
+ "OpType": "DataType"
+ },
+ {
+ "ColumnDefName": "c",
+ "DataTypeName": "RECORD",
+ "Record": [
+ {
+ "ColumnDefName": "d",
+ "DataTypeName": "TEXT",
+ "OpType": "DataType"
+ },
+ {
+ "ColumnDefName": "e",
+ "DataTypeName": "INT8",
+ "OpType": "DataType"
+ }
+ ],
+ "OpType": "DataType"
+ },
+ {
+ "ColumnDefName": "f",
+ "DataTypeName": "FLOAT8",
+ "OpType": "DataType"
+ }
+ ],
+ "IfNotExists": false,
+ "OpType": "CreateTable"
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/08f30345/tajo-core/src/test/resources/results/TestSQLAnalyzer/create_table_nested_2.result
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/resources/results/TestSQLAnalyzer/create_table_nested_2.result b/tajo-core/src/test/resources/results/TestSQLAnalyzer/create_table_nested_2.result
new file mode 100644
index 0000000..4c4b343
--- /dev/null
+++ b/tajo-core/src/test/resources/results/TestSQLAnalyzer/create_table_nested_2.result
@@ -0,0 +1,57 @@
+{
+ "IsExternal": false,
+ "TableName": "t1",
+ "Attributes": [
+ {
+ "ColumnDefName": "a",
+ "DataTypeName": "TEXT",
+ "OpType": "DataType"
+ },
+ {
+ "ColumnDefName": "b",
+ "DataTypeName": "INT4",
+ "OpType": "DataType"
+ },
+ {
+ "ColumnDefName": "c",
+ "DataTypeName": "RECORD",
+ "Record": [
+ {
+ "ColumnDefName": "d",
+ "DataTypeName": "TEXT",
+ "OpType": "DataType"
+ },
+ {
+ "ColumnDefName": "e",
+ "DataTypeName": "INT8",
+ "OpType": "DataType"
+ },
+ {
+ "ColumnDefName": "f",
+ "DataTypeName": "RECORD",
+ "Record": [
+ {
+ "ColumnDefName": "g",
+ "DataTypeName": "INT1",
+ "OpType": "DataType"
+ },
+ {
+ "ColumnDefName": "h",
+ "DataTypeName": "FLOAT4",
+ "OpType": "DataType"
+ }
+ ],
+ "OpType": "DataType"
+ }
+ ],
+ "OpType": "DataType"
+ },
+ {
+ "ColumnDefName": "z",
+ "DataTypeName": "FLOAT8",
+ "OpType": "DataType"
+ }
+ ],
+ "IfNotExists": false,
+ "OpType": "CreateTable"
+}
\ No newline at end of file