From 32ae28d83b217918ce777700f79ced7c91d618e3 Mon Sep 17 00:00:00 2001 From: Jianghua Yang Date: Fri, 22 May 2026 01:25:09 +0800 Subject: [PATCH] PAX: treat PAX tables as AO-like in index path generation Random TID fetches on PAX tables re-decompress entire stripes (1.5 MB ZSTD blocks) per tuple and bypass the buffer pool, just like AO/AOCS. get_index_paths() already routes AO/AOCS relations to Bitmap paths only and skips IndexScan/IndexOnlyScan (the latter is unimplemented for AO). Extend the same treatment to PAX so that a btree index over a PAX table no longer triggers full-table Index Only Scan when enable_seqscan=off, which previously caused customer queries to hang indefinitely. Detection uses the existing PAX_AM_OID; RelOptInfo gains a relam field cached from rd_rel->relam (mirroring amhandler) so the planner can do the comparison without opening the relation. Heap tables and existing AO behavior are unaffected. --- src/backend/optimizer/path/indxpath.c | 9 ++++++++- src/backend/optimizer/util/plancat.c | 1 + src/include/nodes/pathnodes.h | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 1037ada162d..797c38e6cf5 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -813,7 +813,14 @@ get_index_paths(PlannerInfo *root, RelOptInfo *rel, */ if (index->amhasgettuple) { - if (!AMHandlerIsAO(rel->amhandler) || + /* + * PAX shares AO's planner concern: random TID fetch + * re-decompresses whole stripes and bypasses the buffer pool. + * Treat it as AO-like so only Bitmap paths survive add_path + * here. + */ + if ((!AMHandlerIsAO(rel->amhandler) && + rel->relam != PAX_AM_OID) || index->amcostestimate == bmcostestimate) add_path(rel, (Path *) ipath, root); else if (gp_enable_ao_indexscan && !IsA(ipath, IndexOnlyScan)) diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index f1d08a4d128..330a2539a76 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -158,6 +158,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, */ rel->cdbpolicy = RelationGetPartitioningKey(relation); rel->amhandler = relation->rd_amhandler; + rel->relam = relation->rd_rel->relam; /* * Estimate relation size --- unless it's an inheritance parent, in which diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 3cd21590ac9..2c6a2b4bdbe 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -913,6 +913,7 @@ typedef struct RelOptInfo double tuples; struct GpPolicy *cdbpolicy; /* distribution of stored tuples */ Oid amhandler; /* from relcache entry */ + Oid relam; /* pg_class.relam (table AM oid) */ double allvisfrac; Bitmapset *eclass_indexes; /* Indexes in PlannerInfo's eq_classes list of * ECs that mention this rel */