Allow extensions to mark an individual index as disabled.
authorRobert Haas <rhaas@postgresql.org>
Tue, 10 Mar 2026 12:33:55 +0000 (08:33 -0400)
committerRobert Haas <rhaas@postgresql.org>
Tue, 10 Mar 2026 12:33:55 +0000 (08:33 -0400)
Up until now, the only way for a loadable module to disable the use of a
particular index was to use build_simple_rel_hook (or, previous to
yesterday's commit, get_relation_info_hook) to remove it from the index
list. While that works, it has some disadvantages. First, the index
becomes invisible for all purposes, and can no longer be used for
optimizations such as self-join elimination or left join removal, which
can severely degrade the resulting plan.

Second, if the module attempts to compel the use of a certain index
by removing all other indexes from the index list and disabling
other scan types, but the planner is unable to use the chosen index
for some reason, it will fall back to a sequential scan, because that
is only disabled, whereas the other indexes are, from the planner's
point of view, completely gone. While this situation ideally shouldn't
occur, it's hard for a loadable module to be completely sure whether
the planner will view a certain index as usable for a certain query.
If it isn't, it may be better to fall back to a scan using a disabled
index rather than falling back to an also-disabled sequential scan.

Reviewed-by: Alexandra Wang <alexandra.wang.oss@gmail.com>
Discussion: http://postgr.es/m/CA%2BTgmoYS4ZCVAF2jTce%3DbMP0Oq_db_srocR4cZyO0OBp9oUoGg%40mail.gmail.com

src/backend/optimizer/util/pathnode.c
src/include/nodes/pathnodes.h

index c94e077000f5a21a626bb6f5bf9492809814258d..96cc72a776b8d3d28918bfae3a835d81e7cf84ff 100644 (file)
@@ -1122,6 +1122,14 @@ create_index_path(PlannerInfo *root,
 
    cost_index(pathnode, root, loop_count, partial_path);
 
+   /*
+    * cost_index will set disabled_nodes to 1 if this rel is not allowed to
+    * use index scans in general, but it doesn't have the IndexOptInfo to
+    * know whether this specific index has been disabled.
+    */
+   if (index->disabled)
+       pathnode->path.disabled_nodes = 1;
+
    return pathnode;
 }
 
index c175ee95b68c5708e8485e7836a8b2f8c0a7dbc2..27758ec16fe66425e7f566141c6a96d10d462180 100644 (file)
@@ -1412,6 +1412,8 @@ typedef struct IndexOptInfo
    bool        nullsnotdistinct;
    /* is uniqueness enforced immediately? */
    bool        immediate;
+   /* true if paths using this index should be marked disabled */
+   bool        disabled;
    /* true if index doesn't really exist */
    bool        hypothetical;