Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions babel/src/main/codegen/config.fmpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,8 @@ data: {
# Example: "DateFunctionCall()".
builtinFunctionCallMethods: [
"DateFunctionCall()"
"TimestampFunctionCall()"
"TimeFunctionCall()"
"DateaddFunctionCall()"
]

Expand Down
42 changes: 41 additions & 1 deletion babel/src/main/codegen/includes/parserImpls.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ JoinType LeftSemiJoin() :

SqlNode DateFunctionCall() :
{
final SqlFunctionCategory funcType = SqlFunctionCategory.USER_DEFINED_FUNCTION;
final SqlFunctionCategory funcType = SqlFunctionCategory.TIMEDATE;
final SqlIdentifier qualifiedName;
final Span s;
final SqlLiteral quantifier;
Expand All @@ -42,6 +42,46 @@ SqlNode DateFunctionCall() :
}
}

SqlNode TimestampFunctionCall() :
{
final SqlFunctionCategory funcType = SqlFunctionCategory.TIMEDATE;
final SqlIdentifier qualifiedName;
final Span s;
final SqlLiteral quantifier;
final List<? extends SqlNode> args;
}
{
<TIMESTAMP> {
s = span();
qualifiedName = new SqlIdentifier(unquotedIdentifier(), getPos());
}
args = FunctionParameterList(ExprContext.ACCEPT_SUB_QUERY) {
quantifier = (SqlLiteral) args.get(0);
args.remove(0);
return createCall(qualifiedName, s.end(this), funcType, quantifier, args);
}
}

SqlNode TimeFunctionCall() :
{
final SqlFunctionCategory funcType = SqlFunctionCategory.TIMEDATE;
final SqlIdentifier qualifiedName;
final Span s;
final SqlLiteral quantifier;
final List<? extends SqlNode> args;
}
{
<TIME> {
s = span();
qualifiedName = new SqlIdentifier(unquotedIdentifier(), getPos());
}
args = FunctionParameterList(ExprContext.ACCEPT_SUB_QUERY) {
quantifier = (SqlLiteral) args.get(0);
args.remove(0);
return createCall(qualifiedName, s.end(this), funcType, quantifier, args);
}
}

SqlNode DateaddFunctionCall() :
{
final Span s;
Expand Down
140 changes: 129 additions & 11 deletions babel/src/test/resources/sql/big-query.iq
Original file line number Diff line number Diff line change
Expand Up @@ -1051,29 +1051,147 @@ select unix_date(timestamp '2008-12-25') as d;

!ok

#####################################################################
# DATE
# 'date(x) is shorthand for 'cast(x as date)'
select date('1970-01-01') as d;
#
# 1. DATE(year, month, day)
# 2. DATE(timestamp_expression[, time_zone])
# 3. DATE(datetime_expression)
#
# 1. Constructs a DATE from INT64 values representing the year, month, and day.
# 1. Extracts the DATE from a TIMESTAMP expression. It supports an optional
# parameter to specify a time zone. If no time zone is specified, the default
# time zone, UTC, is used.
# 1. Extracts the DATE from a DATETIME expression.
#
# Return Data Type: DATE

select date(2022, 11, 15) as d;
+------------+
| d |
+------------+
| 1970-01-01 |
| 2022-11-15 |
+------------+
(1 row)

!ok

!if (false) {
select date(cast(null as varchar(10))) as d;
+---+
| D |
+---+
| |
+---+
#####################################################################
# TIMESTAMP
#
# TIMESTAMP(string_expression[, time_zone])
# TIMESTAMP(date_expression[, time_zone])
# TIMESTAMP(datetime_expression[, time_zone])
#
# - string_expression[, time_zone]:
# Converts a STRING expression to a TIMESTAMP data type. string_expression
# must include a timestamp literal. If string_expression includes a time_zone
# in the timestamp literal, do not include an explicit time_zone argument.
# - date_expression[, time_zone]: Converts a DATE object to a TIMESTAMP data
# type.
# - datetime_expression[, time_zone]: Converts a DATETIME object to a TIMESTAMP
# data type.
#
# This function supports an optional parameter to specify a time zone. If no
# time zone is specified, the default time zone, UTC, is used.
#
# Return Data Type: TIMESTAMP

# All these timestamps should be equal.
# This tests the BQ timestamp literal string formatter
# (optional 'T', optional leading zeros, optional offset with conversion).
select timestamp("2008-01-01 01:03:05+00") as t_space,
timestamp("2008-01-01T01:03:05+00") as t_iso,
timestamp("2008-01-01 01:03:05") as t_no_offset,
timestamp("2008-1-1 3:5:7+02:02:02") as t_offset;
+---------------------+---------------------+---------------------+---------------------+
| t_space | t_iso | t_no_offset | t_offset |
+---------------------+---------------------+---------------------+---------------------+
| 2008-01-01 01:03:05 | 2008-01-01 01:03:05 | 2008-01-01 01:03:05 | 2008-01-01 01:03:05 |
+---------------------+---------------------+---------------------+---------------------+
(1 row)

!ok

#####################################################################
# TIME
#
# 1. TIME(hour, minute, second)
# 2. TIME(timestamp[, time_zone])
# 3. TIME(datetime)
#
# 1. Constructs a TIME object using INT64 values representing the hour, minute,
# and second.
# 2. Constructs a TIME object using a TIMESTAMP object. It supports an optional
# parameter to specify a time zone. If no time zone is specified, the default
# time zone, UTC, is used.
# 3. Constructs a TIME object using a DATETIME object.
#
# Return Data Type: TIMESTAMP

select time(12, 30, 59) as t;
+----------+
| t |
+----------+
| 12:30:59 |
+----------+
(1 row)

!ok

# Test timezone conversion when converting TIMESTAMP to DATE.
# Denver observes DST whereas Phoenix does not.
# Both cities have a -07:00 offset in winter, but Denver has -06:00 in summer.
select date(timestamp("2008-06-21 06:30:00")) as sum_utc,
date(timestamp("2008-06-21 06:30:00"), "America/Denver") as sum_dst,
date(timestamp("2008-06-21 06:30:00"), "America/Phoenix") as sum_std,
date(timestamp("2008-12-21 06:30:00")) as win_utc,
date(timestamp("2008-12-21 06:30:00"), "America/Denver") as win_dst,
date(timestamp("2008-12-21 06:30:00"), "America/Phoenix") as win_std;
+------------+------------+------------+------------+------------+------------+
| sum_utc | sum_dst | sum_std | win_utc | win_dst | win_std |
+------------+------------+------------+------------+------------+------------+
| 2008-06-21 | 2008-06-21 | 2008-06-20 | 2008-12-21 | 2008-12-20 | 2008-12-20 |
+------------+------------+------------+------------+------------+------------+
(1 row)

!ok

# Test timezone conversion when converting TIMESTAMP to TIME.
# Denver observes DST whereas Phoenix does not.
# Both cities have a -07:00 offset in winter, but Denver has -06:00 in summer.
select time(timestamp("2008-06-21 06:30:00")) as sum_utc,
time(timestamp("2008-06-21 06:30:00"), "America/Denver") as sum_dst,
time(timestamp("2008-06-21 06:30:00"), "America/Phoenix") as sum_std,
time(timestamp("2008-12-21 06:30:00")) as win_utc,
time(timestamp("2008-12-21 06:30:00"), "America/Denver") as win_dst,
time(timestamp("2008-12-21 06:30:00"), "America/Phoenix") as win_std;
+----------+----------+----------+----------+----------+----------+
| sum_utc | sum_dst | sum_std | win_utc | win_dst | win_std |
+----------+----------+----------+----------+----------+----------+
| 06:30:00 | 00:30:00 | 23:30:00 | 06:30:00 | 23:30:00 | 23:30:00 |
+----------+----------+----------+----------+----------+----------+
(1 row)

!ok

# Test timezone conversion when converting DATE to TIMESTAMP.
# Denver observes DST whereas Phoenix does not.
# Both cities have a -07:00 offset in winter, but Denver has -06:00 in summer.
select timestamp(date(2008, 6, 21)) as sum_utc,
timestamp(date(2008, 6, 21), "America/Denver") as sum_dst,
timestamp(date(2008, 6, 21), "America/Phoenix") as sum_std,
timestamp(date(2008, 12, 21)) as win_utc,
timestamp(date(2008, 12, 21), "America/Denver") as win_dst,
timestamp(date(2008, 12, 21), "America/Phoenix") as win_std;
+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+
| sum_utc | sum_dst | sum_std | win_utc | win_dst | win_std |
+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+
| 2008-06-21 00:00:00 | 2008-06-21 06:00:00 | 2008-06-21 07:00:00 | 2008-12-21 00:00:00 | 2008-12-21 07:00:00 | 2008-12-21 07:00:00 |
+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+
(1 row)

!ok
!}

#####################################################################
# DATE_ADD
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@
import static org.apache.calcite.sql.fun.SqlLibraryOperators.SPACE;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.STRCMP;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.TANH;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.TIME;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.TIMESTAMP;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.TIMESTAMP_MICROS;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.TIMESTAMP_MILLIS;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.TIMESTAMP_SECONDS;
Expand Down Expand Up @@ -529,6 +531,10 @@ Builder populate2() {
defineMethod(DATE_FROM_UNIX_DATE, "dateFromUnixDate", NullPolicy.STRICT);
defineMethod(UNIX_DATE, "unixDate", NullPolicy.STRICT);

defineMethod(DATE, "date", NullPolicy.STRICT);
defineMethod(TIMESTAMP, "timestamp", NullPolicy.STRICT);
defineMethod(TIME, "time", NullPolicy.STRICT);

map.put(IS_NULL, new IsNullImplementor());
map.put(IS_NOT_NULL, new IsNotNullImplementor());
map.put(IS_TRUE, new IsTrueImplementor());
Expand Down Expand Up @@ -603,7 +609,6 @@ Builder populate2() {

map.put(COALESCE, new CoalesceImplementor());
map.put(CAST, new CastImplementor());
map.put(DATE, new CastImplementor());

map.put(REINTERPRET, new ReinterpretImplementor());

Expand Down
Loading