vbhanuchander-lang opened a new pull request, #7859:
URL: https://github.com/apache/hop/pull/7859

   Fixes #7544
   
   Adds a **Spark SQL** transform to the native Spark pipeline engine (built on 
the engine from #7486). Every incoming transform is registered as a temporary 
view, so one statement can join, union, filter, window and aggregate them under 
a single Catalyst plan — instead of chaining Hop Join/Filter/Calculator 
transforms that Catalyst cannot optimize across.
   
   As the issue notes, this is deliberately *not* the classic SQL transforms 
(`ExecSql`, `Table Input`, `Dynamic SQL row`): those target RDBMS connections 
over JDBC. This compiles SQL against the pipeline's in-flight `Dataset`s, so no 
database connection is involved.
   
   ## Against the goals in the issue
   
   | # | Goal | Where |
   |---|------|-------|
   | 1 | Dedicated `SparkSql` transform, native-Spark only | `SparkSqlMeta` — 
`supportedEngines = {SparkConst.PLUGIN_ID}` |
   | 2 | N enabled inputs as temp views; zero-input SQL allowed | 
`SparkSqlHandler.registerInputViews` |
   | 3 | Driver-side `${...}` substitution (string concat) | 
`SparkSqlHandler.handleTransform` |
   | 4 | Correct Hop `IRowMeta`; explicit non-empty field list | 
`SparkSqlMeta.getFields` + `projectDeclaredFields` |
   | 5 | Metrics/logging consistent with other handlers | `trackMetrics(..., 
Role.TRANSFORM)`, `SparkBaseTransformHandler` |
   | 6 | hop-run, GUI `local[*]`, `spark-submit` via `MainSpark` | no new 
deploy mode — plain native handler |
   | 7 | Unit tests + docs | see below |
   
   Non-goals respected: no Structured Streaming SQL, no attempt to make the 
JDBC transforms native, no full catalog work.
   
   ## Design notes
   
   **View naming.** The default view name is derived from the incoming 
transform name — characters outside `[A-Za-z0-9_]` become `_`, a leading digit 
is prefixed. `Read orders (raw)` becomes `Read_orders__raw_`, which is correct 
but awkward to type, so the dialog has an **Input views** grid to set an 
explicit name per input. Two inputs resolving to the same view name is an error 
naming both transforms, rather than one silently shadowing the other.
   
   **Why the field list is required.** Hop resolves the row layout at design 
time, before any `SparkSession` exists, so the statement's result schema is 
genuinely unavailable to it. Declaring the fields keeps design-time metadata 
correct and gives downstream generic mapPartitions transforms a layout that 
matches the Dataset. The declared list also drives the output — fields are 
selected in declared order and cast to the Spark type for the Hop type — so the 
two cannot drift apart. Declaring a field the statement doesn't return fails 
with the list of columns it did return.
   
   **One shared-code change:** 
`HopPipelineMetaToSparkConverter.lookupPreviousDataset()` becomes `public` so 
the handler reuses the converter's target-stream rules (Filter/Switch routing) 
rather than duplicating them. Happy to revert to a private copy if you'd rather 
keep the surface closed.
   
   ## Tests
   
   18 new tests, all on a local `SparkSession`, following 
`SparkNativeHandlersTest`:
   
   `SparkSqlHandlerTest` (12) — two-input join; union across 4 partitions under 
one plan; view-name override; default sanitized naming; zero-input `VALUES`; 
variable substitution; declared fields driving output order *and* cast; and the 
error paths (missing declared field, empty field list, empty SQL, colliding 
view names, invalid SQL reporting the registered views).
   
   `SparkSqlMetaTest` (6) — view-name sanitization incl. leading digits and 
null/empty, override lookup, and `getFields` replacing the incoming row.
   
   Full module locally: **186 tests, 0 failures**. `spotless:apply` clean, 
`apache-rat:check` reports 0 unapproved.
   
   ```
   [INFO] Tests run: 12, Failures: 0, Errors: 0, Skipped: 0 -- 
SparkSqlHandlerTest
   [INFO] Tests run:  6, Failures: 0, Errors: 0, Skipped: 0 -- SparkSqlMetaTest
   [INFO] Tests run: 186, Failures: 0, Errors: 0, Skipped: 0
   [INFO] BUILD SUCCESS
   ```
   
   ## Docs
   
   New `spark-sql.adoc` transform page (description, options, input views, 
output fields, variables incl. a warning that substitution is textual, 
limitations), registered in `nav.adoc` and `transforms.adoc`, plus a row in the 
native-handler table in `getting-started-with-native-spark.adoc`.
   
   ## Open questions
   
   - Should a **Get fields** button that runs the statement against a live 
session land in v1, or stay out until there's a design for where the session 
comes from at design time?
   - Field-list ergonomics: happy to add an injection test in the style of 
`SparkLakeTableInputMetaInjectionTest` if you want metadata injection coverage 
for this transform too.


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

Reply via email to