--- title: "0.26.5" description: "ParadeDB release notes for 0.26.5" noindex: true --- See GitHub release: [v0.26.5](https://github.com/paradedb/paradedb/releases/tag/v0.26.5) ## Performance Improvements 🚀 - High-cardinality `GROUP BY` queries on the Aggregate Scan run faster: grouped results are turned into rows in one pass instead of re-searching the bucket tree for every row. ## Stability Improvements 💪 - `pdb.verify_index(..., heapallindexed => true)` and `pdb.verify_all_indexes()` lock each table before its index, including partition leaves, avoiding deadlocks with concurrent `REINDEX` or `VACUUM FULL`. - A `GROUP BY` on a float column now returns the aggregates of a `NaN` group instead of NULL, for queries without `FILTER` aggregates. - `NOT (field = ANY('{}'))` and `field <> ALL('{}')` with an empty array no longer drop every row when combined with a search. - Comparing a NULL value against an indexed array column, such as `NULL::text = ANY(tags)`, no longer raises `pushdown expression should not evaluate to NULL`. ## Breaking Changes 🚨 ### Standalone index access permissions Standalone index reads now check permissions on the backing table. Content-reading APIs, including `paradedb.aggregate()`, require table-level `SELECT` and reject calls when row-level security applies to the effective caller. Callers who need a filtered result under RLS can be given a `SECURITY DEFINER` function, owned by the table owner, that applies the policy's filter in an ordinary `@@@` query. Wrapping `paradedb.aggregate()` itself does not filter rows. Metadata APIs, including `paradedb.schema()`, `index_fields()`, the layer-size functions, `index_created_at()`, `index_created_by()`, `merge_info()` (and its `is_merging()` alias), `vacuum_info()`, `fsm_info()`, `fsm_size()`, `paradedb.index_info()`, `pdb.index_segments()`, and the statistics returned by `pdb.indexes()` also accept callers with the privileges of `pg_stat_scan_tables`, inherited by `pg_monitor`. These trusted monitoring roles can inspect whole-index metadata and document counts without table `SELECT`, including counts across rows hidden by RLS. Other callers still need schema `USAGE`, table-level `SELECT`, and no active RLS; inventory omits indexes they cannot inspect. The monitoring privilege does not authorize document reads, verification, or maintenance. Only the metadata APIs listed above accept monitoring privileges. Other diagnostics, including `vector_config()`, and content reads and verification retain the stricter read policy. `merge_lock_garbage_collect()` requires `MAINTAIN` on the backing table on PostgreSQL 17 and later, including privileges inherited from `pg_maintain`. Table owners qualify implicitly. PostgreSQL 15 and 16 require ownership of the backing table.