Author: amareshwari Date: Wed May 29 11:12:15 2013 New Revision: 1487438 URL: http://svn.apache.org/r1487438 Log: Queries with starting of the month as start period should be considered for MONTHLY update period
Modified: hive/branches/HIVE-4115/ql/src/java/org/apache/hadoop/hive/ql/cube/metadata/CubeFactTable.java hive/branches/HIVE-4115/ql/src/java/org/apache/hadoop/hive/ql/cube/parse/DateUtil.java hive/branches/HIVE-4115/ql/src/test/org/apache/hadoop/hive/ql/cube/parse/TestDateUtil.java hive/branches/HIVE-4115/ql/src/test/org/apache/hadoop/hive/ql/cube/parse/TestMaxUpdateInterval.java Modified: hive/branches/HIVE-4115/ql/src/java/org/apache/hadoop/hive/ql/cube/metadata/CubeFactTable.java URL: http://svn.apache.org/viewvc/hive/branches/HIVE-4115/ql/src/java/org/apache/hadoop/hive/ql/cube/metadata/CubeFactTable.java?rev=1487438&r1=1487437&r2=1487438&view=diff ============================================================================== --- hive/branches/HIVE-4115/ql/src/java/org/apache/hadoop/hive/ql/cube/metadata/CubeFactTable.java (original) +++ hive/branches/HIVE-4115/ql/src/java/org/apache/hadoop/hive/ql/cube/metadata/CubeFactTable.java Wed May 29 11:12:15 2013 @@ -167,6 +167,9 @@ public final class CubeFactTable extends case MONTHLY: intervals = DateUtil.getMonthsBetween(from, to); break; + case WEEKLY: + intervals = DateUtil.getWeeksBetween(from, to); + break; } if (intervals > 0) { @@ -175,7 +178,7 @@ public final class CubeFactTable extends } } } else { - // Below MONTHLY, we can use weight to find out the correct period + // Below WEEKLY, we can use weight to find out the correct period if (diff < i.weight()) { // interval larger than time diff continue; Modified: hive/branches/HIVE-4115/ql/src/java/org/apache/hadoop/hive/ql/cube/parse/DateUtil.java URL: http://svn.apache.org/viewvc/hive/branches/HIVE-4115/ql/src/java/org/apache/hadoop/hive/ql/cube/parse/DateUtil.java?rev=1487438&r1=1487437&r2=1487438&view=diff ============================================================================== --- hive/branches/HIVE-4115/ql/src/java/org/apache/hadoop/hive/ql/cube/parse/DateUtil.java (original) +++ hive/branches/HIVE-4115/ql/src/java/org/apache/hadoop/hive/ql/cube/parse/DateUtil.java Wed May 29 11:12:15 2013 @@ -236,13 +236,18 @@ public class DateUtil { } public static int getMonthsBetween(Date from, Date to) { - from = DateUtils.round(from, Calendar.MONTH); - to = DateUtils.truncate(to, Calendar.MONTH); + // Move 'from' to end of month, unless its the first day of month + if (!from.equals(DateUtils.truncate(from, Calendar.MONTH))) { + from = DateUtils.addMonths(DateUtils.truncate(from, Calendar.MONTH), 1); + } - int months = 0; - from = DateUtils.addMonths(from, 1); + // Move 'to' to beginning of month, unless its the last day of the month + if (!to.equals(DateUtils.round(to, Calendar.MONTH))) { + to = DateUtils.truncate(to, Calendar.MONTH); + } - while (to.after(from)) { + int months = 0; + while (from.before(to)) { from = DateUtils.addMonths(from, 1); months++; } @@ -250,45 +255,102 @@ public class DateUtil { } public static int getQuartersBetween(Date from, Date to) { + int months = getMonthsBetween(from, to); + if (months < 3) { + return 0; + } Calendar cal = Calendar.getInstance(); cal.setTime(from); - int fromQtr = cal.get(Calendar.MONTH) / 3 + 1; + int fromMonth = cal.get(Calendar.MONTH); int fromYear = cal.get(Calendar.YEAR); - cal.setTime(to); - int toQtr = cal.get(Calendar.MONTH) / 3 + 1; - int toYear = cal.get(Calendar.YEAR); - - if (fromYear == toYear) { - if (fromQtr == toQtr) { - return 0; - } else { - return toQtr - fromQtr - 1; - } + // Get the start date of the quarter + int qtrStartMonth; + if (fromMonth % 3 == 0) { + qtrStartMonth = fromMonth; } else { - from = DateUtils.round(from, Calendar.YEAR); - to = DateUtils.truncate(to, Calendar.YEAR); - int quarters = 0; - from = DateUtils.addYears(from, 1); - while (to.after(from)) { - from = DateUtils.addYears(from, 1); - quarters += 4; - } - return quarters + (4 - fromQtr) + (toQtr - 1); + qtrStartMonth = fromMonth - (fromMonth % 3); + } + + cal.clear(); + cal.set(Calendar.MONTH, qtrStartMonth); + cal.set(Calendar.YEAR, fromYear); + cal.set(Calendar.DAY_OF_MONTH, 1); + Date fromQtrStartDate = cal.getTime(); + + int moveUp = 0; + if (fromQtrStartDate.before(from)) { + moveUp = 3 - (fromMonth % 3); } + + if (months % 3 != 0) { + months = months - (months % 3); + } + return (months - moveUp) / 3; } public static int getYearsBetween(Date from, Date to) { - from = DateUtils.round(from, Calendar.YEAR); - to = DateUtils.truncate(to, Calendar.YEAR); - int years = 0; - from = DateUtils.addYears(from, 1); - - while (to.after(from)) { - from = DateUtils.addYears(from, 1); - years++; + int months = getMonthsBetween(from, to); + if (months < 12) { + return 0; + } + + // Get start of year for 'from' date + Calendar cal = Calendar.getInstance(); + cal.setTime(from); + int fromMonth = cal.get(Calendar.MONTH); + int fromYear = cal.get(Calendar.YEAR); + + cal.clear(); + cal.set(Calendar.MONTH, Calendar.JANUARY); + cal.set(Calendar.YEAR, fromYear); + cal.set(Calendar.DAY_OF_MONTH, 1); + + Date yearStartDate = cal.getTime(); + + int moveUp = 0; + if (yearStartDate.before(from)) { + moveUp = 12 - (fromMonth % 12); } - return years; + + if (months % 12 != 0) { + months = months - (months % 12); + } + + return (months - moveUp)/ 12; + } + + public static int getWeeksBetween(Date from, Date to) { + int dayDiff = 0; + Date tmpFrom = from; + while (tmpFrom.before(to)) { + tmpFrom = DateUtils.addDays(tmpFrom, 1); + dayDiff++; + } + + if (dayDiff < 7) { + return 0; + } + + Calendar cal = Calendar.getInstance(); + cal.setTime(from); + int fromWeek = cal.get(Calendar.WEEK_OF_YEAR); + int fromDay = cal.get(Calendar.DAY_OF_WEEK); + int fromYear = cal.get(Calendar.YEAR); + + cal.clear(); + cal.set(Calendar.YEAR, fromYear); + cal.set(Calendar.WEEK_OF_YEAR, fromWeek); + cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); + int maxDayInWeek = cal.getActualMaximum(Calendar.DAY_OF_WEEK); + Date fromWeekStartDate = cal.getTime(); + + if (fromWeekStartDate.before(from)) { + // Count from the start of next week + dayDiff -= (maxDayInWeek - (fromDay - Calendar.SUNDAY)); + } + + return dayDiff / 7; } } Modified: hive/branches/HIVE-4115/ql/src/test/org/apache/hadoop/hive/ql/cube/parse/TestDateUtil.java URL: http://svn.apache.org/viewvc/hive/branches/HIVE-4115/ql/src/test/org/apache/hadoop/hive/ql/cube/parse/TestDateUtil.java?rev=1487438&r1=1487437&r2=1487438&view=diff ============================================================================== --- hive/branches/HIVE-4115/ql/src/test/org/apache/hadoop/hive/ql/cube/parse/TestDateUtil.java (original) +++ hive/branches/HIVE-4115/ql/src/test/org/apache/hadoop/hive/ql/cube/parse/TestDateUtil.java Wed May 29 11:12:15 2013 @@ -2,10 +2,13 @@ package org.apache.hadoop.hive.ql.cube.p import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Calendar; import java.util.Date; import junit.framework.Assert; +import org.apache.commons.lang.time.DateUtils; +import org.junit.Before; import org.junit.Test; /** @@ -20,14 +23,17 @@ public class TestDateUtil { "2013-Jan-01", "2013-Dec-31", "2013-Feb-01", "2013-Apr-25", "2012-Feb-01", "2013-Feb-01", - "2011-Feb-01", "2013-Feb-01" + "2011-Feb-01", "2013-Feb-01", + "2013-Jan-02", "2013-Feb-02", + "2013-Jan-02", "2013-Mar-02", }; public static final SimpleDateFormat DATE_FMT = new SimpleDateFormat("yyyy-MMM-dd"); - private final Date pairs[]; + private Date pairs[]; - public TestDateUtil() { + @Before + public void setUp() { pairs = new Date[testpairs.length]; for (int i = 0; i < testpairs.length; i++) { try { @@ -41,65 +47,120 @@ public class TestDateUtil { @Test public void testMonthsBetween() throws Exception { int i = 0; - Assert.assertEquals(0, DateUtil.getMonthsBetween(pairs[i], pairs[i+1])); + Assert.assertEquals("2013-Jan-01 to 2013-Jan-31", + 1, DateUtil.getMonthsBetween(pairs[i], + DateUtils.round(pairs[i+1], Calendar.MONTH))); i+=2; - Assert.assertEquals(3, DateUtil.getMonthsBetween(pairs[i], pairs[i+1])); + Assert.assertEquals("2013-Jan-01 to 2013-May-31", + 5, DateUtil.getMonthsBetween(pairs[i], + DateUtils.round(pairs[i+1], Calendar.MONTH))); i+=2; - Assert.assertEquals(10, DateUtil.getMonthsBetween(pairs[i], pairs[i+1])); + Assert.assertEquals("2013-Jan-01 to 2013-Dec-31", + 12, + DateUtil.getMonthsBetween(pairs[i], DateUtils.round(pairs[i+1], Calendar.MONTH))); i+=2; - Assert.assertEquals(1, DateUtil.getMonthsBetween(pairs[i], pairs[i+1])); + Assert.assertEquals("2013-Feb-01 to 2013-Apr-25", + 2, DateUtil.getMonthsBetween(pairs[i], pairs[i+1])); i+=2; - Assert.assertEquals(11, DateUtil.getMonthsBetween(pairs[i], pairs[i+1])); + Assert.assertEquals("2012-Feb-01 to 2013-Feb-01", + 12, DateUtil.getMonthsBetween(pairs[i], pairs[i+1])); i+=2; - Assert.assertEquals(23, DateUtil.getMonthsBetween(pairs[i], pairs[i+1])); + Assert.assertEquals("2011-Feb-01 to 2013-Feb-01", + 24, DateUtil.getMonthsBetween(pairs[i], pairs[i+1])); + + i+=2; + Assert.assertEquals("2013-Jan-02 to 2013-Feb-02", + 0, + DateUtil.getMonthsBetween(pairs[i], pairs[i+1])); + + i+=2; + Assert.assertEquals( "2013-Jan-02 to 2013-Mar-02", + 1, DateUtil.getMonthsBetween(pairs[i], pairs[i+1])); } @Test public void testQuartersBetween() throws Exception { int i = 0; - Assert.assertEquals(0, DateUtil.getQuartersBetween(pairs[i], pairs[i+1])); + Assert.assertEquals("2013-Jan-01 to 2013-Jan-31", + 0, DateUtil.getQuartersBetween(pairs[i], pairs[i+1])); i+=2; - Assert.assertEquals(0, DateUtil.getQuartersBetween(pairs[i], pairs[i+1])); + Assert.assertEquals("2013-Jan-01 to 2013-May-31", + 1, DateUtil.getQuartersBetween(pairs[i], pairs[i+1])); i+=2; - Assert.assertEquals(2, DateUtil.getQuartersBetween(pairs[i], pairs[i+1])); + Assert.assertEquals("2013-Jan-01 to 2013-Dec-31", + 4, DateUtil.getQuartersBetween(pairs[i], DateUtils.round(pairs[i+1], Calendar.MONTH))); i+=2; - Assert.assertEquals(0, DateUtil.getQuartersBetween(pairs[i], pairs[i+1])); + Assert.assertEquals("2013-Feb-01 to 2013-Apr-25", + 0, DateUtil.getQuartersBetween(pairs[i], pairs[i+1])); i+=2; - Assert.assertEquals(3, DateUtil.getQuartersBetween(pairs[i], pairs[i+1])); + Assert.assertEquals("2012-Feb-01 to 2013-Feb-01", + 3, DateUtil.getQuartersBetween(pairs[i], pairs[i+1])); i+=2; - Assert.assertEquals(7, DateUtil.getQuartersBetween(pairs[i], pairs[i+1])); + Assert.assertEquals("2011-Feb-01 to 2013-Feb-01", + 7, DateUtil.getQuartersBetween(pairs[i], pairs[i+1])); } @Test public void testYearsBetween() throws Exception { int i = 0; - Assert.assertEquals(0, DateUtil.getYearsBetween(pairs[i], pairs[i+1])); + Assert.assertEquals( "" + pairs[i] + "->" + pairs[i+1], + 0, DateUtil.getYearsBetween(pairs[i], pairs[i+1])); i+=2; - Assert.assertEquals(0, DateUtil.getYearsBetween(pairs[i], pairs[i+1])); + Assert.assertEquals( "" + pairs[i] + "->" + pairs[i+1], + 0, DateUtil.getYearsBetween(pairs[i], pairs[i+1])); i+=2; - Assert.assertEquals(0, DateUtil.getYearsBetween(pairs[i], pairs[i+1])); + Assert.assertEquals( "" + pairs[i] + "->" + pairs[i+1], + 1, DateUtil.getYearsBetween(pairs[i], + DateUtils.round(pairs[i+1], Calendar.MONTH))); i+=2; - Assert.assertEquals(0, DateUtil.getYearsBetween(pairs[i], pairs[i+1])); + Assert.assertEquals( "" + pairs[i] + "->" + pairs[i+1], + 0, DateUtil.getYearsBetween(pairs[i], pairs[i+1])); i+=2; - Assert.assertEquals(0, DateUtil.getYearsBetween(pairs[i], pairs[i+1])); + Assert.assertEquals( "" + pairs[i] + "->" + pairs[i+1], + 0, DateUtil.getYearsBetween(pairs[i], pairs[i+1])); i+=2; - Assert.assertEquals(1, DateUtil.getYearsBetween(pairs[i], pairs[i+1])); + Assert.assertEquals( "" + pairs[i] + "->" + pairs[i+1], + 1, DateUtil.getYearsBetween(pairs[i], pairs[i+1])); + } + + @Test + public void testWeeksBetween() throws Exception { + int weeks = DateUtil.getWeeksBetween(DATE_FMT.parse("2013-May-26"), + DATE_FMT.parse("2013-Jun-2")); + Assert.assertEquals("2013-May-26 to 2013-Jun-2", 1, weeks); + + weeks = DateUtil.getWeeksBetween(DATE_FMT.parse("2013-May-27"), + DATE_FMT.parse("2013-Jun-1")); + Assert.assertEquals("2013-May-27 to 2013-Jun-1", 0, weeks); + + weeks = DateUtil.getWeeksBetween(DATE_FMT.parse("2013-May-25"), + DATE_FMT.parse("2013-Jun-2")); + Assert.assertEquals("2013-May-25 to 2013-Jun-1", 1, weeks); + + weeks = DateUtil.getWeeksBetween(DATE_FMT.parse("2013-May-26"), + DATE_FMT.parse("2013-Jun-9")); + Assert.assertEquals("2013-May-26 to 2013-Jun-8", 2, weeks); + + + weeks = DateUtil.getWeeksBetween(DATE_FMT.parse("2013-May-26"), + DATE_FMT.parse("2013-Jun-10")); + Assert.assertEquals("2013-May-26 to 2013-Jun-10", 2, weeks); } } Modified: hive/branches/HIVE-4115/ql/src/test/org/apache/hadoop/hive/ql/cube/parse/TestMaxUpdateInterval.java URL: http://svn.apache.org/viewvc/hive/branches/HIVE-4115/ql/src/test/org/apache/hadoop/hive/ql/cube/parse/TestMaxUpdateInterval.java?rev=1487438&r1=1487437&r2=1487438&view=diff ============================================================================== --- hive/branches/HIVE-4115/ql/src/test/org/apache/hadoop/hive/ql/cube/parse/TestMaxUpdateInterval.java (original) +++ hive/branches/HIVE-4115/ql/src/test/org/apache/hadoop/hive/ql/cube/parse/TestMaxUpdateInterval.java Wed May 29 11:12:15 2013 @@ -15,7 +15,7 @@ import org.junit.Test; /* * Unit test for maxUpdateIntervalIn method in CubeFactTable */ -public class TestMaxUpdateInterval<periods> { +public class TestMaxUpdateInterval { public static final String[] testpairs = { "2013-Jan-01", "2013-Jan-31", "2013-Jan-01", "2013-May-31", @@ -23,7 +23,8 @@ public class TestMaxUpdateInterval<perio "2013-Feb-01", "2013-Apr-25", "2012-Feb-01", "2013-Feb-01", "2011-Feb-01", "2013-Feb-01", - "2013-Feb-01", "2013-Feb-21" + "2013-Feb-01", "2013-Feb-21", + "2013-Feb-01", "2013-Feb-4" }; public static final SimpleDateFormat DATE_FMT = new SimpleDateFormat( @@ -49,31 +50,43 @@ public class TestMaxUpdateInterval<perio allPeriods.addAll(Arrays.asList(UpdatePeriod.values())); int i = 0; - Assert.assertEquals(UpdatePeriod.DAILY, CubeFactTable.maxIntervalInRange( + Assert.assertEquals("2013-Jan-01 to 2013-Jan-31", + UpdatePeriod.WEEKLY, CubeFactTable.maxIntervalInRange( pairs[i], pairs[i+1], allPeriods)); i+=2; - Assert.assertEquals(UpdatePeriod.MONTHLY, CubeFactTable.maxIntervalInRange( + Assert.assertEquals("2013-Jan-01 to 2013-May-31", + UpdatePeriod.QUARTERLY, CubeFactTable.maxIntervalInRange( pairs[i], pairs[i+1], allPeriods)); i+=2; - Assert.assertEquals(UpdatePeriod.QUARTERLY, CubeFactTable. + Assert.assertEquals("2013-Jan-01 to 2013-Dec-31", + UpdatePeriod.QUARTERLY, CubeFactTable. maxIntervalInRange(pairs[i], pairs[i+1], allPeriods)); i+=2; - Assert.assertEquals(UpdatePeriod.MONTHLY, CubeFactTable.maxIntervalInRange( + Assert.assertEquals("2013-Feb-01 to 2013-Apr-25", + UpdatePeriod.MONTHLY, CubeFactTable.maxIntervalInRange( pairs[i], pairs[i+1], allPeriods)); i+=2; - Assert.assertEquals(UpdatePeriod.QUARTERLY, CubeFactTable. + Assert.assertEquals("2012-Feb-01 to 2013-Feb-01", + UpdatePeriod.QUARTERLY, CubeFactTable. maxIntervalInRange(pairs[i], pairs[i+1], allPeriods)); i+=2; - Assert.assertEquals(UpdatePeriod.YEARLY, CubeFactTable.maxIntervalInRange( + Assert.assertEquals("2011-Feb-01 to 2013-Feb-01", + UpdatePeriod.YEARLY, CubeFactTable.maxIntervalInRange( pairs[i], pairs[i+1], allPeriods)); i+=2; - Assert.assertEquals(UpdatePeriod.WEEKLY, CubeFactTable.maxIntervalInRange( + Assert.assertEquals("2013-Feb-01 to 2013-Feb-21", + UpdatePeriod.WEEKLY, CubeFactTable.maxIntervalInRange( + pairs[i], pairs[i+1], allPeriods)); + + i+=2; + Assert.assertEquals("2013-Feb-01 to 2013-Feb-4", + UpdatePeriod.DAILY, CubeFactTable.maxIntervalInRange( pairs[i], pairs[i+1], allPeriods)); }