Skip to content

Commit

Permalink
[CALCITE-2699] TIMESTAMPADD function now applies to DATE and TIME as …
Browse files Browse the repository at this point in the history
…well as TIMESTAMP (xuqianjin)

Close apache#936
  • Loading branch information
XuQianJin-Stars authored and julianhyde committed Dec 3, 2018
1 parent 16ebc96 commit d0bdec4
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2617,11 +2617,16 @@ public Expression implement(RexToLixTranslator translator, RexCall call,
case MINUS:
trop1 = Expressions.negate(trop1);
}
final BuiltInMethod method =
operand0.getType().getSqlTypeName() == SqlTypeName.TIMESTAMP
? BuiltInMethod.ADD_MONTHS
: BuiltInMethod.ADD_MONTHS_INT;
return Expressions.call(method.method, trop0, trop1);
switch (typeName) {
case TIME:
return Expressions.convert_(trop0, long.class);
default:
final BuiltInMethod method =
operand0.getType().getSqlTypeName() == SqlTypeName.TIMESTAMP
? BuiltInMethod.ADD_MONTHS
: BuiltInMethod.ADD_MONTHS_INT;
return Expressions.call(method.method, trop0, trop1);
}

case INTERVAL_DAY:
case INTERVAL_DAY_HOUR:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@

/**
* The <code>TIMESTAMPADD</code> function, which adds an interval to a
* timestamp.
* datetime (TIMESTAMP, TIME or DATE).
*
* <p>The SQL syntax is
*
* <blockquote>
* <code>TIMESTAMPADD(<i>timestamp interval</i>, <i>quantity</i>,
* <i>timestamp</i>)</code>
* <i>datetime</i>)</code>
* </blockquote>
*
* <p>The interval time unit can one of the following literals:<ul>
Expand All @@ -51,7 +51,7 @@
* <li>YEAR (and synonym SQL_TSI_YEAR)
* </ul>
*
* <p>Returns modified timestamp.
* <p>Returns modified datetime.
*/
public class SqlTimestampAddFunction extends SqlFunction {

Expand Down Expand Up @@ -85,7 +85,11 @@ public static RelDataType deduceType(RelDataTypeFactory typeFactory,
MICROSECOND_PRECISION);
break;
default:
type = typeFactory.createSqlType(SqlTypeName.TIMESTAMP);
if (operandType2.getSqlTypeName() == SqlTypeName.TIME) {
type = typeFactory.createSqlType(SqlTypeName.TIME);
} else {
type = typeFactory.createSqlType(SqlTypeName.TIMESTAMP);
}
}
break;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6957,6 +6957,43 @@ protected static Pair<String, Hook.Closeable> currentTimeString(TimeZone tz) {
"2016-06-30", "DATE NOT NULL");
tester.checkScalar("timestampadd(MONTH, -1, date '2016-03-31')",
"2016-02-29", "DATE NOT NULL");

// TIMESTAMPADD with time; returns a time value.The interval is positive.
tester.checkScalar("timestampadd(SECOND, 1, time '23:59:59')",
"00:00:00", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(MINUTE, 1, time '00:00:00')",
"00:01:00", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(MINUTE, 1, time '23:59:59')",
"00:00:59", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(HOUR, 1, time '23:59:59')",
"00:59:59", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(DAY, 15, time '23:59:59')",
"23:59:59", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(WEEK, 3, time '23:59:59')",
"23:59:59", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(MONTH, 6, time '23:59:59')",
"23:59:59", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(QUARTER, 1, time '23:59:59')",
"23:59:59", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(YEAR, 10, time '23:59:59')",
"23:59:59", "TIME(0) NOT NULL");
// TIMESTAMPADD with time; returns a time value .The interval is negative.
tester.checkScalar("timestampadd(SECOND, -1, time '00:00:00')",
"23:59:59", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(MINUTE, -1, time '00:00:00')",
"23:59:00", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(HOUR, -1, time '00:00:00')",
"23:00:00", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(DAY, -1, time '23:59:59')",
"23:59:59", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(WEEK, -1, time '23:59:59')",
"23:59:59", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(MONTH, -1, time '23:59:59')",
"23:59:59", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(QUARTER, -1, time '23:59:59')",
"23:59:59", "TIME(0) NOT NULL");
tester.checkScalar("timestampadd(YEAR, -1, time '23:59:59')",
"23:59:59", "TIME(0) NOT NULL");
}

@Test public void testTimestampAddFractionalSeconds() {
Expand Down
2 changes: 1 addition & 1 deletion site/_docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1473,7 +1473,7 @@ Not implemented:
| {fn HOUR(date)} | Equivalent to `EXTRACT(HOUR FROM date)`. Returns an integer between 0 and 23.
| {fn MINUTE(date)} | Equivalent to `EXTRACT(MINUTE FROM date)`. Returns an integer between 0 and 59.
| {fn SECOND(date)} | Equivalent to `EXTRACT(SECOND FROM date)`. Returns an integer between 0 and 59.
| {fn TIMESTAMPADD(timeUnit, count, timestamp)} | Adds an interval of *count* *timeUnit*s to a timestamp
| {fn TIMESTAMPADD(timeUnit, count, datetime)} | Adds an interval of *count* *timeUnit*s to a datetime
| {fn TIMESTAMPDIFF(timeUnit, timestamp1, timestamp2)} | Subtracts *timestamp1* from *timestamp2* and returns the result in *timeUnit*s

Not implemented:
Expand Down

0 comments on commit d0bdec4

Please sign in to comment.