Don't use abbreviated keys for the final merge pass.
authorRobert Haas <[email protected]>
Fri, 23 Jan 2015 16:58:31 +0000 (11:58 -0500)
committerRobert Haas <[email protected]>
Fri, 23 Jan 2015 16:58:31 +0000 (11:58 -0500)
When we write tuples out to disk and read them back in, the abbreviated
keys become non-abbreviated, because the readtup routines don't know
anything about abbreviation.  But without this fix, the rest of the
code still thinks the abbreviation-aware compartor should be used,
so chaos ensues.

Report by Andrew Gierth; patch by Peter Geoghegan.

src/backend/utils/sort/tuplesort.c

index 6d3aa889bc5eb2395688ec53d319d4e486e0de6e..b6e302fc9ca4270130d7c100a78813e4e92975b6 100644 (file)
@@ -2172,6 +2172,22 @@ mergeruns(Tuplesortstate *state)
        return;
    }
 
+   if (state->sortKeys->abbrev_converter)
+   {
+       /*
+        * If there are multiple runs to be merged, when we go to read back
+        * tuples from disk, abbreviated keys will not have been stored, and we
+        * don't care to regenerate them.  Disable abbreviation from this point
+        * on.
+        */
+       state->sortKeys->abbrev_converter = NULL;
+       state->sortKeys->comparator = state->sortKeys->abbrev_full_comparator;
+
+       /* Not strictly necessary, but be tidy */
+       state->sortKeys->abbrev_abort = NULL;
+       state->sortKeys->abbrev_full_comparator = NULL;
+   }
+
    /* End of step D2: rewind all output tapes to prepare for merging */
    for (tapenum = 0; tapenum < state->tapeRange; tapenum++)
        LogicalTapeRewind(state->tapeset, tapenum, false);