@@ -239,22 +239,37 @@ public void testDateRangeCast() {
239239
240240 public void testDateRangeWithCurrentTimestamp () {
241241 testDateRangeWithCurrentFunctions ("CURRENT_TIMESTAMP()" , DATE_FORMAT , TestUtils .TEST_CFG .now ());
242+ testDateRangeWithCurrentFunctions_AndRangeOptimization ("CURRENT_TIMESTAMP()" , DATE_FORMAT ,
243+ TestUtils .TEST_CFG .now ().minusDays (1L ).minusSeconds (1L ),
244+ TestUtils .TEST_CFG .now ().plusDays (1L ).plusSeconds (1L ));
242245 }
243246
244247 public void testDateRangeWithCurrentDate () {
245248 testDateRangeWithCurrentFunctions ("CURRENT_DATE()" , DATE_FORMAT , DateUtils .asDateOnly (TestUtils .TEST_CFG .now ()));
249+ testDateRangeWithCurrentFunctions_AndRangeOptimization ("CURRENT_DATE()" , DATE_FORMAT ,
250+ DateUtils .asDateOnly (TestUtils .TEST_CFG .now ().minusDays (2L )),
251+ DateUtils .asDateOnly (TestUtils .TEST_CFG .now ().plusDays (1L )));
246252 }
247253
248254 public void testDateRangeWithToday () {
249255 testDateRangeWithCurrentFunctions ("TODAY()" , DATE_FORMAT , DateUtils .asDateOnly (TestUtils .TEST_CFG .now ()));
256+ testDateRangeWithCurrentFunctions_AndRangeOptimization ("TODAY()" , DATE_FORMAT ,
257+ DateUtils .asDateOnly (TestUtils .TEST_CFG .now ().minusDays (2L )),
258+ DateUtils .asDateOnly (TestUtils .TEST_CFG .now ().plusDays (1L )));
250259 }
251260
252261 public void testDateRangeWithNow () {
253262 testDateRangeWithCurrentFunctions ("NOW()" , DATE_FORMAT , TestUtils .TEST_CFG .now ());
263+ testDateRangeWithCurrentFunctions_AndRangeOptimization ("NOW()" , DATE_FORMAT ,
264+ TestUtils .TEST_CFG .now ().minusDays (1L ).minusSeconds (1L ),
265+ TestUtils .TEST_CFG .now ().plusDays (1L ).plusSeconds (1L ));
254266 }
255267
256268 public void testDateRangeWithCurrentTime () {
257269 testDateRangeWithCurrentFunctions ("CURRENT_TIME()" , TIME_FORMAT , TestUtils .TEST_CFG .now ());
270+ testDateRangeWithCurrentFunctions_AndRangeOptimization ("CURRENT_TIME()" , TIME_FORMAT ,
271+ TestUtils .TEST_CFG .now ().minusDays (1L ).minusSeconds (1L ),
272+ TestUtils .TEST_CFG .now ().plusDays (1L ).plusSeconds (1L ));
258273 }
259274
260275 private void testDateRangeWithCurrentFunctions (String function , String pattern , ZonedDateTime now ) {
@@ -292,6 +307,38 @@ private void testDateRangeWithCurrentFunctions(String function, String pattern,
292307 assertEquals (operator .equals ("=" ) || operator .equals ("!=" ) || operator .equals (">=" ), rq .includeLower ());
293308 assertEquals (pattern , rq .format ());
294309 }
310+
311+ private void testDateRangeWithCurrentFunctions_AndRangeOptimization (String function , String pattern , ZonedDateTime lowerValue ,
312+ ZonedDateTime upperValue ) {
313+ String lowerOperator = randomFrom (new String [] {"<" , "<=" });
314+ String upperOperator = randomFrom (new String [] {">" , ">=" });
315+ // use both date-only interval (1 DAY) and time-only interval (1 second) to cover CURRENT_TIMESTAMP and TODAY scenarios
316+ String interval = "(INTERVAL 1 DAY + INTERVAL 1 SECOND)" ;
317+
318+ PhysicalPlan p = optimizeAndPlan ("SELECT some.string FROM test WHERE date" + lowerOperator + function + " + " + interval
319+ + " AND date " + upperOperator + function + " - " + interval );
320+ assertEquals (EsQueryExec .class , p .getClass ());
321+ EsQueryExec eqe = (EsQueryExec ) p ;
322+ assertEquals (1 , eqe .output ().size ());
323+ assertEquals ("test.some.string" , eqe .output ().get (0 ).qualifiedName ());
324+ assertEquals (DataType .TEXT , eqe .output ().get (0 ).dataType ());
325+
326+ Query query = eqe .queryContainer ().query ();
327+ // the range queries optimization should create a single "range" query with "from" and "to" populated with the values
328+ // in the two branches of the AND condition
329+ assertTrue (query instanceof RangeQuery );
330+ RangeQuery rq = (RangeQuery ) query ;
331+ assertEquals ("date" , rq .field ());
332+
333+ assertEquals (DateFormatter .forPattern (pattern )
334+ .format (upperValue .withNano (DateUtils .getNanoPrecision (null , upperValue .getNano ()))), rq .upper ());
335+ assertEquals (DateFormatter .forPattern (pattern )
336+ .format (lowerValue .withNano (DateUtils .getNanoPrecision (null , lowerValue .getNano ()))), rq .lower ());
337+
338+ assertEquals (lowerOperator .equals ("<=" ), rq .includeUpper ());
339+ assertEquals (upperOperator .equals (">=" ), rq .includeLower ());
340+ assertEquals (pattern , rq .format ());
341+ }
295342
296343 public void testTranslateDateAdd_WhereClause_Painless () {
297344 LogicalPlan p = plan ("SELECT int FROM test WHERE DATE_ADD('quarter',int, date) > '2018-09-04'::date" );
0 commit comments