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/07/02 16:16:42 UTC

[48/51] [partial] TAJO-22: The package prefix should be org.apache.tajo. (DaeMyung Kang via hyunsik)

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/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
new file mode 100644
index 0000000..6fbfa61
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Options.java
@@ -0,0 +1,180 @@
+/**
+ * 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;
+
+import com.google.common.collect.Maps;
+import com.google.gson.annotations.Expose;
+import org.apache.tajo.catalog.json.GsonCreator;
+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 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;
+	
+	@Expose private Map<String,String> keyVals;
+	
+	public Options() {
+		builder = KeyValueSetProto.newBuilder();
+	}
+	
+	public Options(KeyValueSetProto proto) {
+		this.proto = proto;
+		viaProto = true;
+	}
+	
+	public Options(Options options) {
+	  this();
+	  options.initFromProto();
+	  this.keyVals = Maps.newHashMap(options.keyVals);
+	}
+	
+	public static Options create() {
+	  return new Options();
+	}
+	
+	public static Options create(Options options) {
+    return new Options(options);
+  }
+	
+	public void put(String key, String val) {
+		initOptions();
+		setModified();
+		this.keyVals.put(key, val);
+	}
+	
+	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 {
+	    return defaultVal;
+	  }
+	}
+	
+	public Iterator<Entry<String,String>> getAllKeyValus() {
+	  initOptions();
+	  return keyVals.entrySet().iterator();
+	}
+	
+	public String delete(String key) {
+		initOptions();
+		return keyVals.remove(key);
+	}
+	
+	@Override
+	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;
+			}
+			return true;
+		}
+		
+		return false;
+	}
+	
+	@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;    
+    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());
+			}
+		}
+	}
+
+  @Override
+  public void initFromProto() {
+    initOptions();
+  }
+  
+  public String toJSON() {
+    initFromProto();
+    return GsonCreator.getInstance().toJson(this, Options.class);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/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
new file mode 100644
index 0000000..b6b33e9
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Schema.java
@@ -0,0 +1,253 @@
+/**
+ * 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;
+
+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.catalog.exception.AlreadyExistsFieldException;
+import org.apache.tajo.catalog.json.GsonCreator;
+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 {
+  private static final Log LOG = LogFactory.getLog(Schema.class);
+  
+	private SchemaProto proto = SchemaProto.getDefaultInstance();
+	private	SchemaProto.Builder builder = null;
+	boolean viaProto = false;
+
+	@Expose
+	protected List<Column> fields = null;
+	@Expose
+	protected Map<String,Integer> fieldsByName = null;
+
+	public Schema() {
+		builder = SchemaProto.newBuilder();
+	}
+	
+	public Schema(SchemaProto proto) {
+    this.proto = proto;
+    this.viaProto = true;
+  }
+
+	public Schema(Schema schema) {
+	  this();
+		this.fields = new ArrayList<Column>(schema.fields);
+		this.fieldsByName = new HashMap<String, Integer>(schema.fieldsByName);
+	}
+	
+	public Schema(Column [] columns) {
+    this();
+    for(Column c : columns) {
+      addColumn(c);
+    }
+  }
+	
+	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;
+	    }
+	  }
+	  return null;
+	}
+	
+	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());
+      }
+    }
+    return -1;
+  }
+	
+	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);
+			throw new AlreadyExistsFieldException(lowcased);
+		}
+			
+		Column newCol = new Column(lowcased, dataType);
+		fields.add(newCol);
+		fieldsByName.put(lowcased, fields.size() - 1);
+		
+		return this;
+	}
+	
+	public synchronized void addColumn(Column column) {
+		addColumn(column.getQualifiedName(), column.getDataType());		
+	}
+	
+	public synchronized void addColumns(Schema schema) {
+    for(Column column : schema.getColumns()) {
+      addColumn(column);
+    }
+  }
+
+	@Override
+	public boolean equals(Object o) {
+		if (o instanceof Schema) {
+		  Schema other = (Schema) o;
+		  return getProto().equals(other.getProto());
+		}
+		return false;
+	}
+	
+  @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;
+
+    return schema;
+  }
+
+	@Override
+	public SchemaProto getProto() {
+	  if(!viaProto) {
+      mergeLocalToBuilder();
+      proto = builder.build();
+      viaProto = true;
+    }
+	  
+		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());
+			}
+		}
+	}
+
+	public String toString() {
+	  initColumns();
+	  StringBuilder sb = new StringBuilder();
+	  sb.append("{");
+	  int i = 0;
+	  for(Column col : fields) {
+	    sb.append(col);
+	    if (i < fields.size() - 1) {
+	      sb.append(",");
+	    }
+	    i++;
+	  }
+	  sb.append("}");
+	  
+	  return sb.toString();
+	}
+	
+	public String toJson() {
+	  initFromProto();
+	  Gson gson = GsonCreator.getInstance();
+	  return gson.toJson(this, Schema.class);
+		
+	}
+
+  public Column [] toArray() {
+    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/bc6359b8/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/SchemaObject.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/SchemaObject.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/SchemaObject.java
new file mode 100644
index 0000000..0ce0fec
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/SchemaObject.java
@@ -0,0 +1,23 @@
+/**
+ * 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;
+
+public interface SchemaObject {
+	public Schema getSchema();
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/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
new file mode 100644
index 0000000..edf7a2b
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/SortSpec.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;
+
+import com.google.gson.annotations.Expose;
+import org.apache.tajo.catalog.json.GsonCreator;
+
+public class SortSpec implements Cloneable {
+  @Expose
+  private Column sortKey;
+  @Expose private boolean ascending = true;
+  @Expose private boolean nullFirst = false;
+
+  public SortSpec(final Column sortKey) {
+    this.sortKey = sortKey;
+  }
+
+  /**
+   *
+   * @param sortKey columns to sort
+   * @param asc true if the sort order is ascending order
+   * @param nullFirst
+   * Otherwise, it should be false.
+   */
+  public SortSpec(final Column sortKey, final boolean asc,
+                  final boolean nullFirst) {
+    this(sortKey);
+    this.ascending = asc;
+    this.nullFirst = nullFirst;
+  }
+
+  public final boolean isAscending() {
+    return this.ascending;
+  }
+
+  public final void setDescOrder() {
+    this.ascending = false;
+  }
+
+  public final boolean isNullFirst() {
+    return this.nullFirst;
+  }
+
+  public final void setNullFirst() {
+    this.nullFirst = true;
+  }
+
+  public final Column getSortKey() {
+    return this.sortKey;
+  }
+
+  @Override
+  public Object clone() throws CloneNotSupportedException {
+    SortSpec key = (SortSpec) super.clone();
+    key.sortKey = (Column) sortKey.clone();
+    key.ascending = ascending;
+
+    return key;
+  }
+
+  public String toJSON() {
+    sortKey.initFromProto();
+    return GsonCreator.getInstance().toJson(this);
+  }
+
+  public String toString() {
+    return "Sortkey (key="+sortKey
+        + " "+(ascending ? "asc" : "desc")+")";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/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
new file mode 100644
index 0000000..feeb0a8
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDesc.java
@@ -0,0 +1,44 @@
+/**
+ * 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;
+
+import com.google.protobuf.Message;
+import org.apache.hadoop.fs.Path;
+
+public interface TableDesc extends Cloneable {
+  void setId(String tableId);
+  
+  String getId();
+  
+  void setPath(Path path);
+  
+  Path getPath();
+  
+  void setMeta(TableMeta info);
+  
+  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/bc6359b8/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
new file mode 100644
index 0000000..b690ddf
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDescImpl.java
@@ -0,0 +1,214 @@
+/**
+ * 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;
+
+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.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();
+  protected TableDescProto.Builder builder = null;
+  protected boolean viaProto = false;
+  
+	@Expose protected String tableId;
+	@Expose protected Path uri;
+	@Expose protected TableMeta meta;
+  
+	public TableDescImpl() {
+		builder = TableDescProto.newBuilder();
+	}
+	
+	public TableDescImpl(String tableId, TableMeta info, Path path) {
+		this();
+		// tajo deems all identifiers as lowcase characters
+	  this.tableId = tableId.toLowerCase();
+	  this.meta = info;
+	  this.uri = path;	   
+	}
+	
+	public TableDescImpl(String tableId, Schema schema, StoreType type, 
+	    Options options, Path path) {
+	  this(tableId, new TableMetaImpl(schema, type, options), path);
+	}
+	
+	public TableDescImpl(TableDescProto proto) {
+	  this.proto = proto;
+	  viaProto = true;
+	}
+	
+	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;
+	}
+	
+  public Schema getSchema() {
+    return getMeta().getSchema();
+  }
+	
+	public boolean equals(Object object) {
+    if(object instanceof TableDescImpl) {
+      TableDescImpl other = (TableDescImpl) object;
+      
+      return this.getProto().equals(other.getProto());
+    }
+    
+    return false;   
+  }
+	
+	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();
+	  
+	  return desc;
+	}
+	
+	public String toString() {
+	  Gson gson = new GsonBuilder().setPrettyPrinting().
+	      excludeFieldsWithoutExposeAnnotation().create();
+    return gson.toJson(this);
+	}
+	
+	public String toJSON() {
+		initFromProto();
+		Gson gson = GsonCreator.getInstance();
+		
+		return gson.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);
+    }
+    
+    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();
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/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
new file mode 100644
index 0000000..268e70c
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableMeta.java
@@ -0,0 +1,54 @@
+/**
+ * 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;
+
+import org.apache.tajo.catalog.proto.CatalogProtos.StoreType;
+import org.apache.tajo.catalog.proto.CatalogProtos.TableProto;
+import org.apache.tajo.catalog.statistics.TableStat;
+import org.apache.tajo.common.ProtoObject;
+
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+public interface TableMeta extends ProtoObject<TableProto>, Cloneable {
+  
+  void setStorageType(StoreType storeType);
+  
+  StoreType getStoreType();
+  
+  void setSchema(Schema schema);
+  
+  Schema getSchema();
+  
+  void putOption(String key, String val);
+  
+  void setStat(TableStat stat);
+  
+  String getOption(String key);
+  
+  String getOption(String key, String defaultValue);
+  
+  Iterator<Entry<String,String>> getOptions();
+  
+  TableStat getStat();
+  
+  Object clone() throws CloneNotSupportedException;
+  
+  public String toJSON();
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/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
new file mode 100644
index 0000000..8f6b9b6
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableMetaImpl.java
@@ -0,0 +1,280 @@
+/**
+ * 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;
+
+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.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();
+	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;
+	
+	private TableMetaImpl() {
+	  builder = TableProto.newBuilder();
+	}
+	
+	public TableMetaImpl(Schema schema, StoreType type, Options options) {
+	  this();
+	  this.schema = schema;
+    this.storeType = type;
+    this.options = new Options(options);
+  }
+	
+	public TableMetaImpl(Schema schema, StoreType type, Options options,
+	    TableStat stat) {
+    this();
+    this.schema = schema;
+    this.storeType = type;
+    this.options = new Options(options);
+    this.stat = stat;
+  }
+	
+	public TableMetaImpl(TableProto proto) {
+		this.proto = proto;
+		this.viaProto = true;
+	}
+	
+	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);
+  }
+  
+
+  @Override
+  public String getOption(String key) {    
+    return initOptions().get(key);
+  }
+
+  @Override
+  public String getOption(String key, String defaultValue) {
+    return initOptions().get(key, defaultValue);
+  }
+  
+  @Override
+  public Iterator<Entry<String,String>> getOptions() {    
+    return initOptions().getAllKeyValus();
+  }
+	
+	public boolean equals(Object object) {
+		if(object instanceof TableMetaImpl) {
+			TableMetaImpl other = (TableMetaImpl) object;
+			
+			return this.getProto().equals(other.getProto());
+		}
+		
+		return false;		
+	}
+	
+	public int hashCode() {
+	  return Objects.hashCode(getSchema(), storeType);
+	}
+	
+	@Override
+	public Object clone() throws CloneNotSupportedException {    
+	  initFromProto();
+	  TableMetaImpl meta = (TableMetaImpl) super.clone();	  
+	  meta.proto = null;
+    meta.viaProto = false;
+    meta.builder = TableProto.newBuilder();
+    meta.schema = (Schema) schema.clone();
+    meta.storeType = storeType;
+    meta.stat = (TableStat) (stat != null ? stat.clone() : null);
+    meta.options = (Options) (options != null ? options.clone() : null);
+    
+    return meta;
+	}
+	
+	public String toString() {
+	  Gson gson = new GsonBuilder().setPrettyPrinting().
+        excludeFieldsWithoutExposeAnnotation().create();
+	  return gson.toJson(this);
+  }
+	
+	////////////////////////////////////////////////////////////////////////
+	// ProtoObject
+	////////////////////////////////////////////////////////////////////////
+	@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 (this.schema != null) {
+	    builder.setSchema(this.schema.getProto());
+	  }
+	  
+	  if (this.stat != null) {
+	    builder.setStat(this.stat.getProto());
+	  }
+
+	  if (this.storeType != null) {
+      builder.setStoreType(storeType);
+    }
+
+		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());
+		}
+	}
+	
+	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 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/bc6359b8/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableUtil.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableUtil.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableUtil.java
new file mode 100644
index 0000000..6325bd2
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableUtil.java
@@ -0,0 +1,51 @@
+/**
+ * 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;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataInputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.catalog.proto.CatalogProtos.TableProto;
+import org.apache.tajo.util.FileUtil;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+public class TableUtil {
+  public static TableMeta getTableMeta(Configuration conf, Path tablePath) 
+      throws IOException {
+    TableMetaImpl meta = null;
+    
+    FileSystem fs = tablePath.getFileSystem(conf);
+    
+    Path tableMetaPath = new Path(tablePath, ".meta");
+    if(!fs.exists(tableMetaPath)) {
+      throw new FileNotFoundException(".meta file not found in "+tablePath.toString());
+    }
+    FSDataInputStream tableMetaIn = 
+      fs.open(tableMetaPath);
+
+    TableProto tableProto = (TableProto) FileUtil.loadProto(tableMetaIn, 
+      TableProto.getDefaultInstance());
+    meta = new TableMetaImpl(tableProto);
+
+    return meta;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsFieldException.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsFieldException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsFieldException.java
new file mode 100644
index 0000000..ee90278
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsFieldException.java
@@ -0,0 +1,30 @@
+/**
+ * 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.exception;
+
+public class AlreadyExistsFieldException extends CatalogException {
+	private static final long serialVersionUID = 6766228091940775275L;
+
+	public AlreadyExistsFieldException() {
+	}
+
+	public AlreadyExistsFieldException(String fieldName) {
+		super("Already Exists Field: "+fieldName);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsFunctionException.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsFunctionException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsFunctionException.java
new file mode 100644
index 0000000..4bf70ae
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsFunctionException.java
@@ -0,0 +1,27 @@
+/**
+ * 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.exception;
+
+public class AlreadyExistsFunctionException extends CatalogException {
+	private static final long serialVersionUID = 3224521585413794703L;
+
+	public AlreadyExistsFunctionException(String funcName) {
+		super("Already Exists Function: "+funcName);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsIndexException.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsIndexException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsIndexException.java
new file mode 100644
index 0000000..a254514
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsIndexException.java
@@ -0,0 +1,51 @@
+/**
+ * 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.exception;
+
+public class AlreadyExistsIndexException extends CatalogException {
+  private static final long serialVersionUID = 3705839985189534673L;
+
+  /**
+   * 
+   */
+  public AlreadyExistsIndexException() {
+  }
+
+  /**
+   * @param message
+   */
+  public AlreadyExistsIndexException(String message) {
+    super(message);
+  }
+
+  /**
+   * @param cause
+   */
+  public AlreadyExistsIndexException(Throwable cause) {
+    super(cause);
+  }
+
+  /**
+   * @param message
+   * @param cause
+   */
+  public AlreadyExistsIndexException(String message, Throwable cause) {
+    super(message, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsTableException.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsTableException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsTableException.java
new file mode 100644
index 0000000..98c04b5
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/AlreadyExistsTableException.java
@@ -0,0 +1,31 @@
+/**
+ * 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.exception;
+
+
+public class AlreadyExistsTableException extends CatalogException {
+	private static final long serialVersionUID = -641623770742392865L;
+
+	public AlreadyExistsTableException() {		
+	}
+
+	public AlreadyExistsTableException(String tableName) {
+		super("Already Exists Table: "+tableName);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogException.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogException.java
new file mode 100644
index 0000000..760bb71
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/CatalogException.java
@@ -0,0 +1,51 @@
+/**
+ * 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.exception;
+
+public class CatalogException extends RuntimeException {
+  private static final long serialVersionUID = -26362412527118618L;
+
+  /**
+   * 
+   */
+  public CatalogException() {
+  }
+
+  /**
+   * @param message
+   */
+  public CatalogException(String message) {
+    super(message);
+  }
+
+  /**
+   * @param cause
+   */
+  public CatalogException(Throwable cause) {
+    super(cause);
+  }
+
+  /**
+   * @param message
+   * @param cause
+   */
+  public CatalogException(String message, Throwable cause) {
+    super(message, cause);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InvalidTableException.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InvalidTableException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InvalidTableException.java
new file mode 100644
index 0000000..c19888f
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InvalidTableException.java
@@ -0,0 +1,36 @@
+/**
+ * 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.exception;
+
+import org.apache.tajo.exception.InternalException;
+
+public class InvalidTableException extends InternalException {
+
+	private static final long serialVersionUID = -6326266814969872171L;
+
+	public InvalidTableException() {
+	}
+
+	/**
+	 * @param message
+	 */
+	public InvalidTableException(String message) {
+		super(message);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchFunctionException.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchFunctionException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchFunctionException.java
new file mode 100644
index 0000000..fba8d09
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchFunctionException.java
@@ -0,0 +1,29 @@
+/**
+ * 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.exception;
+
+public class NoSuchFunctionException extends RuntimeException {
+	private static final long serialVersionUID = 5062193018697228028L;
+
+	public NoSuchFunctionException() {}
+
+	public NoSuchFunctionException(String funcName) {
+		super("No Such GeneralFunction in Catalog: "+funcName);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchIndexException.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchIndexException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchIndexException.java
new file mode 100644
index 0000000..e22e8bc
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchIndexException.java
@@ -0,0 +1,51 @@
+/**
+ * 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.exception;
+
+public class NoSuchIndexException extends CatalogException {
+  private static final long serialVersionUID = 3705839985189534673L;
+
+  /**
+   * 
+   */
+  public NoSuchIndexException() {
+  }
+
+  /**
+   * @param message
+   */
+  public NoSuchIndexException(String message) {
+    super(message);
+  }
+
+  /**
+   * @param cause
+   */
+  public NoSuchIndexException(Throwable cause) {
+    super(cause);
+  }
+
+  /**
+   * @param message
+   * @param cause
+   */
+  public NoSuchIndexException(String message, Throwable cause) {
+    super(message, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchTableException.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchTableException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchTableException.java
new file mode 100644
index 0000000..bd399b9
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoSuchTableException.java
@@ -0,0 +1,30 @@
+/**
+ * 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.exception;
+
+
+public class NoSuchTableException extends CatalogException {
+	private static final long serialVersionUID = 277182608283894937L;
+
+	public NoSuchTableException() {}
+
+	public NoSuchTableException(String relName) {
+		super("No Such Relation in Catalog: "+relName);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/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
new file mode 100644
index 0000000..d76a345
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/AggFunction.java
@@ -0,0 +1,52 @@
+/**
+ * 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.function;
+
+import com.google.gson.Gson;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.catalog.json.GsonCreator;
+import org.apache.tajo.common.TajoDataTypes.DataType;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.storage.Tuple;
+
+public abstract class AggFunction<T extends Datum> extends Function<T> {
+
+  public AggFunction(Column[] definedArgs) {
+    super(definedArgs);
+  }
+
+  public abstract FunctionContext newContext();
+
+  public abstract void eval(FunctionContext ctx, Tuple params);
+
+  public void merge(FunctionContext ctx, Tuple part) {
+    eval(ctx, part);
+  }
+
+  public abstract Datum getPartialResult(FunctionContext ctx);
+
+  public abstract DataType [] getPartialResultType();
+
+  public abstract T terminate(FunctionContext ctx);
+
+  public String toJSON() {
+    Gson gson = GsonCreator.getInstance();
+    return gson.toJson(this, AggFunction.class);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/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
new file mode 100644
index 0000000..ff8bda0
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/Function.java
@@ -0,0 +1,62 @@
+/**
+ * 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.function;
+
+import com.google.common.base.Objects;
+import com.google.gson.Gson;
+import com.google.gson.annotations.Expose;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.catalog.json.GsonCreator;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.util.TUtil;
+
+public abstract class Function<T extends Datum> implements Cloneable {
+  @Expose protected Column[] definedParams;
+  public final static Column [] NoArgs = new Column [] {};
+
+  public Function(Column[] definedArgs) {
+    this.definedParams = definedArgs;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof Function) {
+      Function other = (Function) obj;
+      return TUtil.checkEquals(definedParams, other.definedParams);
+    } else {
+      return false;
+    }
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hashCode(definedParams);
+  }
+
+  public Object clone() throws CloneNotSupportedException {
+    Function func = (Function) super.clone();
+    func.definedParams = definedParams != null ? definedParams.clone() : null;
+    return func;
+  }
+
+  public String toJSON() {
+    Gson gson = GsonCreator.getInstance();
+    return gson.toJson(this, Function.class);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/FunctionContext.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/FunctionContext.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/FunctionContext.java
new file mode 100644
index 0000000..39f60dd
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/FunctionContext.java
@@ -0,0 +1,22 @@
+/**
+ * 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.function;
+
+public interface FunctionContext {
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/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
new file mode 100644
index 0000000..9a9cb86
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/function/GeneralFunction.java
@@ -0,0 +1,43 @@
+/**
+ * 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.function;
+
+import com.google.gson.Gson;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.catalog.json.GsonCreator;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.storage.Tuple;
+
+public abstract class GeneralFunction<T extends Datum> extends Function<T> {
+  public GeneralFunction(Column[] definedArgs) {
+    super(definedArgs);
+  }
+
+  public abstract Datum eval(Tuple params);
+
+	public enum Type {
+	  AGG,
+	  GENERAL
+	}
+
+  public String toJSON() {
+    Gson gson = GsonCreator.getInstance();
+    return gson.toJson(this, GeneralFunction.class);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/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
new file mode 100644
index 0000000..a5c03f6
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/FunctionAdapter.java
@@ -0,0 +1,54 @@
+/**
+ * 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.*;
+import org.apache.tajo.catalog.function.Function;
+
+import java.lang.reflect.Type;
+
+public class FunctionAdapter implements JsonDeserializer<Function>, JsonSerializer<Function> {
+
+  @Override
+  public JsonElement serialize(Function src, Type typeOfSrc,
+      JsonSerializationContext context) {
+    JsonObject jsonObj = new JsonObject();
+    String className = src.getClass().getCanonicalName();
+    jsonObj.addProperty("className", className);
+    JsonElement jsonElem = context.serialize(src);
+    jsonObj.add("property", jsonElem);
+    return jsonObj;
+  }
+
+  @Override
+  public Function deserialize(JsonElement json, Type typeOfT,
+      JsonDeserializationContext context) throws JsonParseException {
+    JsonObject jsonObject = json.getAsJsonObject();
+    String className = jsonObject.get("className").getAsJsonPrimitive().getAsString();
+    
+    Class clazz;
+    try {
+      clazz = Class.forName(className);
+    } catch (ClassNotFoundException e) {
+      e.printStackTrace();
+      throw new JsonParseException(e);
+    }
+    return context.deserialize(jsonObject.get("property"), clazz);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/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
new file mode 100644
index 0000000..9c56bcd
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/GsonCreator.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.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/bc6359b8/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
new file mode 100644
index 0000000..a5d6477
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/PathDeserializer.java
@@ -0,0 +1,37 @@
+/**
+ * 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/bc6359b8/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
new file mode 100644
index 0000000..e589195
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/PathSerializer.java
@@ -0,0 +1,37 @@
+/**
+ * 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/bc6359b8/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
new file mode 100644
index 0000000..8c63043
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/TableDescAdapter.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.catalog.json;
+
+import com.google.gson.*;
+import org.apache.tajo.catalog.TableDesc;
+
+import java.lang.reflect.Type;
+
+public class TableDescAdapter implements JsonSerializer<TableDesc>, JsonDeserializer<TableDesc> {
+
+	@Override
+	public TableDesc deserialize(JsonElement json, Type type,
+			JsonDeserializationContext ctx) throws JsonParseException {
+		JsonObject jsonObject = json.getAsJsonObject();
+		String className = jsonObject.get("classname").getAsJsonPrimitive().getAsString();
+		
+		Class clazz = null;
+		try {
+			clazz = Class.forName(className);
+		} catch (ClassNotFoundException e) {
+			e.printStackTrace();
+			throw new JsonParseException(e);
+		}
+		return ctx.deserialize(jsonObject.get("property"), clazz);
+	}
+
+	@Override
+	public JsonElement serialize(TableDesc src, Type typeOfSrc,
+			JsonSerializationContext context) {
+		JsonObject jsonObj = new JsonObject();
+		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/bc6359b8/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
new file mode 100644
index 0000000..9c50897
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/json/TableMetaAdapter.java
@@ -0,0 +1,56 @@
+/**
+ * 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.*;
+import org.apache.tajo.catalog.TableMeta;
+
+import java.lang.reflect.Type;
+
+public class TableMetaAdapter implements JsonSerializer<TableMeta>, JsonDeserializer<TableMeta> {
+
+	@Override
+	public TableMeta deserialize(JsonElement json, Type typeOfT,
+			JsonDeserializationContext context) throws JsonParseException {
+		JsonObject jsonObject = json.getAsJsonObject();
+		String className = jsonObject.get("classname").getAsJsonPrimitive().getAsString();
+		
+		Class clazz = null;
+		try {
+			clazz = Class.forName(className);
+		} catch (ClassNotFoundException e) {
+			e.printStackTrace();
+			throw new JsonParseException(e);
+		}
+		return context.deserialize(jsonObject.get("property"), clazz);
+	}
+
+	@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);
+		JsonElement jsonElem = context.serialize(src);
+		jsonObj.add("property", jsonElem);
+		return jsonObj;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/bc6359b8/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/statistics/ColumnStat.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/statistics/ColumnStat.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/statistics/ColumnStat.java
new file mode 100644
index 0000000..ccfae2b
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/statistics/ColumnStat.java
@@ -0,0 +1,246 @@
+/**
+ * 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.statistics;
+
+import com.google.common.base.Objects;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.annotations.Expose;
+import com.google.protobuf.ByteString;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.catalog.proto.CatalogProtos.ColumnStatProto;
+import org.apache.tajo.catalog.proto.CatalogProtos.ColumnStatProtoOrBuilder;
+import org.apache.tajo.common.ProtoObject;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.util.TUtil;
+
+public class ColumnStat implements ProtoObject<ColumnStatProto>, Cloneable {
+  private ColumnStatProto proto = ColumnStatProto.getDefaultInstance();
+  private ColumnStatProto.Builder builder = null;
+  private boolean viaProto = false;
+
+  @Expose private Column column = null;
+  @Expose private Long numDistVals = null;
+  @Expose private Long numNulls = null;
+  @Expose private Datum minValue = null;
+  @Expose private Datum maxValue = null;
+
+  public ColumnStat(Column column) {
+    builder = ColumnStatProto.newBuilder();
+    this.column = column;
+    numDistVals = 0l;
+    numNulls = 0l;
+  }
+
+  public ColumnStat(ColumnStatProto proto) {
+    this.proto = proto;
+    this.viaProto = true;
+  }
+
+  public Column getColumn() {
+    ColumnStatProtoOrBuilder p = viaProto ? proto : builder;
+    if (column != null) {
+      return column;
+    }
+    if (!p.hasColumn()) {
+      return null;
+    }
+    this.column = new Column(p.getColumn());
+
+    return this.column;
+  }
+
+  public Long getNumDistValues() {
+    ColumnStatProtoOrBuilder p = viaProto ? proto : builder;
+    if (numDistVals != null) {
+      return this.numDistVals;
+    }
+    if (!p.hasNumDistVal()) {
+      return null;
+    }
+    this.numDistVals = p.getNumDistVal();
+
+    return this.numDistVals;
+  }
+
+  public void setNumDistVals(long numDistVals) {
+    setModified();
+    this.numDistVals = numDistVals;
+  }
+
+  public boolean minIsNotSet() {
+    return minValue == null && (!proto.hasMinValue());
+  }
+
+  public Datum getMinValue() {
+    ColumnStatProtoOrBuilder p = viaProto ? proto : builder;
+    if (minValue != null) {
+      return this.minValue;
+    }
+    if (!p.hasMinValue()) {
+      return null;
+    }
+    this.minValue = TupleUtil.createFromBytes(getColumn().getDataType(), p.getMinValue().toByteArray());
+
+    return this.minValue;
+  }
+
+  public void setMinValue(Datum minValue) {
+    setModified();
+    this.minValue = minValue;
+  }
+
+  public boolean maxIsNotSet() {
+    return maxValue == null && (!proto.hasMaxValue());
+  }
+
+  public Datum getMaxValue() {
+    ColumnStatProtoOrBuilder p = viaProto ? proto : builder;
+    if (maxValue != null) {
+      return this.maxValue;
+    }
+    if (!p.hasMaxValue()) {
+      return null;
+    }
+    this.maxValue = TupleUtil.createFromBytes(getColumn().getDataType(), p.getMaxValue().toByteArray());
+
+    return this.maxValue;
+  }
+
+  public void setMaxValue(Datum maxValue) {
+    setModified();
+    this.maxValue = maxValue;
+  }
+
+  public Long getNumNulls() {
+    ColumnStatProtoOrBuilder p = viaProto ? proto : builder;
+    if (numNulls != null) {
+      return this.numNulls;
+    }
+    if (!p.hasNumNulls()) {
+      return null;
+    }
+    this.numNulls = p.getNumNulls();
+
+    return this.numNulls;
+  }
+
+  public void setNumNulls(long numNulls) {
+    setModified();
+    this.numNulls = numNulls;
+  }
+
+  private void setModified() {
+    if (viaProto && builder == null) {
+      builder = ColumnStatProto.newBuilder(proto);
+    }
+    viaProto = false;
+  }
+
+  public boolean equals(Object obj) {
+    if (obj instanceof ColumnStat) {
+      ColumnStat other = (ColumnStat) obj;
+      return getColumn().equals(other.getColumn())
+          && getNumDistValues().equals(other.getNumDistValues())
+          && getNumNulls().equals(other.getNumNulls())
+          && TUtil.checkEquals(getMinValue(), other.getMinValue())
+          && TUtil.checkEquals(getMaxValue(), other.getMaxValue());
+    } else {
+      return false;
+    }
+  }
+
+  public int hashCode() {
+    return Objects.hashCode(getNumDistValues(), getNumNulls());
+  }
+
+  public Object clone() throws CloneNotSupportedException {
+    ColumnStat stat = (ColumnStat) super.clone();
+    initFromProto();
+    stat.column = (Column) this.column.clone();
+    stat.numDistVals = numDistVals;
+    stat.numNulls = numNulls;
+    stat.minValue = minValue;
+    stat.maxValue = maxValue;
+
+    return stat;
+  }
+
+  public String toString() {
+    initFromProto();
+    Gson gson = new GsonBuilder().setPrettyPrinting().
+        excludeFieldsWithoutExposeAnnotation().create();
+    return gson.toJson(this);
+  }
+
+  @Override
+  public void initFromProto() {
+    ColumnStatProtoOrBuilder p = viaProto ? proto : builder;
+    if (this.column == null && p.hasColumn()) {
+      this.column = new Column(p.getColumn());
+    }
+    if (this.numDistVals == null && p.hasNumDistVal()) {
+      this.numDistVals = p.getNumDistVal();
+    }
+    if (this.numNulls == null && p.hasNumNulls()) {
+      this.numNulls = p.getNumNulls();
+    }
+    if (this.minValue == null && p.hasMinValue()) {
+      this.minValue = TupleUtil.createFromBytes(getColumn().getDataType(), p.getMinValue().toByteArray());
+    }
+    if (this.maxValue == null && p.hasMaxValue()) {
+      this.maxValue = TupleUtil.createFromBytes(getColumn().getDataType(), p.getMaxValue().toByteArray());
+    }
+  }
+
+  @Override
+  public ColumnStatProto getProto() {
+    if (!viaProto) {
+      mergeLocalToBuilder();
+      proto = builder.build();
+      viaProto = true;
+    }
+
+    return proto;
+  }
+
+  private void mergeLocalToBuilder() {
+    if (builder == null) {
+      builder = ColumnStatProto.newBuilder(proto);
+    }
+    if (this.column != null) {
+      builder.setColumn(this.column.getProto());
+    }
+    if (this.numDistVals != null) {
+      builder.setNumDistVal(this.numDistVals);
+    }
+    if (this.numNulls != null) {
+      builder.setNumNulls(this.numNulls);
+    }
+    if (this.minValue != null) {
+      builder.setMinValue(ByteString.copyFrom(this.minValue.asByteArray()));
+    }
+    if (this.maxValue != null) {
+      builder.setMaxValue(ByteString.copyFrom(this.maxValue.asByteArray()));
+    }
+  }
+}