You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by gu...@apache.org on 2026/09/28 01:20:54 UTC
(spark) branch master updated: [SPARK-59534][SQL] Support implicit casting of DATE and STRING to TIMESTAMP in time_bucket
This is an automated email from the ASF dual-hosted git repository.
HyukjinKwon pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new ded027de5395 [SPARK-59534][SQL] Support implicit casting of DATE and STRING to TIMESTAMP in time_bucket
ded027de5395 is described below
commit ded027de5395f7d2c8510fa8267db03f19090632
Author: Nikolina Vraneš <ni...@databricks.com>
AuthorDate: Mon Sep 28 10:20:37 2026 +0900
[SPARK-59534][SQL] Support implicit casting of DATE and STRING to TIMESTAMP in time_bucket
### What changes were proposed in this pull request?
This PR enables implicit type coercion for the timestamp and origin arguments of
`time_bucket`. Spark casts `DATE` and `STRING` inputs to `TIMESTAMP` in both ANSI and legacy
modes.
The coercion rule leaves `TIME` inputs unchanged because converting `TIME` to `TIMESTAMP`
requires `CURRENT_DATE`. Normal input validation rejects these inputs unless the caller uses an
explicit cast. The rule continues to coerce the bucket-size argument where applicable. String
bucket sizes remain invalid, while an untyped `NULL` bucket size becomes a day-time interval.
### Why are the changes needed?
`time_bucket` rejected `DATE` and `STRING` timestamp and origin arguments instead of applying
Spark's standard timestamp coercion. A targeted rule enables these conversions without adding
an implicit, current-date-dependent conversion from `TIME`.
### Does this PR introduce _any_ user-facing change?
Yes. `time_bucket` now accepts `DATE` and `STRING` values for its timestamp and origin arguments
in both ANSI and legacy modes. For example:
```sql
SELECT time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15');
-- 2024-01-15 00:00:00
SELECT time_bucket(INTERVAL '15' MINUTE, '2024-01-15 10:23:00');
-- 2024-01-15 10:15:00
```
`TIME` requires an explicit cast to `TIMESTAMP`.
### How was this patch tested?
The patch adds ANSI and legacy type-coercion tests for `DATE` and `STRING` conversion, `TIME`
rejection, string bucket-size rejection, and untyped `NULL` bucket-size coercion. It also adds SQL
query coverage for `DATE` and `STRING` timestamp and origin arguments.
```bash
build/sbt 'catalyst/testOnly *TypeCoercionSuite -- -z "time_bucket"'
build/sbt 'sql/testOnly org.apache.spark.sql.SQLQueryTestSuite -- -z "time-bucket.sql"'
```
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: OpenAI Codex (GPT-5)
This pull request and its description were written by Isaac.
Closes #58852 from vranes/effort/time-bucket-date.
Authored-by: Nikolina Vraneš <ni...@databricks.com>
Signed-off-by: Hyukjin Kwon <hy...@databricks.com>
---
.../sql/catalyst/analysis/TypeCoercionHelper.scala | 11 +++
.../catalyst/expressions/datetimeExpressions.scala | 2 +-
.../catalyst/analysis/AnsiTypeCoercionSuite.scala | 3 +
.../sql/catalyst/analysis/TypeCoercionSuite.scala | 59 +++++++++++++-
.../sql-tests/analyzer-results/time-bucket.sql.out | 82 +++++++++++++-------
.../resources/sql-tests/inputs/time-bucket.sql | 13 +++-
.../sql-tests/results/time-bucket.sql.out | 90 +++++++++++++++-------
7 files changed, 198 insertions(+), 62 deletions(-)
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionHelper.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionHelper.scala
index 51cb4f922835..67af8f9ee111 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionHelper.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionHelper.scala
@@ -53,6 +53,7 @@ import org.apache.spark.sql.catalyst.expressions.{
SpecialFrameBoundary,
SpecifiedWindowFrame,
SubtractTimestamps,
+ TimeBucket,
TimestampAddInterval,
WindowSpecDefinition
}
@@ -711,6 +712,16 @@ abstract class TypeCoercionHelper {
}
.getOrElse(b) // If there is no applicable conversion, leave expression unchanged.
+ case t: TimeBucket =>
+ val children = t.children.zip(t.inputTypes).zipWithIndex.map {
+ case ((in, _), index) if index > 0 && in.dataType.isInstanceOf[TimeType] =>
+ // TIME-to-timestamp depends on CURRENT_DATE, so require an explicit cast.
+ in
+ case ((in, expected), _) =>
+ implicitCast(in, expected).getOrElse(in)
+ }
+ t.withNewChildren(children)
+
case e: ImplicitCastInputTypes if e.inputTypes.nonEmpty =>
val children: Seq[Expression] = e.children.zip(e.inputTypes).map {
case (in, expected) =>
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/datetimeExpressions.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/datetimeExpressions.scala
index 722265ac1c47..50f659e1f4d1 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/datetimeExpressions.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/datetimeExpressions.scala
@@ -5410,7 +5410,7 @@ object TimeBucketExpressionBuilder extends ExpressionBuilder {
expressions match {
case Seq(rawBucketSize, rawTs) =>
val bucketSize = retypeNull(rawBucketSize, DayTimeIntervalType())
- // Fall back to TimestampType for bad ts types; ExpectsInputTypes will report it.
+ // Fall back to TimestampType when ts is not a recognized timestamp type.
val tsType = rawTs.dataType match {
case t if acceptsTsType(t) => t
case _ => TimestampType
diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnsiTypeCoercionSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnsiTypeCoercionSuite.scala
index c222655525ec..107ca4300e8c 100644
--- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnsiTypeCoercionSuite.scala
+++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnsiTypeCoercionSuite.scala
@@ -61,6 +61,9 @@ class AnsiTypeCoercionSuite extends TypeCoercionSuiteBase {
override def implicitCast(e: Expression, expectedType: AbstractDataType): Option[Expression] =
AnsiTypeCoercion.implicitCast(e, expectedType)
+ override protected def implicitTypeCastsRule: TypeCoercionRule =
+ AnsiTypeCoercion.ImplicitTypeCasts
+
override def dateTimeOperationsRule: TypeCoercionRule = AnsiTypeCoercion.DateTimeOperations
private def checkWidenType(
diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionSuite.scala
index 80cdf90fc973..9c7832aae43c 100644
--- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionSuite.scala
+++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionSuite.scala
@@ -18,7 +18,7 @@
package org.apache.spark.sql.catalyst.analysis
import java.sql.Timestamp
-import java.time.{Duration, LocalDateTime, Period}
+import java.time.{Duration, LocalDateTime, LocalTime, Period}
import org.apache.spark.internal.config.Tests.IS_TESTING
import org.apache.spark.sql.catalyst.analysis.TypeCoercion._
@@ -45,6 +45,8 @@ abstract class TypeCoercionSuiteBase extends AnalysisTest {
protected def implicitCast(e: Expression, expectedType: AbstractDataType): Option[Expression]
+ protected def implicitTypeCastsRule: TypeCoercionRule
+
protected def dateTimeOperationsRule: TypeCoercionRule
protected def shouldCast(from: DataType, to: AbstractDataType, expected: DataType): Unit = {
@@ -218,6 +220,58 @@ abstract class TypeCoercionSuiteBase extends AnalysisTest {
shouldNotCast(checkedType, IntegralType)
}
+ test("time_bucket implicitly casts date and string timestamp arguments") {
+ val bucketSize = Literal(Duration.ofMinutes(15))
+ val date = Literal(0, DateType)
+ val string = Literal("2024-01-01 00:00:00")
+
+ ruleTest(
+ rule = implicitTypeCastsRule,
+ initial = TimeBucket(bucketSize = bucketSize, ts = date, originTs = string),
+ transformed = TimeBucket(
+ bucketSize = bucketSize,
+ ts = Cast(date, TimestampType),
+ originTs = Cast(string, TimestampType)))
+ }
+
+ test("time_bucket does not implicitly cast time arguments to timestamp") {
+ val bucketSize = Literal(Duration.ofMinutes(15))
+ val time = Literal(LocalTime.of(10, 23, 0))
+ val timeBucket = TimeBucket(bucketSize = bucketSize, ts = time, originTs = time)
+
+ ruleTest(
+ rule = implicitTypeCastsRule,
+ initial = timeBucket,
+ transformed = timeBucket)
+ }
+
+ test("time_bucket does not implicitly cast string bucket size") {
+ val bucketSize = Literal("0 00:15:00")
+ val timestamp = Literal(Timestamp.valueOf("2024-01-01 00:00:00"))
+ val timeBucket = TimeBucket(
+ bucketSize = bucketSize,
+ ts = timestamp,
+ originTs = timestamp)
+
+ ruleTest(
+ rule = implicitTypeCastsRule,
+ initial = timeBucket,
+ transformed = timeBucket)
+ }
+
+ test("time_bucket implicitly casts null bucket size to day-time interval") {
+ val bucketSize = Literal(null)
+ val timestamp = Literal(Timestamp.valueOf("2024-01-01 00:00:00"))
+
+ ruleTest(
+ rule = implicitTypeCastsRule,
+ initial = TimeBucket(bucketSize = bucketSize, ts = timestamp, originTs = timestamp),
+ transformed = TimeBucket(
+ bucketSize = Cast(bucketSize, DayTimeIntervalType()),
+ ts = timestamp,
+ originTs = timestamp))
+ }
+
test("SPARK-56152: implicit type cast - TimeType") {
val checkedType = TimeType()
checkTypeCasting(checkedType, castableTypes = Seq(checkedType, StringType) ++ datetimeTypes)
@@ -600,6 +654,9 @@ class TypeCoercionSuite extends TypeCoercionSuiteBase {
override def implicitCast(e: Expression, expectedType: AbstractDataType): Option[Expression] =
TypeCoercion.implicitCast(e, expectedType)
+ override protected def implicitTypeCastsRule: TypeCoercionRule =
+ TypeCoercion.ImplicitTypeCasts
+
override def dateTimeOperationsRule: TypeCoercionRule = TypeCoercion.DateTimeOperations
private def checkWidenType(
diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/time-bucket.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/time-bucket.sql.out
index 2bc6cc2be0f1..954b7e82b4bb 100644
--- a/sql/core/src/test/resources/sql-tests/analyzer-results/time-bucket.sql.out
+++ b/sql/core/src/test/resources/sql-tests/analyzer-results/time-bucket.sql.out
@@ -310,95 +310,119 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException
-- !query
SELECT time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15')
-- !query analysis
+[Analyzer test output redacted due to nondeterminism]
+
+
+-- !query
+SELECT time_bucket(INTERVAL '15' MINUTE, '2024-01-15 10:23:00')
+-- !query analysis
+[Analyzer test output redacted due to nondeterminism]
+
+
+-- !query
+SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', DATE '2024-01-01')
+-- !query analysis
+[Analyzer test output redacted due to nondeterminism]
+
+
+-- !query
+SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', '2024-01-01 00:00:00')
+-- !query analysis
+[Analyzer test output redacted due to nondeterminism]
+
+
+-- !query
+SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP_NTZ '2024-01-15 10:23:00', DATE '2024-01-01')
+-- !query analysis
org.apache.spark.sql.catalyst.ExtendedAnalysisException
{
"errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
"sqlState" : "42K09",
"messageParameters" : {
- "inputSql" : "\"DATE '2024-01-15'\"",
- "inputType" : "\"DATE\"",
- "paramIndex" : "second",
- "requiredType" : "(\"(TIMESTAMP OR TIMESTAMP WITHOUT TIME ZONE)\" or \"(TIMESTAMP_LTZ(P) OR TIMESTAMP_NTZ(P) WITH P IN [7, 9])\")",
- "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15', TIMESTAMP '1970-01-01 00:00:00')\""
+ "inputSql" : "\"DATE '2024-01-01'\"",
+ "inputType" : "\"TIMESTAMP\"",
+ "paramIndex" : "third",
+ "requiredType" : "\"TIMESTAMP_NTZ\"",
+ "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, TIMESTAMP_NTZ '2024-01-15 10:23:00', DATE '2024-01-01')\""
},
"queryContext" : [ {
"objectType" : "",
"objectName" : "",
"startIndex" : 8,
- "stopIndex" : 59,
- "fragment" : "time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15')"
+ "stopIndex" : 96,
+ "fragment" : "time_bucket(INTERVAL '15' MINUTE, TIMESTAMP_NTZ '2024-01-15 10:23:00', DATE '2024-01-01')"
} ]
}
-- !query
-SELECT time_bucket(INTERVAL '15' MINUTE, '2024-01-15 10:23:00')
+SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP_NTZ '2024-01-15 10:23:00', '2024-01-01 00:00:00')
-- !query analysis
org.apache.spark.sql.catalyst.ExtendedAnalysisException
{
"errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
"sqlState" : "42K09",
"messageParameters" : {
- "inputSql" : "\"2024-01-15 10:23:00\"",
- "inputType" : "\"STRING\"",
- "paramIndex" : "second",
- "requiredType" : "(\"(TIMESTAMP OR TIMESTAMP WITHOUT TIME ZONE)\" or \"(TIMESTAMP_LTZ(P) OR TIMESTAMP_NTZ(P) WITH P IN [7, 9])\")",
- "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, 2024-01-15 10:23:00, TIMESTAMP '1970-01-01 00:00:00')\""
+ "inputSql" : "\"2024-01-01 00:00:00\"",
+ "inputType" : "\"TIMESTAMP\"",
+ "paramIndex" : "third",
+ "requiredType" : "\"TIMESTAMP_NTZ\"",
+ "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, TIMESTAMP_NTZ '2024-01-15 10:23:00', 2024-01-01 00:00:00)\""
},
"queryContext" : [ {
"objectType" : "",
"objectName" : "",
"startIndex" : 8,
- "stopIndex" : 63,
- "fragment" : "time_bucket(INTERVAL '15' MINUTE, '2024-01-15 10:23:00')"
+ "stopIndex" : 100,
+ "fragment" : "time_bucket(INTERVAL '15' MINUTE, TIMESTAMP_NTZ '2024-01-15 10:23:00', '2024-01-01 00:00:00')"
} ]
}
-- !query
-SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', DATE '2024-01-01')
+SELECT time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15', TIMESTAMP_NTZ '2024-01-01 00:00:00')
-- !query analysis
org.apache.spark.sql.catalyst.ExtendedAnalysisException
{
"errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
"sqlState" : "42K09",
"messageParameters" : {
- "inputSql" : "\"DATE '2024-01-01'\"",
- "inputType" : "\"DATE\"",
+ "inputSql" : "\"TIMESTAMP_NTZ '2024-01-01 00:00:00'\"",
+ "inputType" : "\"TIMESTAMP_NTZ\"",
"paramIndex" : "third",
- "requiredType" : "(\"(TIMESTAMP OR TIMESTAMP WITHOUT TIME ZONE)\" or \"(TIMESTAMP_LTZ(P) OR TIMESTAMP_NTZ(P) WITH P IN [7, 9])\")",
- "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', DATE '2024-01-01')\""
+ "requiredType" : "\"TIMESTAMP\"",
+ "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15', TIMESTAMP_NTZ '2024-01-01 00:00:00')\""
},
"queryContext" : [ {
"objectType" : "",
"objectName" : "",
"startIndex" : 8,
- "stopIndex" : 92,
- "fragment" : "time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', DATE '2024-01-01')"
+ "stopIndex" : 96,
+ "fragment" : "time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15', TIMESTAMP_NTZ '2024-01-01 00:00:00')"
} ]
}
-- !query
-SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', '2024-01-01 00:00:00')
+SELECT time_bucket(INTERVAL '15' MINUTE, '2024-01-15 10:23:00', TIMESTAMP_NTZ '2024-01-01 00:00:00')
-- !query analysis
org.apache.spark.sql.catalyst.ExtendedAnalysisException
{
"errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
"sqlState" : "42K09",
"messageParameters" : {
- "inputSql" : "\"2024-01-01 00:00:00\"",
- "inputType" : "\"STRING\"",
+ "inputSql" : "\"TIMESTAMP_NTZ '2024-01-01 00:00:00'\"",
+ "inputType" : "\"TIMESTAMP_NTZ\"",
"paramIndex" : "third",
- "requiredType" : "(\"(TIMESTAMP OR TIMESTAMP WITHOUT TIME ZONE)\" or \"(TIMESTAMP_LTZ(P) OR TIMESTAMP_NTZ(P) WITH P IN [7, 9])\")",
- "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', 2024-01-01 00:00:00)\""
+ "requiredType" : "\"TIMESTAMP\"",
+ "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, 2024-01-15 10:23:00, TIMESTAMP_NTZ '2024-01-01 00:00:00')\""
},
"queryContext" : [ {
"objectType" : "",
"objectName" : "",
"startIndex" : 8,
- "stopIndex" : 96,
- "fragment" : "time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', '2024-01-01 00:00:00')"
+ "stopIndex" : 100,
+ "fragment" : "time_bucket(INTERVAL '15' MINUTE, '2024-01-15 10:23:00', TIMESTAMP_NTZ '2024-01-01 00:00:00')"
} ]
}
diff --git a/sql/core/src/test/resources/sql-tests/inputs/time-bucket.sql b/sql/core/src/test/resources/sql-tests/inputs/time-bucket.sql
index d13ad227a0ea..52cad7bae848 100644
--- a/sql/core/src/test/resources/sql-tests/inputs/time-bucket.sql
+++ b/sql/core/src/test/resources/sql-tests/inputs/time-bucket.sql
@@ -37,14 +37,23 @@ SELECT time_bucket(INTERVAL '1' HOUR, TIMESTAMP_NTZ '2024-01-01 11:27:00', TIMES
-- bucket_size must be an interval (not a string)
SELECT time_bucket('15 minutes', TIMESTAMP '2024-01-15 10:23:00');
--- ts must be TIMESTAMP or TIMESTAMP_NTZ (not DATE or string)
+-- Implicit casts for timestamp arguments
+
+-- DATE and string ts values cast to TIMESTAMP
SELECT time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15');
SELECT time_bucket(INTERVAL '15' MINUTE, '2024-01-15 10:23:00');
--- origin must be TIMESTAMP or TIMESTAMP_NTZ (not DATE or string)
+-- DATE and string origin values cast to TIMESTAMP
SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', DATE '2024-01-01');
SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', '2024-01-01 00:00:00');
+-- DATE and string cast to TIMESTAMP (LTZ). Mixing them with TIMESTAMP_NTZ
+-- makes ts and origin different types, so the call is rejected.
+SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP_NTZ '2024-01-15 10:23:00', DATE '2024-01-01');
+SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP_NTZ '2024-01-15 10:23:00', '2024-01-01 00:00:00');
+SELECT time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15', TIMESTAMP_NTZ '2024-01-01 00:00:00');
+SELECT time_bucket(INTERVAL '15' MINUTE, '2024-01-15 10:23:00', TIMESTAMP_NTZ '2024-01-01 00:00:00');
+
-- Error: bucket_size and origin must be foldable
diff --git a/sql/core/src/test/resources/sql-tests/results/time-bucket.sql.out b/sql/core/src/test/resources/sql-tests/results/time-bucket.sql.out
index 7e59efc9c1e0..b5f734aa9840 100644
--- a/sql/core/src/test/resources/sql-tests/results/time-bucket.sql.out
+++ b/sql/core/src/test/resources/sql-tests/results/time-bucket.sql.out
@@ -338,6 +338,38 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException
-- !query
SELECT time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15')
-- !query schema
+struct<time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15', TIMESTAMP '1970-01-01 00:00:00'):timestamp>
+-- !query output
+2024-01-15 00:00:00
+
+
+-- !query
+SELECT time_bucket(INTERVAL '15' MINUTE, '2024-01-15 10:23:00')
+-- !query schema
+struct<time_bucket(INTERVAL '15' MINUTE, 2024-01-15 10:23:00, TIMESTAMP '1970-01-01 00:00:00'):timestamp>
+-- !query output
+2024-01-15 10:15:00
+
+
+-- !query
+SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', DATE '2024-01-01')
+-- !query schema
+struct<time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', DATE '2024-01-01'):timestamp>
+-- !query output
+2024-01-15 10:15:00
+
+
+-- !query
+SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', '2024-01-01 00:00:00')
+-- !query schema
+struct<time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', 2024-01-01 00:00:00):timestamp>
+-- !query output
+2024-01-15 10:15:00
+
+
+-- !query
+SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP_NTZ '2024-01-15 10:23:00', DATE '2024-01-01')
+-- !query schema
struct<>
-- !query output
org.apache.spark.sql.catalyst.ExtendedAnalysisException
@@ -345,24 +377,24 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException
"errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
"sqlState" : "42K09",
"messageParameters" : {
- "inputSql" : "\"DATE '2024-01-15'\"",
- "inputType" : "\"DATE\"",
- "paramIndex" : "second",
- "requiredType" : "(\"(TIMESTAMP OR TIMESTAMP WITHOUT TIME ZONE)\" or \"(TIMESTAMP_LTZ(P) OR TIMESTAMP_NTZ(P) WITH P IN [7, 9])\")",
- "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15', TIMESTAMP '1970-01-01 00:00:00')\""
+ "inputSql" : "\"DATE '2024-01-01'\"",
+ "inputType" : "\"TIMESTAMP\"",
+ "paramIndex" : "third",
+ "requiredType" : "\"TIMESTAMP_NTZ\"",
+ "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, TIMESTAMP_NTZ '2024-01-15 10:23:00', DATE '2024-01-01')\""
},
"queryContext" : [ {
"objectType" : "",
"objectName" : "",
"startIndex" : 8,
- "stopIndex" : 59,
- "fragment" : "time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15')"
+ "stopIndex" : 96,
+ "fragment" : "time_bucket(INTERVAL '15' MINUTE, TIMESTAMP_NTZ '2024-01-15 10:23:00', DATE '2024-01-01')"
} ]
}
-- !query
-SELECT time_bucket(INTERVAL '15' MINUTE, '2024-01-15 10:23:00')
+SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP_NTZ '2024-01-15 10:23:00', '2024-01-01 00:00:00')
-- !query schema
struct<>
-- !query output
@@ -371,24 +403,24 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException
"errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
"sqlState" : "42K09",
"messageParameters" : {
- "inputSql" : "\"2024-01-15 10:23:00\"",
- "inputType" : "\"STRING\"",
- "paramIndex" : "second",
- "requiredType" : "(\"(TIMESTAMP OR TIMESTAMP WITHOUT TIME ZONE)\" or \"(TIMESTAMP_LTZ(P) OR TIMESTAMP_NTZ(P) WITH P IN [7, 9])\")",
- "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, 2024-01-15 10:23:00, TIMESTAMP '1970-01-01 00:00:00')\""
+ "inputSql" : "\"2024-01-01 00:00:00\"",
+ "inputType" : "\"TIMESTAMP\"",
+ "paramIndex" : "third",
+ "requiredType" : "\"TIMESTAMP_NTZ\"",
+ "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, TIMESTAMP_NTZ '2024-01-15 10:23:00', 2024-01-01 00:00:00)\""
},
"queryContext" : [ {
"objectType" : "",
"objectName" : "",
"startIndex" : 8,
- "stopIndex" : 63,
- "fragment" : "time_bucket(INTERVAL '15' MINUTE, '2024-01-15 10:23:00')"
+ "stopIndex" : 100,
+ "fragment" : "time_bucket(INTERVAL '15' MINUTE, TIMESTAMP_NTZ '2024-01-15 10:23:00', '2024-01-01 00:00:00')"
} ]
}
-- !query
-SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', DATE '2024-01-01')
+SELECT time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15', TIMESTAMP_NTZ '2024-01-01 00:00:00')
-- !query schema
struct<>
-- !query output
@@ -397,24 +429,24 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException
"errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
"sqlState" : "42K09",
"messageParameters" : {
- "inputSql" : "\"DATE '2024-01-01'\"",
- "inputType" : "\"DATE\"",
+ "inputSql" : "\"TIMESTAMP_NTZ '2024-01-01 00:00:00'\"",
+ "inputType" : "\"TIMESTAMP_NTZ\"",
"paramIndex" : "third",
- "requiredType" : "(\"(TIMESTAMP OR TIMESTAMP WITHOUT TIME ZONE)\" or \"(TIMESTAMP_LTZ(P) OR TIMESTAMP_NTZ(P) WITH P IN [7, 9])\")",
- "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', DATE '2024-01-01')\""
+ "requiredType" : "\"TIMESTAMP\"",
+ "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15', TIMESTAMP_NTZ '2024-01-01 00:00:00')\""
},
"queryContext" : [ {
"objectType" : "",
"objectName" : "",
"startIndex" : 8,
- "stopIndex" : 92,
- "fragment" : "time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', DATE '2024-01-01')"
+ "stopIndex" : 96,
+ "fragment" : "time_bucket(INTERVAL '15' MINUTE, DATE '2024-01-15', TIMESTAMP_NTZ '2024-01-01 00:00:00')"
} ]
}
-- !query
-SELECT time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', '2024-01-01 00:00:00')
+SELECT time_bucket(INTERVAL '15' MINUTE, '2024-01-15 10:23:00', TIMESTAMP_NTZ '2024-01-01 00:00:00')
-- !query schema
struct<>
-- !query output
@@ -423,18 +455,18 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException
"errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
"sqlState" : "42K09",
"messageParameters" : {
- "inputSql" : "\"2024-01-01 00:00:00\"",
- "inputType" : "\"STRING\"",
+ "inputSql" : "\"TIMESTAMP_NTZ '2024-01-01 00:00:00'\"",
+ "inputType" : "\"TIMESTAMP_NTZ\"",
"paramIndex" : "third",
- "requiredType" : "(\"(TIMESTAMP OR TIMESTAMP WITHOUT TIME ZONE)\" or \"(TIMESTAMP_LTZ(P) OR TIMESTAMP_NTZ(P) WITH P IN [7, 9])\")",
- "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', 2024-01-01 00:00:00)\""
+ "requiredType" : "\"TIMESTAMP\"",
+ "sqlExpr" : "\"time_bucket(INTERVAL '15' MINUTE, 2024-01-15 10:23:00, TIMESTAMP_NTZ '2024-01-01 00:00:00')\""
},
"queryContext" : [ {
"objectType" : "",
"objectName" : "",
"startIndex" : 8,
- "stopIndex" : 96,
- "fragment" : "time_bucket(INTERVAL '15' MINUTE, TIMESTAMP '2024-01-15 10:23:00', '2024-01-01 00:00:00')"
+ "stopIndex" : 100,
+ "fragment" : "time_bucket(INTERVAL '15' MINUTE, '2024-01-15 10:23:00', TIMESTAMP_NTZ '2024-01-01 00:00:00')"
} ]
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org