uros-b commented on code in PR #56944:
URL: https://github.com/apache/spark/pull/56944#discussion_r3524893433


##########
sql/core/src/test/scala/org/apache/spark/sql/streaming/EventTimeWatermarkSuite.scala:
##########
@@ -1051,4 +1052,92 @@ class EventTimeWatermarkSuite extends StreamTest with 
BeforeAndAfter with Matche
   private def awaitTermination(): AssertOnQuery = Execute("AwaitTermination") 
{ q =>
     q.awaitTermination()
   }
+
+  test("SPARK-57830: withWatermark accepts TimestampLTZNanosType column") {
+    val inputData = MemoryStream[Long]
+    // Use Complete mode so we don't need window-based eviction.
+    // This verifies the type-check fix and nanos->ms conversion in 
EventTimeWatermarkExec.
+    val aggWithWatermark = inputData.toDF()
+      .withColumn("eventTime", timestamp_nanos($"value"))
+      .withWatermark("eventTime", "10 seconds")
+      .groupBy($"eventTime")
+      .agg(count("*") as Symbol("count"))
+      .select($"count".as[Long])
+
+    testStream(aggWithWatermark, outputMode = Complete)(
+      AddData(inputData, 15L * 1000000000L),
+      CheckAnswer(1L),
+      assertEventStats(min = 15, max = 15, avg = 15, wtrmark = 0),
+      AddData(inputData, 10L * 1000000000L, 12L * 1000000000L, 14L * 
1000000000L),
+      CheckAnswer(1L, 1L, 1L, 1L),
+      assertEventStats(min = 10, max = 14, avg = 12, wtrmark = 5),
+      AddData(inputData, 25L * 1000000000L),
+      CheckAnswer(1L, 1L, 1L, 1L, 1L),
+      assertEventStats(min = 25, max = 25, avg = 25, wtrmark = 5)
+    )
+  }
+
+  test("SPARK-57830: withWatermark accepts TimestampNTZNanosType column") {
+    withSQLConf(SQLConf.SESSION_LOCAL_TIMEZONE.key -> "UTC") {
+      val inputData = MemoryStream[Long]
+      val aggWithWatermark = inputData.toDF()
+        .withColumn("eventTime",
+          timestamp_nanos($"value").cast(TimestampNTZNanosType(9)))
+        .withWatermark("eventTime", "10 seconds")
+        .groupBy($"eventTime")
+        .agg(count("*") as Symbol("count"))
+        .select($"count".as[Long])
+
+      testStream(aggWithWatermark, outputMode = Complete)(
+        AddData(inputData, 15L * 1000000000L),
+        CheckAnswer(1L),
+        assertEventStats(min = 15, max = 15, avg = 15, wtrmark = 0),
+        AddData(inputData, 10L * 1000000000L, 12L * 1000000000L, 14L * 
1000000000L),
+        CheckAnswer(1L, 1L, 1L, 1L),
+        assertEventStats(min = 10, max = 14, avg = 12, wtrmark = 5),
+        AddData(inputData, 25L * 1000000000L),
+        CheckAnswer(1L, 1L, 1L, 1L, 1L),
+        assertEventStats(min = 25, max = 25, avg = 25, wtrmark = 5)
+      )
+    }
+  }
+
+  test("SPARK-57830: nanos watermark matches micros watermark for equivalent 
instants") {
+    // Compare that the watermark advancement is identical between a micros 
and nanos column
+    // representing the same instant.
+    val inputDataMicros = MemoryStream[Int]
+    val microsDf = inputDataMicros.toDF()
+      .withColumn("eventTime", timestamp_seconds($"value"))
+      .withWatermark("eventTime", "10 seconds")
+      .groupBy($"eventTime")
+      .agg(count("*") as Symbol("count"))
+      .select($"count".as[Long])
+
+    val inputDataNanos = MemoryStream[Long]
+    val nanosDf = inputDataNanos.toDF()
+      .withColumn("eventTime", timestamp_nanos($"value"))
+      .withWatermark("eventTime", "10 seconds")
+      .groupBy($"eventTime")
+      .agg(count("*") as Symbol("count"))
+      .select($"count".as[Long])
+
+    // Run both streams with the same logical timestamps and verify same 
watermark advancement
+    testStream(microsDf, outputMode = Complete)(
+      AddData(inputDataMicros, 15),
+      CheckAnswer(1L),
+      assertEventStats(min = 15, max = 15, avg = 15, wtrmark = 0),
+      AddData(inputDataMicros, 25),
+      CheckAnswer(1L, 1L),
+      assertEventStats(min = 25, max = 25, avg = 25, wtrmark = 5)
+    )
+
+    testStream(nanosDf, outputMode = Complete)(
+      AddData(inputDataNanos, 15L * 1000000000L),
+      CheckAnswer(1L),
+      assertEventStats(min = 15, max = 15, avg = 15, wtrmark = 0),
+      AddData(inputDataNanos, 25L * 1000000000L),
+      CheckAnswer(1L, 1L),
+      assertEventStats(min = 25, max = 25, avg = 25, wtrmark = 5)
+    )
+  }

Review Comment:
   All three new tests run in Complete output mode, which skips state eviction 
(StateStoreSaveExec only evicts in Append/Update). The new watermarkLiteral 
eviction path (both the non-struct branch and the struct endFieldType branch, 
incl. LessThanOrEqual over TimestampNanosVal ordering) is therefore never 
exercised at runtime, asserted only by construction. Please consider adding an 
Append-mode test that forces eviction of a nano-event-time row.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to