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);
+    }
 }

Reply via email to