Repository: phoenix Updated Branches: refs/heads/4.x-HBase-0.98 c053940a9 -> 3f50a14e9 refs/heads/4.x-HBase-1.0 2852ec774 -> 333d196e3 refs/heads/master 3501d14a6 -> b4641f2cf
PHOENIX-2433 - support additional time units Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/b4641f2c Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/b4641f2c Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/b4641f2c Branch: refs/heads/master Commit: b4641f2cf57efe2c1359ad022883dc7f1fe33bb5 Parents: 3501d14 Author: ravimagham <[email protected]> Authored: Wed Jan 13 01:10:31 2016 -0800 Committer: ravimagham <[email protected]> Committed: Wed Jan 13 01:10:31 2016 -0800 ---------------------------------------------------------------------- .../RoundFloorCeilFunctionsEnd2EndIT.java | 80 +++++++++++++++++--- .../phoenix/expression/ExpressionType.java | 18 +++++ .../expression/function/CeilDateExpression.java | 36 ++++++++- .../function/CeilMonthExpression.java | 44 +++++++++++ .../expression/function/CeilWeekExpression.java | 44 +++++++++++ .../expression/function/CeilYearExpression.java | 44 +++++++++++ .../function/FloorDateExpression.java | 40 +++++++++- .../function/FloorMonthExpression.java | 44 +++++++++++ .../function/FloorWeekExpression.java | 43 +++++++++++ .../function/FloorYearExpression.java | 44 +++++++++++ .../function/RoundDateExpression.java | 42 +++++++--- .../function/RoundJodaDateExpression.java | 63 +++++++++++++++ .../function/RoundMonthExpression.java | 42 ++++++++++ .../function/RoundTimestampExpression.java | 12 +-- .../function/RoundWeekExpression.java | 41 ++++++++++ .../function/RoundYearExpression.java | 42 ++++++++++ .../phoenix/expression/function/TimeUnit.java | 5 +- .../RoundFloorCeilExpressionsTest.java | 19 ++++- 18 files changed, 668 insertions(+), 35 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/it/java/org/apache/phoenix/end2end/RoundFloorCeilFunctionsEnd2EndIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RoundFloorCeilFunctionsEnd2EndIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RoundFloorCeilFunctionsEnd2EndIT.java index cd00354..753d592 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RoundFloorCeilFunctionsEnd2EndIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RoundFloorCeilFunctionsEnd2EndIT.java @@ -102,7 +102,8 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT { @Test public void testRoundingUpDate() throws Exception { Connection conn = DriverManager.getConnection(getUrl()); - ResultSet rs = conn.createStatement().executeQuery("SELECT ROUND(dt, 'day'), ROUND(dt, 'hour', 1), ROUND(dt, 'minute', 1), ROUND(dt, 'second', 1), ROUND(dt, 'millisecond', 1) FROM t1"); + ResultSet rs = conn.createStatement().executeQuery("SELECT ROUND(dt, 'day'), ROUND(dt, 'hour', 1), ROUND(dt, 'minute', 1), ROUND(dt, 'second', 1), " + + " ROUND(dt,'week'), ROUND(dt,'month') , ROUND(dt,'year') FROM t1"); assertTrue(rs.next()); Date expectedDate = DateUtil.parseDate("2012-01-02 00:00:00"); assertEquals(expectedDate, rs.getDate(1)); @@ -110,8 +111,14 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT { assertEquals(expectedDate, rs.getDate(2)); expectedDate = DateUtil.parseDate("2012-01-01 14:25:00"); assertEquals(expectedDate, rs.getDate(3)); - expectedDate = DateUtil.parseDate("2012-01-01 14:25:29"); + expectedDate = DateUtil.parseDate("2012-01-01 14:25:29"); assertEquals(expectedDate, rs.getDate(4)); + expectedDate = DateUtil.parseDate("2012-01-02 00:00:00"); + assertEquals(expectedDate, rs.getDate(5)); + expectedDate = DateUtil.parseDate("2012-01-01 00:00:00"); + assertEquals(expectedDate, rs.getDate(6)); + expectedDate = DateUtil.parseDate("2012-01-01 00:00:00"); + assertEquals(expectedDate, rs.getDate(7)); } @Test @@ -124,7 +131,8 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT { @Test public void testFloorDate() throws Exception { Connection conn = DriverManager.getConnection(getUrl()); - ResultSet rs = conn.createStatement().executeQuery("SELECT FLOOR(dt, 'day', 1), FLOOR(dt, 'hour', 1), FLOOR(dt, 'minute', 1), FLOOR(dt, 'second', 1) FROM t1"); + ResultSet rs = conn.createStatement().executeQuery("SELECT FLOOR(dt, 'day', 1), FLOOR(dt, 'hour', 1), FLOOR(dt, 'minute', 1), FLOOR(dt, 'second', 1)," + + " FLOOR(dt,'week'), FLOOR(dt,'month'), FLOOR(dt,'year') FROM t1"); assertTrue(rs.next()); Date expectedDate = DateUtil.parseDate("2012-01-01 00:00:00"); assertEquals(expectedDate, rs.getDate(1)); @@ -134,6 +142,12 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT { assertEquals(expectedDate, rs.getDate(3)); expectedDate = DateUtil.parseDate("2012-01-01 14:25:28"); assertEquals(expectedDate, rs.getDate(4)); + expectedDate = DateUtil.parseDate("2011-12-26 00:00:00"); + assertEquals(expectedDate, rs.getDate(5)); + expectedDate = DateUtil.parseDate("2012-01-01 00:00:00"); + assertEquals(expectedDate, rs.getDate(6)); + expectedDate = DateUtil.parseDate("2012-01-01 00:00:00"); + assertEquals(expectedDate, rs.getDate(7)); } @Test @@ -146,7 +160,8 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT { @Test public void testCeilDate() throws Exception { Connection conn = DriverManager.getConnection(getUrl()); - ResultSet rs = conn.createStatement().executeQuery("SELECT CEIL(dt, 'day', 1), CEIL(dt, 'hour', 1), CEIL(dt, 'minute', 1), CEIL(dt, 'second', 1) FROM t1"); + ResultSet rs = conn.createStatement().executeQuery("SELECT CEIL(dt, 'day', 1), CEIL(dt, 'hour', 1), CEIL(dt, 'minute', 1), CEIL(dt, 'second', 1), " + + " CEIL(dt,'week') , CEIL(dt,'month') , CEIL(dt,'year') FROM t1"); assertTrue(rs.next()); //Date upserted is 2012-01-01 14:25:28.660. So we will end up bumping up in every case. Date expectedDate = DateUtil.parseDate("2012-01-02 00:00:00"); @@ -157,6 +172,13 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT { assertEquals(expectedDate, rs.getDate(3)); expectedDate = DateUtil.parseDate("2012-01-01 14:25:29"); assertEquals(expectedDate, rs.getDate(4)); + expectedDate = DateUtil.parseDate("2012-01-02 00:00:00"); + System.out.println(String.format(" the expected time is [%s] and the actual time is [%s]",expectedDate.getTime(),rs.getDate(5).getTime())); + assertEquals(expectedDate, rs.getDate(5)); + expectedDate = DateUtil.parseDate("2012-02-01 00:00:00"); + assertEquals(expectedDate, rs.getDate(6)); + expectedDate = DateUtil.parseDate("2013-01-01 00:00:00"); + assertEquals(expectedDate, rs.getDate(7)); } @Test @@ -197,7 +219,8 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT { @Test public void testFloorTimestamp() throws Exception { Connection conn = DriverManager.getConnection(getUrl()); - ResultSet rs = conn.createStatement().executeQuery("SELECT FLOOR(ts, 'day'), FLOOR(ts, 'hour', 1), FLOOR(ts, 'minute', 1), FLOOR(ts, 'second', 1), FLOOR(ts, 'millisecond', 1) FROM t1"); + ResultSet rs = conn.createStatement().executeQuery("SELECT FLOOR(ts, 'day'), FLOOR(ts, 'hour', 1), FLOOR(ts, 'minute', 1), FLOOR(ts, 'second', 1), " + + " FLOOR(ts, 'millisecond', 1) , FLOOR(ts,'week') , FLOOR(ts,'month') FROM t1"); assertTrue(rs.next()); Timestamp expectedTimestamp; expectedTimestamp = new Timestamp(DateUtil.parseDate("2012-01-01 00:00:00").getTime()); @@ -212,6 +235,10 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT { // FLOOR of "2012-01-01 14:25:28.660" + nanosPart will end up removing the nanos part. expectedTimestamp = new Timestamp(DateUtil.parseDate("2012-01-01 14:25:28").getTime() + millisPart); assertEquals(expectedTimestamp, rs.getTimestamp(5)); + expectedTimestamp = new Timestamp(DateUtil.parseDate("2011-12-26 00:00:00").getTime()); + assertEquals(expectedTimestamp, rs.getTimestamp(6)); + expectedTimestamp = new Timestamp(DateUtil.parseDate("2012-01-01 00:00:00").getTime()); + assertEquals(expectedTimestamp, rs.getTimestamp(7)); } @Test @@ -222,9 +249,17 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT { } @Test + public void testWeekFloorTimestampInWhere() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t1 WHERE FLOOR(ts, 'week') = to_date('2011-12-26 00:00:00')"); + assertTrue(rs.next()); + } + + @Test public void testCeilTimestamp() throws Exception { Connection conn = DriverManager.getConnection(getUrl()); - ResultSet rs = conn.createStatement().executeQuery("SELECT CEIL(ts, 'day'), CEIL(ts, 'hour', 1), CEIL(ts, 'minute', 1), CEIL(ts, 'second', 1), CEIL(ts, 'millisecond', 1) FROM t1"); + ResultSet rs = conn.createStatement().executeQuery("SELECT CEIL(ts, 'day'), CEIL(ts, 'hour', 1), CEIL(ts, 'minute', 1), CEIL(ts, 'second', 1), CEIL(ts, 'millisecond', 1)," + + " CEIL(ts,'week'), CEIL(ts,'month') , CEIL(ts,'year') FROM t1"); assertTrue(rs.next()); Timestamp expectedTimestamp; expectedTimestamp = new Timestamp(DateUtil.parseDate("2012-01-02 00:00:00").getTime()); @@ -240,6 +275,12 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT { // That is, it should be evaluated as "2012-01-01 14:25:28.661". expectedTimestamp = new Timestamp(DateUtil.parseDate("2012-01-01 14:25:28").getTime() + millisPart + 1); assertEquals(expectedTimestamp, rs.getTimestamp(5)); + expectedTimestamp = new Timestamp(DateUtil.parseDate("2012-01-02 00:00:00").getTime()); + assertEquals(expectedTimestamp, rs.getTimestamp(6)); + expectedTimestamp = new Timestamp(DateUtil.parseDate("2012-02-01 00:00:00").getTime()); + assertEquals(expectedTimestamp, rs.getTimestamp(7)); + expectedTimestamp = new Timestamp(DateUtil.parseDate("2013-01-01 00:00:00").getTime()); + assertEquals(expectedTimestamp, rs.getTimestamp(8)); } @Test @@ -252,7 +293,8 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT { @Test public void testRoundingUpTime() throws Exception { Connection conn = DriverManager.getConnection(getUrl()); - ResultSet rs = conn.createStatement().executeQuery("SELECT ROUND(t, 'day', 1), ROUND(t, 'hour', 1), ROUND(t, 'minute', 1), ROUND(t, 'second', 1) FROM t1"); + ResultSet rs = conn.createStatement().executeQuery("SELECT ROUND(t, 'day', 1), ROUND(t, 'hour', 1), ROUND(t, 'minute', 1), ROUND(t, 'second', 1)," + + " ROUND(t,'week') , ROUND(t,'month') , ROUND(t,'year') FROM t1"); assertTrue(rs.next()); Time expectedTime = new Time(DateUtil.parseDate("2012-01-02 00:00:00").getTime()); assertEquals(expectedTime, rs.getTime(1)); @@ -262,12 +304,19 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT { assertEquals(expectedTime, rs.getTime(3)); expectedTime = new Time(DateUtil.parseDate("2012-01-01 14:25:29").getTime()); assertEquals(expectedTime, rs.getTime(4)); + expectedTime = new Time(DateUtil.parseDate("2012-01-02 00:00:00").getTime()); + assertEquals(expectedTime, rs.getTime(5)); + expectedTime = new Time(DateUtil.parseDate("2012-01-01 00:00:00").getTime()); + assertEquals(expectedTime, rs.getTime(6)); + expectedTime = new Time(DateUtil.parseDate("2012-01-01 00:00:00").getTime()); + assertEquals(expectedTime, rs.getTime(7)); } @Test public void testFloorTime() throws Exception { Connection conn = DriverManager.getConnection(getUrl()); - ResultSet rs = conn.createStatement().executeQuery("SELECT FLOOR(t, 'day', 1), FLOOR(t, 'hour', 1), FLOOR(t, 'minute', 1), FLOOR(t, 'second', 1) FROM t1"); + ResultSet rs = conn.createStatement().executeQuery("SELECT FLOOR(t, 'day', 1), FLOOR(t, 'hour', 1), FLOOR(t, 'minute', 1), FLOOR(t, 'second', 1), " + + " FLOOR(t, 'week'), FLOOR(t, 'month'), FLOOR(t, 'year') FROM t1"); assertTrue(rs.next()); Time expectedTime = new Time(DateUtil.parseDate("2012-01-01 00:00:00").getTime()); assertEquals(expectedTime, rs.getTime(1)); @@ -277,12 +326,19 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT { assertEquals(expectedTime, rs.getTime(3)); expectedTime = new Time(DateUtil.parseDate("2012-01-01 14:25:28").getTime()); assertEquals(expectedTime, rs.getTime(4)); + expectedTime = new Time(DateUtil.parseDate("2011-12-26 00:00:00").getTime()); + assertEquals(expectedTime, rs.getTime(5)); + expectedTime = new Time(DateUtil.parseDate("2012-01-01 00:00:00").getTime()); + assertEquals(expectedTime, rs.getTime(6)); + expectedTime = new Time(DateUtil.parseDate("2012-01-01 00:00:00").getTime()); + assertEquals(expectedTime, rs.getTime(7)); } @Test public void testCeilTime() throws Exception { Connection conn = DriverManager.getConnection(getUrl()); - ResultSet rs = conn.createStatement().executeQuery("SELECT CEIL(t, 'day', 1), CEIL(t, 'hour', 1), CEIL(t, 'minute', 1), CEIL(t, 'second', 1) FROM t1"); + ResultSet rs = conn.createStatement().executeQuery("SELECT CEIL(t, 'day', 1), CEIL(t, 'hour', 1), CEIL(t, 'minute', 1), CEIL(t, 'second', 1)," + + " CEIL(t,'week') , CEIL(t,'month') , CEIL(t,'year') FROM t1"); assertTrue(rs.next()); Time expectedTime = new Time(DateUtil.parseDate("2012-01-02 00:00:00").getTime()); assertEquals(expectedTime, rs.getTime(1)); @@ -292,6 +348,12 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT { assertEquals(expectedTime, rs.getTime(3)); expectedTime = new Time(DateUtil.parseDate("2012-01-01 14:25:29").getTime()); assertEquals(expectedTime, rs.getTime(4)); + expectedTime = new Time(DateUtil.parseDate("2012-01-02 00:00:00").getTime()); + assertEquals(expectedTime, rs.getTime(5)); + expectedTime = new Time(DateUtil.parseDate("2012-02-01 00:00:00").getTime()); + assertEquals(expectedTime, rs.getTime(6)); + expectedTime = new Time(DateUtil.parseDate("2013-01-01 00:00:00").getTime()); + assertEquals(expectedTime, rs.getTime(7)); } @Test http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java index 6f1d855..f13e265 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java @@ -37,7 +37,10 @@ import org.apache.phoenix.expression.function.CbrtFunction; import org.apache.phoenix.expression.function.CeilDateExpression; import org.apache.phoenix.expression.function.CeilDecimalExpression; import org.apache.phoenix.expression.function.CeilFunction; +import org.apache.phoenix.expression.function.CeilMonthExpression; import org.apache.phoenix.expression.function.CeilTimestampExpression; +import org.apache.phoenix.expression.function.CeilWeekExpression; +import org.apache.phoenix.expression.function.CeilYearExpression; import org.apache.phoenix.expression.function.CoalesceFunction; import org.apache.phoenix.expression.function.ConvertTimezoneFunction; import org.apache.phoenix.expression.function.CountAggregateFunction; @@ -52,6 +55,9 @@ import org.apache.phoenix.expression.function.FirstValueFunction; import org.apache.phoenix.expression.function.FloorDateExpression; import org.apache.phoenix.expression.function.FloorDecimalExpression; import org.apache.phoenix.expression.function.FloorFunction; +import org.apache.phoenix.expression.function.FloorMonthExpression; +import org.apache.phoenix.expression.function.FloorWeekExpression; +import org.apache.phoenix.expression.function.FloorYearExpression; import org.apache.phoenix.expression.function.GetBitFunction; import org.apache.phoenix.expression.function.GetByteFunction; import org.apache.phoenix.expression.function.HourFunction; @@ -86,7 +92,10 @@ import org.apache.phoenix.expression.function.ReverseFunction; import org.apache.phoenix.expression.function.RoundDateExpression; import org.apache.phoenix.expression.function.RoundDecimalExpression; import org.apache.phoenix.expression.function.RoundFunction; +import org.apache.phoenix.expression.function.RoundMonthExpression; import org.apache.phoenix.expression.function.RoundTimestampExpression; +import org.apache.phoenix.expression.function.RoundWeekExpression; +import org.apache.phoenix.expression.function.RoundYearExpression; import org.apache.phoenix.expression.function.SQLIndexTypeFunction; import org.apache.phoenix.expression.function.SQLTableTypeFunction; import org.apache.phoenix.expression.function.SQLViewTypeFunction; @@ -264,6 +273,15 @@ public enum ExpressionType { GetBitFunction(GetBitFunction.class), SetBitFunction(SetBitFunction.class), OctetLengthFunction(OctetLengthFunction.class), + RoundWeekExpression(RoundWeekExpression.class), + RoundMonthExpression(RoundMonthExpression.class), + RoundYearExpression(RoundYearExpression.class), + FloorWeekExpression(FloorWeekExpression.class), + FloorMonthExpression(FloorMonthExpression.class), + FloorYearExpression(FloorYearExpression.class), + CeilWeekExpression(CeilWeekExpression.class), + CeilMonthExpression(CeilMonthExpression.class), + CeilYearExpression(CeilYearExpression.class); ; ExpressionType(Class<? extends Expression> clazz) { http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java index 220b453..a3bf6f8 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java @@ -17,11 +17,17 @@ */ package org.apache.phoenix.expression.function; +import java.sql.Date; import java.sql.SQLException; import java.util.List; -import com.google.common.collect.Lists; +import org.apache.hadoop.hbase.io.ImmutableBytesWritable; import org.apache.phoenix.expression.Expression; +import org.apache.phoenix.expression.LiteralExpression; +import org.apache.phoenix.schema.tuple.Tuple; +import org.apache.phoenix.schema.types.PDataType; + +import com.google.common.collect.Lists; /** * @@ -55,7 +61,19 @@ public class CeilDateExpression extends RoundDateExpression { } public static Expression create(List<Expression> children) throws SQLException { - return new CeilDateExpression(children); + Object timeUnitValue = ((LiteralExpression)children.get(1)).getValue(); + TimeUnit timeUnit = TimeUnit.getTimeUnit(timeUnitValue != null ? timeUnitValue.toString() : null); + switch(timeUnit) { + case WEEK: + return new CeilWeekExpression(children); + case MONTH: + return new CeilMonthExpression(children); + case YEAR: + return new CeilYearExpression(children); + default: + return new CeilDateExpression(children); + } + } CeilDateExpression(List<Expression> children) { @@ -71,5 +89,19 @@ public class CeilDateExpression extends RoundDateExpression { public String getName() { return CeilFunction.NAME; } + + @Override + public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) { + if (children.get(0).evaluate(tuple, ptr)) { + PDataType dataType = getDataType(); + long time = dataType.getCodec().decodeLong(ptr, children.get(0).getSortOrder()); + long value = roundTime(time); + Date d = new Date(value); + byte[] byteValue = dataType.toBytes(d); + ptr.set(byteValue); + return true; + } + return false; + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilMonthExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilMonthExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilMonthExpression.java new file mode 100644 index 0000000..22daeb5 --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilMonthExpression.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.expression.function; + +import java.util.List; + +import org.apache.phoenix.expression.Expression; +import org.joda.time.DateTime; + +/** + * + * Ceil function that rounds up the {@link DateTime} to next month. + */ +public class CeilMonthExpression extends RoundJodaDateExpression { + + public CeilMonthExpression() { + super(); + } + + public CeilMonthExpression(List<Expression> children) { + super(children); + } + + @Override + public long roundDateTime(DateTime dateTime) { + return dateTime.monthOfYear().roundCeilingCopy().getMillis(); + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilWeekExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilWeekExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilWeekExpression.java new file mode 100644 index 0000000..28da94f --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilWeekExpression.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.expression.function; + +import java.util.List; + +import org.apache.phoenix.expression.Expression; +import org.joda.time.DateTime; + +/** + * + * Ceil function that rounds up the {@link DateTime} to next week. + */ +public class CeilWeekExpression extends RoundJodaDateExpression { + + public CeilWeekExpression() { + super(); + } + + public CeilWeekExpression(List<Expression> children) { + super(children); + } + + @Override + public long roundDateTime(DateTime dateTime) { + return dateTime.weekOfWeekyear().roundCeilingCopy().getMillis(); + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilYearExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilYearExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilYearExpression.java new file mode 100644 index 0000000..b6e6b63 --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilYearExpression.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.expression.function; + +import java.util.List; + +import org.apache.phoenix.expression.Expression; +import org.joda.time.DateTime; + +/** + * + * Ceil function that rounds up the {@link DateTime} to next year. + */ +public class CeilYearExpression extends RoundJodaDateExpression { + + public CeilYearExpression() { + super(); + } + + public CeilYearExpression(List<Expression> children) { + super(children); + } + + @Override + public long roundDateTime(DateTime dateTime) { + return dateTime.year().roundCeilingCopy().getMillis(); + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDateExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDateExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDateExpression.java index e3d0543..4dc840e 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDateExpression.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDateExpression.java @@ -17,18 +17,23 @@ */ package org.apache.phoenix.expression.function; +import java.sql.Date; import java.sql.SQLException; import java.util.List; -import com.google.common.collect.Lists; +import org.apache.hadoop.hbase.io.ImmutableBytesWritable; import org.apache.phoenix.expression.CoerceExpression; import org.apache.phoenix.expression.Expression; -import org.apache.phoenix.schema.types.PDate; +import org.apache.phoenix.expression.LiteralExpression; +import org.apache.phoenix.schema.tuple.Tuple; import org.apache.phoenix.schema.types.PDataType; +import org.apache.phoenix.schema.types.PDate; import org.apache.phoenix.schema.types.PTimestamp; import org.apache.phoenix.schema.types.PUnsignedDate; import org.apache.phoenix.schema.types.PUnsignedTimestamp; +import com.google.common.collect.Lists; + /** * * Class encapsulating the FLOOR operation on @@ -41,7 +46,7 @@ public class FloorDateExpression extends RoundDateExpression { public FloorDateExpression() {} - private FloorDateExpression(List<Expression> children) { + protected FloorDateExpression(List<Expression> children) { super(children); } @@ -55,7 +60,20 @@ public class FloorDateExpression extends RoundDateExpression { newChildren.addAll(children.subList(1, children.size())); children = newChildren; } - return new FloorDateExpression(children); + + Object timeUnitValue = ((LiteralExpression)children.get(1)).getValue(); + TimeUnit timeUnit = TimeUnit.getTimeUnit(timeUnitValue != null ? timeUnitValue.toString() : null); + switch(timeUnit) { + case WEEK: + return new FloorWeekExpression(children); + case MONTH: + return new FloorMonthExpression(children); + case YEAR: + return new FloorYearExpression(children); + default: + return new FloorDateExpression(children); + } + } /** @@ -87,4 +105,18 @@ public class FloorDateExpression extends RoundDateExpression { public String getName() { return FloorFunction.NAME; } + + @Override + public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) { + if (children.get(0).evaluate(tuple, ptr)) { + PDataType dataType = getDataType(); + long time = dataType.getCodec().decodeLong(ptr, children.get(0).getSortOrder()); + long value = roundTime(time); + Date d = new Date(value); + byte[] byteValue = dataType.toBytes(d); + ptr.set(byteValue); + return true; + } + return false; + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorMonthExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorMonthExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorMonthExpression.java new file mode 100644 index 0000000..cf80205 --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorMonthExpression.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.expression.function; + +import java.util.List; + +import org.apache.phoenix.expression.Expression; +import org.joda.time.DateTime; + +/** + * + * Floor function that rounds up the {@link DateTime} to start of month. + */ +public class FloorMonthExpression extends RoundJodaDateExpression { + + public FloorMonthExpression() { + super(); + } + + public FloorMonthExpression(List<Expression> children) { + super(children); + } + + @Override + public long roundDateTime(DateTime datetime) { + return datetime.monthOfYear().roundFloorCopy().getMillis(); + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorWeekExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorWeekExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorWeekExpression.java new file mode 100644 index 0000000..b6596c9 --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorWeekExpression.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.expression.function; + +import java.util.List; + +import org.apache.phoenix.expression.Expression; +import org.joda.time.DateTime; + +/** + * Floor function that rounds up the {@link DateTime} to start of week. + */ +public class FloorWeekExpression extends RoundJodaDateExpression { + + public FloorWeekExpression() { + super(); + } + + public FloorWeekExpression(List<Expression> children) { + super(children); + } + + @Override + public long roundDateTime(DateTime datetime) { + return datetime.weekOfWeekyear().roundFloorCopy().getMillis(); + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorYearExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorYearExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorYearExpression.java new file mode 100644 index 0000000..4ac8792 --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorYearExpression.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.expression.function; + +import java.util.List; + +import org.apache.phoenix.expression.Expression; +import org.joda.time.DateTime; + +/** + * + * Floor function that rounds up the {@link DateTime} to start of year. + */ +public class FloorYearExpression extends RoundJodaDateExpression { + + public FloorYearExpression() { + super(); + } + + public FloorYearExpression(List<Expression> children) { + super(children); + } + + @Override + public long roundDateTime(DateTime datetime) { + return datetime.year().roundFloorCopy().getMillis(); + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java index e410e34..b0b4f99 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java @@ -48,7 +48,7 @@ import com.google.common.collect.Lists; /** * Function used to bucketize date/time values by rounding them to * an even increment. Usage: - * ROUND(<date/time col ref>,<'day'|'hour'|'minute'|'second'|'millisecond'>,<optional integer multiplier>) + * ROUND(<date/time col ref>,<'day'|'hour'|'minute'|'second'|'millisecond'|'week'|'month'|'year'>,<optional integer multiplier>) * The integer multiplier is optional and is used to do rollups to a partial time unit (i.e. 10 minute rollup) * The function returns a {@link org.apache.phoenix.schema.types.PDate} @@ -58,6 +58,7 @@ import com.google.common.collect.Lists; public class RoundDateExpression extends ScalarFunction { long divBy; + protected TimeUnit timeUnit; public static final String NAME = "ROUND"; @@ -92,7 +93,23 @@ public class RoundDateExpression extends ScalarFunction { } public static Expression create(List<Expression> children) throws SQLException { - return new RoundDateExpression(children); + int numChildren = children.size(); + if(numChildren < 2 || numChildren > 3) { + throw new IllegalArgumentException("Wrong number of arguments : " + numChildren); + } + Object timeUnitValue = ((LiteralExpression)children.get(1)).getValue(); + TimeUnit timeUnit = TimeUnit.getTimeUnit(timeUnitValue != null ? timeUnitValue.toString() : null); + switch(timeUnit) { + case WEEK: + return new RoundWeekExpression(children); + case MONTH: + return new RoundMonthExpression(children); + case YEAR: + return new RoundYearExpression(children); + default: + return new RoundDateExpression(children); + } + } static Expression getTimeUnitExpr(TimeUnit timeUnit) throws SQLException { @@ -106,14 +123,13 @@ public class RoundDateExpression extends ScalarFunction { RoundDateExpression(List<Expression> children) { super(children.subList(0, 1)); int numChildren = children.size(); - if(numChildren < 2 || numChildren > 3) { - throw new IllegalArgumentException("Wrong number of arguments : " + numChildren); - } Object timeUnitValue = ((LiteralExpression)children.get(1)).getValue(); Object multiplierValue = numChildren > 2 ? ((LiteralExpression)children.get(2)).getValue() : null; int multiplier = multiplierValue == null ? 1 :((Number)multiplierValue).intValue(); - TimeUnit timeUnit = TimeUnit.getTimeUnit(timeUnitValue != null ? timeUnitValue.toString() : null); - divBy = multiplier * TIME_UNIT_MS[timeUnit.ordinal()]; + timeUnit = TimeUnit.getTimeUnit(timeUnitValue != null ? timeUnitValue.toString() : null); + if(timeUnit.ordinal() < TIME_UNIT_MS.length) { + divBy = multiplier * TIME_UNIT_MS[timeUnit.ordinal()]; + } } @@ -139,7 +155,6 @@ public class RoundDateExpression extends ScalarFunction { PDataType dataType = getDataType(); long time = dataType.getCodec().decodeLong(ptr, children.get(0).getSortOrder()); long value = roundTime(time); - Date d = new Date(value); byte[] byteValue = dataType.toBytes(d); ptr.set(byteValue); @@ -174,12 +189,19 @@ public class RoundDateExpression extends ScalarFunction { public void readFields(DataInput input) throws IOException { super.readFields(input); divBy = WritableUtils.readVLong(input); - } + if(divBy < 0) { + divBy = -(divBy + 1); + String tunit = WritableUtils.readString(input); + timeUnit = TimeUnit.valueOf(tunit); + } + } @Override public void write(DataOutput output) throws IOException { super.write(output); - WritableUtils.writeVLong(output, divBy); + // Negating the divBy is done to avoid breaking backward compatibility. refer PHOENIX-2433. + WritableUtils.writeVLong(output, -(divBy + 1)); + WritableUtils.writeString(output, timeUnit.name()); } @Override http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundJodaDateExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundJodaDateExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundJodaDateExpression.java new file mode 100644 index 0000000..0dba80b --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundJodaDateExpression.java @@ -0,0 +1,63 @@ +/* + * 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.phoenix.expression.function; + +import java.sql.Date; +import java.util.List; + +import org.apache.hadoop.hbase.io.ImmutableBytesWritable; +import org.apache.phoenix.expression.Expression; +import org.apache.phoenix.schema.tuple.Tuple; +import org.apache.phoenix.schema.types.PDataType; +import org.joda.time.DateTime; +import org.joda.time.chrono.ISOChronology; + +/** + * + * Base class for functions that use joda time. + * Used primarily by FLOOR , ROUND and CEIL on the time units WEEK,MONTH and YEAR. + */ +public abstract class RoundJodaDateExpression extends RoundDateExpression{ + + public RoundJodaDateExpression(){} + + public RoundJodaDateExpression(List<Expression> children) { + super(children); + } + + @Override + public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) { + if (children.get(0).evaluate(tuple, ptr)) { + PDataType dataType = getDataType(); + long time = dataType.getCodec().decodeLong(ptr, children.get(0).getSortOrder()); + DateTime dt = new DateTime(time,ISOChronology.getInstanceUTC()); + long value = roundDateTime(dt); + Date d = new Date(value); + byte[] byteValue = dataType.toBytes(d); + ptr.set(byteValue); + return true; + } + return false; + } + + /** + * @param dateTime + * @return Time in millis. + */ + public abstract long roundDateTime(DateTime dateTime); +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundMonthExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundMonthExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundMonthExpression.java new file mode 100644 index 0000000..5ca21da --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundMonthExpression.java @@ -0,0 +1,42 @@ +/* + * 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.phoenix.expression.function; + +import java.util.List; + +import org.apache.phoenix.expression.Expression; +import org.joda.time.DateTime; + +/** + * + * Rounds off the given {@link DateTime} to month. + */ +public class RoundMonthExpression extends RoundJodaDateExpression { + + public RoundMonthExpression(){} + + public RoundMonthExpression(List<Expression> children) { + super(children); + } + + @Override + public long roundDateTime(DateTime dateTime) { + return dateTime.monthOfYear().roundHalfEvenCopy().getMillis(); + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundTimestampExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundTimestampExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundTimestampExpression.java index 215cf79..9129285 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundTimestampExpression.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundTimestampExpression.java @@ -22,19 +22,19 @@ import java.sql.Timestamp; import java.util.List; import org.apache.hadoop.hbase.io.ImmutableBytesWritable; - -import com.google.common.collect.Lists; import org.apache.phoenix.expression.CoerceExpression; import org.apache.phoenix.expression.Expression; import org.apache.phoenix.expression.LiteralExpression; +import org.apache.phoenix.schema.SortOrder; +import org.apache.phoenix.schema.tuple.Tuple; +import org.apache.phoenix.schema.types.PDataType; +import org.apache.phoenix.schema.types.PDataType.PDataCodec; import org.apache.phoenix.schema.types.PDate; import org.apache.phoenix.schema.types.PTimestamp; import org.apache.phoenix.schema.types.PUnsignedDate; import org.apache.phoenix.schema.types.PUnsignedTimestamp; -import org.apache.phoenix.schema.SortOrder; -import org.apache.phoenix.schema.types.PDataType; -import org.apache.phoenix.schema.types.PDataType.PDataCodec; -import org.apache.phoenix.schema.tuple.Tuple; + +import com.google.common.collect.Lists; /** * http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundWeekExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundWeekExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundWeekExpression.java new file mode 100644 index 0000000..0572e19 --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundWeekExpression.java @@ -0,0 +1,41 @@ +/* + * 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.phoenix.expression.function; + +import java.util.List; + +import org.apache.phoenix.expression.Expression; +import org.joda.time.DateTime; + +/** + * + * Rounds off the given {@link DateTime} to the nearest Monday. + */ +public class RoundWeekExpression extends RoundJodaDateExpression { + + public RoundWeekExpression(){} + + public RoundWeekExpression(List<Expression> children) { + super(children); + } + + @Override + public long roundDateTime(DateTime dateTime) { + return dateTime.weekOfWeekyear().roundHalfEvenCopy().getMillis(); + } +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundYearExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundYearExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundYearExpression.java new file mode 100644 index 0000000..b73d05a --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundYearExpression.java @@ -0,0 +1,42 @@ +/* + * 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.phoenix.expression.function; + +import java.util.List; + +import org.apache.phoenix.expression.Expression; +import org.joda.time.DateTime; + +/** + * + * Rounds off the given {@link DateTime} to year. + */ +public class RoundYearExpression extends RoundJodaDateExpression { + + public RoundYearExpression(){} + + public RoundYearExpression(List<Expression> children) { + super(children); + } + + @Override + public long roundDateTime(DateTime dateTime) { + return dateTime.year().roundHalfEvenCopy().getMillis(); + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/main/java/org/apache/phoenix/expression/function/TimeUnit.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/TimeUnit.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/TimeUnit.java index dff52f5..c59669a 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/TimeUnit.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/TimeUnit.java @@ -24,7 +24,10 @@ public enum TimeUnit { HOUR("hour"), MINUTE("minute"), SECOND("second"), - MILLISECOND("millisecond"); + MILLISECOND("millisecond"), + WEEK("week"), + MONTH("month"), + YEAR("year"); private String value; http://git-wip-us.apache.org/repos/asf/phoenix/blob/b4641f2c/phoenix-core/src/test/java/org/apache/phoenix/expression/RoundFloorCeilExpressionsTest.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/test/java/org/apache/phoenix/expression/RoundFloorCeilExpressionsTest.java b/phoenix-core/src/test/java/org/apache/phoenix/expression/RoundFloorCeilExpressionsTest.java index c9f81fe..5022e71 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/expression/RoundFloorCeilExpressionsTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/expression/RoundFloorCeilExpressionsTest.java @@ -43,11 +43,11 @@ import org.apache.phoenix.expression.function.ScalarFunction; import org.apache.phoenix.expression.function.TimeUnit; import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr; import org.apache.phoenix.query.KeyRange; -import org.apache.phoenix.schema.types.PDecimal; import org.apache.phoenix.schema.IllegalDataException; +import org.apache.phoenix.schema.types.PDataType; import org.apache.phoenix.schema.types.PDate; +import org.apache.phoenix.schema.types.PDecimal; import org.apache.phoenix.schema.types.PInteger; -import org.apache.phoenix.schema.types.PDataType; import org.apache.phoenix.schema.types.PVarchar; import org.apache.phoenix.util.DateUtil; import org.junit.Test; @@ -615,5 +615,18 @@ public class RoundFloorCeilExpressionsTest { } } - + + @Test + public void testFloorDateExpressionForWeek() throws Exception { + Expression dateLiteral = LiteralExpression.newConstant(DateUtil.parseDate("2016-01-07 08:17:28"), PDate.INSTANCE); + Expression floorDateExpression = FloorDateExpression.create(dateLiteral, TimeUnit.WEEK); + + ImmutableBytesWritable ptr = new ImmutableBytesWritable(); + floorDateExpression.evaluate(null, ptr); + Object result = floorDateExpression.getDataType().toObject(ptr); + + assertTrue(result instanceof Date); + Date resultDate = (Date)result; + assertEquals(DateUtil.parseDate("2016-01-04 00:00:00"), resultDate); + } }
