> ## Documentation Index
> Fetch the complete documentation index at: https://www.paradedb.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 0.26.5

> ParadeDB release notes for 0.26.5

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.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.