You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Let operators inside a control block read loop variables through $var property references #8635
Inside a control block (LoopStart/LoopEnd), the iteration state — the loop's variables such as i — reaches every operator as a state message, but no built-in operator can use it. An operator's properties are read once when its executor is initialized, before any message has arrived, and the executor is built from a frozen descriptor JSON with no substitution stage. Today the only operator that reads a state key is If; a Filter inside a loop cannot take its threshold from the loop.
Let a property of any operator inside a block refer to a loop variable as $i, with no change to the operator's source.
Proposed Solution or Design
Parse phase (unchanged wire format). The frontend sends $i as the property value. When $i meets a numeric or boolean property, the parser puts in a typed placeholder so the descriptor still deserializes, and records the reference on the operator (stateReferences: JSON pointer → variable name). String properties keep the literal. The sidecar is hidden from the property-panel schema.
Compile phase. The compiler decides which operators lie inside a loop block. Inside a block, the references are kept, including whole-string $name literals. Outside every block, a string such as $AAPL stays a literal, and a reference in a numeric or boolean property is a compile error.
Late binding. An executor whose descriptor carries stateReferences is created as a late-bound wrapper. It forwards the state messages, binds the placeholders at the first tuple from their merged values (patching the descriptor and instantiating the real executor), and reuses the bound values for every tuple of the iteration. A tuple that arrives while a referenced variable is still missing is an error naming it.
Registering the state on Python operators (state) is #8641. Out of scope here: operators whose Scala descriptor interpolates property values into generated Python code (the sklearn operators); their values never reach a Scala executor, so Python-side binding is a follow-up. UDF-side sugar and the frontend are separate issues (#8636).
Acceptance
A Filter inside a loop with predicate value $i filters with the current iteration's i, verified end to end in LoopIntegrationSpec.
Unit tests for the plan rewriter (string, integer and nested-pointer references) and for the late-bound executor (bind at the first state, reuse, error when unbound / unknown name).
Activity
feat(amber): bind $K loop-variable references in operators
feat(frontend): accept $variable references in loop blocks
feat(amber): bind $K loop-variable references in operators
feat(amber): bind $K loop-variable references in operators
feat(amber): bind $K loop-variable references in operators
feat(amber): bind $K loop-variable references in operators
feat(amber): bind $K loop-variable references in operators
feat(amber): bind $K loop-variable references in operators
feat(amber): bind $i loop-variable references in operators (apache#8639)
fix(amber): reject $i in settings the plan is built from (apache#8750)