Commit d4842d0
committed
Restore contsel/contjoinsel for containment & key-existence operators (#2356)
The containment (`@>`, `<@`, `@>>`, `<<@`) and key-existence (`?`, `?|`,
`?&`) operators on `agtype` were bound to `matchingsel`/`matchingjoinsel`
on the PG14+ source tree. `matchingsel` is built for pattern operators
(LIKE/regex) and during planning invokes the operator's underlying
function (`agtype_contains`) once per `pg_statistic` MCV. With realistic
statistics targets that produces a planner-time regression that
dominates simple OLTP-style point queries.
Restore the lighter `contsel`/`contjoinsel` helpers used by PostgreSQL
core's jsonb operators (`@>`, `<@`, `?` on jsonb), which matches
upstream's long-standing precedent for the same operator family.
Changes:
* `sql/agtype_operators.sql`, `sql/agtype_exists.sql`: 10 operators
flipped from `matchingsel`/`matchingjoinsel` to
`contsel`/`contjoinsel`.
* `age--1.7.0--y.y.y.sql`: appended `ALTER OPERATOR ... SET (RESTRICT,
JOIN)` for all 10 operators so existing installs flip on
`ALTER EXTENSION age UPDATE`.
* `regress/sql/containment_selectivity.sql` (+ `expected/.out`): pin
the bindings via `pg_operator`, plus a "no leaked matchingsel"
aggregate guard and functional smoke for all 10 operators. The
guard catches future regressions if a new operator is added without
the right selectivity helper.
* `regress/expected/cypher_match.out`, `regress/expected/cypher_vle.out`:
refresh expected to reflect new (and better) plan shapes that the
lower-selectivity helper produces — `test_enable_containment` now
picks Nested Loop + Index Only Scans over a Seq Scan/Hash Join, and
two `MATCH p=...` and `show_list_use_vle` queries flip row order
(queries had no `ORDER BY`; result set is unchanged, only ordering).
* `Makefile`: register `containment_selectivity` in `REGRESS`.
Validation:
* Build: clean, `-Werror`.
* Regression: 36/37 tests pass under `EXTRA_TESTS="pgvector
fuzzystrmatch pg_trgm"`. Only `age_upgrade` fails — pre-existing on
master at 774e781 (verified by `git stash && installcheck`).
* Reporter's exact methodology (LDBC-SNB-style snb_graph + pgbench on
`bench_message_content`) reproduces the regression and the fix:
| Metric | matchingsel | contsel | Delta |
|----------------------------|-------------|---------|-------|
| EXPLAIN planning time (ms) | 1.42 | 0.97 | -32% |
| EXPLAIN execution time (ms)| 0.34 | 0.31 | ~equal|
| pgbench TPS (8c x 30s) | 5247 | 7378 | +40.6%|
Run with `default_statistics_target = 1000` to populate MCV lists,
matching the reporter's analyzed-graph conditions.
* Upgrade path: validated end-to-end during the benchmark — operator
bindings were flipped from `matchingsel` -> `contsel` via the same
`ALTER OPERATOR` statements the upgrade SQL ships, while operators
remained functional throughout.
Driver workflows (python/go/node/jdbc) intentionally not run: this PR
only adjusts pg_operator selectivity metadata. There is no C, type, or
protocol change that drivers could observe.
Closes #2356.1 parent 73d0705 commit d4842d0
10 files changed
Lines changed: 2261 additions & 45 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
183 | 183 | | |
184 | 184 | | |
185 | 185 | | |
186 | | - | |
| 186 | + | |
| 187 | + | |
187 | 188 | | |
188 | 189 | | |
189 | 190 | | |
| |||
0 commit comments