Skip to content

Filter evaluation perf - #2721

Merged
norberttech merged 2 commits into
1.xfrom
filter-evaluation-perf
Nov 2, 2026
Merged

norberttech merged 2 commits into
1.xfrom
filter-evaluation-perf

Conversation

@norberttech

Copy link
Copy Markdown
Member

Resolves: #xxx

Change Log


Added

  • flow-php/etl - Native sort, group ids and grouped sum/avg/count kernels behind Backend
  • flow-php/etl - Projection pushdown of the columns a plan outputs into file sources
  • flow-php/parquet - readStoredColumns() and writeStoredColumns() exchanging dates, timestamps, times and uuids as stored values
  • flow-php/flow-php-ext - RustGroupTable, native sort and grouped totals/counts
  • flow-php/arrow-ext - Stored column reads and writes

Fixed

  • flow-php/etl-adapter-parquet - Partitioned reads with metadata columns declared _input_file_uri twice

Changed

  • flow-php/etl - Filters evaluate each AND conjunct on its own
  • flow-php/etl - count() reads no columns
  • flow-php/etl - Sum and avg of one column share one running total
  • flow-php/etl - External sort spills in batch-size frames and releases its buffer
  • flow-php/etl - Parallel partial aggregates take the grouped path
  • flow-php/etl - Floe files are read in exact windows
  • flow-php/etl - Sort values moved to Values\Sort and KeyEncoder to Values\Grouping
  • flow-php/etl-adapter-parquet - Filter-only columns are decoded only where statistics leave the filter open
  • flow-php/etl-adapter-parquet - Reads and writes stored values instead of PHP objects
  • flow-php/arrow-ext - Skips the row filter on row groups whose statistics prove every row matches
  • flow-php/arrow-ext - Builds datetimes without a string parse on verified PHP layouts
  • flow-php/arrow-ext - Out-of-range values are refused with InvalidArgumentException
  • flow-php/flow-php-ext - Floe frames are validated once

Removed

  • flow-php/etl - Aggregators::aggregate() and Aggregators::merge()
  • flow-php/etl - Group and GroupKey
  • flow-php/etl-adapter-parquet - ParquetEncoder and the value converters

Deprecated

Security

- Parquet answers pushed conjuncts exactly, so Flow no longer re-filters them in PHP
- pushed conjuncts run before the ones kept in PHP; offset is pushed into Parquet
- float > / >= pushdown keeps NaN rows; partition filters handle files without the partition
- native comparison, null checks and arithmetic in flow_php behind new Backend methods
- Rust Parquet reads fill batches across row groups and decode scattered selections faster
- prose docblocks in IO/Extractor/File replaced by tests that state each rule
…ster arrow-only Parquet

- native Backend::sort (stable, PHP order) for memory, external, window and top-n sorts; k-way merge sorts blocks natively
- external sort spills in batch-size frames and releases its buffer, so peak PHP memory no longer grows with the data
- group by assigns dense group ids (GroupTable, native RustGroupTable) and aggregates each batch per column (GroupedAggregation); sum, avg and count run columnar, every other aggregation through PerGroupAggregation
- sum and avg of one column share one running total; avg divides on floats when the result provably equals the decimal one
- parallel partial aggregates take the same grouped path as in-process aggregation
- a filter evaluates each conjunct of an AND on its own, natively where it can
- the optimizer pushes the columns a plan outputs into file sources; Parquet decodes filter-only columns only where statistics leave the filter open, and count() reads no column
- arrow-ext skips the row filter on row groups whose statistics prove every row matches
- Parquet readers and writers exchange stored values (readStoredColumns/writeStoredColumns): dates, timestamps, times and uuids as their physicals; the Parquet value converters and ParquetEncoder are removed
- arrow-ext builds datetimes without a string parse on verified PHP layouts; arrow-only reads fill batches across row groups
- Floe files are read in exact windows, without buffer concatenation; Floe frames are validated once
- Aggregators::aggregate() and merge() are removed
- partitioned reads with metadata columns no longer declare _input_file_uri twice
- Sort values moved to Flow\ETL\Values\Sort and KeyEncoder to Flow\ETL\Values\Grouping
@norberttech norberttech added this to the 0.47.0 milestone Nov 2, 2026
@codecov

codecov Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.68683% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.56%. Comparing base (7d3c573) to head (55e13e8).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff              @@
##                1.x    #2721      +/-   ##
============================================
+ Coverage     87.00%   90.56%   +3.55%     
- Complexity     2232    31336   +29104     
============================================
  Files          2197     2185      -12     
  Lines         93901    90474    -3427     
============================================
+ Hits          81703    81941     +238     
+ Misses        12198     8533    -3665     
Components Coverage Δ
etl 95.96% <98.13%> (+0.20%) ⬆️
cli 87.24% <ø> (+2.43%) ⬆️
lib-array-dot 96.52% <ø> (ø)
lib-azure-sdk 64.17% <ø> (+1.02%) ⬆️
lib-doctrine-dbal-bulk 94.25% <ø> (+0.66%) ⬆️
lib-filesystem 88.96% <ø> (+6.01%) ⬆️
lib-types 94.64% <ø> (ø)
lib-parquet 82.80% <ø> (-0.05%) ⬇️
lib-parquet-viewer 83.15% <ø> (ø)
lib-snappy 89.86% <ø> (-0.89%) ⬇️
lib-dremel 0.00% <ø> (ø)
lib-postgresql 89.44% <ø> (+4.52%) ⬆️
lib-telemetry 86.85% <ø> (+20.44%) ⬆️
bridge-filesystem-async-aws 96.12% <ø> (+12.36%) ⬆️
bridge-filesystem-azure 94.39% <ø> (+13.90%) ⬆️
bridge-filesystem-sftp 90.29% <ø> (+4.85%) ⬆️
bridge-monolog-http 96.84% <ø> (ø)
bridge-monolog-telemetry 92.85% <ø> (+13.03%) ⬆️
bridge-openapi-specification 91.95% <ø> (ø)
symfony-http-foundation 80.76% <ø> (+0.64%) ⬆️
bridge-psr18-telemetry 100.00% <ø> (ø)
bridge-psr3-telemetry 98.95% <ø> (+17.37%) ⬆️
bridge-psr7-telemetry 100.00% <ø> (ø)
bridge-telemetry-otlp 90.11% <ø> (+10.24%) ⬆️
bridge-symfony-http-foundation-telemetry 92.85% <ø> (ø)
bridge-symfony-filesystem-bundle 90.72% <ø> (ø)
bridge-symfony-filesystem-cache 98.18% <ø> (ø)
bridge-symfony-postgresql-bundle 93.35% <ø> (+1.29%) ⬆️
bridge-symfony-postgresql-cache 94.41% <ø> (ø)
bridge-symfony-postgresql-messenger 98.80% <ø> (ø)
bridge-symfony-postgresql-session 93.65% <ø> (ø)
bridge-symfony-telemetry-bundle 90.76% <ø> (+0.38%) ⬆️
adapter-chartjs 82.11% <ø> (ø)
adapter-csv 97.67% <ø> (+9.17%) ⬆️
adapter-doctrine 95.13% <ø> (ø)
adapter-google-sheet 97.49% <ø> (+28.31%) ⬆️
adapter-http 87.18% <ø> (ø)
adapter-json 90.59% <ø> (+4.38%) ⬆️
adapter-logger 47.05% <ø> (ø)
adapter-parquet 97.20% <95.00%> (+1.48%) ⬆️
adapter-text 97.68% <ø> (-0.02%) ⬇️
adapter-xml 98.01% <ø> (-0.01%) ⬇️
adapter-avro 6.25% <ø> (ø)
adapter-excel 96.77% <ø> (+9.55%) ⬆️
adapter-postgresql 97.34% <ø> (+0.10%) ⬆️
adapter-seal 89.91% <ø> (ø)
bridge-phpunit-postgresql 75.30% <ø> (ø)
bridge-phpunit-telemetry 87.36% <ø> (ø)
bridge-phpstan-types 0.00% <ø> (ø)
bridge-postgresql-valinor 100.00% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@norberttech
norberttech merged commit 659e787 into 1.x Nov 2, 2026
42 of 43 checks passed
@norberttech
norberttech deleted the filter-evaluation-perf branch November 2, 2026 19:35
@github-project-automation github-project-automation Bot moved this from Todo to Done in Roadmap Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant