Hi!

I found problem while vacuuming with composite type (version 9.0.4). It's not so easy to reproduce, but it's clear what happens.

CREATE TYPE mytype AS (p point, r float8);
CREATE TABLE mytable (mt mytype);
-- create opclass fir GiST
CREATE INDEX myidx ON mytable USING gist (mt);

And vacuum fails with message:
ERROR:  could not identify a comparison function for type point

I added an assert to all such error and got a backtrace:
 #0  0x0000000800de8fcc in kill () from /lib/libc.so.7
(gdb) bt
#0  0x0000000800de8fcc in kill () from /lib/libc.so.7
#1  0x0000000800de7dcb in abort () from /lib/libc.so.7
#2 0x00000000007bb05f in ExceptionalCondition (conditionName=Could not find the frame base for "ExceptionalCondition".
) at assert.c:57
#3  0x000000000073839a in record_cmp (fcinfo=0x7fffffffcb80) at rowtypes.c:910
#4  0x0000000000739005 in btrecordcmp (fcinfo=0x7fffffffcb80)
    at rowtypes.c:1236
#5  0x00000000007eb63b in myFunctionCall2 (flinfo=0x7fffffffd170,
    arg1=34521714600, arg2=34521722960) at tuplesort.c:2506
#6  0x00000000007eb598 in inlineApplySortFunction (
    sortFunction=0x7fffffffd170, sk_flags=0, datum1=34521714600,
    isNull1=0 '\0', datum2=34521722960, isNull2=0 '\0') at tuplesort.c:2546
#7  0x00000000007eb50a in ApplySortFunction (sortFunction=0x7fffffffd170,
    sortFlags=0, datum1=34521714600, isNull1=0 '\0', datum2=34521722960,
    isNull2=0 '\0') at tuplesort.c:2565
#8  0x000000000055694f in compare_scalars (a=0x809a9f038, b=0x809a9f048,
    arg=0x7fffffffd150) at analyze.c:2702
#9  0x00000000007fd2cc in qsort_arg (a=0x809a9f038, n=611, es=16,
    cmp=0x5568e0 <compare_scalars>, arg=0x7fffffffd150) at qsort_arg.c:129
#10 0x0000000000555bb6 in compute_scalar_stats (stats=0x809a06ca0,
    fetchfunc=0x554920 <ind_fetch_func>, samplerows=611, totalrows=611)
    at analyze.c:2298
#11 0x000000000055279a in compute_index_stats (onerel=0x8011ac828,
    totalrows=611, indexdata=0x8011e10e8, nindexes=1, rows=0x809a0c038,
    numrows=611, col_context=0x8011ceed8) at analyze.c:764
#12 0x0000000000551eb8 in do_analyze_rel (onerel=0x8011ac828,
    vacstmt=0x7fffffffd880, inh=0 '\0') at analyze.c:501
#13 0x0000000000551437 in analyze_rel (relid=16483, vacstmt=0x7fffffffd880,
    bstrategy=0x80117c588) at analyze.c:217
#14 0x00000000005b0b52 in vacuum (vacstmt=0x7fffffffd880, relid=16483,
    do_toast=0 '\0', bstrategy=0x80117c588, for_wraparound=0 '\0',
    isTopLevel=1 '\001') at vacuum.c:246
#15 0x0000000000674f06 in autovacuum_do_vac_analyze (tab=0x80117cf88,
    bstrategy=0x80117c588) at autovacuum.c:2692
#16 0x0000000000674403 in do_autovacuum () at autovacuum.c:2262
....

So, I think, std_typanalyze() does wrong choice between compute_minimal_stats() and compute_scalar_stats() because row type has defined comparison function ( btrecordcmp() ) but searching of actual set of comparisons functions per row's columns occurs too late - when btrecordcmp() is already started.

I don't have in idea how to fix it without massive refactoring. std_typanalyze() should be a bit clever to dig possibility of comparison or compute_scalar_stats() should switch to compute_minimal_stats() if underlying functions fail with such error.

Obviously, workaround is a adding dummy comparison function for points.

--
Teodor Sigaev                                   E-mail: teo...@sigaev.ru
                                                   WWW: http://www.sigaev.ru/

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to