Re: [BUGFIX] amcanbackward is not checked before building backward index paths

From: Andrew Gierth <andrew(at)tao11(dot)riddles(dot)org(dot)uk>
To: Alvaro Herrera <alvherre(at)2ndquadrant(dot)com>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com>, Nikita Glukhov <n(dot)gluhov(at)postgrespro(dot)ru>, PostgreSQL mailing lists <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: [BUGFIX] amcanbackward is not checked before building backward index paths
Date: 2018-05-17 17:28:46
Message-ID: 87r2ma43hl.fsf@news-spur.riddles.org.uk
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

>>>>> "Alvaro" == Alvaro Herrera <alvherre(at)2ndquadrant(dot)com> writes:

>> "Can the scan direction be changed in mid-scan (to support FETCH
>> FORWARD and FETCH BACKWARD on a cursor)?"

How about,

"Can the scan direction be changed in mid-scan (to support FETCH
BACKWARD on a cursor without needing materialization)?"

Alvaro> To me that sounds like the flag is a prerequisite of using the
Alvaro> cursor in either direction. But maybe "to support both FETCH
Alvaro> FORWARD and FETCH BACKWARD on the same cursor" is sufficient.
Alvaro> Or maybe "to support changing scan direction on a cursor".

Alvaro> To make matters worse, IIUC it's actually fine to read the
Alvaro> cursor in one direction to completion, then in the other
Alvaro> direction to completion, without this flag, right?

If you explicitly declare your cursor as SCROLL, which you should do if
you want to fetch backward in it, then it's always OK to switch
directions - the planner will have inserted a Materialize node if one is
needed. If you didn't declare it with SCROLL, and it's not implicitly
SCROLL as per the rules below, you can't fetch backward in it at all
regardless of whether you reached the end. (see error message in
PortalRunSelect for where this happens)

(I found a bit of a wart in that code: MOVE/FETCH ABSOLUTE will
arbitrarily fail or not fail on a no-scroll cursor according to the
absolute position requested - if it's closer to 1 than the current
position it'll rewind to the start, which always works, then scan
forwards; but if it's closer to the current position, it'll try moving
backwards even in a no-scroll cursor.)

What amcanbackward actually affects, as I read the code, is this:

1. ExecSupportsBackwardScan applied to an IndexScan or IndexOnlyScan is
true if and only if amcanbackward is true.

2. If you specify neither SCROLL nor NO SCROLL when creating a cursor,
then the cursor is implicitly SCROLL if and only if the topmost plan
node returns true from ExecSupportsBackwardScan.

3. If you specify SCROLL when creating a cursor, then the planner
inserts a Materialize node on the top of the plan if
ExecSupportsBackwardScan is not true of the previous top plan node.

--
Andrew (irc:RhodiumToad)

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2018-05-17 17:34:20 Re: [BUGFIX] amcanbackward is not checked before building backward index paths
Previous Message Robert Haas 2018-05-17 17:07:29 Re: [PROPOSAL] Shared Ispell dictionaries