Skip to content

Fix:stale parameter handling in the Pipeline Executor when retries are enabled and variables are inherited from parent scopes - #9059

Open
beatum wants to merge 35 commits into
apache:mainfrom
beatum:fix-cache-variable
Open

beatum wants to merge 35 commits into
apache:mainfrom
beatum:fix-cache-variable

Conversation

@beatum

@beatum beatum commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR fixes stale parameter handling in the Pipeline Executor when retries are enabled and variables are inherited from parent scopes.

The previous retry flow could reuse stale inherited variable values or previous attempt parameter values, causing child pipeline executions to behave inconsistently across retries. This patch ensures each retry reflects the newest available context while preserving explicit mappings.

Testing

  • Added/updated PipelineExecutor unit tests covering variable refresh, retry value selection, and retry execution sequencing.

happy.he and others added 30 commits September 11, 2026 10:07
- Skip only explicit JSONB operator tokens: `?|`, `?&`, `??`, `??|`,
  and `??&`.
- Consume complete operator tokens so `col ?? ?` still counts the trailing
  `?` as a bind parameter.
- Stop treating all `[...]` expressions as bracket-quoted identifiers.
- Add dialect-aware bracket handling for SQL Server.
- Preserve PostgreSQL parameter markers in `ARRAY[?]` and `ARRAY[?, ?]`.
- Apply the same parsing behavior to the Database Join path.
- Expand regression coverage for JSONB operators, `LIKE`, `NOT LIKE`,
  `BETWEEN`, `SELECT ? FROM dual`, and ARRAY expressions.
@hansva

hansva commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Can we have a ticket and a reproduction path for this please. I'm not sure the code change reflect the expectations you/we have. As far as I can see every retry read the same row, and that row doesn't change while the retries run.

@beatum

beatum commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Thanks again for the detailed review and feedback. i have implemented all three fixes in PipelineExecutor and updated the tests to lock in the expected behavior.

Retry parameter handling

executeWithRetries() now always reuses the original attempt-0 parameter values on retries.
Fixed the buffered-row fallback to preserve column positions (including null values) and use row metadata conversion instead of Object.toString().

Variable refresh on retries

Retry attempts now refresh variables from the live parent variable scopes and JVM properties instead of relying on the pipeline's copied snapshot.
Transform variables are also refreshed so inherited child parameters and static values such as ${ACCESS_TOKEN} pick up updated values before each retry.

Test updates

Replaced the stub-based retry test with a real-path scenario that verifies both retry attempts receive the original attempt-0 parameter list, including correct null handling.
Added a test to verify row metadata conversion is used instead of raw toString().
Strengthened the variable refresh tests to cover updated parent-scope values and JVM property fallback behavior across retry attempts.

@beatum

beatum commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks for the quick response @hansva .

Of course. I've prepared a small example for testing purposes and uploaded it to the following repository:

https://github.com/beatum/apache-hop-demo.git

When the variable is set to rabbit, the pipeline logs that the door opens.
When the variable is set to monkey, the pipeline follows the monkey branch and demonstrates the retry/recovery behavior.

2026/10/23 08:59:24 - Hop - Pipeline opened.
2026/10/23 08:59:24 - Hop - Launching pipeline [main]...
2026/10/23 08:59:24 - Hop - Started executing pipeline 'main'.
2026/10/23 08:59:24 - GUI - Getting revisions for path - original: 'main.hpl', normalized: 'main.hpl'
2026/10/23 08:59:24 - main - Executing this pipeline using the Local Pipeline Engine with run configuration 'local'
2026/10/23 08:59:24 - main - Execution started for pipeline [main]
2026/10/23 08:59:24 - SysInfo.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:24 - room - Executing this pipeline using the Local Pipeline Engine with run configuration 'local'
2026/10/23 08:59:24 - room - Execution started for pipeline [room]
2026/10/23 08:59:24 - SysInfo.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:24 - JavaScript.0 - ECMAScript language level set to ES6.
2026/10/23 08:59:24 - JavaScript.0 - Optimization level set to 9.
2026/10/23 08:59:25 - JavaScript.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - Monkey.0 - 
2026/10/23 08:59:25 - Monkey.0 - ------------> Linenr 1------------------------------
2026/10/23 08:59:25 - Monkey.0 - Monkey 🐒🐒🐒 can't open the door without a key yet.
2026/10/23 08:59:25 - Monkey.0 - 🔒🔒🔒🔒🔒🔒🔒🔒🔒🔒🔒🔒🔒🔒🔒
2026/10/23 08:59:25 - Monkey.0 - 
2026/10/23 08:59:25 - Monkey.0 - animal = monkey
2026/10/23 08:59:25 - Monkey.0 - 
2026/10/23 08:59:25 - Monkey.0 - ====================
2026/10/23 08:59:25 - Door.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - Monkey.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - changeAnimal - Executing this pipeline using the Local Pipeline Engine with run configuration 'local'
2026/10/23 08:59:25 - changeAnimal - Execution started for pipeline [changeAnimal]
2026/10/23 08:59:25 - SysInfo.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - JavaScript.0 - ECMAScript language level set to ES6.
2026/10/23 08:59:25 - JavaScript.0 - Optimization level set to 9.
2026/10/23 08:59:25 - Write to log.0 - 
2026/10/23 08:59:25 - Write to log.0 - ------------> Linenr 1------------------------------
2026/10/23 08:59:25 - Write to log.0 - In the Change Animal pipelie===============================
2026/10/23 08:59:25 - Write to log.0 - 
2026/10/23 08:59:25 - Write to log.0 - animal = rabbit
2026/10/23 08:59:25 - Write to log.0 - 
2026/10/23 08:59:25 - Write to log.0 - ====================
2026/10/23 08:59:25 - JavaScript.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - Write to log.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - changeAnimal - Pipeline duration : 0.039 seconds [  0.039" ]
2026/10/23 08:59:25 - changeAnimal - Execution finished on a local pipeline engine with run configuration 'local'
2026/10/23 08:59:25 - MonkeyRecovered.0 - 
2026/10/23 08:59:25 - MonkeyRecovered.0 - ------------> Linenr 1------------------------------
2026/10/23 08:59:25 - MonkeyRecovered.0 - Monkey recovered the key and the animal was reset to rabbit. The door can now be opened.
2026/10/23 08:59:25 - MonkeyRecovered.0 - 
2026/10/23 08:59:25 - MonkeyRecovered.0 - ExecutionTime = 50
2026/10/23 08:59:25 - MonkeyRecovered.0 - ExecutionResult = Y
2026/10/23 08:59:25 - MonkeyRecovered.0 - ExecutionNrErrors = 0
2026/10/23 08:59:25 - MonkeyRecovered.0 - ExecutionLinesRead = 1
2026/10/23 08:59:25 - MonkeyRecovered.0 - ExecutionLinesWritten = 1
2026/10/23 08:59:25 - MonkeyRecovered.0 - ExecutionLinesInput = 0
2026/10/23 08:59:25 - MonkeyRecovered.0 - ExecutionLinesOutput = 0
2026/10/23 08:59:25 - MonkeyRecovered.0 - ExecutionLinesRejected = 0
2026/10/23 08:59:25 - MonkeyRecovered.0 - ExecutionLinesUpdated = 0
2026/10/23 08:59:25 - MonkeyRecovered.0 - ExecutionLinesDeleted = 0
2026/10/23 08:59:25 - MonkeyRecovered.0 - ExecutionFilesRetrieved = 0
2026/10/23 08:59:25 - MonkeyRecovered.0 - ExecutionExitStatus = 0
2026/10/23 08:59:25 - MonkeyRecovered.0 - ExecutionLogText = 2026/10/23 08:59:25 - changeAnimal - Executing this pipeline using the Local Pipeline Engine with run configuration 'local'
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - changeAnimal - Execution started for pipeline [changeAnimal]
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - SysInfo.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - JavaScript.0 - ECMAScript language level set to ES6.
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - JavaScript.0 - Optimization level set to 9.
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - Write to log.0 - 
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - Write to log.0 - ------------> Linenr 1------------------------------
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - Write to log.0 - In the Change Animal pipelie===============================
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - Write to log.0 - 
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - Write to log.0 - animal = rabbit
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - Write to log.0 - 
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - Write to log.0 - ====================
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - JavaScript.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - Write to log.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - changeAnimal - Pipeline duration : 0.039 seconds [  0.039" ]
2026/10/23 08:59:25 - MonkeyRecovered.0 - 2026/10/23 08:59:25 - changeAnimal - Execution finished on a local pipeline engine with run configuration 'local'
2026/10/23 08:59:25 - MonkeyRecovered.0 - 
2026/10/23 08:59:25 - MonkeyRecovered.0 - ExecutionLogChannelId = f4ce3c6f-a3ca-4ee1-9419-50473af9f315
2026/10/23 08:59:25 - MonkeyRecovered.0 - 
2026/10/23 08:59:25 - MonkeyRecovered.0 - ====================
2026/10/23 08:59:25 - changeAnimal.hpl.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - MonkeyRecovered.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - Abort.0 - ERROR: Row nr 1 causing abort "Abort and log as an error": [50], [Y], [0], [1], [1], [0], [0], [0], [0], [0], [0], [0], [2026/10/23 08:59:25 - changeAnimal - Executing this pipeline using the Local Pipeline Engine with run configuration 'local'
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - changeAnimal - Execution started for pipeline [changeAnimal]
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - SysInfo.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - JavaScript.0 - ECMAScript language level set to ES6.
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - JavaScript.0 - Optimization level set to 9.
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - Write to log.0 - 
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - Write to log.0 - ------------> Linenr 1------------------------------
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - Write to log.0 - In the Change Animal pipelie===============================
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - Write to log.0 - 
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - Write to log.0 - animal = rabbit
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - Write to log.0 - 
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - Write to log.0 - ====================
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - JavaScript.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - Write to log.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - changeAnimal - Pipeline duration : 0.039 seconds [  0.039" ]
2026/10/23 08:59:25 - Abort.0 - 2026/10/23 08:59:25 - changeAnimal - Execution finished on a local pipeline engine with run configuration 'local'
2026/10/23 08:59:25 - Abort.0 - ], [f4ce3c6f-a3ca-4ee1-9419-50473af9f315]
2026/10/23 08:59:25 - Abort.0 - ERROR: Aborting after having seen 1 rows.
2026/10/23 08:59:25 - Abort.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=1)
2026/10/23 08:59:25 - room - Pipeline duration : 0.589 seconds [  0.589" ]
2026/10/23 08:59:25 - room - Execution finished on a local pipeline engine with run configuration 'local'
2026/10/23 08:59:25 - room - Pipeline detected one or more transforms with errors.
2026/10/23 08:59:25 - room - Pipeline is killing the other transforms!
2026/10/23 08:59:25 - room - Executing this pipeline using the Local Pipeline Engine with run configuration 'local'
2026/10/23 08:59:25 - room - Execution started for pipeline [room]
2026/10/23 08:59:25 - SysInfo.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - JavaScript.0 - ECMAScript language level set to ES6.
2026/10/23 08:59:25 - JavaScript.0 - Optimization level set to 9.
2026/10/23 08:59:25 - Lucky.0 - 
2026/10/23 08:59:25 - Lucky.0 - ------------> Linenr 1------------------------------
2026/10/23 08:59:25 - Lucky.0 - The door is opened===================== 🐇🐇🐇🐇🐇🐇🐇🐇🐇🐇
2026/10/23 08:59:25 - Lucky.0 - Lucky 🎆🎆🎆🎆🎆🎆🎆🎆🎆
2026/10/23 08:59:25 - Lucky.0 - 
2026/10/23 08:59:25 - Lucky.0 - animal = rabbit
2026/10/23 08:59:25 - Lucky.0 - 
2026/10/23 08:59:25 - Lucky.0 - ====================
2026/10/23 08:59:25 - JavaScript.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - Door.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - Lucky.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2026/10/23 08:59:25 - room - Pipeline duration : 0.098 seconds [  0.098" ]
2026/10/23 08:59:25 - room - Execution finished on a local pipeline engine with run configuration 'local'
2026/10/23 08:59:25 - room.hpl.0 - Finished processing (I=0, O=0, R=1, W=0, U=0, E=0)
2026/10/23 08:59:25 - main - Pipeline duration : 0.849 seconds [  0.849" ]
2026/10/23 08:59:25 - Hop - Pipeline 'main' completed.
2026/10/23 08:59:25 - main - Execution finished on a local pipeline engine with run configuration 'local'

Feel free to try it out, and let me know if you need any additional information.

Have fun! 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants