From: | Alexander Korotkov <aekorotkov(at)gmail(dot)com> |
---|---|
To: | Peter Geoghegan <pg(at)bowt(dot)ie> |
Cc: | Pavel Borisov <pashkin(dot)elfe(at)gmail(dot)com>, Konstantin Knizhnik <knizhnik(at)garret(dot)ru>, PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Index range search optimization |
Date: | 2023-09-29 06:35:24 |
Message-ID: | CAPpHfdt784+20TDtKt0voyQET-8PxpSwBJztpuPcGe7DU0wFBg@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Hi, Peter.
On Fri, Sep 29, 2023 at 4:57 AM Peter Geoghegan <pg(at)bowt(dot)ie> wrote:
> On Fri, Sep 22, 2023 at 7:24 AM Alexander Korotkov <aekorotkov(at)gmail(dot)com> wrote:
> > The thing is that NULLs could appear in the middle of matching values.
> >
> > # WITH t (a, b) AS (VALUES ('a', 'b'), ('a', NULL), ('b', 'a'))
> > SELECT a, b, (a, b) > ('a', 'a') FROM t ORDER BY (a, b);
> > a | b | ?column?
> > ---+------+----------
> > a | b | t
> > a | NULL | NULL
> > b | a | t
> > (3 rows)
> >
> > So we can't just skip the row comparison operator, because we can meet
> > NULL at any place.
>
> But why would SK_ROW_HEADER be any different? Is it related to this
> existing case inside _bt_check_rowcompare()?:
>
> if (subkey->sk_flags & SK_ISNULL)
> {
> /*
> * Unlike the simple-scankey case, this isn't a disallowed case.
> * But it can never match. If all the earlier row comparison
> * columns are required for the scan direction, we can stop the
> * scan, because there can't be another tuple that will succeed.
> */
> if (subkey != (ScanKey) DatumGetPointer(skey->sk_argument))
> subkey--;
> if ((subkey->sk_flags & SK_BT_REQFWD) &&
> ScanDirectionIsForward(dir))
> *continuescan = false;
> else if ((subkey->sk_flags & SK_BT_REQBKWD) &&
> ScanDirectionIsBackward(dir))
> *continuescan = false;
> return false;
> }
Yes, exactly. Our row comparison operators don't match if there is any
null inside the row. But you can find these rows within the matching
range.
> I noticed that you're not initializing so->firstPage correctly for the
> _bt_endpoint() path, which is used when the initial position of the
> scan is either the leftmost or rightmost page. That is, it's possible
> to reach _bt_readpage() without having reached the point in
> _bt_first() where you initialize so->firstPage to "true".
Good catch, thank you!
> It would probably make sense if the flag was initialized to "false" in
> the same way as most other scan state is already, somewhere in
> nbtree.c. Probably in btrescan().
Makes sense, initialisation is added.
------
Regards,
Alexander Korotkov
Attachment | Content-Type | Size |
---|---|---|
0001-Skip-checking-of-scan-keys-required-for-direction-v8.patch | application/octet-stream | 11.2 KB |
From | Date | Subject | |
---|---|---|---|
Next Message | Dean Rasheed | 2023-09-29 07:12:56 | Re: Infinite Interval |
Previous Message | Michael Paquier | 2023-09-29 06:19:47 | Re: Add a new BGWORKER_BYPASS_ROLELOGINCHECK flag |