Обсуждение: [sqlsmith] Segfault in expand_tuple

Поиск
Список
Период
Сортировка

[sqlsmith] Segfault in expand_tuple

От
Andreas Seltenreich
Дата:
Hi,

the following query triggers a segfault for me when run against the
regression database.  Testing was done with master at 039eb6e92f.
Backtrace below.

regards,
Andreas

select
  case when pg_catalog.lastval() < pg_catalog.pg_stat_get_bgwriter_maxwritten_clean() then case when
pg_catalog.circle_sub_pt(
      cast(cast(null as circle) as circle),
      cast((select location from public.emp limit 1 offset 13)
         as point)) ~ cast(nullif(case when cast(null as box) &> (select boxcol from public.brintest limit 1 offset 2)
         then (select f1 from public.circle_tbl limit 1 offset 4)
           else (select f1 from public.circle_tbl limit 1 offset 4)
           end,
      case when (select pg_catalog.max(class) from public.f_star)
         ~~ ref_0.c then cast(null as circle) else cast(null as circle) end
        ) as circle) then ref_0.a else ref_0.a end
       else case when pg_catalog.circle_sub_pt(
      cast(cast(null as circle) as circle),
      cast((select location from public.emp limit 1 offset 13)
         as point)) ~ cast(nullif(case when cast(null as box) &> (select boxcol from public.brintest limit 1 offset 2)
         then (select f1 from public.circle_tbl limit 1 offset 4)
           else (select f1 from public.circle_tbl limit 1 offset 4)
           end,
      case when (select pg_catalog.max(class) from public.f_star)
         ~~ ref_0.c then cast(null as circle) else cast(null as circle) end
        ) as circle) then ref_0.a else ref_0.a end
       end as c0,
  case when (select intervalcol from public.brintest limit 1 offset 1)
     >= cast(null as "interval") then case when ((select pg_catalog.max(roomno) from public.room)
         !~~ ref_0.c)
    and (cast(null as xid) <> 100) then ref_0.b else ref_0.b end
       else case when ((select pg_catalog.max(roomno) from public.room)
         !~~ ref_0.c)
    and (cast(null as xid) <> 100) then ref_0.b else ref_0.b end
       end as c1,
  ref_0.a as c2,
  (select a from public.idxpart1 limit 1 offset 5) as c3,
  ref_0.b as c4,
    pg_catalog.stddev(
      cast((select pg_catalog.sum(float4col) from public.brintest)
     as float4)) over (partition by ref_0.a,ref_0.b,ref_0.c order by ref_0.b) as c5,
  cast(nullif(ref_0.b, ref_0.a) as int4) as c6, ref_0.b as c7, ref_0.c as c8
from
  public.mlparted3 as ref_0
where true;

Core was generated by `postgres: smith regression [local] SELECT  '.
Program terminated with signal SIGSEGV, Segmentation fault.
(gdb) bt
#0  0x0000556c14759cb8 in expand_tuple (targetHeapTuple=targetHeapTuple@entry=0x0, 
    targetMinimalTuple=targetMinimalTuple@entry=0x7ffe8088a118, sourceTuple=<optimized out>, tupleDesc=<optimized
out>)
    at heaptuple.c:984
#1  0x0000556c1475bb46 in minimal_expand_tuple (sourceTuple=<optimized out>, tupleDesc=<optimized out>) at
heaptuple.c:1015
#2  0x0000556c14917177 in ExecCopySlotMinimalTuple (slot=<optimized out>) at execTuples.c:631
#3  0x0000556c14ba8ada in copytup_heap (state=0x556c16c4f5e8, stup=0x7ffe8088a180, tup=<optimized out>) at
tuplesort.c:3585
#4  0x0000556c14baf8e6 in tuplesort_puttupleslot (state=state@entry=0x556c16c4f5e8, slot=<optimized out>) at
tuplesort.c:1444
#5  0x0000556c14937791 in ExecSort (pstate=0x556c16c3ac50) at nodeSort.c:112
#6  0x0000556c1493c6f4 in ExecProcNode (node=0x556c16c3ac50) at ../../../src/include/executor/executor.h:239
#7  begin_partition (winstate=winstate@entry=0x556c16c3a6b8) at nodeWindowAgg.c:1110
#8  0x0000556c149403aa in ExecWindowAgg (pstate=0x556c16c3a6b8) at nodeWindowAgg.c:2094
#9  0x0000556c1490c0ca in ExecProcNode (node=0x556c16c3a6b8) at ../../../src/include/executor/executor.h:239
#10 ExecutePlan (execute_once=<optimized out>, dest=0x7f25481b5e88, direction=<optimized out>, numberTuples=0, 
    sendTuples=<optimized out>, operation=CMD_SELECT, use_parallel_mode=<optimized out>, planstate=0x556c16c3a6b8, 
    estate=0x556c16c1bbf8) at execMain.c:1729
#11 standard_ExecutorRun (queryDesc=0x556c16c250c8, direction=<optimized out>, count=0, execute_once=<optimized out>)
    at execMain.c:364
#12 0x0000556c14a6b40c in PortalRunSelect (portal=portal@entry=0x556c16b96468, forward=forward@entry=true, count=0, 
    count@entry=9223372036854775807, dest=dest@entry=0x7f25481b5e88) at pquery.c:937
#13 0x0000556c14a6ca90 in PortalRun (portal=portal@entry=0x556c16b96468, count=count@entry=9223372036854775807, 
    isTopLevel=isTopLevel@entry=true, run_once=run_once@entry=true, dest=dest@entry=0x7f25481b5e88, 
    altdest=altdest@entry=0x7f25481b5e88, completionTag=0x7ffe8088a500 "") at pquery.c:778
#14 0x0000556c14a6859b in exec_simple_query (
    query_string=0x556c16b2b438 "select\n  case when pg_catalog.lastval() <
pg_catalog.pg_stat_get_bgwriter_maxwritten_clean()then case when pg_catalog.circle_sub_pt(\n\t  cast(cast(null as
circle)as circle),\n\t  cast((select location "...) at postgres.c:1121
 
#15 0x0000556c14a6a341 in PostgresMain (argc=<optimized out>, argv=argv@entry=0x556c16b56ad8, dbname=<optimized out>, 
    username=<optimized out>) at postgres.c:4149
#16 0x0000556c1474eac4 in BackendRun (port=0x556c16b4c030) at postmaster.c:4409
#17 BackendStartup (port=0x556c16b4c030) at postmaster.c:4081
#18 ServerLoop () at postmaster.c:1754
#19 0x0000556c149ec017 in PostmasterMain (argc=3, argv=0x556c16b257d0) at postmaster.c:1362
#20 0x0000556c1475006d in main (argc=3, argv=0x556c16b257d0) at main.c:228


Re: [sqlsmith] Segfault in expand_tuple

От
Andres Freund
Дата:
Hi,

On 2018-04-07 21:28:39 +0200, Andreas Seltenreich wrote:
> the following query triggers a segfault for me when run against the
> regression database.  Testing was done with master at 039eb6e92f.
> Backtrace below.

Andrew, that looks like it's in your area?

> Core was generated by `postgres: smith regression [local] SELECT  '.
> Program terminated with signal SIGSEGV, Segmentation fault.
> (gdb) bt
> #0  0x0000556c14759cb8 in expand_tuple (targetHeapTuple=targetHeapTuple@entry=0x0, 
>     targetMinimalTuple=targetMinimalTuple@entry=0x7ffe8088a118, sourceTuple=<optimized out>, tupleDesc=<optimized
out>)
>     at heaptuple.c:984
> #1  0x0000556c1475bb46 in minimal_expand_tuple (sourceTuple=<optimized out>, tupleDesc=<optimized out>) at
heaptuple.c:1015
> #2  0x0000556c14917177 in ExecCopySlotMinimalTuple (slot=<optimized out>) at execTuples.c:631
> #3  0x0000556c14ba8ada in copytup_heap (state=0x556c16c4f5e8, stup=0x7ffe8088a180, tup=<optimized out>) at
tuplesort.c:3585
> #4  0x0000556c14baf8e6 in tuplesort_puttupleslot (state=state@entry=0x556c16c4f5e8, slot=<optimized out>) at
tuplesort.c:1444
> #5  0x0000556c14937791 in ExecSort (pstate=0x556c16c3ac50) at nodeSort.c:112
> #6  0x0000556c1493c6f4 in ExecProcNode (node=0x556c16c3ac50) at ../../../src/include/executor/executor.h:239
> #7  begin_partition (winstate=winstate@entry=0x556c16c3a6b8) at nodeWindowAgg.c:1110
> #8  0x0000556c149403aa in ExecWindowAgg (pstate=0x556c16c3a6b8) at nodeWindowAgg.c:2094
> #9  0x0000556c1490c0ca in ExecProcNode (node=0x556c16c3a6b8) at ../../../src/include/executor/executor.h:239


Greetings,

Andres Freund


Re: [sqlsmith] Segfault in expand_tuple

От
Andrew Dunstan
Дата:

On 04/07/2018 03:28 PM, Andreas Seltenreich wrote:
> Hi,
>
> the following query triggers a segfault for me when run against the
> regression database.  Testing was done with master at 039eb6e92f.
> Backtrace below.
>
[large query]

> Core was generated by `postgres: smith regression [local] SELECT  '.
> Program terminated with signal SIGSEGV, Segmentation fault.
> (gdb) bt
> #0  0x0000556c14759cb8 in expand_tuple (targetHeapTuple=targetHeapTuple@entry=0x0, 
>     targetMinimalTuple=targetMinimalTuple@entry=0x7ffe8088a118, sourceTuple=<optimized out>, tupleDesc=<optimized
out>)
>     at heaptuple.c:984
> #1  0x0000556c1475bb46 in minimal_expand_tuple (sourceTuple=<optimized out>, tupleDesc=<optimized out>) at
heaptuple.c:1015
> #2  0x0000556c14917177 in ExecCopySlotMinimalTuple (slot=<optimized out>) at execTuples.c:631
> #3  0x0000556c14ba8ada in copytup_heap (state=0x556c16c4f5e8, stup=0x7ffe8088a180, tup=<optimized out>) at
tuplesort.c:3585
> #4  0x0000556c14baf8e6 in tuplesort_puttupleslot (state=state@entry=0x556c16c4f5e8, slot=<optimized out>) at
tuplesort.c:1444
> #5  0x0000556c14937791 in ExecSort (pstate=0x556c16c3ac50) at nodeSort.c:112
> #6  0x0000556c1493c6f4 in ExecProcNode (node=0x556c16c3ac50) at ../../../src/include/executor/executor.h:239
> #7  begin_partition (winstate=winstate@entry=0x556c16c3a6b8) at nodeWindowAgg.c:1110
> #8  0x0000556c149403aa in ExecWindowAgg (pstate=0x556c16c3a6b8) at nodeWindowAgg.c:2094



Yeah, thanks for the report. An obvious fix is this where we treat any
case where attrmiss is entirely missing as meaning NULL for every
attribute we need to supply:

diff --git a/src/backend/access/common/heaptuple.c
b/src/backend/access/common/heaptuple.c
index c646456..b9802b9 100644
--- a/src/backend/access/common/heaptuple.c
+++ b/src/backend/access/common/heaptuple.c
@@ -981,7 +981,7 @@ expand_tuple(HeapTuple *targetHeapTuple,
 
        Form_pg_attribute attr = TupleDescAttr(tupleDesc, attnum);
 
-       if (attrmiss[attnum].ammissingPresent)
+       if (attrmiss && attrmiss[attnum].ammissingPresent)
        {
            fill_val(attr,
                     nullBits ? &nullBits : NULL,


although it might be a very small optimization to move the additional
test outside the loop.


I have cut down the query that generates the failure to this:

    select
        ref_0.a as c2,
        pg_catalog.stddev(
          cast((select pg_catalog.sum(float4col) from public.brintest)
    as float4))
           over (partition by ref_0.a,ref_0.b,ref_0.c order by ref_0.b)
        as c5
    from
      public.mlparted3 as ref_0;

Not sure if we want to produce something more self-contained for the
regression set. Clearly we should add something, as Tom has reminded me,
to make sure the code path is exercised.

cheers

andrew

-- 
Andrew Dunstan                https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services