Failure assertion in GROUPS mode of window function in current HEAD

From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Failure assertion in GROUPS mode of window function in current HEAD
Date: 2018-07-04 14:24:32
Message-ID: CAD21AoDrWqycq-w_+Bx1cjc+YUhZ11XTj9rfxNiNDojjBx8Fjw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

I got an assertion failure when I use GROUPS mode and specifies offset
without ORDER BY clause. The reproduction steps and the backtrace I
got are following.

=# create table test as select 1 as c;
=# select sum(c) over (partition by c groups between 1 preceding and
current row) from test;
TRAP: FailedAssertion("!(ptr >= 0 && ptr < state->readptrcount)",
File: "tuplestore.c", Line: 478)

#0 0x0000003b3ce32495 in raise () from /lib64/libc.so.6
#1 0x0000003b3ce33c75 in abort () from /lib64/libc.so.6
#2 0x0000000000a2ef5a in ExceptionalCondition (conditionName=0xc99f38
"!(ptr >= 0 && ptr < state->readptrcount)", errorType=0xc99f22
"FailedAssertion",
fileName=0xc99ec0 "tuplestore.c", lineNumber=478) at assert.c:54
#3 0x0000000000a7fa7d in tuplestore_select_read_pointer
(state=0x139e4a0, ptr=-1) at tuplestore.c:478
#4 0x00000000007216cd in update_frameheadpos (winstate=0x137fc30) at
nodeWindowAgg.c:1655
#5 0x000000000071fb7f in eval_windowaggregates (winstate=0x137fc30)
at nodeWindowAgg.c:735
#6 0x0000000000722ac8 in ExecWindowAgg (pstate=0x137fc30) at
nodeWindowAgg.c:2196
#7 0x00000000006e5776 in ExecProcNodeFirst (node=0x137fc30) at
execProcnode.c:445
#8 0x00000000006da945 in ExecProcNode (node=0x137fc30) at
../../../src/include/executor/executor.h:237
#9 0x00000000006dd2fc in ExecutePlan (estate=0x137fa18,
planstate=0x137fc30, use_parallel_mode=false, operation=CMD_SELECT,
sendTuples=true,
numberTuples=0, direction=ForwardScanDirection, dest=0x138b098,
execute_once=true) at execMain.c:1726
#10 0x00000000006daf2c in standard_ExecutorRun (queryDesc=0x13785b8,
direction=ForwardScanDirection, count=0, execute_once=true) at
execMain.c:363
#11 0x00000000006dad48 in ExecutorRun (queryDesc=0x13785b8,
direction=ForwardScanDirection, count=0, execute_once=true) at
execMain.c:306
#12 0x00000000008c7626 in PortalRunSelect (portal=0x12f3bd8,
forward=true, count=0, dest=0x138b098) at pquery.c:932
#13 0x00000000008c72b4 in PortalRun (portal=0x12f3bd8,
count=9223372036854775807, isTopLevel=true, run_once=true,
dest=0x138b098, altdest=0x138b098,
completionTag=0x7fffaece38b0 "") at pquery.c:773
#14 0x00000000008c1288 in exec_simple_query (
query_string=0x128e938 "select sum(c) over (partition by c groups
between 1 preceding and current row) from test;") at postgres.c:1122
#15 0x00000000008c555e in PostgresMain (argc=1, argv=0x12b8258,
dbname=0x12b80d8 "postgres", username=0x12b80b0 "masahiko") at
postgres.c:4153
#16 0x0000000000822c3c in BackendRun (port=0x12b0020) at postmaster.c:4361
#17 0x00000000008223aa in BackendStartup (port=0x12b0020) at postmaster.c:4033
#18 0x000000000081e84b in ServerLoop () at postmaster.c:1706
#19 0x000000000081e17d in PostmasterMain (argc=5, argv=0x1289330) at
postmaster.c:1379
#20 0x00000000007452d0 in main (argc=5, argv=0x1289330) at main.c:228

The cause of this assertion failure is that we attempted to select a
read pointer (framehead_ptr) that is not allocated. We allocate read
pointers for both frame head and tail when begin a new partition in
begin_partition(). The current code doesn't allocate them as follows
if ORDER BY clause is omitted, but this behavior doesn't match to both
update_framheadpos() and update_framtailpos() which always use each
read pointer in GROUPS offset mode.

if ((winstate->frameOptions & (FRAMEOPTION_RANGE | FRAMEOPTION_GROUPS)) &&
node->ordNumCols != 0)
{
if (!(winstate->frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING))
winstate->framehead_ptr =
tuplestore_alloc_read_pointer(winstate->buffer, 0);
if (!(winstate->frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING))
winstate->frametail_ptr =
tuplestore_alloc_read_pointer(winstate->buffer, 0);
}

Since this issue relates to only GROUPS mode it happen in PostgreSQL
11 or later. Attached patch fixes this issue and add regression tests
for testing GROUPS mode without ORDER BY clause.

Regards,

--
Masahiko Sawada
NIPPON TELEGRAPH AND TELEPHONE CORPORATION
NTT Open Source Software Center

Attachment Content-Type Size
fix_groups_mode_window_func.patch application/octet-stream 9.0 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Peter Geoghegan 2018-07-04 15:01:08 Re: Locking considerations of REINDEX
Previous Message Alvaro Herrera 2018-07-04 13:57:31 Re: Non-reserved replication slots and slot advancing