Properly check index mark/restore in ExecSupportsMarkRestore.
authorAndrew Gierth
Tue, 24 Nov 2020 20:58:32 +0000 (20:58 +0000)
committerAndrew Gierth
Tue, 24 Nov 2020 21:16:58 +0000 (21:16 +0000)
Previously this code assumed that all IndexScan nodes supported
mark/restore, which is not true since it depends on optional index AM
support functions. This could lead to errors about missing support
functions in rare edge cases of mergejoins with no sort keys, where an
unordered non-btree index scan was placed on the inner path without a
protecting Materialize node. (Normally, the fact that merge join
requires ordered input would avoid this error.)

Backpatch all the way since this bug is ancient.

Per report from Eugen Konkov on irc.

Discussion: https://postgr.es/m/[email protected]

src/backend/executor/execAmi.c
src/backend/optimizer/util/plancat.c
src/include/nodes/pathnodes.h

index e2154ba86aa5a2f0b0bf9047560a5e31924c6499..0c10f1d35c2b4301662dbda4dc799d69c60ff9f1 100644 (file)
@@ -417,6 +417,11 @@ ExecSupportsMarkRestore(Path *pathnode)
    {
        case T_IndexScan:
        case T_IndexOnlyScan:
+           /*
+            * Not all index types support mark/restore.
+            */
+           return castNode(IndexPath, pathnode)->indexinfo->amcanmarkpos;
+
        case T_Material:
        case T_Sort:
            return true;
index 25545029d7ad1c98de3432affada747249218c11..3c7f3087a8b526b1aebdc38445354337e7625712 100644 (file)
@@ -275,6 +275,8 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
            info->amhasgettuple = (amroutine->amgettuple != NULL);
            info->amhasgetbitmap = amroutine->amgetbitmap != NULL &&
                relation->rd_tableam->scan_bitmap_next_block != NULL;
+           info->amcanmarkpos = (amroutine->ammarkpos != NULL &&
+                                 amroutine->amrestrpos != NULL);
            info->amcostestimate = amroutine->amcostestimate;
            Assert(info->amcostestimate != NULL);
 
index 485d1b06c910f2f64fcf599d7e37d02ff51e59a0..8d1ad3339f20c0a161d180416c38c8803c2992ff 100644 (file)
@@ -864,6 +864,7 @@ struct IndexOptInfo
    bool        amhasgettuple;  /* does AM have amgettuple interface? */
    bool        amhasgetbitmap; /* does AM have amgetbitmap interface? */
    bool        amcanparallel;  /* does AM support parallel scan? */
+   bool        amcanmarkpos;   /* does AM support mark/restore? */
    /* Rather than include amapi.h here, we declare amcostestimate like this */
    void        (*amcostestimate) ();   /* AM's cost estimator */
 };