New Features ✨
-
Join Scan now runs the faceted form
pdb.agg(...) OVER ()(i.e.pdb.agg(...)as a window function) over a join. The document covers every row the join produces, whileORDER BY ... LIMITstill picks the rows returned, so a page of search results across tables carries its facets in the same query. The document can also feed other target list expressions, such aspdb.agg(...) OVER () ->> 'value'. The spec follows the same rules aspdb.agg()over joins; see Limitations for the shapes this path turns down (#6359). -
Aggregate Scan now reports workers requested and launched, the worker selection method, and estimated parallel costs in
EXPLAIN ANALYZE.
Performance Improvements 🚀
-
Range-partitioned joins (
paradedb.enable_range_partitioned_join) no longer walk every document of a segment that crosses the first partition’s edge to find the rows with a NULL join key. Selective queries on that partition now cost the same as on the others. -
Join Scan now lazily fetches row
ctids during visibility checks and projection. For blocks marked all-visible in PostgreSQL’s visibility map, index fast-fieldctidlookups are avoided entirely, reading significantly fewer buffers in queries that filter or sort before projecting rows (#6665). -
A join of three or more range-partitioned tables now keeps its first join task-local when the two tables share a
partition_bykey. This removes one network shuffle of the larger table. - Small aggregations avoid parallel worker startup when serial execution is cheaper. Worker estimates account for query traversal, aggregation work, and heap visibility checks.
- Queries made up of term, match, phrase, and match-all clauses use index statistics to estimate matches, reducing planning time. Boolean combinations and score wrappers around these queries use the same path.
Stability Improvements 💪
-
Retrying index creation after a rolled-back subtransaction, such as a PL/pgSQL
EXCEPTIONblock or aROLLBACK TO SAVEPOINT, now persists its tokenizer settings correctly, so the committed index remains usable from new connections. -
Aggregate Scan now runs a
GROUP BYquery that filters a grouping key to one value, or that selects a column the primary key decides. These queries fell back to Postgres, andpdb.agg()failed (#6606). This also fixes wrong rows forGROUP BY date(ts)under a window function (#6633), and an error on aGROUP BYkey that is a cast (#6632). -
Aggregate Scan now runs a
GROUP BYquery with aHAVINGcondition that has no aggregate, such as a condition on a grouping key, and a grouped subquery with a condition of the outer query on a grouping key. Postgres moves such a condition toWHERE, and the scan declined the query withHAVING clause is not supported. Apdb.agg()query with such a condition failed with the same message (#6636). -
A search query whose heap filter compares a column to a parameter (
lib = $2in a generic plan, or a nested-loop parameter from aLATERALjoin) no longer crashes the backend or fails withunrecognized node typewhen the scan returnsparadedb.score()orparadedb.snippet(), when an aggregate has aFILTERclause, or whenEXPLAIN ANALYZEprints a wrapped aggregate (#6492). -
A
dateofinfinityor-infinityno longer fails index builds, inserts or searches. Infinitedate,timestampandtimestamptzconstants in a search, and adaterangewith an infinite bound, now work too (#6722).