Skip to content

Scope VGI316 to table functions only (fix scalar/aggregate false positives)#10

Merged
rustyconover merged 1 commit into
mainfrom
fix/vgi316-table-functions-only
Jul 12, 2026
Merged

Scope VGI316 to table functions only (fix scalar/aggregate false positives)#10
rustyconover merged 1 commit into
mainfrom
fix/vgi316-table-functions-only

Conversation

@rustyconover

Copy link
Copy Markdown
Contributor

Problem

VGI316 (array-argument-could-be-table) fired on scalar and aggregate functions, but its only suggested remedy — "expose it as a table function that takes a table/relation input, so callers pass a subquery (FROM …)" — is structurally impossible for a scalar/aggregate function. A scalar function returns one value per row and cannot take a relation as an argument. Flagging them was a false positive with no achievable fix.

The motivating case: ortools.main.max_flow_value(arcs) — a SCALAR function returning BIGINT — was flagged identically to the real table-function solvers.

Fix

  • targets narrowed from (SCALAR_FUNCTION, AGGREGATE, MACRO, TABLE_FUNCTION) to (TABLE_FUNCTION,).
  • check() now iterates the existing _iter_table_functions(ctx) helper (used by every other table-function rule in the module) instead of iter_all_functions().
  • MACRO was also dropped: DuckDB macros take scalar expressions, not relations, so the "pass a subquery FROM…" advice is equally impossible for them.
  • The single-array-argument condition (len(array_args) != 1 continue) is unchanged.

This change only ever removes findings (it narrows targets), so it cannot introduce a new finding on any worker.

Verification against vgi-ortools

Before: 6 VGI316 warnings. After: 5.

function kind before after
max_flow_value(arcs) scalar fired removed (false positive)
max_flow(arcs) table_function fired still fires
solve_assignment(cost) table_function fired still fires
solve_jobshop(tasks) table_function fired still fires
solve_knapsack(weights) table_function fired still fires
solve_tsp(distance) table_function fired still fires

The 5 residual findings are genuine table-function cases (whether ortools should reshape/document them is a separate decision) — the deliverable here is that the scalar false positive is gone.

Gates

ruff format / ruff check / mypy / pydoclint / pytest (505 passed) / gen_rules_doc.py --check all green. RULES.md regenerated; VGI316 unit test updated to assert a scalar/aggregate with a matrix arg is NOT flagged while a table function still IS.

🤖 Generated with Claude Code

VGI316's only remedy — expose a table/relation input so callers pass a
subquery `FROM …` — is structurally possible only for a table function. A
scalar or aggregate function returns one value per row and cannot take a
relation argument; DuckDB macros take scalar expressions, not relations. So
flagging scalar/aggregate/macro functions with a nested-array argument was a
false positive with no achievable fix (e.g. ortools' scalar max_flow_value).

Narrow `targets` to `(TABLE_FUNCTION,)` and iterate `_iter_table_functions`
in `check()`. This only ever removes findings, never adds any. Regenerated
RULES.md and updated the VGI316 unit test to assert a scalar/aggregate with a
matrix arg is not flagged while a table function still is.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rustyconover rustyconover merged commit 4ec1174 into main Jul 12, 2026
4 checks passed
@rustyconover rustyconover deleted the fix/vgi316-table-functions-only branch July 12, 2026 17:23
rustyconover added a commit that referenced this pull request Jul 12, 2026
Scope VGI316 to table functions only (#10): a scalar/aggregate/macro function
with a matrix argument can never be rewritten to take a relation input, so
flagging it was a false positive. Only removes findings; no worker can regress.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant