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/12/02 09:24:43 UTC

git commit: TAJO-352: Implement right/left(text, size) function. (DaeMyung Kang via hyunsik)

Updated Branches:
  refs/heads/master 528c914f9 -> 43ec04aaa


TAJO-352: Implement right/left(text, size) function. (DaeMyung Kang via hyunsik)


Project: http://git-wip-us.apache.org/repos/asf/incubator-tajo/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tajo/commit/43ec04aa
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tajo/tree/43ec04aa
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tajo/diff/43ec04aa

Branch: refs/heads/master
Commit: 43ec04aaa34ffe5c5da2cfd05ff919ffac44044b
Parents: 528c914
Author: Hyunsik Choi <hy...@apache.org>
Authored: Mon Dec 2 17:23:50 2013 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Mon Dec 2 17:24:29 2013 +0900

----------------------------------------------------------------------
 CHANGES.txt                                     |  6 +-
 .../java/org/apache/tajo/datum/TextDatum.java   |  2 +
 .../org/apache/tajo/engine/parser/SQLParser.g4  | 12 +++-
 .../tajo/engine/function/string/Left.java       | 73 +++++++++++++++++++
 .../tajo/engine/function/string/Right.java      | 74 ++++++++++++++++++++
 .../apache/tajo/engine/parser/SQLAnalyzer.java  |  2 +-
 .../java/org/apache/tajo/master/TajoMaster.java |  8 +++
 .../TestStringOperatorsAndFunctions.java        | 56 +++++++++++++++
 8 files changed, 230 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/43ec04aa/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 1646d4c..0ad8c3c 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,6 +4,9 @@ Release 0.8.0 - unreleased
 
   NEW FEATURES
 
+    TAJO-352: Implement right/left(text, size) function. 
+    (DaeMyung Kang via hyunsik)
+
     TAJO-346: Implement hex function. (DaeMyung Kang via hyunsik)
 
     TAJO-349: Implement md5(text). (DaeMyung Kang via hyunsik)
@@ -34,7 +37,8 @@ Release 0.8.0 - unreleased
 
   IMPROVEMENTS
 
-    TAJO-317: Improve TajoResourceManager to support more elaborate resource management. (Keuntae Park via jihoon)
+    TAJO-317: Improve TajoResourceManager to support more elaborate resource 
+    management. (Keuntae Park via jihoon)
 
     TAJO-314: Make TaskScheduler be pluggable. (jihoon)
 

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/43ec04aa/tajo-common/src/main/java/org/apache/tajo/datum/TextDatum.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/TextDatum.java b/tajo-common/src/main/java/org/apache/tajo/datum/TextDatum.java
index 779d5ea..a7234b7 100644
--- a/tajo-common/src/main/java/org/apache/tajo/datum/TextDatum.java
+++ b/tajo-common/src/main/java/org/apache/tajo/datum/TextDatum.java
@@ -30,6 +30,8 @@ public class TextDatum extends Datum {
   @Expose private int size;
   @Expose private byte [] bytes;
 
+  public static final TextDatum EMPTY_TEXT = new TextDatum("");
+
   public TextDatum() {
     super(TajoDataTypes.Type.TEXT);
   }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/43ec04aa/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
index b071b82..2cc415f 100644
--- a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
+++ b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
@@ -1050,7 +1050,17 @@ unique_predicate
 */
 
 routine_invocation
-  : Identifier LEFT_PAREN sql_argument_list? RIGHT_PAREN
+  : function_name LEFT_PAREN sql_argument_list? RIGHT_PAREN
+  ;
+
+function_names_for_reserved_words
+  : LEFT
+  | RIGHT
+  ;
+
+function_name
+  : Identifier
+  | function_names_for_reserved_words
   ;
 
 sql_argument_list

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/43ec04aa/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/function/string/Left.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/function/string/Left.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/function/string/Left.java
new file mode 100644
index 0000000..3d25cd8
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/function/string/Left.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.datum.TextDatum;
+import org.apache.tajo.engine.function.GeneralFunction;
+import org.apache.tajo.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text left(string text, int size)
+ */
+public class Left extends GeneralFunction {
+  public Left() {
+    super(new Column[] {
+        new Column("text", 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/incubator-tajo/blob/43ec04aa/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/function/string/Right.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/function/string/Right.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/function/string/Right.java
new file mode 100644
index 0000000..43421fd
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/function/string/Right.java
@@ -0,0 +1,74 @@
+/**
+ * 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.storage.Tuple;
+
+/**
+ * Function definition
+ *
+ * text right(string text, int size)
+ */
+public class Right extends GeneralFunction {
+  public Right() {
+    super(new Column[] {
+        new Column("text", 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/incubator-tajo/blob/43ec04aa/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
index 48d5858..04980f7 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
@@ -769,7 +769,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
 
   @Override
   public FunctionExpr visitRoutine_invocation(SQLParser.Routine_invocationContext ctx) {
-    String signature = ctx.Identifier().getText();
+    String signature = ctx.function_name().getText();
     FunctionExpr function = new FunctionExpr(signature);
     if (ctx.sql_argument_list() != null) {
       int numArgs = ctx.sql_argument_list().value_expression().size();

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/43ec04aa/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/TajoMaster.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/TajoMaster.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/TajoMaster.java
index a3a85c4..2fe4213 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/TajoMaster.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/TajoMaster.java
@@ -345,6 +345,14 @@ public class TajoMaster extends CompositeService {
             CatalogUtil.newSimpleDataTypeArray(Type.TEXT)));
 
     sqlFuncs.add(
+        new FunctionDesc("left", Left.class, FunctionType.GENERAL,
+            CatalogUtil.newSimpleDataType(Type.TEXT),
+            CatalogUtil.newSimpleDataTypeArray(Type.TEXT, Type.INT4)));
+    sqlFuncs.add(
+        new FunctionDesc("right", Right.class, FunctionType.GENERAL,
+            CatalogUtil.newSimpleDataType(Type.TEXT),
+            CatalogUtil.newSimpleDataTypeArray(Type.TEXT, Type.INT4)));
+    sqlFuncs.add(
         new FunctionDesc("to_hex", ToHex.class, FunctionType.GENERAL,
             CatalogUtil.newSimpleDataType(Type.TEXT),
             CatalogUtil.newSimpleDataTypeArray(Type.INT4)));

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/43ec04aa/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/function/TestStringOperatorsAndFunctions.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/function/TestStringOperatorsAndFunctions.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/function/TestStringOperatorsAndFunctions.java
index 221249a..c62c494 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/function/TestStringOperatorsAndFunctions.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/function/TestStringOperatorsAndFunctions.java
@@ -150,6 +150,62 @@ public class TestStringOperatorsAndFunctions extends ExprTestBase {
   }
 
   @Test
+  public void testLeft() throws IOException {
+    testSimpleEval("select left('abcdef',1) as col1 ", new String[]{"a"});
+    testSimpleEval("select left('abcdef',2) as col1 ", new String[]{"ab"});
+    testSimpleEval("select left('abcdef',3) as col1 ", new String[]{"abc"});
+    testSimpleEval("select left('abcdef',4) as col1 ", new String[]{"abcd"});
+    testSimpleEval("select left('abcdef',5) as col1 ", new String[]{"abcde"});
+    testSimpleEval("select left('abcdef',6) as col1 ", new String[]{"abcdef"});
+    testSimpleEval("select left('abcdef',7) as col1 ", new String[]{"abcdef"});
+//    testSimpleEval("select from_left('abcdef',-1) as col1 ", new String[]{"abcde"});
+//    testSimpleEval("select from_left('abcdef',-2) as col1 ", new String[]{"abcd"});
+//    testSimpleEval("select from_left('abcdef',-3) as col1 ", new String[]{"abc"});
+//    testSimpleEval("select from_left('abcdef',-4) as col1 ", new String[]{"ab"});
+//    testSimpleEval("select from_left('abcdef',-5) as col1 ", new String[]{"a"});
+//    testSimpleEval("select from_left('abcdef',-6) as col1 ", new String[]{""});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", INT4);
+    schema.addColumn("col3", TEXT);
+
+    // for null tests
+    testEval(schema, "table1", ",1,ghi", "select left(col1,1) is null from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc,,ghi", "select left(col1,col2) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "abc,1,ghi", "select left(col1,1) || left(col3,3) from table1", new String[]{"aghi"});
+  }
+
+  @Test
+  public void testRight() throws IOException {
+    testSimpleEval("select right('abcdef',1) as col1 ", new String[]{"f"});
+    testSimpleEval("select right('abcdef',2) as col1 ", new String[]{"ef"});
+    testSimpleEval("select right('abcdef',3) as col1 ", new String[]{"def"});
+    testSimpleEval("select right('abcdef',4) as col1 ", new String[]{"cdef"});
+    testSimpleEval("select right('abcdef',5) as col1 ", new String[]{"bcdef"});
+    testSimpleEval("select right('abcdef',6) as col1 ", new String[]{"abcdef"});
+    testSimpleEval("select right('abcdef',7) as col1 ", new String[]{"abcdef"});
+//    testSimpleEval("select from_right('abcdef',-1) as col1 ", new String[]{"bcdef"});
+//    testSimpleEval("select from_right('abcdef',-2) as col1 ", new String[]{"cdef"});
+//    testSimpleEval("select from_right('abcdef',-3) as col1 ", new String[]{"def"});
+//    testSimpleEval("select from_right('abcdef',-4) as col1 ", new String[]{"ef"});
+//    testSimpleEval("select from_right('abcdef',-5) as col1 ", new String[]{"f"});
+//    testSimpleEval("select from_right('abcdef',-6) as col1 ", new String[]{""});
+
+    Schema schema = new Schema();
+    schema.addColumn("col1", TEXT);
+    schema.addColumn("col2", INT4);
+    schema.addColumn("col3", TEXT);
+
+    // for null tests
+    testEval(schema, "table1", ",1,ghi", "select right(col1,1) is null from table1", new String[]{"t"});
+    testEval(schema, "table1", "abc,,ghi", "select right(col1,col2) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "abc,1,ghi", "select right(col1,1) || right(col3,3) from table1", new String[]{"cghi"});
+  }
+
+  @Test
   public void testReverse() throws IOException {
     testSimpleEval("select reverse('abcdef') as col1 ", new String[]{"fedcba"});
     testSimpleEval("select reverse('가') as col1 ", new String[]{"가"});