wayne-x-wang commented on issue #7170:
URL: https://github.com/apache/kyuubi/issues/7170#issuecomment-6261767373

   <p><span>I reproduced this on Kyuubi master at commit </span><code 
dir="ltr">771be6a18</code><span>, using Spark 3.5.8, Scala 2.12.19, and JDK 
17.</span></p><p><span>The results suggest that we need to distinguish 
</span><code dir="ltr">QueryExecution.id</code><span>, the SQL </span><code 
dir="ltr">executionId</code><span>, and </span><code 
dir="ltr">rootExecutionId</code><span>.</span></p><p><strong><span>1. Reusing 
one DataFrame for two actions</span></strong></p><pre dir="ltr"><code>val df = 
spark.sql("SELECT 7170 AS lineage_execution_id")
   df.collect()
   df.collect()</code></pre><p><span>The captured events were:</span></p><pre 
dir="ltr"><code>QueryExecution.id:              0
   SQL Start/End execution IDs:    [0, 1]
   Lineage event execution IDs:    [0, 0]</code></pre><p><span>One </span><code 
dir="ltr">QueryExecution</code><span> can therefore correspond to multiple SQL 
executions. A simple </span><code dir="ltr">qe.id -&gt; 
executionId</code><span> mapping would not represent this relationship 
reliably.</span></p><p><strong><span>2. CTAS and 
rootExecutionId</span></strong></p><p><span>I also tested:</span></p><pre 
dir="ltr"><code>CREATE TABLE lineage_ctas_source (id INT) USING parquet;
   INSERT INTO lineage_ctas_source VALUES (1), (2);
   
   CREATE TABLE lineage_ctas_target USING parquet
   AS SELECT id FROM lineage_ctas_source;</code></pre><p><span>The listener was 
registered before the CTAS </span><code dir="ltr">spark.sql()</code><span> 
call, since the command executes eagerly. The captured values 
were:</span></p><div><div><div>
   Execution | End.qe.id | SQL executionId | Start.rootExecutionId | Lineage 
executionId
   -- | -- | -- | -- | --
   CreateDataSourceTableAsSelectCommand | 5 | 2 | 2 | 5
   InsertIntoHadoopFsRelationCommand | 7 | 3 | 2 | 7
   
   </div></div></div><p><span>This confirms the relationship mentioned in 
SPARK-41752: the outer and nested executions have different execution IDs but 
share the same root execution ID. However, </span><code 
dir="ltr">rootExecutionId</code><span> does not resolve the mismatch between 
</span><code dir="ltr">qe.id</code><span> and the SQL execution 
ID.</span></p><p><span>The target table contained the expected rows 
</span><code dir="ltr">[1, 2]</code><span>. Both regression cases fail on the 
execution-ID assertions, while the three existing tests in </span><code 
dir="ltr">OperationLineageEventSuite</code><span> 
pass.</span></p><p><strong><span>Proposed 
scope</span></strong></p><p><span>Process </span><code 
dir="ltr">SparkListenerSQLExecutionEnd</code><span> directly and pass its 
actual </span><code dir="ltr">executionId</code><span>, together with its 
</span><code dir="ltr">qe</code><span>, to the lineage dispatchers. This would 
preserve the existing lineage parser and event fields whi
 le correcting the IDs emitted through </span><code 
dir="ltr">SPARK_EVENT</code><span> and </span><code 
dir="ltr">KYUUBI_EVENT</code><span>.</span></p><p><span>Root-level grouping 
could remain a separate concern: consumers can correlate the corrected 
execution ID with </span><code 
dir="ltr">SparkListenerSQLExecutionStart.rootExecutionId</code><span>.</span></p><p><strong><span>Compatibility
 questions</span></strong></p><p><span>The current entry point is registered 
through </span><code dir="ltr">spark.sql.queryExecutionListeners</code><span>, 
whose callbacks do not expose the SQL execution ID. An additional </span><code 
dir="ltr">SparkListener</code><span> would typically use </span><code 
dir="ltr">spark.extraListeners</code><span>.</span></p><p><span>Would 
introducing this new entry point, retaining/deprecating the existing 
QueryExecutionListener entry point, be acceptable? Or would you prefer 
preserving the current configuration contract?</span></p><p><span>The 
implementation would
  also need to address duplicate emission when both entry points are 
configured, session scope, failure events, and replayed events without runtime 
</span><code dir="ltr">qe</code><span> metadata. Access to the runtime 
End-event fields would require a version-tested adapter because those fields 
are </span><code 
dir="ltr">private[sql]</code><span>.</span></p><p><span>Separately, the nested 
CTAS write produced </span><code dir="ltr">lineage=None</code><span>: its 
</span><code dir="ltr">catalogTable</code><span> was absent and the parser 
logged a </span><code dir="ltr">MatchError</code><span>. The outer CTAS event 
contained the expected table and column lineage. I would keep that parser issue 
separate from the execution-ID correction.</span></p><p><span>No production fix 
has been implemented yet. I would appreciate feedback on the proposed direction 
and configuration compatibility before proceeding.</span></p>


-- 
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