Avoid sharing subpath list structure when flattening nested AppendRels.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 23 Sep 2010 23:34:56 +0000 (19:34 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 23 Sep 2010 19:42:08 +0000 (19:42 +0000)
In some situations the original coding led to corrupting the child AppendRel's
subpaths list, effectively adding other members of the parent's list to it.
This was usually masked because we never made any further use of the child's
list, but given the right combination of circumstances, we could do so.  The
visible symptom would be a relation getting scanned twice, as in bug #5673
from David Schmitt.

Backpatch to 8.2, which is as far back as the risky coding appears.  The
example submitted by David only fails in 8.4 and later, but I'm not convinced
that there aren't any even-more-obscure cases where 8.2 and 8.3 would fail.

src/backend/optimizer/path/allpaths.c

index 88b09a2a8bad86bc673745fc347d570732ecd1e3..ba264c3c0f574e0f25c40a54fe58308705aaa683 100644 (file)
@@ -350,7 +350,7 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
        childpath = childrel->cheapest_total_path;
        if (IsA(childpath, AppendPath))
            subpaths = list_concat(subpaths,
-                                  ((AppendPath *) childpath)->subpaths);
+                           list_copy(((AppendPath *) childpath)->subpaths));
        else
            subpaths = lappend(subpaths, childpath);