postgresql/src
Tom Lane b8f3682769 Fix a low-probability crash in our qsort implementation.
It's standard for quicksort implementations, after having partitioned the
input into two subgroups, to recurse to process the smaller partition and
then handle the larger partition by iterating.  This method guarantees
that no more than log2(N) levels of recursion can be needed.  However,
Bentley and McIlroy argued that checking to see which partition is smaller
isn't worth the cycles, and so their code doesn't do that but just always
recurses on the left partition.  In most cases that's fine; but with
worst-case input we might need O(N) levels of recursion, and that means
that qsort could be driven to stack overflow.  Such an overflow seems to
be the only explanation for today's report from Yiqing Jin of a SIGSEGV
in med3_tuple while creating an index of a couple billion entries with a
very large maintenance_work_mem setting.  Therefore, let's spend the few
additional cycles and lines of code needed to choose the smaller partition
for recursion.

Also, fix up the qsort code so that it properly uses size_t not int for
some intermediate values representing numbers of items.  This would only
be a live risk when sorting more than INT_MAX bytes (in qsort/qsort_arg)
or tuples (in qsort_tuple), which I believe would never happen with any
caller in the current core code --- but perhaps it could happen with
call sites in third-party modules?  In any case, this is trouble waiting
to happen, and the corrected code is probably if anything shorter and
faster than before, since it removes sign-extension steps that had to
happen when converting between int and size_t.

In passing, move a couple of CHECK_FOR_INTERRUPTS() calls so that it's
not necessary to preserve the value of "r" across them, and prettify
the output of gen_qsort_tuple.pl a little.

Back-patch to all supported branches.  The odds of hitting this issue
are probably higher in 9.4 and up than before, due to the new ability
to allocate sort workspaces exceeding 1GB, but there's no good reason
to believe that it's impossible to crash older branches this way.
2015-07-16 22:57:46 -04:00
..
backend Fix a low-probability crash in our qsort implementation. 2015-07-16 22:57:46 -04:00
bin Fix assorted memory leaks. 2015-07-12 16:25:51 -04:00
common Unlink static libraries before rebuilding them. 2015-03-01 13:06:33 -05:00
include Back-patch some minor bug fixes in GUC code. 2015-06-28 18:38:06 -04:00
interfaces Improve handling of out-of-memory in libpq. 2015-07-07 18:45:17 +03:00
makefiles Remove USE_VPATH make variable from PGXS 2014-12-04 08:45:48 -05:00
pl PL/Perl: Add alternative expected file for Perl 5.22 2015-07-03 14:08:11 -04:00
port Fix a low-probability crash in our qsort implementation. 2015-07-16 22:57:46 -04:00
template Revert to using --enable-auto-import in Cygwin builds. 2014-02-16 15:14:04 -05:00
test Fix some typos in regression test comments. 2015-07-05 13:14:50 -04:00
timezone Update time zone data files to tzdata release 2015d. 2015-05-15 19:35:51 -04:00
tools Turn install.bat into a pure one line wrapper fort he perl script. 2015-07-07 16:31:52 +03:00
tutorial pgindent run for 9.4 2014-05-06 12:12:18 -04:00
.gitignore Convert cvsignore to gitignore, and add .gitignore for build targets. 2010-09-22 12:57:04 +02:00
bcc32.mak Autoconfiscate selection of 64-bit int type for 64-bit large object API. 2012-10-07 21:52:43 -04:00
DEVELOPERS Replace a couple of references to files that no longer exist in the source 2009-05-04 08:08:47 +00:00
Makefile Create libpgcommon, and move pg_malloc et al to it 2013-02-12 11:21:05 -03:00
Makefile.global.in Make numeric form of PG version number readily available in Makefiles. 2015-07-05 12:01:01 -04:00
Makefile.shlib Unlink static libraries before rebuilding them. 2015-03-01 13:06:33 -05:00
nls-global.mk Setup error context callback for transaction lock waits 2014-03-19 15:10:36 -03:00
win32.mak Autoconfiscate selection of 64-bit int type for 64-bit large object API. 2012-10-07 21:52:43 -04:00