Skip to content

perf(parser): short-circuit _parse_pivots when not at PIVOT/UNPIVOT#7557

Merged
georgesittas merged 1 commit intomainfrom
parse-pivots-guard
Apr 24, 2026
Merged

perf(parser): short-circuit _parse_pivots when not at PIVOT/UNPIVOT#7557
georgesittas merged 1 commit intomainfrom
parse-pivots-guard

Conversation

@tobymao
Copy link
Copy Markdown
Owner

@tobymao tobymao commented Apr 24, 2026

Summary

`_parse_pivots` is called once per Join and after most table refs, but always builds a callable-iterator + `list()` even when the next token can never start a `PIVOT`/`UNPIVOT` clause. Guard on the token type up front so the common no-pivot path is a single membership check.

Perf

Measured on the 200-JOIN `many_joins` benchmark with `sqlglot[c]`:

trimmed_mean (interleaved A/B)
Before 4.51 ms
After 4.36 ms

~3% faster on join-heavy parses. Perf report showed `_parse_pivots` at 1.89% of parse before; the change reduces it to near zero in the common case. No measurable effect on pure Python (interpreter overhead dominates).

Test plan

  • Pivot / unpivot tests still pass (`make test`)
  • ARRAY JOIN + pivot combinations parse correctly

…/UNPIVOT

_parse_pivots runs once per Join and most table refs, but always
builds an iter+list even when the next token can never start a PIVOT
clause. Guard on the token type up front so the common no-pivot path
is a single check.

Small but consistent win under mypyc (~1-3% on join-heavy queries
like many_joins). No behavior change.
@github-actions
Copy link
Copy Markdown
Contributor

SQLGlot Integration Test Results

Comparing:

  • this branch (sqlglot:parse-pivots-guard, sqlglot version: parse-pivots-guard)
  • baseline (main, sqlglot version: 0.0.1.dev1)

By Dialect

dialect main sqlglot:parse-pivots-guard transitions links
bigquery -> bigquery 24645/24650 passed (100.0%) 23495/23495 passed (100.0%) No change full result / delta
bigquery -> duckdb 867/1154 passed (75.1%) 0/0 passed (0.0%) Results not found full result / delta
duckdb -> duckdb 5823/5823 passed (100.0%) 5823/5823 passed (100.0%) No change full result / delta
snowflake -> duckdb 1063/1961 passed (54.2%) 1063/1961 passed (54.2%) No change full result / delta
snowflake -> snowflake 65133/65133 passed (100.0%) 65133/65133 passed (100.0%) No change full result / delta
databricks -> databricks 1370/1370 passed (100.0%) 1370/1370 passed (100.0%) No change full result / delta
postgres -> postgres 6042/6042 passed (100.0%) 6042/6042 passed (100.0%) No change full result / delta
redshift -> redshift 7101/7101 passed (100.0%) 7101/7101 passed (100.0%) No change full result / delta

Overall

main: 113234 total, 112044 passed (pass rate: 98.9%), sqlglot version: 0.0.1.dev1

sqlglot:parse-pivots-guard: 110925 total, 110027 passed (pass rate: 99.2%), sqlglot version: parse-pivots-guard

Transitions:
No change

Dialect pair changes: 0 previous results not found, 1 current results not found

✅ 34 test(s) passed

@georgesittas georgesittas merged commit fc6e7cb into main Apr 24, 2026
8 checks passed
@georgesittas georgesittas deleted the parse-pivots-guard branch April 24, 2026 12:02
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.

2 participants