@@ -139,17 +139,55 @@ class CometTemporalExpressionSuite extends CometTestBase with AdaptiveSparkPlanH
139139 }
140140 }
141141
142- test(" unix_timestamp - timestamp_ntz input falls back to Spark" ) {
143- // TimestampNTZ is not supported because Comet incorrectly applies timezone
144- // conversion. TimestampNTZ stores local time without timezone, so the unix
145- // timestamp should just be the value divided by microseconds per second.
142+ test(" unix_timestamp - timestamp_ntz input" ) {
146143 val r = new Random (42 )
147144 val ntzSchema = StructType (Seq (StructField (" ts_ntz" , DataTypes .TimestampNTZType , true )))
148145 val ntzDF = FuzzDataGenerator .generateDataFrame(r, spark, ntzSchema, 100 , DataGenOptions ())
149146 ntzDF.createOrReplaceTempView(" ntz_tbl" )
150- checkSparkAnswerAndFallbackReason(
151- " SELECT ts_ntz, unix_timestamp(ts_ntz) from ntz_tbl order by ts_ntz" ,
152- " unix_timestamp does not support input type: TimestampNTZType" )
147+ checkSparkAnswerAndOperator(
148+ " SELECT ts_ntz, unix_timestamp(ts_ntz) from ntz_tbl order by ts_ntz" )
149+ }
150+
151+ test(" hour/minute/second - timestamp_ntz input" ) {
152+ val r = new Random (42 )
153+ val ntzSchema = StructType (Seq (StructField (" ts_ntz" , DataTypes .TimestampNTZType , true )))
154+ val ntzDF = FuzzDataGenerator .generateDataFrame(r, spark, ntzSchema, 100 , DataGenOptions ())
155+ ntzDF.createOrReplaceTempView(" ntz_tbl" )
156+ checkSparkAnswerAndOperator(
157+ " SELECT ts_ntz, hour(ts_ntz), minute(ts_ntz), second(ts_ntz) from ntz_tbl order by ts_ntz" )
158+ }
159+
160+ test(" date_trunc - timestamp_ntz input" ) {
161+ val r = new Random (42 )
162+ val ntzSchema = StructType (Seq (StructField (" ts_ntz" , DataTypes .TimestampNTZType , true )))
163+ val reasonableBaseDate =
164+ new java.text.SimpleDateFormat (" yyyy-MM-dd HH:mm:ss" ).parse(" 2024-06-15 12:00:00" ).getTime
165+ val ntzDF = FuzzDataGenerator .generateDataFrame(
166+ r,
167+ spark,
168+ ntzSchema,
169+ 100 ,
170+ DataGenOptions (baseDate = reasonableBaseDate))
171+ ntzDF.createOrReplaceTempView(" ntz_tbl" )
172+ for (format <- CometTruncTimestamp .supportedFormats) {
173+ checkSparkAnswerAndOperator(
174+ s " SELECT ts_ntz, date_trunc(' $format', ts_ntz) from ntz_tbl order by ts_ntz " )
175+ }
176+ }
177+
178+ test(" date_format - timestamp_ntz input" ) {
179+ withSQLConf(SQLConf .SESSION_LOCAL_TIMEZONE .key -> " UTC" ) {
180+ val r = new Random (42 )
181+ val ntzSchema = StructType (Seq (StructField (" ts_ntz" , DataTypes .TimestampNTZType , true )))
182+ val ntzDF = FuzzDataGenerator .generateDataFrame(r, spark, ntzSchema, 100 , DataGenOptions ())
183+ ntzDF.createOrReplaceTempView(" ntz_tbl" )
184+ val supportedFormats =
185+ CometDateFormat .supportedFormats.keys.toSeq.filterNot(_.contains(" '" ))
186+ for (format <- supportedFormats) {
187+ checkSparkAnswerAndOperator(
188+ s " SELECT ts_ntz, date_format(ts_ntz, ' $format') from ntz_tbl order by ts_ntz " )
189+ }
190+ }
153191 }
154192
155193 test(" unix_timestamp - string input falls back to Spark" ) {
0 commit comments