Re: Optimizing nbtree ScalarArrayOp execution, allowing multi-column ordered scans, skip scan

From: Peter Geoghegan <pg(at)bowt(dot)ie>
To: Alexander Lakhin <exclusion(at)gmail(dot)com>
Cc: Matthias van de Meent <boekewurm+postgres(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Tomas Vondra <tomas(dot)vondra(at)enterprisedb(dot)com>, Jeff Davis <pgsql(at)j-davis(dot)com>, benoit <benoit(at)hopsandfork(dot)com>, Alexander Korotkov <aekorotkov(at)gmail(dot)com>, Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
Subject: Re: Optimizing nbtree ScalarArrayOp execution, allowing multi-column ordered scans, skip scan
Date: 2024-08-26 14:58:50
Message-ID: CAH2-Wzk-EoQmR0ptjvC7A7E5Wx9zg+nq3+dMnaevQ=TPg_e1eQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Mon, Aug 26, 2024 at 10:00 AM Alexander Lakhin <exclusion(at)gmail(dot)com> wrote:
> I'm sorry to bother you again, but I've come across another assertion
> failure.

You've found a real bug. I should be the one apologizing - not you.

> Please try the following query (I use a clean "postgres" database,
> just after initdb):
> EXPLAIN SELECT conname
> FROM pg_constraint WHERE conname IN ('pkey', 'ID')
> ORDER BY conname DESC;
>
> SELECT conname
> FROM pg_constraint WHERE conname IN ('pkey', 'ID')
> ORDER BY conname DESC;

The problem is that _bt_checkkeys_look_ahead didn't quite get
everything right with sanitizing the page offset number it uses to
check if a later tuple is before the recently advanced array scan
keys. The page offset itself was checked, but in a way that was faulty
in cases where the int16 we use could overflow.

I can fix the bug by making sure that pstate->targetdistance (an int16
variable) can only be doubled when it actually makes sense. That way
there can never be an int16 overflow, and so the final offnum cannot
underflow to a value that's much higher than the page's max offset
number.

This approach works:

/*
* The look ahead distance starts small, and ramps up as each call here
* allows _bt_readpage to skip over more tuples
*/
if (!pstate->targetdistance)
pstate->targetdistance = LOOK_AHEAD_DEFAULT_DISTANCE;
- else
+ else if (pstate->targetdistance < MaxIndexTuplesPerPage / 2)
pstate->targetdistance *= 2;

I'll push a fix along these lines shortly.

Thanks for the report!
--
Peter Geoghegan

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Pavel Stehule 2024-08-26 14:59:46 Re: [PATCH] Add CANONICAL option to xmlserialize
Previous Message Tom Lane 2024-08-26 14:49:15 Re: BitmapHeapScan streaming read user and prelim refactoring