You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by ji...@apache.org on 2013/12/26 05:49:21 UTC
git commit: TAJO-439: Time literal support. (DaeMyung Kang via jihoon)
Updated Branches:
refs/heads/master 9d86ff7bc -> 3a5a617c6
TAJO-439: Time literal support. (DaeMyung Kang via jihoon)
Project: http://git-wip-us.apache.org/repos/asf/incubator-tajo/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tajo/commit/3a5a617c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tajo/tree/3a5a617c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tajo/diff/3a5a617c
Branch: refs/heads/master
Commit: 3a5a617c6bb1dd10d026ab0735f9031623a66d30
Parents: 9d86ff7
Author: Jihoon Son <ji...@apache.org>
Authored: Thu Dec 26 13:48:37 2013 +0900
Committer: Jihoon Son <ji...@apache.org>
Committed: Thu Dec 26 13:48:37 2013 +0900
----------------------------------------------------------------------
CHANGES.txt | 2 +
.../java/org/apache/tajo/algebra/OpType.java | 3 +-
.../org/apache/tajo/algebra/TimeLiteral.java | 51 ++++++++
.../org/apache/tajo/datum/DatumFactory.java | 4 +-
.../java/org/apache/tajo/datum/TimeDatum.java | 10 ++
.../org/apache/tajo/engine/parser/SQLParser.g4 | 7 +-
.../apache/tajo/engine/parser/SQLAnalyzer.java | 12 +-
.../tajo/engine/planner/AlgebraVisitor.java | 1 +
.../tajo/engine/planner/BaseAlgebraVisitor.java | 5 +
.../tajo/engine/planner/LogicalPlanner.java | 129 +++++++++++++------
.../tajo/engine/eval/TestSQLDateTimeTypes.java | 6 +
.../storage/TextSerializerDeserializer.java | 5 +
12 files changed, 193 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3a5a617c/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 8fbc6bb..385ef9f 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,6 +4,8 @@ Release 0.8.0 - unreleased
NEW FEATURES
+ TAJO-439: Time literal support. (DaeMyung Kang via jihoon)
+
TAJO-437: Timestamp literal support. (hyunsik)
TAJO-382: Implement encode/decode functions. (Seungun Choe via jihoon)
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3a5a617c/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java
----------------------------------------------------------------------
diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java
index a58f103..3022ea1 100644
--- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java
@@ -97,6 +97,7 @@ public enum OpType {
Cast(CastExpr.class),
Literal(LiteralValue.class),
NullLiteral(NullLiteral.class),
+ TimeLiteral(TimeLiteral.class),
TimestampLiteral(TimestampLiteral.class);
private Class baseClass;
@@ -128,4 +129,4 @@ public enum OpType {
return OpType.valueOf(json.getAsString());
}
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3a5a617c/tajo-algebra/src/main/java/org/apache/tajo/algebra/TimeLiteral.java
----------------------------------------------------------------------
diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/TimeLiteral.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/TimeLiteral.java
new file mode 100644
index 0000000..e939128
--- /dev/null
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/TimeLiteral.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.algebra;
+
+import com.google.common.base.Objects;
+
+public class TimeLiteral extends Expr {
+ private TimeValue time;
+
+ public TimeLiteral(TimeValue time) {
+ super(OpType.TimeLiteral);
+ this.time = time;
+ }
+
+ public TimeValue getTime() {
+ return time;
+ }
+
+ public String toString() {
+ return time.toString();
+ }
+
+ public int hashCode() {
+ return Objects.hashCode(time);
+ }
+
+ @Override
+ boolean equalsTo(Expr expr) {
+ if (expr instanceof TimeLiteral) {
+ TimeLiteral another = (TimeLiteral) expr;
+ return time.equals(another.time);
+ }
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3a5a617c/tajo-common/src/main/java/org/apache/tajo/datum/DatumFactory.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/DatumFactory.java b/tajo-common/src/main/java/org/apache/tajo/datum/DatumFactory.java
index 0c98084..de645c1 100644
--- a/tajo-common/src/main/java/org/apache/tajo/datum/DatumFactory.java
+++ b/tajo-common/src/main/java/org/apache/tajo/datum/DatumFactory.java
@@ -299,8 +299,10 @@ public class DatumFactory {
return new TimeDatum(datum.asInt8());
case TEXT:
return new TimeDatum(datum.asChars());
+ case TIME:
+ return (TimeDatum) datum;
default:
- throw new InvalidCastException(datum.type() + " cannot be casted to TIMESTAMP type");
+ throw new InvalidCastException(datum.type() + " cannot be casted to TIME type");
}
}
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3a5a617c/tajo-common/src/main/java/org/apache/tajo/datum/TimeDatum.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/TimeDatum.java b/tajo-common/src/main/java/org/apache/tajo/datum/TimeDatum.java
index f6fac63..9f67249 100644
--- a/tajo-common/src/main/java/org/apache/tajo/datum/TimeDatum.java
+++ b/tajo-common/src/main/java/org/apache/tajo/datum/TimeDatum.java
@@ -38,6 +38,16 @@ public class TimeDatum extends Datum {
time = new LocalTime(value);
}
+ public TimeDatum(int hour, int minute, int second) {
+ super(TajoDataTypes.Type.TIME);
+ time = new LocalTime(hour, minute, second);
+ }
+
+ public TimeDatum(int hour, int minute, int second, int millis) {
+ super(TajoDataTypes.Type.TIME);
+ time = new LocalTime(hour, minute, second, millis);
+ }
+
public TimeDatum(String timeStr) {
super(TajoDataTypes.Type.TIME);
time = LocalTime.parse(timeStr, DEFAULT_FORMATTER);
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3a5a617c/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 1a7f903..06a2b7a 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
@@ -188,6 +188,11 @@ general_literal
datetime_literal
: timestamp_literal
+ | time_literal
+ ;
+
+time_literal
+ : TIME time_string=Character_String_Literal
;
timestamp_literal
@@ -1138,4 +1143,4 @@ null_ordering
insert_statement
: INSERT (OVERWRITE)? INTO table_name (LEFT_PAREN column_name_list RIGHT_PAREN)? query_expression
| INSERT (OVERWRITE)? INTO LOCATION path=Character_String_Literal (USING file_type=Identifier (param_clause)?)? query_expression
- ;
\ No newline at end of file
+ ;
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3a5a617c/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 a2777c5..54a90da 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
@@ -1263,7 +1263,17 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
@Override
public Expr visitDatetime_literal(@NotNull SQLParser.Datetime_literalContext ctx) {
- return visitTimestamp_literal(ctx.timestamp_literal());
+ if (checkIfExist(ctx.time_literal())) {
+ return visitTime_literal(ctx.time_literal());
+ } else {
+ return visitTimestamp_literal(ctx.timestamp_literal());
+ }
+ }
+
+ @Override
+ public Expr visitTime_literal(SQLParser.Time_literalContext ctx) {
+ String timePart = stripQuote(ctx.time_string.getText());
+ return new TimeLiteral(parseTime(timePart));
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3a5a617c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
index 385158e..dcfc6fc 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
@@ -99,5 +99,6 @@ public interface AlgebraVisitor<CONTEXT, RESULT> {
RESULT visitLiteral(CONTEXT ctx, Stack<OpType> stack, LiteralValue expr) throws PlanningException;
RESULT visitNullLiteral(CONTEXT ctx, Stack<OpType> stack, NullLiteral expr) throws PlanningException;
RESULT visitTimestampLiteral(CONTEXT ctx, Stack<OpType> stack, TimestampLiteral expr) throws PlanningException;
+ RESULT visitTimeLiteral(CONTEXT ctx, Stack<OpType> stack, TimeLiteral expr) throws PlanningException;
}
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3a5a617c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
index f2cf1f8..1aeef5f 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
@@ -636,4 +636,9 @@ public class BaseAlgebraVisitor<CONTEXT, RESULT> implements AlgebraVisitor<CONTE
public RESULT visitTimestampLiteral(CONTEXT ctx, Stack<OpType> stack, TimestampLiteral expr) throws PlanningException {
return null;
}
+
+ @Override
+ public RESULT visitTimeLiteral(CONTEXT ctx, Stack<OpType> stack, TimeLiteral expr) throws PlanningException {
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3a5a617c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
index 6581c66..11da7b7 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
@@ -39,6 +39,7 @@ import org.apache.tajo.datum.Datum;
import org.apache.tajo.datum.DatumFactory;
import org.apache.tajo.datum.NullDatum;
import org.apache.tajo.datum.TimestampDatum;
+import org.apache.tajo.datum.TimeDatum;
import org.apache.tajo.engine.eval.*;
import org.apache.tajo.engine.exception.InvalidQueryException;
import org.apache.tajo.engine.exception.UndefinedFunctionException;
@@ -1040,6 +1041,69 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
return dropTableNode;
}
+ public static int [] dateToIntArray(String years, String months, String days)
+ throws PlanningException {
+ int year = Integer.valueOf(years);
+ int month = Integer.valueOf(months);
+ int day = Integer.valueOf(days);
+
+ if (!(1 <= year && year <= 9999)) {
+ throw new PlanningException(String.format("Years (%d) must be between 1 and 9999 integer value", year));
+ }
+
+ if (!(1 <= month && month <= 12)) {
+ throw new PlanningException(String.format("Months (%d) must be between 1 and 12 integer value", month));
+ }
+
+ if (!(1<= day && day <= 31)) {
+ throw new PlanningException(String.format("Days (%d) must be between 1 and 31 integer value", day));
+ }
+
+ int [] results = new int[3];
+ results[0] = year;
+ results[1] = month;
+ results[2] = day;
+
+ return results;
+ }
+
+ public static int [] timeToIntArray(String hours, String minutes, String seconds, String fractionOfSecond)
+ throws PlanningException {
+ int hour = Integer.valueOf(hours);
+ int minute = Integer.valueOf(minutes);
+ int second = Integer.valueOf(seconds);
+ int fraction = 0;
+ if (fractionOfSecond != null) {
+ fraction = Integer.valueOf(fractionOfSecond);
+ }
+
+ if (!(0 <= hour && hour <= 23)) {
+ throw new PlanningException(String.format("Hours (%d) must be between 0 and 24 integer value", hour));
+ }
+
+ if (!(0 <= minute && minute <= 59)) {
+ throw new PlanningException(String.format("Minutes (%d) must be between 0 and 59 integer value", minute));
+ }
+
+ if (!(0 <= second && second <= 59)) {
+ throw new PlanningException(String.format("Seconds (%d) must be between 0 and 59 integer value", second));
+ }
+
+ if (fraction != 0) {
+ if (!(0 <= fraction && fraction <= 999)) {
+ throw new PlanningException(String.format("Seconds (%d) must be between 0 and 999 integer value", fraction));
+ }
+ }
+
+ int [] results = new int[4];
+ results[0] = hour;
+ results[1] = minute;
+ results[2] = second;
+ results[3] = fraction;
+
+ return results;
+ }
+
/*===============================================================================================
Expression SECTION
===============================================================================================*/
@@ -1068,51 +1132,40 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
throw new RuntimeException("Unsupported type: " + literal.getValueType());
}
+ case TimeLiteral: {
+ TimeLiteral timeLiteral = (TimeLiteral) expr;
+ TimeValue timeValue = timeLiteral.getTime();
+ int [] times = LogicalPlanner.timeToIntArray(timeValue.getHours(),
+ timeValue.getMinutes(),
+ timeValue.getSeconds(),
+ timeValue.getSecondsFraction());
+
+ TimeDatum datum;
+ if (times[3] == 0) {
+ datum = new TimeDatum(times[0], times[1], times[2]);
+ } else {
+ datum = new TimeDatum(times[0], times[1], times[2], times[3]);
+ }
+ return new ConstEval(datum);
+ }
+
case TimestampLiteral: {
TimestampLiteral timestampLiteral = (TimestampLiteral) expr;
DateValue dateValue = timestampLiteral.getDate();
TimeValue timeValue = timestampLiteral.getTime();
- int years;
- int months;
- int days;
- int hours;
- int minutes;
- int seconds;
-
- years = Integer.valueOf(dateValue.getYears());
- if (!(1 <= years && years <= 9999)) {
- throw new PlanningException(String.format("Years (%d) must be between 1 and 9999 integer value", years));
- }
- months = Integer.valueOf(dateValue.getMonths());
- if (!(1 <= months && months <= 12)) {
- throw new PlanningException(String.format("Months (%d) must be between 1 and 12 integer value", months));
- }
- days = Integer.valueOf(dateValue.getDays());
- if (!(1<= days && days <= 31)) {
- throw new PlanningException(String.format("Days (%d) must be between 1 and 31 integer value", days));
- }
-
- hours = Integer.valueOf(timeValue.getHours());
- if (!(0 <= hours && hours <= 23)) {
- throw new PlanningException(String.format("Hours (%d) must be between 0 and 24 integer value", hours));
- }
- minutes = Integer.valueOf(timeValue.getMinutes());
- if (!(0 <= minutes && minutes <= 59)) {
- throw new PlanningException(String.format("Minutes (%d) must be between 0 and 59 integer value", minutes));
- }
- seconds = Integer.valueOf(timeValue.getSeconds());
- if (!(0 <= seconds && seconds <= 59)) {
- throw new PlanningException(String.format("Seconds (%d) must be between 0 and 59 integer value", seconds));
- }
+ int [] dates = LogicalPlanner.dateToIntArray(dateValue.getYears(),
+ dateValue.getMonths(),
+ dateValue.getDays());
+ int [] times = LogicalPlanner.timeToIntArray(timeValue.getHours(),
+ timeValue.getMinutes(),
+ timeValue.getSeconds(),
+ timeValue.getSecondsFraction());
DateTime dateTime;
- if (timeValue.hasSecondsFraction()) {
- int secondsFraction = Integer.valueOf(timeValue.getSecondsFraction());
- if (!(0 <= secondsFraction && secondsFraction <= 999))
- throw new PlanningException(String.format("Seconds (%d) must be between 0 and 999 integer value", seconds));
- dateTime = new DateTime(years, months, days, hours, minutes, seconds, secondsFraction);
+ if (times[3] == 0) {
+ dateTime = new DateTime(dates[0], dates[1], dates[2], times[0], times[1], times[2]);
} else {
- dateTime = new DateTime(years, months, days, hours, minutes, seconds);
+ dateTime = new DateTime(dates[0], dates[1], dates[2], times[0], times[1], times[3]);
}
return new ConstEval(new TimestampDatum(dateTime));
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3a5a617c/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestSQLDateTimeTypes.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestSQLDateTimeTypes.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestSQLDateTimeTypes.java
index fb1699f..9eb4d1d 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestSQLDateTimeTypes.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestSQLDateTimeTypes.java
@@ -29,4 +29,10 @@ public class TestSQLDateTimeTypes extends ExprTestBase {
testSimpleEval("select to_char(TIMESTAMP '1970-01-17 10:09:37', 'yyyy-MM-dd HH:mm:ss');",
new String[]{"1970-01-17 10:09:37"});
}
+
+ @Test
+ public void testTimeLiteral() throws IOException {
+ testSimpleEval("select TIME '10:09:37';",
+ new String[]{"10:09:37"});
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3a5a617c/tajo-core/tajo-core-storage/src/main/java/org/apache/tajo/storage/TextSerializerDeserializer.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-storage/src/main/java/org/apache/tajo/storage/TextSerializerDeserializer.java b/tajo-core/tajo-core-storage/src/main/java/org/apache/tajo/storage/TextSerializerDeserializer.java
index b80b461..9995a4a 100644
--- a/tajo-core/tajo-core-storage/src/main/java/org/apache/tajo/storage/TextSerializerDeserializer.java
+++ b/tajo-core/tajo-core-storage/src/main/java/org/apache/tajo/storage/TextSerializerDeserializer.java
@@ -77,6 +77,7 @@ public class TextSerializerDeserializer implements SerializerDeserializer {
case FLOAT8:
case INET4:
case DATE:
+ case TIME:
case TIMESTAMP:
bytes = datum.asTextBytes();
length = bytes.length;
@@ -149,6 +150,10 @@ public class TextSerializerDeserializer implements SerializerDeserializer {
datum = isNull(bytes, offset, length, nullCharacters) ? NullDatum.get()
: DatumFactory.createDate(new String(bytes, offset, length));
break;
+ case TIME:
+ datum = isNull(bytes, offset, length, nullCharacters) ? NullDatum.get()
+ : DatumFactory.createTime(new String(bytes, offset, length));
+ break;
case TIMESTAMP:
datum = isNull(bytes, offset, length, nullCharacters) ? NullDatum.get()
: DatumFactory.createTimeStamp(new String(bytes, offset, length));