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/08/08 04:17:15 UTC

[4/4] git commit: TAJO-95: Eliminate the lazy copy approach from the classes wrapping protobuf-generated classes. (hyunsik)

TAJO-95: Eliminate the lazy copy approach from the classes wrapping protobuf-generated classes. (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/1c677cc5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tajo/tree/1c677cc5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tajo/diff/1c677cc5

Branch: refs/heads/master
Commit: 1c677cc5cc5353177879af157f3bf19a0a1fe1d3
Parents: 87420eb
Author: Hyunsik Choi <hy...@apache.org>
Authored: Thu Aug 8 11:15:40 2013 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Thu Aug 8 11:15:40 2013 +0900

----------------------------------------------------------------------
 CHANGES.txt                                     |  12 +-
 .../tajo/catalog/AbstractCatalogClient.java     |  14 +-
 .../java/org/apache/tajo/catalog/Column.java    |  86 ++-------
 .../org/apache/tajo/catalog/FunctionDesc.java   | 170 +++---------------
 .../java/org/apache/tajo/catalog/IndexDesc.java | 165 +++--------------
 .../java/org/apache/tajo/catalog/Options.java   | 107 ++++-------
 .../java/org/apache/tajo/catalog/Schema.java    | 107 +++--------
 .../java/org/apache/tajo/catalog/SortSpec.java  |  31 +++-
 .../java/org/apache/tajo/catalog/TableDesc.java |   7 +-
 .../org/apache/tajo/catalog/TableDescImpl.java  | 101 ++---------
 .../java/org/apache/tajo/catalog/TableMeta.java |   5 +-
 .../org/apache/tajo/catalog/TableMetaImpl.java  | 168 ++++--------------
 .../tajo/catalog/function/AggFunction.java      |   9 +-
 .../apache/tajo/catalog/function/Function.java  |  12 +-
 .../tajo/catalog/function/GeneralFunction.java  |  12 +-
 .../tajo/catalog/json/CatalogGsonHelper.java    |  86 +++++++++
 .../tajo/catalog/json/FunctionAdapter.java      |   3 +-
 .../apache/tajo/catalog/json/GsonCreator.java   |  72 --------
 .../tajo/catalog/json/PathDeserializer.java     |  37 ----
 .../tajo/catalog/json/PathSerializer.java       |  37 ----
 .../tajo/catalog/json/TableDescAdapter.java     |   9 +-
 .../tajo/catalog/json/TableMetaAdapter.java     |   6 +-
 .../tajo/catalog/statistics/ColumnStat.java     | 137 ++++-----------
 .../apache/tajo/catalog/statistics/StatSet.java |  24 +--
 .../tajo/catalog/statistics/TableStat.java      | 174 +++++-------------
 .../org/apache/tajo/catalog/TestColumn.java     |  24 ++-
 .../apache/tajo/catalog/TestFunctionDesc.java   |  39 ++--
 .../org/apache/tajo/catalog/TestSchema.java     |  20 ++-
 .../org/apache/tajo/catalog/TestTableDesc.java  |  53 +++---
 .../org/apache/tajo/catalog/TestTableMeta.java  |  67 +++++--
 .../tajo/catalog/statistics/TestColumnStat.java |  16 +-
 .../tajo/catalog/statistics/TestTableStat.java  |   9 +-
 .../tajo/catalog/statistics/TestColumnStat.java |  68 -------
 .../tajo/catalog/statistics/TestStatSet.java    |  67 -------
 .../catalog/statistics/TestStatisticsUtil.java  |  68 -------
 .../tajo/catalog/statistics/TestTableStat.java  |  74 --------
 .../org/apache/tajo/QueryUnitAttemptId.java     |  18 +-
 .../main/java/org/apache/tajo/QueryUnitId.java  |  17 +-
 .../org/apache/tajo/common/ProtoObject.java     |   1 -
 .../java/org/apache/tajo/datum/ArrayDatum.java  |   6 -
 .../java/org/apache/tajo/datum/BitDatum.java    |   5 -
 .../java/org/apache/tajo/datum/BlobDatum.java   |   6 -
 .../org/apache/tajo/datum/BooleanDatum.java     |   5 -
 .../java/org/apache/tajo/datum/CharDatum.java   |   6 -
 .../main/java/org/apache/tajo/datum/Datum.java  |  12 +-
 .../java/org/apache/tajo/datum/Float4Datum.java |   6 -
 .../java/org/apache/tajo/datum/Float8Datum.java |   6 -
 .../java/org/apache/tajo/datum/Inet4Datum.java  |   6 -
 .../java/org/apache/tajo/datum/Int2Datum.java   |   6 -
 .../java/org/apache/tajo/datum/Int4Datum.java   |   6 -
 .../java/org/apache/tajo/datum/Int8Datum.java   |   6 -
 .../java/org/apache/tajo/datum/NullDatum.java   |   5 -
 .../java/org/apache/tajo/datum/TextDatum.java   |  12 +-
 .../apache/tajo/datum/json/DatumAdapter.java    |  55 ------
 .../org/apache/tajo/datum/json/GsonCreator.java |  44 -----
 .../apache/tajo/gson/ClassNameDeserializer.java |  44 -----
 .../apache/tajo/gson/ClassNameSerializer.java   |  39 ----
 .../org/apache/tajo/gson/DataTypeAdapter.java   |  64 -------
 .../org/apache/tajo/gson/DatumTypeAdapter.java  |  55 ------
 .../org/apache/tajo/gson/PathDeserializer.java  |  40 -----
 .../org/apache/tajo/gson/PathSerializer.java    |  40 -----
 .../apache/tajo/json/ClassNameDeserializer.java |  44 +++++
 .../apache/tajo/json/ClassNameSerializer.java   |  46 +++++
 .../org/apache/tajo/json/CommonGsonHelper.java  |  70 ++++++++
 .../org/apache/tajo/json/DataTypeAdapter.java   |  63 +++++++
 .../java/org/apache/tajo/json/DatumAdapter.java |  54 ++++++
 .../org/apache/tajo/json/DatumTypeAdapter.java  |  55 ++++++
 .../java/org/apache/tajo/json/GsonHelper.java   |  49 ++++++
 .../java/org/apache/tajo/json/GsonObject.java   |  23 +++
 .../org/apache/tajo/json/GsonSerDerAdapter.java |  25 +++
 .../org/apache/tajo/json/PathDeserializer.java  |  40 +++++
 .../org/apache/tajo/json/PathSerializer.java    |  42 +++++
 .../main/java/org/apache/tajo/util/TUtil.java   |   8 +
 .../org/apache/tajo/datum/TestBoolDatum.java    |   2 +-
 .../org/apache/tajo/datum/TestBytesDatum.java   |   8 +-
 .../org/apache/tajo/datum/TestInet4Datum.java   |   6 +-
 .../tajo/engine/eval/AggFuncCallEval.java       |  12 +-
 .../org/apache/tajo/engine/eval/BinaryEval.java |   7 -
 .../apache/tajo/engine/eval/CaseWhenEval.java   |  38 ++--
 .../org/apache/tajo/engine/eval/ConstEval.java  |   7 -
 .../org/apache/tajo/engine/eval/EvalNode.java   |  23 ++-
 .../org/apache/tajo/engine/eval/FieldEval.java  |   7 -
 .../apache/tajo/engine/eval/FuncCallEval.java   |   8 -
 .../org/apache/tajo/engine/eval/FuncEval.java   |   8 -
 .../apache/tajo/engine/json/CoreGsonHelper.java |  94 ++++++++++
 .../tajo/engine/json/EvalNodeAdapter.java       |   3 +-
 .../tajo/engine/json/FragmentDeserializer.java  |   4 +-
 .../tajo/engine/json/FromTableDeserializer.java |   2 +-
 .../apache/tajo/engine/json/GsonCreator.java    |  81 ---------
 .../tajo/engine/json/LogicalNodeAdapter.java    |   3 +-
 .../apache/tajo/engine/planner/FromTable.java   |  19 +-
 .../org/apache/tajo/engine/planner/Target.java  |   9 +-
 .../tajo/engine/planner/logical/BinaryNode.java |  16 +-
 .../engine/planner/logical/CreateTableNode.java |   5 -
 .../engine/planner/logical/DropTableNode.java   |   8 -
 .../engine/planner/logical/EvalExprNode.java    |  18 +-
 .../tajo/engine/planner/logical/ExceptNode.java |   7 -
 .../engine/planner/logical/GroupbyNode.java     |  27 +--
 .../engine/planner/logical/IndexScanNode.java   |  14 +-
 .../engine/planner/logical/IntersectNode.java   |   7 -
 .../tajo/engine/planner/logical/JoinNode.java   |   5 -
 .../tajo/engine/planner/logical/LimitNode.java  |   8 +-
 .../engine/planner/logical/LogicalNode.java     |  22 ++-
 .../engine/planner/logical/LogicalRootNode.java |   7 -
 .../engine/planner/logical/ProjectionNode.java  |   5 -
 .../tajo/engine/planner/logical/ScanNode.java   |   5 -
 .../engine/planner/logical/SelectionNode.java   |   9 +-
 .../tajo/engine/planner/logical/SortNode.java   |  18 +-
 .../engine/planner/logical/StoreTableNode.java  |  15 +-
 .../tajo/engine/planner/logical/UnaryNode.java  |   9 +-
 .../tajo/engine/planner/logical/UnionNode.java  |   7 -
 .../planner/logical/extended/ReceiveNode.java   |  10 +-
 .../planner/logical/extended/SendNode.java      |  11 +-
 .../tajo/engine/query/QueryUnitRequestImpl.java |  48 +----
 .../org/apache/tajo/master/GlobalEngine.java    |   2 +-
 .../apache/tajo/master/TaskSchedulerImpl.java   |   4 +-
 .../java/org/apache/tajo/util/IndexUtil.java    |   6 +-
 .../main/java/org/apache/tajo/worker/Task.java  |   5 +-
 .../java/org/apache/tajo/worker/TaskRunner.java |  29 +--
 .../java/org/apache/tajo/TestQueryUnitId.java   | 167 ------------------
 .../test/java/org/apache/tajo/TestTajoIds.java  | 167 ++++++++++++++++++
 .../apache/tajo/engine/eval/TestEvalTree.java   |  10 +-
 .../tajo/engine/planner/TestLogicalPlanner.java |  54 ++++--
 .../apache/tajo/master/TestRepartitioner.java   |   4 +-
 .../org/apache/tajo/storage/TestFragment.java   |  18 --
 .../org/apache/tajo/worker/TaskRunnerTest.java  |   4 +-
 .../java/org/apache/tajo/storage/CSVFile.java   |   6 +-
 .../java/org/apache/tajo/storage/Fragment.java  | 176 +++----------------
 .../java/org/apache/tajo/storage/RawFile.java   |   7 +-
 .../java/org/apache/tajo/storage/RowFile.java   |   6 +-
 .../apache/tajo/storage/TupleComparator.java    |   4 -
 .../tajo/storage/json/FragmentDeserializer.java |   2 +-
 .../apache/tajo/storage/json/GsonCreator.java   |  77 --------
 .../tajo/storage/json/StorageGsonHelper.java    |  90 ++++++++++
 .../tajo/storage/rcfile/RCFileWrapper.java      |   2 +-
 135 files changed, 1646 insertions(+), 2941 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 97eaa6b..e7bea99 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -15,6 +15,9 @@ Release 0.2.0 - unreleased
 
   IMPROVEMENTS
 
+    TAJO-95: Eliminate the lazy copy approach from the classes wrapping
+    protobuf-generated classes. (hyunsik)
+
     TAJO-102: Add AlgebraVisitor and Refactor LogicalPlanner to use the visitor.    (hyunsik)
 
     TAJO-87: Integration of tajo algebra module and SQL parser. (hyunsik)
@@ -27,9 +30,11 @@ Release 0.2.0 - unreleased
 
     TAJO-79: Refactor and Improve TajoCli. (hyunsik)
 
-    TAJO-77: Rename TabletProto as FragmentProto in CatalogProtos.proto. (jihoon)
+    TAJO-77: Rename TabletProto as FragmentProto in CatalogProtos.proto. 
+    (jihoon)
 
-    TAJO-22: The package prefix should be org.apache.tajo. (DaeMyung Kang via hyunsik)
+    TAJO-22: The package prefix should be org.apache.tajo. (DaeMyung Kang via 
+    hyunsik)
 
     TAJO-75: Separate SQL.g into SQLParser.g and SQLLexer.g. (hyunsik)
 
@@ -83,7 +88,8 @@ Release 0.2.0 - unreleased
 
   BUG FIXES
 
-    TAJO-82: NullPointerException occurs when Schema is converted as an array of columns. (jihoon)
+    TAJO-82: NullPointerException occurs when Schema is converted as an array 
+    of columns. (jihoon)
 
     TAJO-65: Invalid pom.xml configurations for source directories. 
     (Takuya Ueshin via hyunsik)

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java
index f9eebfc..ac4c796 100644
--- a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java
+++ b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java
@@ -87,7 +87,12 @@ public abstract class AbstractCatalogClient implements CatalogService {
     }
     int size = response.getFunctionDescCount();
     for (int i = 0; i < size; i++) {
-      list.add(new FunctionDesc(response.getFunctionDesc(i)));
+      try {
+        list.add(new FunctionDesc(response.getFunctionDesc(i)));
+      } catch (ClassNotFoundException e) {
+        LOG.error(e);
+        return null;
+      }
     }
     return list;
   }
@@ -239,7 +244,12 @@ public abstract class AbstractCatalogClient implements CatalogService {
       LOG.error(e);
       return null;
     }
-    return new FunctionDesc(descProto);
+    try {
+      return new FunctionDesc(descProto);
+    } catch (ClassNotFoundException e) {
+      LOG.error(e);
+      return null;
+    }
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Column.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Column.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Column.java
index e1adc53..c215661 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Column.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Column.java
@@ -19,20 +19,18 @@
 package org.apache.tajo.catalog;
 
 import com.google.gson.annotations.Expose;
-import org.apache.tajo.catalog.json.GsonCreator;
+import org.apache.tajo.json.GsonObject;
+import org.apache.tajo.catalog.json.CatalogGsonHelper;
 import org.apache.tajo.catalog.proto.CatalogProtos.ColumnProto;
-import org.apache.tajo.catalog.proto.CatalogProtos.ColumnProtoOrBuilder;
 import org.apache.tajo.common.ProtoObject;
 import org.apache.tajo.common.TajoDataTypes;
 import org.apache.tajo.common.TajoDataTypes.DataType;
 
-public class Column implements ProtoObject<ColumnProto>, Cloneable {
-	private ColumnProto proto = ColumnProto.getDefaultInstance();
+public class Column implements ProtoObject<ColumnProto>, Cloneable, GsonObject {
 	private ColumnProto.Builder builder = null;
-	private boolean viaProto = false;
 	
-	@Expose protected String name;
-	@Expose protected DataType dataType;
+	@Expose protected String name; // required
+	@Expose protected DataType dataType; // required
 	
 	public Column() {
 		this.builder = ColumnProto.newBuilder();
@@ -49,21 +47,10 @@ public class Column implements ProtoObject<ColumnProto>, Cloneable {
   }
 	
 	public Column(ColumnProto proto) {
-		this.proto = proto;
-		this.viaProto = true;
+		this(proto.getColumnName(), proto.getDataType());
 	}
-	
 
 	public String getQualifiedName() {
-		ColumnProtoOrBuilder p = viaProto ? proto : builder;
-		if(name != null) {
-			return this.name;
-		}
-		if(!p.hasColumnName()) {
-			return null;			
-		}		
-		this.name = p.getColumnName();
-		
 		return this.name;
 	}
 	
@@ -87,25 +74,14 @@ public class Column implements ProtoObject<ColumnProto>, Cloneable {
   }
 	
 	public void setName(String name) {
-	  setModified();
 		this.name = name.toLowerCase();
 	}
 	
 	public DataType getDataType() {
-		ColumnProtoOrBuilder p = viaProto ? proto : builder;
-		if(dataType != null) {
-			return this.dataType;
-		}
-		if(!p.hasDataType()) {
-			return null;
-		}
-		this.dataType = p.getDataType();
-		
 		return this.dataType;
 	}
 	
 	public void setDataType(DataType dataType) {
-		setModified();
 		this.dataType = dataType;
 	}
 	
@@ -126,9 +102,6 @@ public class Column implements ProtoObject<ColumnProto>, Cloneable {
   @Override
   public Object clone() throws CloneNotSupportedException {
     Column column = (Column) super.clone();
-    initFromProto();
-    column.proto = null;
-    column.viaProto = false;
     column.builder = ColumnProto.newBuilder();
     column.name = name;
     column.dataType = dataType;
@@ -137,51 +110,18 @@ public class Column implements ProtoObject<ColumnProto>, Cloneable {
 
 	@Override
 	public ColumnProto getProto() {
-	  if(!viaProto) {
-      mergeLocalToBuilder();
-      proto = builder.build();
-      viaProto = true;
-    }
-	  
-	  return proto;
-	}
-	
-	private void setModified() {
-	  if (viaProto && builder == null) {
-	    builder = ColumnProto.newBuilder(proto);
-	  }
-	  viaProto = false;
-	}
-	
-	private void mergeLocalToBuilder() {
-	  if (builder == null) {
-	    builder = ColumnProto.newBuilder(proto);
-	  }
-		if (this.name != null) {
-			builder.setColumnName(this.name);			
-		}
-		if (this.dataType != null) {
-			builder.setDataType(this.dataType);
-		}
+    builder.setColumnName(this.name);
+    builder.setDataType(this.dataType);
+
+    return builder.build();
 	}
 	
 	public String toString() {
 	  return getQualifiedName() +" (" + getDataType().getType() +")";
 	}
-	
-	public String toJSON() {
-		initFromProto();
-		return GsonCreator.getInstance().toJson(this);
-	}
 
-	@Override
-	public void initFromProto() {
-		ColumnProtoOrBuilder p = viaProto ? proto : builder;
-		if (this.name == null && p.hasColumnName()) {
-			this.name = p.getColumnName();
-		}
-		if (this.dataType == null && p.hasDataType()) {
-			this.dataType = p.getDataType();
-		}
+  @Override
+	public String toJson() {
+		return CatalogGsonHelper.toJson(this, Column.class);
 	}
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/FunctionDesc.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/FunctionDesc.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/FunctionDesc.java
index 93bcadd..8f678b9 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/FunctionDesc.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/FunctionDesc.java
@@ -18,13 +18,11 @@
 
 package org.apache.tajo.catalog;
 
-import com.google.gson.Gson;
 import com.google.gson.annotations.Expose;
+import org.apache.tajo.json.GsonObject;
 import org.apache.tajo.catalog.function.Function;
-import org.apache.tajo.catalog.function.GeneralFunction;
-import org.apache.tajo.catalog.json.GsonCreator;
+import org.apache.tajo.catalog.json.CatalogGsonHelper;
 import org.apache.tajo.catalog.proto.CatalogProtos.FunctionDescProto;
-import org.apache.tajo.catalog.proto.CatalogProtos.FunctionDescProtoOrBuilder;
 import org.apache.tajo.catalog.proto.CatalogProtos.FunctionType;
 import org.apache.tajo.common.ProtoObject;
 import org.apache.tajo.common.TajoDataTypes.DataType;
@@ -33,10 +31,8 @@ import org.apache.tajo.exception.InternalException;
 import java.lang.reflect.Constructor;
 import java.util.Arrays;
 
-public class FunctionDesc implements ProtoObject<FunctionDescProto>, Cloneable {
-  private FunctionDescProto proto = FunctionDescProto.getDefaultInstance();
-  private FunctionDescProto.Builder builder = null;
-  private boolean viaProto = false;
+public class FunctionDesc implements ProtoObject<FunctionDescProto>, Cloneable, GsonObject {
+  private FunctionDescProto.Builder builder = FunctionDescProto.newBuilder();
   
   @Expose private String signature;
   @Expose private Class<? extends Function> funcClass;
@@ -45,12 +41,10 @@ public class FunctionDesc implements ProtoObject<FunctionDescProto>, Cloneable {
   @Expose private DataType [] params;
 
   public FunctionDesc() {
-    this.builder = FunctionDescProto.newBuilder();
   }
-  
+
   public FunctionDesc(String signature, Class<? extends Function> clazz,
       FunctionType funcType, DataType [] retType, DataType [] params) {
-    this();
     this.signature = signature.toLowerCase();
     this.funcClass = clazz;
     this.funcType = funcType;
@@ -58,12 +52,12 @@ public class FunctionDesc implements ProtoObject<FunctionDescProto>, Cloneable {
     this.params = params;
   }
   
-  public FunctionDesc(FunctionDescProto proto) {
-    this.proto = proto;
-    this.viaProto = true;
+  public FunctionDesc(FunctionDescProto proto) throws ClassNotFoundException {
+    this(proto.getSignature(), proto.getClassName(), proto.getType(),
+        newNoNameSchema(proto.getReturnType()),
+        proto.getParameterTypesList().toArray(new DataType[proto.getParameterTypesCount()]));
   }
 
-  @SuppressWarnings("unchecked")
   public FunctionDesc(String signature, String className, FunctionType type,
                       DataType [] retType, DataType... argTypes) throws ClassNotFoundException {
     this(signature, (Class<? extends Function>) Class.forName(className), type,
@@ -85,75 +79,28 @@ public class FunctionDesc implements ProtoObject<FunctionDescProto>, Cloneable {
   }
 
   public String getSignature() {
-    FunctionDescProtoOrBuilder p = viaProto ? proto : builder;
-    if (this.signature != null) {
-      return this.signature;
-    }
-    if (!proto.hasSignature()) {
-      return null;
-    }
-    this.signature = p.getSignature();
     return this.signature;
   }
 
   @SuppressWarnings("unchecked")
   public Class<? extends Function> getFuncClass() throws InternalException {
-    FunctionDescProtoOrBuilder p = viaProto ? proto : builder;
-    if (this.funcClass != null) {
-      return this.funcClass;
-    }
-    if (!p.hasClassName()) {
-      return null;
-    }
-    try {
-      this.funcClass = (Class<? extends Function>)Class.forName(p.getClassName());
-    } catch (ClassNotFoundException e) {
-      throw new InternalException("The function class ("+p.getClassName()+") cannot be loaded");
-    }
     return this.funcClass;
   }
 
   public FunctionType getFuncType() {
-    FunctionDescProtoOrBuilder p = viaProto ? proto : builder;
-    if (this.funcType != null) {
-      return this.funcType;
-    }
-    if (!p.hasType()) {
-      return null;
-    }
-    this.funcType = p.getType();
     return this.funcType;
   }
 
   public DataType [] getParamTypes() {
-    FunctionDescProtoOrBuilder p = viaProto ? proto : builder;
-    if (this.params != null) {
-      return this.params;
-    }
-    if (p.getParameterTypesCount() == 0) {
-      return null;
-    }
-    this.params = p.getParameterTypesList().toArray(
-        new DataType[p.getParameterTypesCount()]);
     return this.params;
   }
 
   public DataType [] getReturnType() {
-    FunctionDescProtoOrBuilder p = viaProto ? proto : builder;
-    if (this.returnType != null) {
-      return newNoNameSchema(this.returnType);
-    }
-    if (!p.hasReturnType()) {
-      return null;
-    }
-    this.returnType = newNoNameSchema(p.getReturnType());
     return this.returnType;
-    
   }
 
   public static DataType [] newNoNameSchema(DataType ... types) {
-    DataType [] dataTypes = types.clone();
-    return dataTypes;
+    return types.clone();
   }
   
   @Override
@@ -169,14 +116,10 @@ public class FunctionDesc implements ProtoObject<FunctionDescProto>, Cloneable {
   @Override
   public Object clone() throws CloneNotSupportedException{
     FunctionDesc desc  = (FunctionDesc)super.clone();
-    desc.proto = this.proto;
-    desc.builder = this.builder == null?null:this.builder.clone();
     
     desc.signature = this.signature;
-    desc.params = this.params;
-    
+    desc.params = params.clone();
     desc.returnType = this.returnType;
-    desc.viaProto = this.viaProto;
     desc.funcClass = this.funcClass;
     
     return desc;
@@ -184,91 +127,28 @@ public class FunctionDesc implements ProtoObject<FunctionDescProto>, Cloneable {
 
   @Override
   public FunctionDescProto getProto() {
-    mergeLocalToProto();
-    proto = viaProto ? proto : builder.build();
-    viaProto = true;
-    return proto;
-  }
-  
-  private void maybeInitBuilder() {
-    if (viaProto || builder == null) {
-      builder = FunctionDescProto.newBuilder(proto);
-    }
-    viaProto = false;
-  }
-  
-  private void mergeLocalToBuilder() {
-    if (this.signature  != null) {     
-      builder.setSignature(this.signature);
-    }
-    if (this.funcClass != null) {
-      builder.setClassName(this.funcClass.getName());
-    }
-    if (this.funcType != null) {
-      builder.setType(this.funcType);
-    }
-    if (this.returnType != null) {
-      builder.setReturnType(this.returnType[0]);
-    }
-    if (this.params != null) {
+    if (builder == null) {
+      builder = FunctionDescProto.newBuilder();
+    } else {
+      builder.clear();
+    }
+    builder.setSignature(this.signature);
+    builder.setClassName(this.funcClass.getName());
+    builder.setType(this.funcType);
+    builder.setReturnType(this.returnType[0]);
+
+    if (this.params != null) { // repeated field
       builder.addAllParameterTypes(Arrays.asList(params));
     }
-  }
-  
-  private void mergeLocalToProto() {
-    if(viaProto) {
-      maybeInitBuilder();
-    }
-    mergeLocalToBuilder();
-    proto = builder.build();
-    viaProto = true;
-  }
-  
-  @SuppressWarnings("unchecked")
-  private void mergeProtoToLocal() throws InternalException {
-	  FunctionDescProtoOrBuilder p = viaProto ? proto : builder;
-	  if (signature == null && p.hasSignature()) {
-		  signature = p.getSignature();
-	  }
-	  if (funcClass == null && p.hasClassName()) {
-		  try {
-			  this.funcClass = 
-			      (Class<? extends GeneralFunction>)Class.forName(p.getClassName());
-		  } catch (ClassNotFoundException e) {
-			  throw new InternalException("The function class ("+p.getClassName()+") cannot be loaded");
-		  }
-	  }
-	  if (funcType == null && p.hasType()) {
-		  funcType = p.getType();
-	  }
-	  if (returnType == null && p.hasReturnType()) {
-		  returnType = newNoNameSchema(p.getReturnType());
-	  }
-	  if (params == null && p.getParameterTypesCount() > 0) {
-		  params = new DataType[p.getParameterTypesCount()];
-		  for (int i = 0; i < p.getParameterTypesCount(); i++) {
-			  params[i] = p.getParameterTypes(i);
-		  }
-	  }
+    return builder.build();
   }
   
   @Override
   public String toString() {
 	  return getProto().toString();
   }
-
-  @Override
-  public void initFromProto() {
-    try {
-      mergeProtoToLocal();
-    } catch (InternalException e) {
-      e.printStackTrace();
-    }
-  }
   
-  public String toJSON() {
-    initFromProto();
-    Gson gson = GsonCreator.getInstance();
-    return gson.toJson(this, FunctionDesc.class);
+  public String toJson() {
+    return CatalogGsonHelper.toJson(this, FunctionDesc.class);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/IndexDesc.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/IndexDesc.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/IndexDesc.java
index fb6058e..9465946 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/IndexDesc.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/IndexDesc.java
@@ -21,24 +21,20 @@ package org.apache.tajo.catalog;
 import com.google.common.base.Objects;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
-import com.google.gson.annotations.Expose;
 import org.apache.tajo.catalog.proto.CatalogProtos.IndexDescProto;
-import org.apache.tajo.catalog.proto.CatalogProtos.IndexDescProtoOrBuilder;
 import org.apache.tajo.catalog.proto.CatalogProtos.IndexMethod;
 import org.apache.tajo.common.ProtoObject;
 
 public class IndexDesc implements ProtoObject<IndexDescProto>, Cloneable {
-  private IndexDescProto proto;
   private IndexDescProto.Builder builder;
-  private boolean viaProto;
   
-  @Expose private String name;
-  @Expose private String tableId;
-  @Expose private Column column;
-  @Expose private IndexMethod indexMethod;
-  @Expose private boolean isUnique = false;
-  @Expose private boolean isClustered = false;
-  @Expose private boolean isAscending = false;
+  private String name; // required
+  private String tableId; // required
+  private Column column; // required
+  private IndexMethod indexMethod; // required
+  private boolean isUnique = false; // optional [default = false]
+  private boolean isClustered = false; // optional [default = false]
+  private boolean isAscending = false; // optional [default = false]
   
   public IndexDesc() {
     this.builder = IndexDescProto.newBuilder();
@@ -57,172 +53,52 @@ public class IndexDesc implements ProtoObject<IndexDescProto>, Cloneable {
   }
   
   public IndexDesc(IndexDescProto proto) {
-    this.proto = proto;
-    this.viaProto = true;
+    this(proto.getName(), proto.getTableId(), new Column(proto.getColumn()),
+        proto.getIndexMethod(), proto.getIsUnique(), proto.getIsClustered(), proto.getIsAscending());
   }
   
   public String getName() {
-    IndexDescProtoOrBuilder p = viaProto ? proto : builder;
-    if (this.name != null) {
-      return name;
-    }
-    if (!p.hasName()) {
-      return null;
-    }
-    this.name = p.getName();
-    
     return name;
   }
   
   public String getTableId() {
-    IndexDescProtoOrBuilder p = viaProto ? proto : builder;
-    if (this.tableId != null) {
-      return tableId;
-    }
-    if (!p.hasTableId()) {
-      return null;
-    }
-    this.tableId = p.getTableId();
-    
     return tableId;
   }
   
   public Column getColumn() {
-    IndexDescProtoOrBuilder p = viaProto ? proto : builder;
-    if (this.column != null) {
-      return column;
-    }
-    if (!p.hasColumn()) {
-      return null;
-    }
-    this.column = new Column(p.getColumn());
-    
     return column;
   }
   
   public IndexMethod getIndexMethod() {
-    IndexDescProtoOrBuilder p = viaProto ? proto : builder;    
-    if (this.indexMethod != null) {
-      return this.indexMethod;
-    }
-    if (!p.hasIndexMethod()) { // if isCluster == false and proto has no set
-      return null;
-    }
-    this.indexMethod = p.getIndexMethod();
-    
     return this.indexMethod;
   }
   
   public boolean isClustered() {
-    IndexDescProtoOrBuilder p = viaProto ? proto : builder;
-    if (isClustered) {
-      return true;
-    }
-    if (!p.hasIsClustered()) { // if isCluster == false and proto has no set
-      return false;
-    }
-    this.isClustered = p.getIsClustered();
-    
     return this.isClustered;
   }
   
   public boolean isUnique() {
-    IndexDescProtoOrBuilder p = viaProto ? proto : builder;    
-    if (isUnique) {
-      return true;
-    }
-    if (!p.hasIsUnique()) { // if isCluster == false and proto has no set
-      return false;
-    }
-    this.isUnique = p.getIsUnique();
-    
     return this.isUnique;
   }
   
   public boolean isAscending() {
-    IndexDescProtoOrBuilder p = viaProto ? proto : builder;    
-    if (isAscending) {
-      return true;
-    }
-    if (!p.hasIsAscending()) { // if isCluster == false and proto has no set
-      return false;
-    }
-    this.isAscending = p.getIsAscending();
-    
     return this.isAscending;
   }
 
   @Override
   public IndexDescProto getProto() {
-    if(!viaProto) {
-      mergeLocalToBuilder();
-      proto = builder.build();
-      viaProto = true;
-    }
-    
-    return proto;
-  }
-  
-  @SuppressWarnings("unused")
-  private void setModified() {
-    if (viaProto && builder == null) {
-      builder = IndexDescProto.newBuilder(proto);
-    }
-    viaProto = false;
-  }
-  
-  private void mergeLocalToBuilder() {
     if (builder == null) {
-      builder = IndexDescProto.newBuilder(proto);
-    }
-    if (this.name != null) {
-      builder.setName(this.name);
-    }
-    if (this.tableId != null) {
-      builder.setTableId(this.tableId);
-    }
-    if (this.column != null) {
-      builder.setColumn(this.column.getProto());
-    }
-    if (this.indexMethod != null) {
-      builder.setIndexMethod(indexMethod);
-    }
-    if (this.isUnique) {
-      builder.setIsUnique(this.isUnique);
-    }
-    if (this.isClustered) {
-      builder.setIsClustered(this.isClustered);
-    }
-    if (this.isAscending) {
-      builder.setIsAscending(this.isAscending);
-    }
-  }
-  
-  @Override
-  public void initFromProto() {
-    IndexDescProtoOrBuilder p = viaProto ? proto : builder;
-    if (this.name == null && p.hasName()) {
-      this.name = p.getName();
-    }
-    if (this.tableId == null && p.hasTableId()) {
-      this.tableId = p.getTableId();
-    }
-    if (this.column == null && p.hasColumn()) {
-      this.column = new Column(p.getColumn());
-    }
-    if (this.indexMethod == null && p.hasIndexMethod()) {
-      this.indexMethod = p.getIndexMethod();
-    }
-    if (this.isUnique == false && p.hasIsUnique()) {
-      this.isUnique = p.getIsUnique();
-    }
-    if (this.isClustered == false && p.hasIsClustered()) {
-      this.isUnique = p.getIsUnique();
-    }
-    if (this.isAscending == false && p.hasIsAscending()) {
-      this.isAscending = p.getIsAscending();
-    }
-    viaProto = false;
+      builder = IndexDescProto.newBuilder();
+    }
+    builder.setName(this.name);
+    builder.setTableId(this.tableId);
+    builder.setColumn(this.column.getProto());
+    builder.setIndexMethod(indexMethod);
+    builder.setIsUnique(this.isUnique);
+    builder.setIsClustered(this.isClustered);
+    builder.setIsAscending(this.isAscending);
+
+    return builder.build();
   }
   
   public boolean equals(Object obj) {
@@ -247,7 +123,6 @@ public class IndexDesc implements ProtoObject<IndexDescProto>, Cloneable {
   
   public Object clone() throws CloneNotSupportedException {
     IndexDesc desc = (IndexDesc) super.clone();
-    initFromProto();
     desc.name = name;
     desc.tableId = tableId;
     desc.column = (Column) column.clone();

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Options.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Options.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Options.java
index afd27b2..d5aa559 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Options.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Options.java
@@ -18,42 +18,38 @@
 
 package org.apache.tajo.catalog;
 
-import com.google.common.collect.Maps;
 import com.google.gson.annotations.Expose;
-import org.apache.tajo.catalog.json.GsonCreator;
+import org.apache.tajo.json.GsonObject;
+import org.apache.tajo.catalog.json.CatalogGsonHelper;
 import org.apache.tajo.catalog.proto.CatalogProtos.KeyValueProto;
 import org.apache.tajo.catalog.proto.CatalogProtos.KeyValueSetProto;
-import org.apache.tajo.catalog.proto.CatalogProtos.KeyValueSetProtoOrBuilder;
 import org.apache.tajo.common.ProtoObject;
+import org.apache.tajo.util.TUtil;
 
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
 
-public class Options implements ProtoObject<KeyValueSetProto>, Cloneable {
-	@Expose(serialize=false,deserialize=false)
-	private KeyValueSetProto proto = KeyValueSetProto.getDefaultInstance();
-	@Expose(serialize=false,deserialize=false)
-	private KeyValueSetProto.Builder builder = null;
-	@Expose(serialize=false,deserialize=false)
-	private boolean viaProto = false;
+public class Options implements ProtoObject<KeyValueSetProto>, Cloneable, GsonObject {
+	private KeyValueSetProto.Builder builder = KeyValueSetProto.newBuilder();
 	
 	@Expose private Map<String,String> keyVals;
 	
 	public Options() {
-		builder = KeyValueSetProto.newBuilder();
+    keyVals = TUtil.newHashMap();
 	}
 	
 	public Options(KeyValueSetProto proto) {
-		this.proto = proto;
-		viaProto = true;
+    this.keyVals = TUtil.newHashMap();
+    for(KeyValueProto keyval : proto.getKeyvalList()) {
+      this.keyVals.put(keyval.getKey(), keyval.getValue());
+    }
 	}
 	
 	public Options(Options options) {
 	  this();
-	  options.initFromProto();
-	  this.keyVals = Maps.newHashMap(options.keyVals);
+	  this.keyVals.putAll(options.keyVals);
 	}
 	
 	public static Options create() {
@@ -65,30 +61,22 @@ public class Options implements ProtoObject<KeyValueSetProto>, Cloneable {
   }
 	
 	public void put(String key, String val) {
-		initOptions();
-		setModified();
 		this.keyVals.put(key, val);
 	}
 
   public void putAll(Map<String, String> keyValues) {
-    initOptions();
-    setModified();
     this.keyVals.putAll(keyValues);
   }
 	
 	public void putAll(Options options) {
-	  initOptions();
-	  setModified();
 	  this.keyVals.putAll(options.keyVals);
 	}
 	
 	public String get(String key) {
-		initOptions();
 		return this.keyVals.get(key);
 	}
 	
 	public String get(String key, String defaultVal) {
-	  initOptions();
 	  if(keyVals.containsKey(key))
 	    return keyVals.get(key);
 	  else {
@@ -97,12 +85,10 @@ public class Options implements ProtoObject<KeyValueSetProto>, Cloneable {
 	}
 	
 	public Iterator<Entry<String,String>> getAllKeyValus() {
-	  initOptions();
 	  return keyVals.entrySet().iterator();
 	}
 	
 	public String delete(String key) {
-		initOptions();
 		return keyVals.remove(key);
 	}
 	
@@ -110,8 +96,6 @@ public class Options implements ProtoObject<KeyValueSetProto>, Cloneable {
 	public boolean equals(Object object) {
 		if(object instanceof Options) {
 			Options other = (Options)object;
-			initOptions();
-			other.initOptions();
 			for(Entry<String, String> entry : other.keyVals.entrySet()) {
 				if(!keyVals.get(entry.getKey()).equals(entry.getValue()))
 					return false;
@@ -125,62 +109,33 @@ public class Options implements ProtoObject<KeyValueSetProto>, Cloneable {
 	@Override
   public Object clone() throws CloneNotSupportedException {    
     Options options = (Options) super.clone();
-    initFromProto();
-    options.proto = null;
-    options.viaProto = false;
     options.builder = KeyValueSetProto.newBuilder();
-    options.keyVals = keyVals != null ? new HashMap<String, String>(keyVals) :
-      null;    
+    options.keyVals = keyVals != null ? new HashMap<String, String>(keyVals) : null;
     return options;
 	}
 	
 	@Override
 	public KeyValueSetProto getProto() {
-	  if(!viaProto) {
-      mergeLocalToBuilder();
-      proto = builder.build();
-      viaProto = true;
-    }	  
-		return proto;
-	}
-	
-	private void initOptions() {
-		if (this.keyVals != null) {
-			return;
-		}
-		KeyValueSetProtoOrBuilder p = viaProto ? proto : builder;
-		this.keyVals = Maps.newHashMap();
-		for(KeyValueProto keyval:p.getKeyvalList()) {
-			this.keyVals.put(keyval.getKey(), keyval.getValue());
-		}		
-	}
-	
-	private void setModified() {
-		if (viaProto || builder == null) {
-			builder = KeyValueSetProto.newBuilder(proto);
-		}
-		viaProto = false;
-	}
-	
-	private void mergeLocalToBuilder() {
-		KeyValueProto.Builder kvBuilder = null;
-		if(this.keyVals != null) {
-			for(Entry<String,String> kv : keyVals.entrySet()) {
-				kvBuilder = KeyValueProto.newBuilder();
-				kvBuilder.setKey(kv.getKey());
-				kvBuilder.setValue(kv.getValue());
-				builder.addKeyval(kvBuilder.build());
-			}
-		}
-	}
+    if (builder == null) {
+      builder = KeyValueSetProto.newBuilder();
+    } else {
+      builder.clear();
+    }
 
-  @Override
-  public void initFromProto() {
-    initOptions();
-  }
+    KeyValueProto.Builder kvBuilder;
+    if(this.keyVals != null) {
+      for(Entry<String,String> kv : keyVals.entrySet()) {
+        kvBuilder = KeyValueProto.newBuilder();
+        kvBuilder.setKey(kv.getKey());
+
+        kvBuilder.setValue(kv.getValue());
+        builder.addKeyval(kvBuilder.build());
+      }
+    }
+    return builder.build();
+	}
   
-  public String toJSON() {
-    initFromProto();
-    return GsonCreator.getInstance().toJson(this, Options.class);
+  public String toJson() {
+    return CatalogGsonHelper.toJson(this, Options.class);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Schema.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Schema.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Schema.java
index 7a0168c..9fee40f 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Schema.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Schema.java
@@ -18,46 +18,45 @@
 
 package org.apache.tajo.catalog;
 
-import com.google.gson.Gson;
 import com.google.gson.annotations.Expose;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.tajo.json.GsonObject;
 import org.apache.tajo.catalog.exception.AlreadyExistsFieldException;
-import org.apache.tajo.catalog.json.GsonCreator;
+import org.apache.tajo.catalog.json.CatalogGsonHelper;
 import org.apache.tajo.catalog.proto.CatalogProtos.ColumnProto;
 import org.apache.tajo.catalog.proto.CatalogProtos.SchemaProto;
-import org.apache.tajo.catalog.proto.CatalogProtos.SchemaProtoOrBuilder;
 import org.apache.tajo.common.ProtoObject;
 import org.apache.tajo.common.TajoDataTypes.DataType;
 import org.apache.tajo.common.TajoDataTypes.Type;
 
 import java.util.*;
 
-public class Schema implements ProtoObject<SchemaProto>, Cloneable {
+public class Schema implements ProtoObject<SchemaProto>, Cloneable, GsonObject {
   private static final Log LOG = LogFactory.getLog(Schema.class);
-  
-	private SchemaProto proto = SchemaProto.getDefaultInstance();
-	private	SchemaProto.Builder builder = null;
-	boolean viaProto = false;
+	private	SchemaProto.Builder builder = SchemaProto.newBuilder();
 
-	@Expose
-	protected List<Column> fields = null;
-	@Expose
-	protected Map<String,Integer> fieldsByName = null;
+	@Expose protected List<Column> fields = null;
+	@Expose protected Map<String,Integer> fieldsByName = null;
 
 	public Schema() {
-		builder = SchemaProto.newBuilder();
+    this.fields = new ArrayList<Column>();
+    this.fieldsByName = new TreeMap<String, Integer>();
 	}
 	
 	public Schema(SchemaProto proto) {
-    this.proto = proto;
-    this.viaProto = true;
+    this.fields = new ArrayList<Column>();
+    this.fieldsByName = new HashMap<String, Integer>();
+    for(ColumnProto colProto : proto.getFieldsList()) {
+      fields.add(new Column(colProto));
+      fieldsByName.put(colProto.getColumnName(), fields.size() - 1);
+    }
   }
 
 	public Schema(Schema schema) {
 	  this();
-		this.fields = new ArrayList<Column>(schema.fields);
-		this.fieldsByName = new TreeMap<String, Integer>(schema.fieldsByName);
+		this.fields.addAll(schema.fields);
+		this.fieldsByName.putAll(schema.fieldsByName);
 	}
 	
 	public Schema(Column [] columns) {
@@ -68,18 +67,15 @@ public class Schema implements ProtoObject<SchemaProto>, Cloneable {
   }
 	
 	public int getColumnNum() {
-		initColumns();
 		return this.fields.size();
 	}
 
 	public Column getColumn(String colName) {
-		initColumns();
 		Integer cid = fieldsByName.get(colName.toLowerCase());
 		return cid != null ? fields.get(cid) : null;
 	}
 	
 	public Column getColumnByName(String colName) {
-	  initColumns();
 	  for (Column col : fields) {
 	    if (col.getColumnName().equals(colName.toLowerCase())) {
 	      return col;
@@ -89,17 +85,14 @@ public class Schema implements ProtoObject<SchemaProto>, Cloneable {
 	}
 	
 	public Column getColumn(int id) {
-	  initColumns();
 	  return fields.get(id);
 	}
 	
 	public int getColumnId(String colName) {
-	  initColumns();
 	  return fieldsByName.get(colName.toLowerCase());
 	}
 
   public int getColumnIdByName(String colName) {
-    initColumns();
     for (Column col : fields) {
       if (col.getColumnName().equals(colName.toLowerCase())) {
         return fieldsByName.get(col.getQualifiedName());
@@ -109,47 +102,22 @@ public class Schema implements ProtoObject<SchemaProto>, Cloneable {
   }
 	
 	public Collection<Column> getColumns() {
-		initColumns();
 		return fields;
 	}
 	
 	public void alter(int idx, Column column) {
-	  initColumns();
 	  this.fields.set(idx, column);
 	}
 	
 	public boolean contains(String colName) {
-		initColumns();
 		return fieldsByName.containsKey(colName.toLowerCase());
 	}
-	
-	public void initFromProto() {
-		initColumns();
-		for (Column col : fields) {
-		  col.initFromProto();
-		}
-	}
-
-	private void initColumns() {
-		if (this.fields != null) {
-			return;
-		}
-		SchemaProtoOrBuilder p = viaProto ? proto : builder;
-		this.fields = new ArrayList<Column>();
-		this.fieldsByName = new HashMap<String, Integer>();
-		for(ColumnProto colProto : p.getFieldsList()) {
-			fields.add(new Column(colProto));
-			fieldsByName.put(colProto.getColumnName(), fields.size() - 1);
-		}
-	}
 
   public synchronized Schema addColumn(String name, Type type) {
     return addColumn(name, CatalogUtil.newDataTypeWithoutLen(type));
   }
 
   public synchronized Schema addColumn(String name, DataType dataType) {
-		initColumns();
-		setModified();
 		String lowcased = name.toLowerCase();
 		if(fieldsByName.containsKey(lowcased)) {
 		  LOG.error("Already exists column " + lowcased);
@@ -185,46 +153,25 @@ public class Schema implements ProtoObject<SchemaProto>, Cloneable {
   @Override
   public Object clone() throws CloneNotSupportedException {
     Schema schema = (Schema) super.clone();
-    initFromProto();
-    schema.viaProto = false;
     schema.builder = SchemaProto.newBuilder();
     schema.fields = fields != null ? new ArrayList<Column>(fields) : null;
-    schema.fieldsByName = fieldsByName != null ? new HashMap<String, Integer>(fieldsByName) : null;
+    schema.fieldsByName = fieldsByName != null ? new TreeMap<String, Integer>(fieldsByName) : null;
 
     return schema;
   }
 
 	@Override
 	public SchemaProto getProto() {
-	  if(!viaProto) {
-      mergeLocalToBuilder();
-      proto = builder.build();
-      viaProto = true;
+    builder.clearFields();
+    if (this.fields  != null) {
+      for(Column col : fields) {
+        builder.addFields(col.getProto());
+      }
     }
-	  
-		return proto;
-	}
-
-	private void setModified() {
-		viaProto = false;
-	}
-
-	private void mergeLocalToBuilder() {
-	  if (builder == null) {
-	    builder = SchemaProto.newBuilder(proto);
-	  } else {	  
-	    builder.clearFields();
-	  }
-	  
-		if (this.fields  != null) {			
-			for(Column col : fields) {
-				builder.addFields(col.getProto());
-			}
-		}
+    return builder.build();
 	}
 
 	public String toString() {
-	  initColumns();
 	  StringBuilder sb = new StringBuilder();
 	  sb.append("{");
 	  int i = 0;
@@ -239,16 +186,14 @@ public class Schema implements ProtoObject<SchemaProto>, Cloneable {
 	  
 	  return sb.toString();
 	}
-	
+
+  @Override
 	public String toJson() {
-	  initFromProto();
-	  Gson gson = GsonCreator.getInstance();
-	  return gson.toJson(this, Schema.class);
+	  return CatalogGsonHelper.toJson(this, Schema.class);
 		
 	}
 
   public Column [] toArray() {
-    initFromProto();
     return this.fields.toArray(new Column[this.fields.size()]);
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/SortSpec.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/SortSpec.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/SortSpec.java
index edf7a2b..be73eb3 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/SortSpec.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/SortSpec.java
@@ -19,11 +19,12 @@
 package org.apache.tajo.catalog;
 
 import com.google.gson.annotations.Expose;
-import org.apache.tajo.catalog.json.GsonCreator;
+import org.apache.tajo.json.GsonObject;
+import org.apache.tajo.catalog.json.CatalogGsonHelper;
 
-public class SortSpec implements Cloneable {
-  @Expose
-  private Column sortKey;
+
+public class SortSpec implements Cloneable, GsonObject {
+  @Expose private Column sortKey;
   @Expose private boolean ascending = true;
   @Expose private boolean nullFirst = false;
 
@@ -38,8 +39,7 @@ public class SortSpec implements Cloneable {
    * @param nullFirst
    * Otherwise, it should be false.
    */
-  public SortSpec(final Column sortKey, final boolean asc,
-                  final boolean nullFirst) {
+  public SortSpec(final Column sortKey, final boolean asc, final boolean nullFirst) {
     this(sortKey);
     this.ascending = asc;
     this.nullFirst = nullFirst;
@@ -70,13 +70,26 @@ public class SortSpec implements Cloneable {
     SortSpec key = (SortSpec) super.clone();
     key.sortKey = (Column) sortKey.clone();
     key.ascending = ascending;
+    key.nullFirst = nullFirst;
 
     return key;
   }
 
-  public String toJSON() {
-    sortKey.initFromProto();
-    return GsonCreator.getInstance().toJson(this);
+  @Override
+  public boolean equals(Object object) {
+    if (object instanceof SortSpec) {
+      SortSpec other = (SortSpec) object;
+      return sortKey.equals(other.sortKey) &&
+          ascending == other.ascending &&
+          nullFirst == other.nullFirst;
+    } else {
+      return false;
+    }
+  }
+
+  @Override
+  public String toJson() {
+    return CatalogGsonHelper.toJson(this, SortSpec.class);
   }
 
   public String toString() {

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDesc.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDesc.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDesc.java
index feeb0a8..d46bd14 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDesc.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDesc.java
@@ -20,8 +20,9 @@ package org.apache.tajo.catalog;
 
 import com.google.protobuf.Message;
 import org.apache.hadoop.fs.Path;
+import org.apache.tajo.json.GsonObject;
 
-public interface TableDesc extends Cloneable {
+public interface TableDesc extends Cloneable, GsonObject {
   void setId(String tableId);
   
   String getId();
@@ -35,10 +36,6 @@ public interface TableDesc extends Cloneable {
   TableMeta getMeta();
   
   Message getProto();
-  
-  void initFromProto();
-  
-  String toJSON();
  
   Object clone() throws CloneNotSupportedException;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDescImpl.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDescImpl.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDescImpl.java
index b690ddf..2771157 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDescImpl.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDescImpl.java
@@ -22,21 +22,17 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.annotations.Expose;
 import org.apache.hadoop.fs.Path;
-import org.apache.tajo.catalog.json.GsonCreator;
+import org.apache.tajo.catalog.json.CatalogGsonHelper;
 import org.apache.tajo.catalog.proto.CatalogProtos.StoreType;
 import org.apache.tajo.catalog.proto.CatalogProtos.TableDescProto;
-import org.apache.tajo.catalog.proto.CatalogProtos.TableDescProtoOrBuilder;
 import org.apache.tajo.common.ProtoObject;
 
-public class TableDescImpl implements TableDesc, ProtoObject<TableDescProto>,
-    Cloneable {
-  protected TableDescProto proto = TableDescProto.getDefaultInstance();
+public class TableDescImpl implements TableDesc, ProtoObject<TableDescProto>, Cloneable {
   protected TableDescProto.Builder builder = null;
-  protected boolean viaProto = false;
   
-	@Expose protected String tableId;
-	@Expose protected Path uri;
-	@Expose protected TableMeta meta;
+	@Expose protected String tableId; // required
+	@Expose protected Path uri; // required
+	@Expose protected TableMeta meta; // required
   
 	public TableDescImpl() {
 		builder = TableDescProto.newBuilder();
@@ -56,65 +52,32 @@ public class TableDescImpl implements TableDesc, ProtoObject<TableDescProto>,
 	}
 	
 	public TableDescImpl(TableDescProto proto) {
-	  this.proto = proto;
-	  viaProto = true;
+	  this(proto.getId(), new TableMetaImpl(proto.getMeta()), new Path(proto.getPath()));
 	}
 	
 	public void setId(String tableId) {
-	  setModified();
 	  // tajo deems all identifiers as lowcase characters
 		this.tableId = tableId.toLowerCase();
 	}
 	
   public String getId() {
-    TableDescProtoOrBuilder p = viaProto ? proto : builder;
-    
-    if (tableId != null) {
-      return this.tableId;
-    }
-    if (!p.hasId()) {
-      return null;
-    }
-    this.tableId = p.getId();
-    
     return this.tableId;
   }
 	
 	public void setPath(Path uri) {
-	  setModified();
 		this.uri = uri;
 	}
 	
   public Path getPath() {
-    TableDescProtoOrBuilder p = viaProto ? proto : builder;
-    
-    if (uri != null) {
-      return this.uri;
-    }
-    if (!proto.hasPath()) {
-      return null;
-    }
-    this.uri = new Path(p.getPath());
-    
     return this.uri;
   }
   
   @Override
   public void setMeta(TableMeta info) {
-    setModified();
     this.meta = info;
   }
 	
 	public TableMeta getMeta() {
-	  TableDescProtoOrBuilder p = viaProto ? proto : builder;
-    
-    if (meta != null) {
-      return this.meta;
-    }
-    if (!p.hasMeta()) {
-      return null;
-    }
-    this.meta = new TableMetaImpl(p.getMeta());
 	  return this.meta;
 	}
 	
@@ -134,10 +97,7 @@ public class TableDescImpl implements TableDesc, ProtoObject<TableDescProto>,
 	
 	public Object clone() throws CloneNotSupportedException {	  
 	  TableDescImpl desc = (TableDescImpl) super.clone();
-	  initFromProto();
-	  desc.proto = null;
 	  desc.builder = TableDescProto.newBuilder();
-	  desc.viaProto = false;
 	  desc.tableId = tableId;
 	  desc.uri = uri;
 	  desc.meta = (TableMeta) meta.clone();
@@ -151,64 +111,23 @@ public class TableDescImpl implements TableDesc, ProtoObject<TableDescProto>,
     return gson.toJson(this);
 	}
 	
-	public String toJSON() {
-		initFromProto();
-		Gson gson = GsonCreator.getInstance();
-		
-		return gson.toJson(this, TableDesc.class);
+	public String toJson() {
+		return CatalogGsonHelper.toJson(this, TableDesc.class);
 	}
 
   public TableDescProto getProto() {
-    if(!viaProto) {
-      mergeLocalToBuilder();
-      proto = builder.build();
-      viaProto = true;
-    }
-    
-    return proto;
-  }
-  
-  private void setModified() {
-    if (viaProto && builder == null) {
-      builder = TableDescProto.newBuilder(proto);
-    }
-    viaProto = false;
-  }
-  
-  protected void mergeLocalToBuilder() {
     if (builder == null) {
-      builder = TableDescProto.newBuilder(proto);
+      builder = TableDescProto.newBuilder();
     }
-    
     if (this.tableId != null) {
       builder.setId(this.tableId);
     }
-    
     if (this.uri != null) {
       builder.setPath(this.uri.toString());
     }
-    
     if (this.meta != null) {
       builder.setMeta(meta.getProto());
     }
-  }
-  
-  private void mergeProtoToLocal() {
-	  TableDescProtoOrBuilder p = viaProto ? proto : builder;
-	  if (tableId == null && p.hasId()) {
-		  tableId = p.getId();
-	  }
-	  if (uri == null && p.hasPath()) {
-		  uri = new Path(p.getPath());
-	  }
-	  if (meta == null && p.hasMeta()) {
-		  meta = new TableMetaImpl(p.getMeta());
-	  }
-  }
-
-  @Override
-  public void initFromProto() {
-	  mergeProtoToLocal();
-    meta.initFromProto();
+    return builder.build();
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableMeta.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableMeta.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableMeta.java
index 268e70c..184bd33 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableMeta.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableMeta.java
@@ -18,6 +18,7 @@
 
 package org.apache.tajo.catalog;
 
+import org.apache.tajo.json.GsonObject;
 import org.apache.tajo.catalog.proto.CatalogProtos.StoreType;
 import org.apache.tajo.catalog.proto.CatalogProtos.TableProto;
 import org.apache.tajo.catalog.statistics.TableStat;
@@ -26,7 +27,7 @@ import org.apache.tajo.common.ProtoObject;
 import java.util.Iterator;
 import java.util.Map.Entry;
 
-public interface TableMeta extends ProtoObject<TableProto>, Cloneable {
+public interface TableMeta extends ProtoObject<TableProto>, Cloneable, GsonObject {
   
   void setStorageType(StoreType storeType);
   
@@ -49,6 +50,4 @@ public interface TableMeta extends ProtoObject<TableProto>, Cloneable {
   TableStat getStat();
   
   Object clone() throws CloneNotSupportedException;
-  
-  public String toJSON();
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableMetaImpl.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableMetaImpl.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableMetaImpl.java
index 8f6b9b6..e5d5a75 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableMetaImpl.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableMetaImpl.java
@@ -22,28 +22,22 @@ import com.google.common.base.Objects;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.annotations.Expose;
-import org.apache.tajo.catalog.json.GsonCreator;
+import org.apache.tajo.json.GsonObject;
+import org.apache.tajo.catalog.json.CatalogGsonHelper;
 import org.apache.tajo.catalog.proto.CatalogProtos.StoreType;
 import org.apache.tajo.catalog.proto.CatalogProtos.TableProto;
-import org.apache.tajo.catalog.proto.CatalogProtos.TableProtoOrBuilder;
 import org.apache.tajo.catalog.statistics.TableStat;
 
 import java.util.Iterator;
 import java.util.Map.Entry;
 
-public class TableMetaImpl implements TableMeta {
-	protected TableProto proto = TableProto.getDefaultInstance();
+public class TableMetaImpl implements TableMeta, GsonObject {
 	protected TableProto.Builder builder = null;
-	protected boolean viaProto = false;	
 	
-	@Expose
-	protected Schema schema;
-	@Expose
-	protected StoreType storeType;
-	@Expose
-	protected Options options;
-	@Expose
-	protected TableStat stat;
+	@Expose protected Schema schema;
+	@Expose protected StoreType storeType;
+	@Expose protected Options options;
+	@Expose	protected TableStat stat;
 	
 	private TableMetaImpl() {
 	  builder = TableProto.newBuilder();
@@ -66,86 +60,55 @@ public class TableMetaImpl implements TableMeta {
   }
 	
 	public TableMetaImpl(TableProto proto) {
-		this.proto = proto;
-		this.viaProto = true;
+    this();
+    schema = new Schema(proto.getSchema());
+    storeType = proto.getStoreType();
+    options = new Options(proto.getParams());
+
+    if (proto.hasStat() && stat == null) {
+      stat = new TableStat(proto.getStat());
+    }
 	}
 	
 	public void setStorageType(StoreType storeType) {
-    setModified();
     this.storeType = storeType;
   }	
 	
 	public StoreType getStoreType() {
-	  TableProtoOrBuilder p = viaProto ? proto : builder;
-		
-		if(storeType != null) {
-			return this.storeType;
-		}
-		if(!p.hasStoreType()) {
-			return null;
-		}
-		this.storeType = p.getStoreType();
-		
 		return this.storeType;		
 	}
 	
   public void setSchema(Schema schema) {
-    setModified();
     this.schema = schema;
   }
 	
 	public Schema getSchema() {
-		TableProtoOrBuilder p = viaProto ? proto : builder;
-		
-		if(schema != null) {
-			return this.schema;
-		}
-		if(!proto.hasSchema()) {
-		  return null;
-		}
-		this.schema = new Schema(p.getSchema());
-		
 		return this.schema;
 	}
 	
   public void setOptions(Options options) {
-    setModified();
     this.options = options;
   }
 
-  private Options initOptions() {
-    TableProtoOrBuilder p = viaProto ? proto : builder;
-    if(this.options != null) {
-      return this.options;
-    }
-    if(!p.hasParams()) {
-      return null;
-    }
-    this.options = new Options(p.getParams());
-    
-    return this.options;
-  }  
-
   @Override
   public void putOption(String key, String val) {
-    setModified();
-    initOptions().put(key, val);
+    options.put(key, val);
   }
   
 
   @Override
   public String getOption(String key) {    
-    return initOptions().get(key);
+    return options.get(key);
   }
 
   @Override
   public String getOption(String key, String defaultValue) {
-    return initOptions().get(key, defaultValue);
+    return options.get(key, defaultValue);
   }
   
   @Override
   public Iterator<Entry<String,String>> getOptions() {    
-    return initOptions().getAllKeyValus();
+    return options.getAllKeyValus();
   }
 	
 	public boolean equals(Object object) {
@@ -163,11 +126,8 @@ public class TableMetaImpl implements TableMeta {
 	}
 	
 	@Override
-	public Object clone() throws CloneNotSupportedException {    
-	  initFromProto();
-	  TableMetaImpl meta = (TableMetaImpl) super.clone();	  
-	  meta.proto = null;
-    meta.viaProto = false;
+	public Object clone() throws CloneNotSupportedException {
+	  TableMetaImpl meta = (TableMetaImpl) super.clone();
     meta.builder = TableProto.newBuilder();
     meta.schema = (Schema) schema.clone();
     meta.storeType = storeType;
@@ -188,93 +148,31 @@ public class TableMetaImpl implements TableMeta {
 	////////////////////////////////////////////////////////////////////////
 	@Override
 	public TableProto getProto() {
-	  if(!viaProto) {
-      mergeLocalToBuilder();
-      proto = builder.build();
-      viaProto = true;  
-    }
-		return proto;
-	}
-
-  private void setModified() {
-    if (viaProto || builder == null) {
-      builder = TableProto.newBuilder(proto);
-    }
-    this.viaProto = false;
-  }
-	
-	private void mergeLocalToBuilder() {
-    if (this.builder == null) {      
-      this.builder = TableProto.newBuilder(proto);
+    if (builder == null) {
+      builder = TableProto.newBuilder();
     }
-	  
-	  if (this.schema != null) {
-	    builder.setSchema(this.schema.getProto());
-	  }
-	  
-	  if (this.stat != null) {
-	    builder.setStat(this.stat.getProto());
-	  }
+    builder.setSchema(this.schema.getProto());
+    builder.setStoreType(storeType);
+    builder.setParams(options.getProto());
 
-	  if (this.storeType != null) {
-      builder.setStoreType(storeType);
+    if (this.stat != null) {
+      builder.setStat(this.stat.getProto());
     }
-
-		if (this.options != null) {
-		  builder.setParams(options.getProto());
-		}
-	}
-	
-  ////////////////////////////////////////////////////////////////////////
-  // For Json
-  ////////////////////////////////////////////////////////////////////////	
-	private void mergeProtoToLocal() {
-		TableProtoOrBuilder p = viaProto ? proto : builder;
-		if (schema == null) {
-			schema = new Schema(p.getSchema());
-		}
-		if (p.hasStat() && stat == null) {
-		  stat = new TableStat(p.getStat());
-		}
-		if (storeType == null && p.hasStoreType()) {
-			storeType = p.getStoreType();
-		}
-		if (options == null && p.hasParams()) {
-			options = new Options(p.getParams());
-		}
+    return builder.build();
 	}
-	
-	public void initFromProto() {
-		mergeProtoToLocal();
-    schema.initFromProto();
-    if (stat != null) {
-      stat.initFromProto();
-    }
-	}
-	
-	public String toJSON() {
-		initFromProto();
-		Gson gson = GsonCreator.getInstance();
-		return gson.toJson(this, TableMeta.class);
+
+  @Override
+	public String toJson() {
+		return CatalogGsonHelper.toJson(this, TableMeta.class);
 	}
 
   @Override
   public void setStat(TableStat stat) {
-    setModified();
     this.stat = stat;
   }
 
   @Override
   public TableStat getStat() {
-    TableProtoOrBuilder p = viaProto ? proto : builder;
-    if (stat != null) {
-      return stat;
-    }
-    if (!p.hasStat()) {
-      return null;
-    }
-    stat = new TableStat(p.getStat());
-    
     return this.stat;
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/AggFunction.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/AggFunction.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/AggFunction.java
index d76a345..6eb6a8b 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/AggFunction.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/AggFunction.java
@@ -18,9 +18,8 @@
 
 package org.apache.tajo.catalog.function;
 
-import com.google.gson.Gson;
 import org.apache.tajo.catalog.Column;
-import org.apache.tajo.catalog.json.GsonCreator;
+import org.apache.tajo.catalog.json.CatalogGsonHelper;
 import org.apache.tajo.common.TajoDataTypes.DataType;
 import org.apache.tajo.datum.Datum;
 import org.apache.tajo.storage.Tuple;
@@ -45,8 +44,8 @@ public abstract class AggFunction<T extends Datum> extends Function<T> {
 
   public abstract T terminate(FunctionContext ctx);
 
-  public String toJSON() {
-    Gson gson = GsonCreator.getInstance();
-    return gson.toJson(this, AggFunction.class);
+  @Override
+  public String toJson() {
+    return CatalogGsonHelper.toJson(this, AggFunction.class);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/Function.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/Function.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/Function.java
index ff8bda0..6d3feff 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/Function.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/Function.java
@@ -19,14 +19,14 @@
 package org.apache.tajo.catalog.function;
 
 import com.google.common.base.Objects;
-import com.google.gson.Gson;
 import com.google.gson.annotations.Expose;
+import org.apache.tajo.json.GsonObject;
 import org.apache.tajo.catalog.Column;
-import org.apache.tajo.catalog.json.GsonCreator;
+import org.apache.tajo.catalog.json.CatalogGsonHelper;
 import org.apache.tajo.datum.Datum;
 import org.apache.tajo.util.TUtil;
 
-public abstract class Function<T extends Datum> implements Cloneable {
+public abstract class Function<T extends Datum> implements Cloneable, GsonObject {
   @Expose protected Column[] definedParams;
   public final static Column [] NoArgs = new Column [] {};
 
@@ -55,8 +55,8 @@ public abstract class Function<T extends Datum> implements Cloneable {
     return func;
   }
 
-  public String toJSON() {
-    Gson gson = GsonCreator.getInstance();
-    return gson.toJson(this, Function.class);
+  @Override
+  public String toJson() {
+    return CatalogGsonHelper.toJson(this, Function.class);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/GeneralFunction.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/GeneralFunction.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/GeneralFunction.java
index 9a9cb86..7f639ae 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/GeneralFunction.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/GeneralFunction.java
@@ -18,13 +18,13 @@
 
 package org.apache.tajo.catalog.function;
 
-import com.google.gson.Gson;
+import org.apache.tajo.json.GsonObject;
 import org.apache.tajo.catalog.Column;
-import org.apache.tajo.catalog.json.GsonCreator;
+import org.apache.tajo.catalog.json.CatalogGsonHelper;
 import org.apache.tajo.datum.Datum;
 import org.apache.tajo.storage.Tuple;
 
-public abstract class GeneralFunction<T extends Datum> extends Function<T> {
+public abstract class GeneralFunction<T extends Datum> extends Function<T> implements GsonObject {
   public GeneralFunction(Column[] definedArgs) {
     super(definedArgs);
   }
@@ -36,8 +36,8 @@ public abstract class GeneralFunction<T extends Datum> extends Function<T> {
 	  GENERAL
 	}
 
-  public String toJSON() {
-    Gson gson = GsonCreator.getInstance();
-    return gson.toJson(this, GeneralFunction.class);
+  @Override
+  public String toJson() {
+    return CatalogGsonHelper.toJson(this, GeneralFunction.class);
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/CatalogGsonHelper.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/CatalogGsonHelper.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/CatalogGsonHelper.java
new file mode 100644
index 0000000..a3e9e94
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/CatalogGsonHelper.java
@@ -0,0 +1,86 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.catalog.json;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.json.GsonObject;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.catalog.TableMeta;
+import org.apache.tajo.catalog.function.AggFunction;
+import org.apache.tajo.catalog.function.Function;
+import org.apache.tajo.catalog.function.GeneralFunction;
+import org.apache.tajo.common.TajoDataTypes.DataType;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.json.*;
+import org.apache.tajo.util.TUtil;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+
+public class CatalogGsonHelper {
+  private static Gson gson;
+  private static Gson gsonPretty;
+
+  private CatalogGsonHelper() {
+  }
+
+  private static Map<Type, GsonSerDerAdapter> registerAdapters() {
+    Map<Type, GsonSerDerAdapter> adapters = TUtil.newHashMap();
+    adapters.put(Class.class, new ClassNameSerializer());
+    adapters.put(Path.class, new PathSerializer());
+    adapters.put(TableDesc.class, new TableDescAdapter());
+    adapters.put(TableMeta.class, new TableMetaAdapter());
+    adapters.put(Function.class, new FunctionAdapter());
+    adapters.put(GeneralFunction.class, new FunctionAdapter());
+    adapters.put(AggFunction.class, new FunctionAdapter());
+    adapters.put(Datum.class, new DatumAdapter());
+    adapters.put(DataType.class, new DataTypeAdapter());
+    return adapters;
+  }
+
+  public static Gson getInstance() {
+    if (gson == null ) {
+      GsonHelper helper = new GsonHelper(registerAdapters());
+      gson = helper.getGson();
+    }
+    return gson;
+  }
+
+  public static Gson getPrettyInstance() {
+    if (gsonPretty == null) {
+      GsonBuilder prettyBuilder = new GsonBuilder()
+          .setPrettyPrinting()
+          .excludeFieldsWithoutExposeAnnotation();
+      GsonHelper.registerAdapters(prettyBuilder, registerAdapters());
+      gsonPretty = prettyBuilder.create();
+    }
+
+    return gsonPretty;
+  }
+
+  public static String toJson(GsonObject object, Class<? extends GsonObject> clazz) {
+    return getInstance().toJson(object, clazz);
+  }
+
+  public static <T extends GsonObject> T fromJson(String json, Class<T> clazz) {
+    return getInstance().fromJson(json, clazz);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/FunctionAdapter.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/FunctionAdapter.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/FunctionAdapter.java
index a5c03f6..4736631 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/FunctionAdapter.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/FunctionAdapter.java
@@ -20,10 +20,11 @@ package org.apache.tajo.catalog.json;
 
 import com.google.gson.*;
 import org.apache.tajo.catalog.function.Function;
+import org.apache.tajo.json.GsonSerDerAdapter;
 
 import java.lang.reflect.Type;
 
-public class FunctionAdapter implements JsonDeserializer<Function>, JsonSerializer<Function> {
+public class FunctionAdapter implements GsonSerDerAdapter<Function> {
 
   @Override
   public JsonElement serialize(Function src, Type typeOfSrc,

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/GsonCreator.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/GsonCreator.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/GsonCreator.java
deleted file mode 100644
index 9c56bcd..0000000
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/GsonCreator.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.catalog.json;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import org.apache.hadoop.fs.Path;
-import org.apache.tajo.catalog.TableDesc;
-import org.apache.tajo.catalog.TableMeta;
-import org.apache.tajo.catalog.function.AggFunction;
-import org.apache.tajo.catalog.function.Function;
-import org.apache.tajo.catalog.function.GeneralFunction;
-import org.apache.tajo.common.TajoDataTypes.DataType;
-import org.apache.tajo.datum.Datum;
-import org.apache.tajo.datum.json.DatumAdapter;
-import org.apache.tajo.gson.ClassNameDeserializer;
-import org.apache.tajo.gson.ClassNameSerializer;
-import org.apache.tajo.gson.DataTypeAdapter;
-
-public class GsonCreator {
-	private static GsonBuilder builder;
-	private static Gson gson;
-	
-	private static void init() {
-		if (builder == null) {
-			builder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation();
-      builder.registerTypeAdapter(Class.class, new ClassNameSerializer());
-      builder.registerTypeAdapter(Class.class, new ClassNameDeserializer());
-			builder.registerTypeAdapter(Path.class, new PathSerializer());
-			builder.registerTypeAdapter(Path.class, new PathDeserializer());
-			builder.registerTypeAdapter(TableDesc.class, new TableDescAdapter());
-			builder.registerTypeAdapter(TableMeta.class, new TableMetaAdapter());
-			builder.registerTypeAdapter(Function.class, new FunctionAdapter());
-      builder.registerTypeAdapter(GeneralFunction.class, new FunctionAdapter());
-      builder.registerTypeAdapter(AggFunction.class, new FunctionAdapter());
-			builder.registerTypeAdapter(Datum.class, new DatumAdapter());
-      builder.registerTypeAdapter(DataType.class, new DataTypeAdapter());
-		}
-	}
-
-	public static Gson getInstance() {
-	  init();
-	  if (gson == null ) {
-	    gson = builder.create();
-	  }
-	  return gson;
-	}
-
-	public static Gson getPrettyInstance() {
-	  init();
-	  if (gson == null ) {
-	    gson = builder.setPrettyPrinting().create();
-	  }
-	  return gson;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/PathDeserializer.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/PathDeserializer.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/PathDeserializer.java
deleted file mode 100644
index a5d6477..0000000
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/PathDeserializer.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.catalog.json;
-
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParseException;
-import org.apache.hadoop.fs.Path;
-
-import java.lang.reflect.Type;
-
-public class PathDeserializer implements JsonDeserializer<Path> {
-
-	@Override
-	public Path deserialize(JsonElement arg0, Type arg1,
-			JsonDeserializationContext arg2) throws JsonParseException {
-		return new Path(arg0.getAsJsonPrimitive().getAsString());
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/PathSerializer.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/PathSerializer.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/PathSerializer.java
deleted file mode 100644
index e589195..0000000
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/PathSerializer.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.catalog.json;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonPrimitive;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
-import org.apache.hadoop.fs.Path;
-
-import java.lang.reflect.Type;
-
-public class PathSerializer implements JsonSerializer<Path> {
-
-	@Override
-	public JsonElement serialize(Path arg0, Type arg1,
-			JsonSerializationContext arg2) {
-		return new JsonPrimitive(arg0.toString());
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/TableDescAdapter.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/TableDescAdapter.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/TableDescAdapter.java
index 8c63043..e34ef61 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/TableDescAdapter.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/TableDescAdapter.java
@@ -20,10 +20,11 @@ package org.apache.tajo.catalog.json;
 
 import com.google.gson.*;
 import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.json.GsonSerDerAdapter;
 
 import java.lang.reflect.Type;
 
-public class TableDescAdapter implements JsonSerializer<TableDesc>, JsonDeserializer<TableDesc> {
+public class TableDescAdapter implements GsonSerDerAdapter<TableDesc> {
 
 	@Override
 	public TableDesc deserialize(JsonElement json, Type type,
@@ -31,7 +32,7 @@ public class TableDescAdapter implements JsonSerializer<TableDesc>, JsonDeserial
 		JsonObject jsonObject = json.getAsJsonObject();
 		String className = jsonObject.get("classname").getAsJsonPrimitive().getAsString();
 		
-		Class clazz = null;
+		Class clazz;
 		try {
 			clazz = Class.forName(className);
 		} catch (ClassNotFoundException e) {
@@ -48,12 +49,8 @@ public class TableDescAdapter implements JsonSerializer<TableDesc>, JsonDeserial
 		String className = src.getClass().getCanonicalName();
 		jsonObj.addProperty("classname", className);
 
-		if (src.getClass().getSimpleName().equals("TableDescImpl")) {
-			src.initFromProto();
-		}
 		JsonElement jsonElem = context.serialize(src);
 		jsonObj.add("property", jsonElem);
 		return jsonObj;
 	}
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/1c677cc5/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/TableMetaAdapter.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/TableMetaAdapter.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/TableMetaAdapter.java
index 9c50897..f8c02e2 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/TableMetaAdapter.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/TableMetaAdapter.java
@@ -20,10 +20,11 @@ package org.apache.tajo.catalog.json;
 
 import com.google.gson.*;
 import org.apache.tajo.catalog.TableMeta;
+import org.apache.tajo.json.GsonSerDerAdapter;
 
 import java.lang.reflect.Type;
 
-public class TableMetaAdapter implements JsonSerializer<TableMeta>, JsonDeserializer<TableMeta> {
+public class TableMetaAdapter implements GsonSerDerAdapter<TableMeta> {
 
 	@Override
 	public TableMeta deserialize(JsonElement json, Type typeOfT,
@@ -31,7 +32,7 @@ public class TableMetaAdapter implements JsonSerializer<TableMeta>, JsonDeserial
 		JsonObject jsonObject = json.getAsJsonObject();
 		String className = jsonObject.get("classname").getAsJsonPrimitive().getAsString();
 		
-		Class clazz = null;
+		Class clazz;
 		try {
 			clazz = Class.forName(className);
 		} catch (ClassNotFoundException e) {
@@ -44,7 +45,6 @@ public class TableMetaAdapter implements JsonSerializer<TableMeta>, JsonDeserial
 	@Override
 	public JsonElement serialize(TableMeta src, Type typeOfSrc,
 			JsonSerializationContext context) {
-		src.initFromProto();
 		JsonObject jsonObj = new JsonObject();
 		String className = src.getClass().getCanonicalName();
 		jsonObj.addProperty("classname", className);