tajo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hyun...@apache.org
Subject [43/51] [partial] TAJO-752: Escalate sub modules in tajo-core into the top-level modules. (hyunsik)
Date Fri, 18 Apr 2014 10:31:55 GMT
http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/FindInSet.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/FindInSet.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/FindInSet.java
new file mode 100644
index 0000000..0c3e221
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/FindInSet.java
@@ -0,0 +1,116 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * find_in_set(text,str_array) - Returns the first occurrence of str in str_array where str_array
+ * is a comma-delimited string.
+ *
+ * Returns null if either argument is null.
+ * Returns 0 if the first argument has any commas.
+ *
+ * Example:
+ * SELECT find_in_set('cr','crt,c,cr,c,def') FROM src LIMIT 1;\n"
+ * -> result: 3
+ */
+@Description(
+  functionName = "find_in_set",
+  description = "Returns the first occurrence of str in str_array where str_array is a comma-delimited string",
+  detail = "Returns null if either argument is null.\n"
+      + "Returns 0 if the first argument has any commas.",
+  example = "> SELECT find_in_set('cr','crt,c,cr,c,def');\n"
+          + "3",
+  returnType = TajoDataTypes.Type.INT4,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT, TajoDataTypes.Type.TEXT})}
+)
+public class FindInSet extends GeneralFunction {
+  public FindInSet() {
+    super(new Column[]{
+        new Column("string", TajoDataTypes.Type.TEXT),
+        new Column("str_array", TajoDataTypes.Type.TEXT)
+    });
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum finding = params.get(0);
+    Datum textArray = params.get(1);
+
+    if (finding instanceof NullDatum || textArray instanceof NullDatum) {
+      return NullDatum.get();
+    }
+
+    byte[] searchBytes = finding.asByteArray();
+
+    //  Returns 0 if the first argument has any commas.
+    for (int i = 0; i < finding.size(); i++) {
+      if (searchBytes[i] == ',') {
+        return DatumFactory.createInt4(0);
+      }
+    }
+
+    byte[] arrayData = textArray.asByteArray();
+    int findingLength = finding.size();
+
+    int posInTextArray = 0;
+    int curLengthOfCandidate = 0;
+    boolean matching = true;
+
+    for (int i = 0; i < textArray.size(); i++) {
+
+      if (arrayData[i] == ',') {
+        posInTextArray++;
+        if (matching && curLengthOfCandidate == findingLength) {
+          return DatumFactory.createInt4(posInTextArray);
+        } else {
+          matching = true;
+          curLengthOfCandidate = 0;
+        }
+      } else {
+        if (curLengthOfCandidate + 1 <= findingLength) {
+          if (!matching || searchBytes[curLengthOfCandidate] != arrayData[i]) {
+            matching = false;
+          }
+        } else {
+          matching = false;
+        }
+        curLengthOfCandidate++;
+      }
+
+    }
+
+    if (matching && curLengthOfCandidate == findingLength) {
+      posInTextArray++;
+      return DatumFactory.createInt4(posInTextArray);
+    } else {
+      return DatumFactory.createInt4(0);
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/HexStringConverter.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/HexStringConverter.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/HexStringConverter.java
new file mode 100644
index 0000000..3b33359
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/HexStringConverter.java
@@ -0,0 +1,65 @@
+/**
+ * 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.engine.function.string;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class HexStringConverter {
+  private static HexStringConverter hexStringConverter = null;
+
+  public static HexStringConverter getInstance() {
+    if (hexStringConverter==null)
+      hexStringConverter = new HexStringConverter();
+    return hexStringConverter;
+  }
+
+  private HexStringConverter() {
+  }
+
+  public String encodeHex(String str) {
+    StringBuffer buf = new StringBuffer();
+
+    for(int i=0; i<str.length(); i++) {
+      String tmp = Integer.toHexString(str.charAt(i));
+      if(tmp.length() == 1)
+        buf.append("0x0" + tmp);
+      else
+        buf.append("0x" + tmp);
+    }
+
+    return buf.toString();
+  }
+
+  public String decodeHex(String hexString) {
+    Pattern p = Pattern.compile("(0x([a-fA-F0-9]{2}([a-fA-F0-9]{2})?))");
+    Matcher m = p.matcher(hexString);
+
+    StringBuffer buf = new StringBuffer();
+    int hashCode = 0;
+    while( m.find() ) {
+      hashCode = Integer.decode("0x" + m.group(2));
+      m.appendReplacement(buf, new String( Character.toChars(hashCode)));
+    }
+
+    m.appendTail(buf);
+
+    return buf.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/InitCap.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/InitCap.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/InitCap.java
new file mode 100644
index 0000000..4347dbb
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/InitCap.java
@@ -0,0 +1,60 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.commons.lang.WordUtils;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text initcap(string text)
+ */
+@Description(
+  functionName = "initcap",
+  description = "Convert the first letter of each word to upper case "
+          + " and the rest to lower case..",
+  example = "> SELECT initcap('hi THOMAS');\n"
+          + "Hi Thomas",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT})}
+)
+public class InitCap extends GeneralFunction {
+  public InitCap() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT)
+    });
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    if(datum instanceof NullDatum) return NullDatum.get();
+
+    return DatumFactory.createText(WordUtils.capitalizeFully(datum.asChars()));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/LTrim.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/LTrim.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/LTrim.java
new file mode 100644
index 0000000..db6b714
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/LTrim.java
@@ -0,0 +1,77 @@
+/**
+ * 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.engine.function.string;
+
+import com.google.gson.annotations.Expose;
+import org.apache.commons.lang.StringUtils;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.eval.FunctionEval;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text ltrim(string text [, characters text])
+ */
+@Description(
+  functionName = "ltrim",
+  description = "Remove the longest string containing only "
+          + "characters from characters (a space by default) "
+          + "from the start of string.",
+  example = "> SELECT ltrim('zzzytrim', 'xyz');\n"
+          + "trim",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT}),
+          @ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT,TajoDataTypes.Type.TEXT})}
+)
+public class LTrim extends GeneralFunction {
+  @Expose private boolean hasTrimCharacters;
+
+  public LTrim() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT),
+        new Column("characters", TajoDataTypes.Type.TEXT),
+    });
+  }
+
+  public void init(FunctionEval.ParamType[] paramTypes) {
+    if (paramTypes.length == 2) {
+      hasTrimCharacters = true;
+    }
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    if(datum instanceof NullDatum) return NullDatum.get();
+
+    if (!hasTrimCharacters) {
+      return DatumFactory.createText(StringUtils.stripStart(datum.asChars(), null));
+    } else {
+      return DatumFactory.createText(StringUtils.stripStart(datum.asChars(), params.get(1).asChars()));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Left.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Left.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Left.java
new file mode 100644
index 0000000..31469f5
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Left.java
@@ -0,0 +1,84 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.datum.TextDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text left(string text, int size)
+ */
+@Description(
+  functionName = "left",
+  description = "First n characters in the string.",
+  example = "> SELECT left('ABC', 2);\n"
+          + "AB",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT,
+          TajoDataTypes.Type.INT4})}
+)
+public class Left extends GeneralFunction {
+  public Left() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT),
+        new Column("size", TajoDataTypes.Type.INT4)
+    });
+  }
+
+  public int getSize(int length, int size) {
+    if (size < 0) {
+        size = length + size;
+        if (size < 0) {
+            size = 0;
+        }
+    }
+
+    return (size < length) ? size : length;
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    if(datum instanceof NullDatum) return NullDatum.get();
+
+    Datum sizeDatum = params.get(1);
+    if(sizeDatum instanceof NullDatum) return NullDatum.get();
+
+    String data = datum.asChars();
+    int length = data.length();
+    int size = sizeDatum.asInt4();
+
+    size = getSize(length, size);
+    if (size == 0) {
+        return TextDatum.EMPTY_TEXT;
+    }
+
+    return DatumFactory.createText(data.substring(0, size));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Length.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Length.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Length.java
new file mode 100644
index 0000000..389f358
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Length.java
@@ -0,0 +1,61 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * INT4 length(string text)
+ */
+@Description(
+  functionName = "length",
+  description = "Number of characters in string.",
+  example = "> SELECT length('Tajo');\n"
+          + "4",
+  returnType = TajoDataTypes.Type.INT4,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT})}
+)
+public class Length  extends GeneralFunction {
+
+  public Length() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT)
+    });
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    if(datum instanceof NullDatum) {
+      return NullDatum.get();
+    }
+
+    return DatumFactory.createInt4(datum.asChars().length());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Locate.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Locate.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Locate.java
new file mode 100644
index 0000000..67ee389
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Locate.java
@@ -0,0 +1,106 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.engine.function.string;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition.
+ * 
+ * INT4 locate(string TEXT, substr TEXT, [, pos INT4])
+ */
+@Description(
+  functionName = "locate",
+  description = "Location of specified substring",
+  example = "> SELECT locate('high', 'ig')\n"
+          + "2",
+  returnType = TajoDataTypes.Type.INT4,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT, TajoDataTypes.Type.TEXT}),
+      @ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT, TajoDataTypes.Type.TEXT, TajoDataTypes.Type.INT4})
+  }
+)
+public class Locate extends GeneralFunction {
+  public Locate() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT),
+        new Column("substr", TajoDataTypes.Type.TEXT),
+        new Column("pos", TajoDataTypes.Type.INT4)
+    });
+  }
+  
+  /**
+   * Returns the position of the first occurance of substr in string after position pos (using one-based index).
+   * 
+   * if substr is empty string, it always matches except 
+   * pos is greater than string length + 1.(mysql locate() function spec.)
+   * At any not matched case, it returns 0.
+   */
+  private int locate(String str, String substr, int pos) {
+    if (substr.length() == 0) {
+      if (pos <= (str.length() + 1)) {
+        return pos;
+      }
+      else {
+        return 0;
+      }
+    }
+    int idx = StringUtils.indexOf(str, substr, pos - 1);
+    if (idx == -1) {
+      return 0;
+    }
+    return idx + 1;
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum strDatum = params.get(0);
+    if(strDatum instanceof NullDatum) {
+      return NullDatum.get();
+    }
+    Datum substrDatum = params.get(1);
+    if (substrDatum instanceof NullDatum) {
+      return NullDatum.get();
+    }
+    
+    int pos = 1;  // one-based index
+    if (params.size() > 2) {
+      pos = params.get(2).asInt4();
+      if (pos < 0) {
+        return DatumFactory.createInt4(0);  // negative value is not acceptable.
+      }
+      if (pos == 0) {
+        pos = 1;  // one-based index
+      }
+    }
+    
+    String str = strDatum.asChars();
+    String substr = substrDatum.asChars();
+    
+    return DatumFactory.createInt4(locate(str, substr, pos));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Lower.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Lower.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Lower.java
new file mode 100644
index 0000000..80c8192
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Lower.java
@@ -0,0 +1,58 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text lower(string text)
+ */
+@Description(
+  functionName = "lower",
+  description = "Convert string to lower case",
+  example = "> SELECT lower('ToM');\n"
+          + "tom",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT})}
+)
+public class Lower extends GeneralFunction {
+  public Lower() {
+    super(new Column[] {
+        new Column("text", TajoDataTypes.Type.TEXT)
+    });
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    if(datum instanceof NullDatum) return NullDatum.get();
+
+    return DatumFactory.createText(datum.asChars().toLowerCase());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Lpad.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Lpad.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Lpad.java
new file mode 100644
index 0000000..bc0031e
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Lpad.java
@@ -0,0 +1,90 @@
+/**
+ * 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.engine.function.string;
+
+import com.google.gson.annotations.Expose;
+import org.apache.commons.lang.StringUtils;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.eval.FunctionEval;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text lpad(string text, length int [, fill text])
+ */
+@Description(
+  functionName = "lpad",
+  description = "Fill up the string to length length by prepending the characters fill (a space by default)",
+  detail = "If the string is already longer than length then it is truncated (on the right)",
+  example = "> SELECT lpad('hi', 5, 'xy');\n"
+      + "xyxhi",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT, TajoDataTypes.Type.INT4}),
+                @ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT, TajoDataTypes.Type.INT4, TajoDataTypes.Type.TEXT})}
+)
+public class Lpad extends GeneralFunction {
+  @Expose private boolean hasFillCharacters;
+
+  public Lpad() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT),
+        new Column("length", TajoDataTypes.Type.INT4),
+        new Column("fill_text", TajoDataTypes.Type.TEXT)
+    });
+  }
+
+  public void init(FunctionEval.ParamType[] paramTypes) {
+    if (paramTypes.length == 3) {
+      hasFillCharacters = true;
+    }
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    Datum lengthDatum = params.get(1);
+
+    if (datum instanceof NullDatum) return NullDatum.get();
+    if (lengthDatum instanceof NullDatum) return NullDatum.get();
+
+    Datum fillText = NullDatum.get();
+
+    if (hasFillCharacters) {
+      fillText = params.get(2);
+    } else {
+      fillText = DatumFactory.createText(" ");
+    }
+
+    int templen = lengthDatum.asInt4() - datum.asChars().length();
+
+    if (templen <= 0) {
+      return DatumFactory.createText(datum.asChars().substring(0,lengthDatum.asInt4()));
+    } else {
+      return DatumFactory.createText(StringUtils.leftPad(datum.asChars(), lengthDatum.asInt4(), fillText.asChars()));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Md5.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Md5.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Md5.java
new file mode 100644
index 0000000..fb5f73c
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Md5.java
@@ -0,0 +1,65 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+import java.security.*;
+import org.apache.commons.codec.binary.Hex;
+
+/**
+ * Function definition
+ *
+ * text md5(string text)
+ */
+@Description(
+  functionName = "md5",
+  description = "Calculates the MD5 hash of string",
+  example = "> SELECT md5('abc');\n"
+          + "900150983cd24fb0 d6963f7d28e17f72",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT})}
+)
+public class Md5 extends GeneralFunction {
+  public Md5() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT)
+    });
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    if(datum instanceof NullDatum) return NullDatum.get();
+
+    try {
+        MessageDigest md = MessageDigest.getInstance("MD5");
+        return DatumFactory.createText(new String(Hex.encodeHex(md.digest(datum.asByteArray()))));
+    } catch (NoSuchAlgorithmException e){
+        return NullDatum.get();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/OctetLength.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/OctetLength.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/OctetLength.java
new file mode 100644
index 0000000..dc71907
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/OctetLength.java
@@ -0,0 +1,61 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * INT4 octet_length(string text)
+ */
+@Description(
+  functionName = "octet_length",
+  description = "Number of bytes in string. ",
+  example = "> SELECT octet_length('jose');\n"
+        + "4",
+  returnType = TajoDataTypes.Type.INT4,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT})}
+)
+public class OctetLength  extends GeneralFunction {
+
+  public OctetLength() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT)
+    });
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    if(datum instanceof NullDatum) {
+      return NullDatum.get();
+    }
+
+    return DatumFactory.createInt4(datum.asByteArray().length);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/QuoteIdent.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/QuoteIdent.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/QuoteIdent.java
new file mode 100644
index 0000000..d5237d7
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/QuoteIdent.java
@@ -0,0 +1,67 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text quote_ident(string text)
+ *
+ * Description:
+ * Return a quoted string.
+ */
+@Description(
+  functionName = "quote_ident",
+  description = "Return the given string suitably quoted to be used as an identifier in an SQL statement string",
+  detail = "Quotes are added only if necessary "
+        + "(i.e., if the string contains non-identifier characters or would be case-folded).\n"
+        + "Embedded quotes are properly doubled.",
+  example = "> SELECT quote_ident('Foo bar');\n"
+      + "\"Foo bar\"",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT})}
+)
+public class QuoteIdent extends GeneralFunction {
+  public QuoteIdent() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT)
+    });
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+
+    if(datum instanceof NullDatum) {
+      return NullDatum.get();
+    }
+
+    return DatumFactory.createText("\"" + datum.asChars() + "\"");
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/RTrim.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/RTrim.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/RTrim.java
new file mode 100644
index 0000000..9e3ff8d
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/RTrim.java
@@ -0,0 +1,76 @@
+/**
+ * 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.engine.function.string;
+
+import com.google.gson.annotations.Expose;
+import org.apache.commons.lang.StringUtils;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.eval.FunctionEval;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text rtrim(string text [, characters text])
+ */
+@Description(
+  functionName = "rtrim",
+  description = "Remove the longest string containing only "
+          + " characters from characters (a space by default) "
+          + " from the end of string.",
+  example = "> SELECT rtrim('trimxxxx', 'x');\n"
+          + "trim",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT}),
+          @ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT,TajoDataTypes.Type.TEXT})}
+)
+public class RTrim extends GeneralFunction {
+  @Expose private boolean hasTrimCharacters;
+
+  public RTrim() {
+    super(new Column[] {
+        new Column("text", TajoDataTypes.Type.TEXT),
+    });
+  }
+
+  public void init(FunctionEval.ParamType[] paramTypes) {
+    if (paramTypes.length == 2) {
+      hasTrimCharacters = true;
+    }
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    if(datum instanceof NullDatum) return NullDatum.get();
+
+    if (!hasTrimCharacters) {
+      return DatumFactory.createText(StringUtils.stripEnd(datum.asChars(), null));
+    } else {
+      return DatumFactory.createText(StringUtils.stripEnd(datum.asChars(), params.get(1).asChars()));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/RegexpReplace.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/RegexpReplace.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/RegexpReplace.java
new file mode 100644
index 0000000..2b59d34
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/RegexpReplace.java
@@ -0,0 +1,115 @@
+/**
+ * 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.engine.function.string;
+
+import com.google.gson.annotations.Expose;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.*;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static org.apache.tajo.engine.eval.FunctionEval.ParamType;
+
+/**
+ * This function is defined as:
+ * <pre>
+ * regexp_replace(string text, pattern text, replacement text [, flags text])
+ * </pre>
+ *
+ * flags is not supported yet.
+ */
+@Description(
+  functionName = "regexp_replace",
+  description = " Replace substring(s) matching a POSIX regular expression.",
+  example = "> SELECT regexp_replace('Thomas', '.[mN]a.', 'M');\n"
+          + "ThM",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT,
+          TajoDataTypes.Type.TEXT,TajoDataTypes.Type.TEXT})}
+)
+public class RegexpReplace extends GeneralFunction {
+  @Expose protected boolean isPatternConstant;
+
+  // transient variables
+  protected String pattern;
+  private boolean isAlwaysNull = false;
+  private BooleanDatum result;
+  protected Pattern compiled;
+
+  public RegexpReplace() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT),
+        new Column("pattern", TajoDataTypes.Type.TEXT),
+        new Column("replacement", TajoDataTypes.Type.INT4),
+        new Column("flags", TajoDataTypes.Type.INT4), // it is not supported yet.
+    });
+  }
+
+  public void init(ParamType [] paramTypes) {
+    if (paramTypes[0] == ParamType.NULL || paramTypes[1] == ParamType.NULL || paramTypes[2] == ParamType.NULL) {
+      isAlwaysNull = true;
+    } else if (paramTypes[1] == ParamType.CONSTANT) {
+      isPatternConstant = true;
+    }
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum thisValue = params.get(0);
+    Datum thisPattern = params.get(1);
+    Datum thisReplacement = params.get(2);
+    boolean nullResult = isAlwaysNull
+        || thisValue instanceof NullDatum
+        || thisReplacement instanceof NullDatum
+        || thisPattern instanceof NullDatum;
+
+    Pattern thisCompiled;
+    if (!nullResult) {
+      if (compiled != null) {
+        thisCompiled = compiled;
+      } else {
+        thisCompiled = Pattern.compile(thisPattern.asChars());
+
+        // if a regular expression pattern is a constant,
+        // it will be reused in every call
+        if (isPatternConstant) {
+          compiled = thisCompiled;
+        }
+      }
+
+      Matcher matcher = thisCompiled.matcher(thisValue.asChars());
+      String replacement = thisReplacement.asChars();
+      StringBuffer sb = new StringBuffer();
+      while (matcher.find()) {
+        matcher.appendReplacement(sb, replacement);
+      }
+      matcher.appendTail(sb);
+
+      return DatumFactory.createText(sb.toString());
+    } else {
+      return NullDatum.get();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Repeat.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Repeat.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Repeat.java
new file mode 100644
index 0000000..4c52a6e
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Repeat.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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text reverse(string text)
+ */
+@Description(
+  functionName = "repeat",
+  description = "Repeat string the specified number of times.",
+  example = "> SELECT repeat('Pg', 4);\n"
+          + "PgPgPgPg",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT,
+          TajoDataTypes.Type.INT4})}
+)
+public class Repeat extends GeneralFunction {
+  public Repeat() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT),
+        new Column("count", TajoDataTypes.Type.INT4)
+    });
+  }
+
+  private String repeat(String word, int count) {
+    StringBuilder builder = new StringBuilder();
+    for (int i = 0; i < count; i++) {
+        builder.append(word);
+    } 
+
+    return builder.toString();
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    if(datum instanceof NullDatum) return NullDatum.get();
+
+    Datum countDatum = params.get(1);
+    if(countDatum instanceof NullDatum) return NullDatum.get();
+
+    return DatumFactory.createText(repeat(datum.asChars(), countDatum.asInt4()));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Reverse.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Reverse.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Reverse.java
new file mode 100644
index 0000000..a77ba69
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Reverse.java
@@ -0,0 +1,58 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text reverse(string text)
+ */
+@Description(
+  functionName = "reverse",
+  description = "Reverse str",
+  example = "> SELECT reverse('TAJO');\n"
+          + "OJAT",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT})}
+)
+public class Reverse extends GeneralFunction {
+  public Reverse() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT)
+    });
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    if(datum instanceof NullDatum) return NullDatum.get();
+
+    return DatumFactory.createText(new StringBuffer(datum.asChars()).reverse().toString());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Right.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Right.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Right.java
new file mode 100644
index 0000000..aa0dad0
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Right.java
@@ -0,0 +1,85 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.datum.TextDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text right(string text, int size)
+ */
+@Description(
+  functionName = "right",
+  description = "Last n characters in the string",
+  example = "> SELECT right('ABC', 2);\n"
+          + "BC",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT,
+          TajoDataTypes.Type.INT4})}
+)
+public class Right extends GeneralFunction {
+  public Right() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT),
+        new Column("size", TajoDataTypes.Type.INT4)
+    });
+  }
+
+  public int getSize(int length, int size) {
+    if (size < 0) {
+        size = length + size;
+        if (size < 0) {
+            size = 0;
+        }
+    }
+
+    return (size < length) ? size : length;
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    if(datum instanceof NullDatum) return NullDatum.get();
+
+    Datum sizeDatum = params.get(1);
+    if(sizeDatum instanceof NullDatum) return NullDatum.get();
+
+    String data = datum.asChars();
+    int length = data.length();
+    int size = sizeDatum.asInt4();
+
+    size = getSize(length, size);
+    if (size == 0) {
+        return TextDatum.EMPTY_TEXT;
+    }
+
+    int startIdx = length - size;
+    return DatumFactory.createText(data.substring(startIdx, length));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Rpad.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Rpad.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Rpad.java
new file mode 100644
index 0000000..225777b
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Rpad.java
@@ -0,0 +1,90 @@
+/**
+ * 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.engine.function.string;
+
+import com.google.gson.annotations.Expose;
+import org.apache.commons.lang.StringUtils;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.eval.FunctionEval;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+
+/**
+ * Function definition
+ *
+ * text rpad(string text, length int [, fill text])
+ */
+@Description(
+  functionName = "rpad",
+  description = "Fill up the string to length length by appending the characters fill (a space by default)",
+  detail = "If the string is already longer than length then it is truncated.",
+  example = "> SELECT rpad('hi', 5, 'xy');\n"
+      + "hixyx",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT, TajoDataTypes.Type.INT4}),
+                @ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT, TajoDataTypes.Type.INT4, TajoDataTypes.Type.TEXT})}
+)
+public class Rpad extends GeneralFunction {
+  @Expose private boolean hasFillCharacters;
+
+  public Rpad() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT),
+        new Column("length", TajoDataTypes.Type.INT4),
+        new Column("fill_text", TajoDataTypes.Type.TEXT)
+    });
+  }
+
+  public void init(FunctionEval.ParamType[] paramTypes) {
+    if (paramTypes.length == 3) {
+      hasFillCharacters = true;
+    }
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    Datum lengthDatum = params.get(1);
+
+    if(datum instanceof NullDatum) return NullDatum.get();
+    if(lengthDatum instanceof NullDatum) return NullDatum.get();
+
+    Datum fillText=NullDatum.get();
+    if(hasFillCharacters) {
+      fillText=params.get(2);
+    }
+    else {
+      fillText=DatumFactory.createText(" ");
+    }
+
+    int templen = lengthDatum.asInt4() - datum.asChars().length();
+
+    if(templen<=0)
+      return DatumFactory.createText(datum.asChars().substring(0,lengthDatum.asInt4()));
+
+    return DatumFactory.createText(StringUtils.rightPad(datum.asChars(), lengthDatum.asInt4(), fillText.asChars()));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/SplitPart.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/SplitPart.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/SplitPart.java
new file mode 100644
index 0000000..fd1de55
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/SplitPart.java
@@ -0,0 +1,73 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text split_part(string text, delimiter text, field int)
+ */
+@Description(
+  functionName = "split_part",
+  description = "Split string on delimiter and return the given field",
+  example = "> SELECT split_part('abc~@~def~@~ghi', '~@~', 2);\n"
+          + "def",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT,
+          TajoDataTypes.Type.TEXT,TajoDataTypes.Type.INT4})}
+)
+public class SplitPart extends GeneralFunction {
+  public SplitPart() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT),
+        new Column("delimiter", TajoDataTypes.Type.TEXT),
+        new Column("field", TajoDataTypes.Type.INT4),
+    });
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum text = params.get(0);
+    Datum part = params.get(2);
+
+    if (text.isNull() || part.isNull()) {
+      return NullDatum.get();
+    }
+
+    String [] split = StringUtils.splitByWholeSeparatorPreserveAllTokens(text.asChars(), params.get(1).asChars(), -1);
+    int idx = params.get(2).asInt4() - 1;
+    if (split.length > idx) {
+      return DatumFactory.createText(split[idx]);
+    } else {
+      // If part is larger than the number of string portions, it will returns NULL.
+      return NullDatum.get();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/StrPos.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/StrPos.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/StrPos.java
new file mode 100644
index 0000000..d6f88de
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/StrPos.java
@@ -0,0 +1,73 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * int strpos(string text, substring text))
+ */
+@Description(
+  functionName = "strpos",
+  description = "Location of specified substring.",
+  example = "> SELECT strpos('tajo', 'aj');\n"
+          + "2",
+  returnType = TajoDataTypes.Type.INT4,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT,
+          TajoDataTypes.Type.TEXT})}
+)
+public class StrPos extends GeneralFunction {
+  public StrPos() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT),
+        new Column("substring", TajoDataTypes.Type.TEXT)
+    });
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum valueDatum = params.get(0);
+    if(valueDatum instanceof NullDatum) {
+      return NullDatum.get();
+    }
+
+    Datum substringDatum = params.get(1);
+    if(substringDatum instanceof NullDatum) {
+      return NullDatum.get();
+    }
+
+    String value = valueDatum.asChars();
+    String substring = substringDatum.asChars();
+    if(substring.length() == 0) {
+      return DatumFactory.createInt4(1);
+    }
+
+    return DatumFactory.createInt4(value.indexOf(substring) + 1);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/StrPosb.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/StrPosb.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/StrPosb.java
new file mode 100644
index 0000000..56fb3a1
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/StrPosb.java
@@ -0,0 +1,120 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Function definition
+ *
+ * int strposb(string text, substring text))
+ */
+@Description(
+  functionName = "strposb",
+  description = "Binary location of specified substring.",
+  example = "> SELECT strpos('tajo', 'aj');\n"
+      + "2",
+  returnType = TajoDataTypes.Type.INT4,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT,
+          TajoDataTypes.Type.TEXT})}
+)
+public class StrPosb extends GeneralFunction {
+  public StrPosb() {
+    super(new Column[] {
+        new Column("text", TajoDataTypes.Type.TEXT),
+        new Column("substring", TajoDataTypes.Type.TEXT)
+    });
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum valueDatum = params.get(0);
+    if(valueDatum instanceof NullDatum) {
+      return NullDatum.get();
+    }
+
+    Datum substringDatum = params.get(1);
+    if(substringDatum instanceof NullDatum) {
+      return NullDatum.get();
+    }
+
+    String value = valueDatum.asChars();
+    String substring = substringDatum.asChars();
+    if(substring.length() == 0) {
+      return DatumFactory.createInt4(1);
+    }
+
+    return DatumFactory.createInt4(findText(value, substring) + 1);
+  }
+
+  /**
+   * finds the location of specified substring.
+   * @param value
+   * @param substring
+   * @return
+   */
+  public static int findText(String value, String substring) {
+    //This method is copied from Hive's GenericUDFUtils.findText()
+    int start = 0;
+    byte[] valueBytes = value.getBytes();
+    byte[] substrBytes = substring.getBytes();
+
+    ByteBuffer src = ByteBuffer.wrap(valueBytes, 0, valueBytes.length);
+    ByteBuffer tgt = ByteBuffer.wrap(substrBytes, 0, substrBytes.length);
+    byte b = tgt.get();
+    src.position(start);
+
+    while (src.hasRemaining()) {
+      if (b == src.get()) { // matching first byte
+        src.mark(); // save position in loop
+        tgt.mark(); // save position in target
+        boolean found = true;
+        int pos = src.position() - 1;
+        while (tgt.hasRemaining()) {
+          if (!src.hasRemaining()) { // src expired first
+            tgt.reset();
+            src.reset();
+            found = false;
+            break;
+          }
+          if (!(tgt.get() == src.get())) {
+            tgt.reset();
+            src.reset();
+            found = false;
+            break; // no match
+          }
+        }
+        if (found) {
+          return pos;
+        }
+      }
+    }
+    return -1; // not found
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Substr.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Substr.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Substr.java
new file mode 100644
index 0000000..74492b1
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Substr.java
@@ -0,0 +1,94 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text substr(string text, from int4 [, length int4])
+ */
+@Description(
+  functionName = "substr",
+  description = "Extract substring.",
+  example = "> SELECT substr('alphabet', 3, 2);\n"
+          + "ph",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {
+    @ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT,TajoDataTypes.Type.INT4}),
+    @ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT,TajoDataTypes.Type.INT4,
+                              TajoDataTypes.Type.INT4})
+  } 
+)
+public class Substr extends GeneralFunction {
+  public Substr() {
+    super(new Column[] {
+        new Column("text", TajoDataTypes.Type.TEXT),
+        new Column("from", TajoDataTypes.Type.INT4),
+        new Column("length", TajoDataTypes.Type.INT4)    //optional
+    });
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum valueDatum = params.get(0);
+    Datum fromDatum = params.get(1);
+    Datum countDatum = params.size() > 2 ? params.get(2) : null;
+
+    if(valueDatum instanceof NullDatum || fromDatum instanceof NullDatum || countDatum instanceof NullDatum) {
+      return NullDatum.get();
+    }
+
+    String value = valueDatum.asChars();
+    int from = fromDatum.asInt4();
+    int strLength = value.length();
+    int count;
+
+    if (countDatum == null) {
+      count = strLength;
+    } else {
+      count = (countDatum.asInt4() + from) - 1;
+    }
+
+    if (count > strLength) {
+      count = strLength;
+    }
+
+    if (from < 1) {
+      from = 0;
+    } else {
+      from --;
+    }
+
+    if (from >= count) {
+      return DatumFactory.createText("");
+    }
+
+    return DatumFactory.createText(value.substring(from, count));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/ToBin.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/ToBin.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/ToBin.java
new file mode 100644
index 0000000..3048aa8
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/ToBin.java
@@ -0,0 +1,65 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+
+/**
+ * Function definition
+ * text ToBin(int n) - returns n in binary
+ *   Example:
+ *   SELECT Tobin(22) FROM src LIMIT 1;
+ *   -> result: '10110'
+ */
+@Description(
+  functionName = "to_bin",
+  description = "Returns n in binary.",
+  example = "> SELECT to_bin(22);\n"
+      + "10110",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.INT8}),
+      @ParamTypes(paramTypes = {TajoDataTypes.Type.INT4})}
+)
+public class ToBin extends GeneralFunction {
+
+  public ToBin() {
+    super(new Column[] {
+        new Column("n", TajoDataTypes.Type.INT8)
+    });
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    if(datum instanceof NullDatum) {
+      return NullDatum.get();
+    }
+
+    return  DatumFactory.createText(Long.toBinaryString(datum.asInt8()));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/ToHex.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/ToHex.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/ToHex.java
new file mode 100644
index 0000000..a8624ab
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/ToHex.java
@@ -0,0 +1,76 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.commons.codec.binary.Hex;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text to_hex(text)
+ * text to_hex(int)
+ */
+@Description(
+  functionName = "to_hex",
+  description = "Convert the argument to hexadecimal",
+  example = "SELECT to_hex(15);\n"
+          + "F",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.INT4}),
+          @ParamTypes(paramTypes = {TajoDataTypes.Type.INT8})}
+)
+public class ToHex extends GeneralFunction {
+
+  public ToHex() {
+    super(new Column[] {
+        new Column("n", TajoDataTypes.Type.INT8)
+    });
+  }
+
+  public String trimZero(String hexString) {
+    int len = hexString.length();
+    for (int i = 0; i < len; i++) {
+        if (hexString.charAt(i) != '0') {
+            return hexString.substring(i);
+        }
+    }
+
+    return hexString;
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    if(datum instanceof NullDatum) {
+      return NullDatum.get();
+    }
+
+    String ret = new String(Hex.encodeHex(datum.asByteArray()));
+    return DatumFactory.createText(trimZero(ret));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Upper.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Upper.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Upper.java
new file mode 100644
index 0000000..47d38ba
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/string/Upper.java
@@ -0,0 +1,58 @@
+/**
+ * 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.engine.function.string;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.function.annotation.Description;
+import org.apache.tajo.engine.function.annotation.ParamTypes;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text upper(string text)
+ */
+@Description(
+  functionName = "upper",
+  description = "Convert string to upper case.",
+  example = "> SELECT upper('tajo');\n"
+          + "TAJO",
+  returnType = TajoDataTypes.Type.TEXT,
+  paramTypes = {@ParamTypes(paramTypes = {TajoDataTypes.Type.TEXT})}
+)
+public class Upper extends GeneralFunction {
+  public Upper() {
+    super(new Column[] {
+        new Column("string", TajoDataTypes.Type.TEXT)
+    });
+  }
+
+  @Override
+  public Datum eval(Tuple params) {
+    Datum datum = params.get(0);
+    if(datum instanceof NullDatum) return NullDatum.get();
+
+    return DatumFactory.createText(datum.asChars().toUpperCase());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/json/CoreGsonHelper.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/json/CoreGsonHelper.java b/tajo-core/src/main/java/org/apache/tajo/engine/json/CoreGsonHelper.java
new file mode 100644
index 0000000..4dfb314
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/json/CoreGsonHelper.java
@@ -0,0 +1,90 @@
+/**
+ * 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.engine.json;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.catalog.TableMeta;
+import org.apache.tajo.catalog.function.Function;
+import org.apache.tajo.catalog.json.FunctionAdapter;
+import org.apache.tajo.catalog.json.TableMetaAdapter;
+import org.apache.tajo.common.TajoDataTypes.DataType;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.engine.eval.EvalNode;
+import org.apache.tajo.engine.function.AggFunction;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.engine.planner.logical.LogicalNode;
+import org.apache.tajo.json.*;
+import org.apache.tajo.util.TUtil;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+
+public class CoreGsonHelper {
+  private static Gson gson;
+  private static Gson gsonPretty;
+
+  private CoreGsonHelper() {
+  }
+	
+	private static Map<Type, GsonSerDerAdapter> registerAdapters() {
+    Map<Type, GsonSerDerAdapter> adapters = TUtil.newHashMap();
+    adapters.put(Path.class, new PathSerializer());
+    adapters.put(Class.class, new ClassNameSerializer());
+    adapters.put(LogicalNode.class, new LogicalNodeAdapter());
+    adapters.put(EvalNode.class, new EvalNodeAdapter());
+    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/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/json/EvalNodeAdapter.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/json/EvalNodeAdapter.java b/tajo-core/src/main/java/org/apache/tajo/engine/json/EvalNodeAdapter.java
new file mode 100644
index 0000000..69b906f
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/json/EvalNodeAdapter.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.engine.json;
+
+import com.google.gson.*;
+import org.apache.tajo.engine.eval.EvalNode;
+import org.apache.tajo.engine.eval.EvalType;
+import org.apache.tajo.engine.planner.logical.NodeType;
+import org.apache.tajo.json.GsonSerDerAdapter;
+
+import java.lang.reflect.Type;
+
+public class EvalNodeAdapter implements GsonSerDerAdapter<EvalNode> {
+
+  @Override
+  public EvalNode deserialize(JsonElement json, Type type,
+                              JsonDeserializationContext ctx) throws JsonParseException {
+    JsonObject jsonObject = json.getAsJsonObject();
+    String nodeName = jsonObject.get("type").getAsString();
+    Class clazz = EvalType.valueOf(nodeName).getBaseClass();
+    return ctx.deserialize(jsonObject.get("body"), clazz);
+  }
+
+  @Override
+  public JsonElement serialize(EvalNode evalNode, Type type,
+                               JsonSerializationContext ctx) {
+    JsonObject json = new JsonObject();
+    json.addProperty("type", evalNode.getType().name());
+    json.add("body", ctx.serialize(evalNode));
+    return json;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/026368be/tajo-core/src/main/java/org/apache/tajo/engine/json/LogicalNodeAdapter.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/json/LogicalNodeAdapter.java b/tajo-core/src/main/java/org/apache/tajo/engine/json/LogicalNodeAdapter.java
new file mode 100644
index 0000000..e2becef
--- /dev/null
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/json/LogicalNodeAdapter.java
@@ -0,0 +1,50 @@
+/**
+ * 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.engine.json;
+
+import com.google.gson.*;
+import org.apache.tajo.engine.planner.logical.LogicalNode;
+import org.apache.tajo.engine.planner.logical.NodeType;
+import org.apache.tajo.json.GsonSerDerAdapter;
+
+import java.lang.reflect.Type;
+
+public class LogicalNodeAdapter implements GsonSerDerAdapter<LogicalNode> {
+
+  @Override
+  public LogicalNode deserialize(JsonElement src, Type type,
+                                 JsonDeserializationContext ctx) throws JsonParseException {
+    JsonObject jsonObject = src.getAsJsonObject();
+    String nodeName = jsonObject.get("type").getAsString();
+    Class clazz = NodeType.valueOf(nodeName).getBaseClass();
+    return ctx.deserialize(jsonObject.get("body"), clazz);
+  }
+
+  @Override
+  public JsonElement serialize(LogicalNode src, Type typeOfSrc,
+                               JsonSerializationContext context) {
+    JsonObject json = new JsonObject();
+    json.addProperty("type", src.getType().name());
+    json.add("body", context.serialize(src));
+    return json;
+  }
+}


Mime
View raw message