Yaoxuan Wu created SPARK-60784:
----------------------------------

             Summary: Structured Streaming: dropDuplicates / distinct after an 
aggregation in Complete output mode drops groups from later micro-batches
                 Key: SPARK-60784
                 URL: https://issues.apache.org/jira/browse/SPARK-60784
             Project: Spark
          Issue Type: Bug
          Components: Structured Streaming
    Affects Versions: 4.1.1, 4.2.0, 3.5.8, 4.0.0
            Reporter: Yaoxuan Wu


{code:python}
import tempfile
d = tempfile.mkdtemp()
spark.createDataFrame([(1,), (2,)], "k 
int").coalesce(1).write.mode("append").parquet(d)   # file 1
spark.createDataFrame([(2,), (3,)], "k 
int").coalesce(1).write.mode("append").parquet(d)   # file 2

batches = {}
q = (spark.readStream.schema("k int").option("maxFilesPerTrigger", 1).parquet(d)
     .groupBy("k").count().dropDuplicates()
     .writeStream.outputMode("complete")
     .foreachBatch(lambda df, i: batches.__setitem__(i, sorted(df.collect())))
     .trigger(availableNow=True).start())
q.awaitTermination()
print(batches[max(batches)])
# expected (the complete result table, = the batch query): [Row(k=1, count=1), 
Row(k=2, count=2), Row(k=3, count=1)]
# actual:                                                   [Row(k=2, count=2), 
Row(k=3, count=1)]
{code}
In Complete mode every micro-batch should contain the whole result table. The 
aggregation does emit all groups in each batch, but the following 
{{dropDuplicates}} (or {{distinct()}}) keeps its keys in state across batches 
and drops every group row it saw before unchanged, so k = 1 disappears from the 
second batch.

Cause: {{UnsupportedOperationChecker.checkForStreaming}} only requires an 
aggregation for Complete mode ({{case InternalOutputModes.Complete if 
aggregates.isEmpty}}); a {{Deduplicate}} after the aggregation is not checked 
({{containsCompleteData}} is only used for {{Sort}}), and 
{{isStatefulOperation}} counts a {{Deduplicate}} as stateful only when its keys 
have an event-time column, so the chained-stateful-operator check does not see 
it either. At runtime {{StateStoreSaveExec}} in Complete mode returns all 
groups each batch and {{StreamingDeduplicateExec}} filters them by 
{{store.keyExists(key)}}. The query should either be rejected or the 
deduplication should not keep state across batches in Complete mode.

Reproduces on 3.5.8, 4.0.0, 4.1.1 and 4.2.0.




--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

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

Reply via email to