TAJO-2043: Implement new data type and schema.

Closes #934
diff --git a/CHANGES b/CHANGES
index 4f43450..b5ff5f4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -8,6 +8,8 @@
 
   IMPROVEMENT
 
+    TAJO-2043: Implement new data type and schema. (hyunsik)
+
     TAJO-2090: Bump up orc version to 0.141. (hyunsik)
 
     TAJO-2089: Improve null handling in UDF. (jinho)
diff --git a/tajo-common/src/main/java/org/apache/tajo/schema/Schema.java b/tajo-common/src/main/java/org/apache/tajo/schema/Schema.java
new file mode 100644
index 0000000..d505062
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/schema/Schema.java
@@ -0,0 +1,106 @@
+/**
+ * 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.schema;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import org.apache.tajo.type.Type;
+import org.apache.tajo.util.StringUtils;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.apache.tajo.common.TajoDataTypes.Type.RECORD;
+
+/**
+ * A field is a pair of a name and a type. Schema is an ordered list of fields.
+ */
+public class Schema {
+  private final ImmutableList<NamedType> namedTypes;
+
+  public Schema(Collection<NamedType> namedTypes) {
+    this.namedTypes = ImmutableList.copyOf(namedTypes);
+  }
+
+  public static Schema Schema(NamedType...fields) {
+    return new Schema(Arrays.asList(fields));
+  }
+
+  public static Schema Schema(Collection<NamedType> fields) {
+    return new Schema(fields);
+  }
+
+  @Override
+  public String toString() {
+    return StringUtils.join(namedTypes, ",");
+  }
+
+  public static NamedStructType Struct(String name, NamedType... namedTypes) {
+    return new NamedStructType(name, Arrays.asList(namedTypes));
+  }
+
+  public static NamedStructType Struct(String name, Collection<NamedType> namedTypes) {
+    return new NamedStructType(name, namedTypes);
+  }
+
+  public static NamedPrimitiveType Field(String name, Type type) {
+    return new NamedPrimitiveType(name, type);
+  }
+
+  public static abstract class NamedType {
+    protected final String name;
+
+    public NamedType(String name) {
+      this.name = name;
+    }
+
+    public String name() {
+      return this.name;
+    }
+  }
+
+  public static class NamedPrimitiveType extends NamedType {
+    private final Type type;
+
+    NamedPrimitiveType(String name, Type type) {
+      super(name);
+      Preconditions.checkArgument(type.baseType() != RECORD);
+      this.type = type;
+    }
+
+    @Override
+    public String toString() {
+      return name + " " + type;
+    }
+  }
+
+  public static class NamedStructType extends NamedType {
+    private final ImmutableList<NamedType> namedTypes;
+
+    public NamedStructType(String name, Collection<NamedType> namedTypes) {
+      super(name);
+      this.namedTypes = ImmutableList.copyOf(namedTypes);
+    }
+
+    @Override
+    public String toString() {
+      return name + " record (" + StringUtils.join(namedTypes, ",") + ")";
+    }
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Array.java b/tajo-common/src/main/java/org/apache/tajo/type/Array.java
new file mode 100644
index 0000000..cd02d1e
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Array.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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+import java.util.Objects;
+
+public class Array extends Type {
+  private final Type elementType;
+
+  public Array(Type elementType) {
+    this.elementType = elementType;
+  }
+
+  public Type elementType() {
+    return this.elementType;
+  }
+
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.ARRAY;
+  }
+
+  @Override
+  public String toString() {
+    return "array<" + elementType + ">";
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(baseType(), elementType);
+  }
+
+  @Override
+  public boolean equals(Object object) {
+    if (object instanceof Array) {
+      return elementType.equals(((Array)object).elementType);
+    }
+
+    return false;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Blob.java b/tajo-common/src/main/java/org/apache/tajo/type/Blob.java
new file mode 100644
index 0000000..104dd12
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Blob.java
@@ -0,0 +1,28 @@
+/**
+ * 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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+public class Blob extends Type {
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.BLOB;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Bool.java b/tajo-common/src/main/java/org/apache/tajo/type/Bool.java
new file mode 100644
index 0000000..ddd7300
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Bool.java
@@ -0,0 +1,28 @@
+/**
+ * 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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+public class Bool extends Type {
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.BOOLEAN;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Char.java b/tajo-common/src/main/java/org/apache/tajo/type/Char.java
new file mode 100644
index 0000000..04857ec
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Char.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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+import java.util.Objects;
+
+public class Char extends Type {
+  private final int length;
+
+  public Char(int length) {
+    this.length = length;
+  }
+
+  public int length() {
+    return length;
+  }
+
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.CHAR;
+  }
+
+  @Override
+  public String toString() {
+    return "char(" + length + ")";
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(baseType(), length);
+  }
+
+  @Override
+  public boolean equals(Object object) {
+    if (object instanceof Char) {
+      return length == ((Char) object).length;
+    }
+
+    return false;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Date.java b/tajo-common/src/main/java/org/apache/tajo/type/Date.java
new file mode 100644
index 0000000..0febc1a
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Date.java
@@ -0,0 +1,28 @@
+/**
+ * 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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+public class Date extends Type {
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.DATE;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Float4.java b/tajo-common/src/main/java/org/apache/tajo/type/Float4.java
new file mode 100644
index 0000000..47ccd6b
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Float4.java
@@ -0,0 +1,28 @@
+/**
+ * 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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+public class Float4 extends Type {
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.FLOAT4;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Float8.java b/tajo-common/src/main/java/org/apache/tajo/type/Float8.java
new file mode 100644
index 0000000..6d2702c
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Float8.java
@@ -0,0 +1,28 @@
+/**
+ * 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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+public class Float8 extends Type {
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.FLOAT8;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Int2.java b/tajo-common/src/main/java/org/apache/tajo/type/Int2.java
new file mode 100644
index 0000000..44db4cb
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Int2.java
@@ -0,0 +1,28 @@
+/**
+ * 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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+public class Int2 extends Type {
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.INT2;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Int4.java b/tajo-common/src/main/java/org/apache/tajo/type/Int4.java
new file mode 100644
index 0000000..0837e2c
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Int4.java
@@ -0,0 +1,28 @@
+/**
+ * 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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+public class Int4 extends Type {
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.INT4;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Int8.java b/tajo-common/src/main/java/org/apache/tajo/type/Int8.java
new file mode 100644
index 0000000..3d4049c
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Int8.java
@@ -0,0 +1,28 @@
+/**
+ * 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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+public class Int8 extends Type {
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.INT8;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Map.java b/tajo-common/src/main/java/org/apache/tajo/type/Map.java
new file mode 100644
index 0000000..afc1cc3
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Map.java
@@ -0,0 +1,66 @@
+/**
+ * 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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+import java.util.Objects;
+
+public class Map extends Type {
+  private final Type keyType;
+  private final Type valueType;
+
+  public Map(Type keyType, Type valueType) {
+    this.keyType = keyType;
+    this.valueType = valueType;
+  }
+
+  public Type keyType() {
+    return this.keyType;
+  }
+
+  public Type valueType() {
+    return this.valueType;
+  }
+
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.MAP;
+  }
+
+  @Override
+  public String toString() {
+    return "map<" + keyType + "," + valueType + ">";
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(baseType(), keyType, valueType);
+  }
+
+  @Override
+  public boolean equals(Object object) {
+    if (object instanceof Map) {
+      Map other = (Map) object;
+      return keyType.equals(other.keyType) && valueType.equals(other.valueType);
+    }
+
+    return false;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Numeric.java b/tajo-common/src/main/java/org/apache/tajo/type/Numeric.java
new file mode 100644
index 0000000..75ef392
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Numeric.java
@@ -0,0 +1,66 @@
+/**
+ * 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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+import java.util.Objects;
+
+public class Numeric extends Type {
+  private final int precision;
+  private final int scale;
+
+  public Numeric(int precision, int scale) {
+    this.precision = precision;
+    this.scale = scale;
+  }
+
+  public int precision() {
+    return this.precision;
+  }
+
+  public int scale() {
+    return this.scale;
+  }
+
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.NUMERIC;
+  }
+
+  @Override
+  public String toString() {
+    return "numeric(" + precision + "," + scale + ")";
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(baseType(), precision, scale);
+  }
+
+  @Override
+  public boolean equals(Object object) {
+    if (object instanceof Numeric) {
+      Numeric other = (Numeric) object;
+      return precision == other.precision && scale == other.scale;
+    }
+
+    return false;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Struct.java b/tajo-common/src/main/java/org/apache/tajo/type/Struct.java
new file mode 100644
index 0000000..551eb81
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Struct.java
@@ -0,0 +1,72 @@
+/**
+ * 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.type;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.util.StringUtils;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+
+public class Struct extends Type {
+  private final ImmutableList<Type> memberTypes;
+
+  public Struct(Collection<Type> memberTypes) {
+    this.memberTypes = ImmutableList.copyOf(memberTypes);
+  }
+
+  public int size() {
+    return memberTypes.size();
+  }
+
+  public Type memberType(int idx) {
+    return memberTypes.get(idx);
+  }
+
+  public List<Type> memberTypes() {
+    return this.memberTypes;
+  }
+
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.RECORD;
+  }
+
+  @Override
+  public String toString() {
+    return "struct(" + StringUtils.join(memberTypes, ",") + ")";
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(baseType(), Objects.hash(memberTypes));
+  }
+
+  @Override
+  public boolean equals(Object object) {
+    if (object instanceof Struct) {
+      Struct other = (Struct) object;
+      return memberTypes.equals(other.memberTypes);
+    }
+
+    return false;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Text.java b/tajo-common/src/main/java/org/apache/tajo/type/Text.java
new file mode 100644
index 0000000..e523afe
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Text.java
@@ -0,0 +1,28 @@
+/**
+ * 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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+public class Text extends Type {
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.TEXT;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Time.java b/tajo-common/src/main/java/org/apache/tajo/type/Time.java
new file mode 100644
index 0000000..3b1414c
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Time.java
@@ -0,0 +1,28 @@
+/**
+ * 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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+public class Time extends Type {
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.TIME;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Timestamp.java b/tajo-common/src/main/java/org/apache/tajo/type/Timestamp.java
new file mode 100644
index 0000000..5b02314
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Timestamp.java
@@ -0,0 +1,28 @@
+/**
+ * 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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+public class Timestamp extends Type {
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.TIMESTAMP;
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Type.java b/tajo-common/src/main/java/org/apache/tajo/type/Type.java
new file mode 100644
index 0000000..363ffc4
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Type.java
@@ -0,0 +1,128 @@
+/**
+ * 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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+public abstract class Type {
+  public abstract TajoDataTypes.Type baseType();
+
+  protected static String typeName(TajoDataTypes.Type type) {
+    return type.name().toLowerCase();
+  }
+
+  @Override
+  public int hashCode() {
+    return baseType().hashCode();
+  }
+
+  @Override
+  public boolean equals(Object t) {
+    if (t instanceof Type) {
+      return ((Type)t).baseType() == baseType();
+    }
+    return false;
+  }
+
+  @Override
+  public String toString() {
+    return typeName(baseType());
+  }
+
+  public static Bool Bool() {
+    return new Bool();
+  }
+
+  public static Int2 Int2() {
+    return new Int2();
+  }
+
+  public static Int4 Int4() {
+    return new Int4();
+  }
+
+  public static Int8 Int8() {
+    return new Int8();
+  }
+
+  public static Float4 Float4() {
+    return new Float4();
+  }
+
+  public static Float8 Float8() {
+    return new Float8();
+  }
+
+  public static int DEFAULT_SCALE = 0;
+
+  public static Numeric Numeric(int precision) {
+    return new Numeric(precision, DEFAULT_SCALE);
+  }
+
+  public static Numeric Numeric(int precision, int scale) {
+    return new Numeric(precision, scale);
+  }
+
+  public static Date Date() {
+    return new Date();
+  }
+
+  public static Time Time() {
+    return new Time();
+  }
+
+  public static Timestamp Timestamp() {
+    return new Timestamp();
+  }
+
+  public static Char Char(int len) {
+    return new Char(len);
+  }
+
+  public static Varchar Varchar(int len) {
+    return new Varchar(len);
+  }
+
+  public static Text Text() {
+    return new Text();
+  }
+
+  public static Blob Blob() {
+    return new Blob();
+  }
+
+  public static Struct Struct(Collection<Type> types) {
+    return new Struct(types);
+  }
+
+  public static Struct Struct(Type ... types) {
+    return new Struct(Arrays.asList(types));
+  }
+
+  public static Array Array(Type type) {
+    return new Array(type);
+  }
+
+  public static Map Map(Type keyType, Type valueType) {
+    return new Map(keyType, valueType);
+  }
+}
diff --git a/tajo-common/src/main/java/org/apache/tajo/type/Varchar.java b/tajo-common/src/main/java/org/apache/tajo/type/Varchar.java
new file mode 100644
index 0000000..6dc2c50
--- /dev/null
+++ b/tajo-common/src/main/java/org/apache/tajo/type/Varchar.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.type;
+
+import org.apache.tajo.common.TajoDataTypes;
+
+import java.util.Objects;
+
+public class Varchar extends Type {
+  private final int length;
+
+  public Varchar(int length) {
+    this.length = length;
+  }
+
+  public int length() {
+    return length;
+  }
+
+  @Override
+  public TajoDataTypes.Type baseType() {
+    return TajoDataTypes.Type.VARCHAR;
+  }
+
+  @Override
+  public String toString() {
+    return "varchar(" + length + ")";
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(baseType(), length);
+  }
+
+  @Override
+  public boolean equals(Object object) {
+    if (object instanceof Varchar) {
+      return length == ((Varchar) object).length;
+    }
+
+    return false;
+  }
+}
diff --git a/tajo-common/src/main/proto/DataTypes.proto b/tajo-common/src/main/proto/DataTypes.proto
index 1e10be2..7cf09d3 100644
--- a/tajo-common/src/main/proto/DataTypes.proto
+++ b/tajo-common/src/main/proto/DataTypes.proto
@@ -60,7 +60,8 @@
   BLOB = 45;
 
   RECORD = 51; // nested structure type
-  MAP    = 52; // map type
+  ARRAY  = 52; // array type
+  MAP    = 53; // map type
 
   ANY = 61; // Any type
   UDT = 62; // user-defined function
diff --git a/tajo-common/src/test/java/org/apache/tajo/schema/TestSchema.java b/tajo-common/src/test/java/org/apache/tajo/schema/TestSchema.java
new file mode 100644
index 0000000..da5a4d3
--- /dev/null
+++ b/tajo-common/src/test/java/org/apache/tajo/schema/TestSchema.java
@@ -0,0 +1,47 @@
+/**
+ * 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.schema;
+
+import org.junit.Test;
+
+import static org.apache.tajo.schema.Schema.*;
+import static org.apache.tajo.type.Type.*;
+import static org.junit.Assert.assertEquals;
+
+public class TestSchema {
+
+  @Test
+  public final void testSchema1() {
+    NamedType struct1 = Struct("f12", Field("f1", Int8()), Field("f2", Int4()));
+    NamedType struct2 = Struct("f34", Field("f3", Int8()), Field("f4", Int4()));
+    Schema schema = Schema(struct1, struct2);
+
+    assertEquals(schema.toString(), "f12 record (f1 int8,f2 int4),f34 record (f3 int8,f4 int4)");
+  }
+
+  @Test
+  public final void testSchema2() {
+    NamedType f1 = Field("x", Array(Int8()));
+    NamedType f2 = Field("y", Int8());
+    NamedType f3 = Struct("z", Field("z-1", Time()), Field("z-2", Array(Int8())));
+    Schema schema = Schema(f1, f2, f3);
+
+    assertEquals(schema.toString(), "x array<int8>,y int8,z record (z-1 time,z-2 array<int8>)");
+  }
+}
\ No newline at end of file
diff --git a/tajo-common/src/test/java/org/apache/tajo/type/TestType.java b/tajo-common/src/test/java/org/apache/tajo/type/TestType.java
new file mode 100644
index 0000000..9023af0
--- /dev/null
+++ b/tajo-common/src/test/java/org/apache/tajo/type/TestType.java
@@ -0,0 +1,102 @@
+/**
+ * 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.type;
+
+import org.junit.Test;
+
+import static org.apache.tajo.common.TajoDataTypes.Type.*;
+import static org.apache.tajo.type.Type.*;
+import static org.junit.Assert.assertEquals;
+
+public class TestType {
+  @Test
+  public final void testPrimitiveTypes() {
+    assertEquals(Bool().baseType(), BOOLEAN);
+    assertEquals(Int2().baseType(), INT2);
+    assertEquals(Int4().baseType(), INT4);
+    assertEquals(Int8().baseType(), INT8);
+    assertEquals(Float4().baseType(), FLOAT4);
+    assertEquals(Float8().baseType(), FLOAT8);
+    assertEquals(Date().baseType(), DATE);
+    assertEquals(Time().baseType(), TIME);
+    assertEquals(Timestamp().baseType(), TIMESTAMP);
+
+    Numeric n = Numeric(4, 2);
+    assertEquals(n.baseType(), NUMERIC);
+    assertEquals(n.precision(), 4);
+    assertEquals(n.scale(), 2);
+
+    assertEquals(Blob().baseType(), BLOB);
+
+    Char c = Char(2);
+    assertEquals(c.baseType(), CHAR);
+    assertEquals(c.length(), 2);
+
+    Varchar varchar = Varchar(2);
+    assertEquals(varchar.baseType(), VARCHAR);
+    assertEquals(varchar.length(), 2);
+
+    Struct struct = Struct(Int8(), Array(Float8()));
+    assertEquals(struct.baseType(), RECORD);
+    assertEquals(struct.memberType(0).baseType(), INT8);
+    assertEquals(struct.memberType(1).baseType(), ARRAY);
+
+    Map map = Map(Int8(), Array(Timestamp()));
+    assertEquals(map.baseType(), MAP);
+    assertEquals(map.keyType().baseType(), INT8);
+    assertEquals(map.valueType().baseType(), ARRAY);
+
+    Array array = Array(Int8());
+    assertEquals(array.baseType(), ARRAY);
+    assertEquals(array.elementType().baseType(), INT8);
+  }
+
+  @Test
+  public final void testToString() {
+    assertEquals("boolean", Bool().toString());
+    assertEquals("int2", Int2().toString());
+    assertEquals("int4", Int4().toString());
+    assertEquals("int8", Int8().toString());
+    assertEquals("float4", Float4().toString());
+    assertEquals("float8", Float8().toString());
+    assertEquals("date", Date().toString());
+    assertEquals("time", Time().toString());
+    assertEquals("timestamp", Timestamp().toString());
+
+    Numeric n = Numeric(4, 2);
+    assertEquals("numeric(4,2)", n.toString());
+
+    assertEquals("blob", Blob().toString());
+
+    Char c = Char(2);
+    assertEquals("char(2)", c.toString());
+
+    Varchar varchar = Varchar(2);
+    assertEquals("varchar(2)", varchar.toString());
+
+    Struct struct = Struct(Int8(), Array(Float8()));
+    assertEquals("struct(int8,array<float8>)", struct.toString());
+
+    Map map = Map(Int8(), Array(Timestamp()));
+    assertEquals("map<int8,array<timestamp>>", map.toString());
+
+    Array array = Array(Int8());
+    assertEquals("array<int8>", array.toString());
+  }
+}
\ No newline at end of file