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
docs: add window function literal detection to make-pythonic skill
Add Technique 1b to detect literal-only arguments in window functions.
Window functions enforce literals in partition_evaluator() via
get_scalar_value_from_args() / downcast_ref::<Literal>(), not in
invoke_with_args() (scalar) or accumulator() (aggregate). Updates the
decision flow to branch on scalar vs aggregate vs window.
Known window functions with literal-only arguments: ntile (n), lead/lag
(offset, default_value), nth_value (n).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There are four concrete techniques to check, in order of signal strength:
67
+
There are five concrete techniques to check, in order of signal strength:
68
68
69
69
#### Technique 1: Check `invoke_with_args()` for literal-only enforcement (strongest signal)
70
70
@@ -123,6 +123,41 @@ Known aggregate functions with literal-only arguments:
123
123
-`string_agg` — `delimiter` (str)
124
124
-`nth_value` — `n` (int)
125
125
126
+
#### Technique 1b: Check `partition_evaluator()` for literal-only enforcement (window functions)
127
+
128
+
Window functions do not have `invoke_with_args()` or `accumulator()`. Instead, they enforce literal-only arguments in their `partition_evaluator()` method, which constructs the evaluator that processes each partition.
Look for `get_scalar_value_from_args()` calls inside `partition_evaluator()`. This helper (defined in the window crate's `utils.rs`) calls `downcast_ref::<Literal>()` and errors with `"There is only support Literal types for field at idx: {index} in Window Function"`.
exec_datafusion_err!("NTILE requires a positive integer")
148
+
})?;
149
+
// ...
150
+
}
151
+
```
152
+
153
+
**If you find this pattern:** The argument is **Category B** — accept only the corresponding native Python type, not `Expr`. The function will error at planning time with a non-literal expression.
154
+
155
+
Known window functions with literal-only arguments:
#### Technique 2: Check the `Signature` for data type constraints
127
162
128
163
Each function defines a `Signature::coercible(...)` that specifies what data types each argument accepts, using `Coercion` entries. This tells you the expected **data type** even if it doesn't enforce literal-only.
@@ -173,7 +208,7 @@ let decimal_places: Option<i32> = match args.scalar_arguments.get(1) {
173
208
#### Decision flow
174
209
175
210
```
176
-
Is the function a scalar UDF or an aggregate?
211
+
What kind of function is this?
177
212
Scalar UDF:
178
213
Is argument rejected at runtime if not a literal?
179
214
(check invoke_with_args for ColumnarValue::Scalar-only match + exec_err!)
@@ -185,6 +220,12 @@ Is the function a scalar UDF or an aggregate?
185
220
downcast_ref::<Literal>() + error)
186
221
→ YES: Category B — accept only native type, no Expr
187
222
→ NO: continue below
223
+
Window:
224
+
Is argument rejected at planning time if not a literal?
225
+
(check partition_evaluator() for get_scalar_value_from_args /
226
+
downcast_ref::<Literal>() + error)
227
+
→ YES: Category B — accept only native type, no Expr
228
+
→ NO: continue below
188
229
189
230
Does the Signature constrain it to a specific data type?
190
231
→ YES: Category A — accept Expr | <native type matching the constraint>
0 commit comments