Re: fix for BUG #3720: wrong results at using ltree
| От | Tomas Vondra |
|---|---|
| Тема | Re: fix for BUG #3720: wrong results at using ltree |
| Дата | |
| Msg-id | 20200124182915.zz7hzdkijzsb4ic4@development обсуждение исходный текст |
| Ответ на | Re: fix for BUG #3720: wrong results at using ltree (Alexander Korotkov <a.korotkov@postgrespro.ru>) |
| Ответы |
Re: fix for BUG #3720: wrong results at using ltree
Re: fix for BUG #3720: wrong results at using ltree |
| Список | pgsql-hackers |
Hi Nikita,
This patch seems inactive / stuck in "waiting on author" since November.
It's marked as bugfix, so it'd be good to get it committed instead of
just punting it to the next CF.
I did a quick review, and I came mostly with the same two complaints as
Alexander ...
On Wed, Jul 17, 2019 at 09:33:46PM +0300, Alexander Korotkov wrote:
>Hi Nikita,
>
>On Tue, Jul 16, 2019 at 6:52 PM Nikita Glukhov <n.gluhov@postgrespro.ru> wrote:
>> I looked at "ltree syntax improvement" patch and found two more very
>> old bugs in ltree/lquery (fixes are attached):
>
>Thank you for the fixes. I've couple notes on them.
>
>0001-Fix-max-size-checking-for-ltree-and-lquery.patch
>
>+#define LTREE_MAX_LEVELS Min(PG_UINT16_MAX, MaxAllocSize / sizeof(nodeitem))
>+#define LQUERY_MAX_LEVELS Min(PG_UINT16_MAX, MaxAllocSize / ITEMSIZE)
>
>Looks over caution. PG_UINT16_MAX is not even close to MaxAllocSize /
>sizeof(nodeitem) or MaxAllocSize / ITEMSIZE.
>
Yeah, I'm also puzzled by the usage of PG_UINT16_MAX here. It's so much
lower than the other values we could jut use the constant directly, but
let's say the structs could grow from the ~16B to chnge this.
The main question is why we need PG_UINT16_MAX at all? It kinda implies
we need to squish the value into a 2B counter or something, but is that
actually true? I don't see anything like that in ltree_io.c.
So it seems more like an arbitrary value considered "sane" - which is
fine, but then a comment saying so would be nice, and we could pick a
value that is "nicer" for humans. Or just use value computed from the
MaxAllocSize limit, without the Min().
>0002-Fix-successive-lquery-ops.patch
>
>diff --git a/contrib/ltree/lquery_op.c b/contrib/ltree/lquery_op.c
>index 62172d5..d4f4941 100644
>--- a/contrib/ltree/lquery_op.c
>+++ b/contrib/ltree/lquery_op.c
>@@ -255,8 +255,8 @@ checkCond(lquery_level *curq, int query_numlevel,
>ltree_level *curt, int tree_nu
> }
> else
> {
>- low_pos = cur_tpos + curq->low;
>- high_pos = cur_tpos + curq->high;
>+ low_pos = Min(low_pos + curq->low, PG_UINT16_MAX);
>+ high_pos = Min(high_pos + curq->high, PG_UINT16_MAX);
> if (ptr && ptr->q)
> {
> ptr->nq++;
>@@ -282,8 +282,8 @@ checkCond(lquery_level *curq, int query_numlevel,
>ltree_level *curt, int tree_nu
> }
> else
> {
>- low_pos = cur_tpos + curq->low;
>- high_pos = cur_tpos + curq->high;
>+ low_pos = Min(low_pos + curq->low, PG_UINT16_MAX);
>+ high_pos = Min(high_pos + curq->high, PG_UINT16_MAX);
> }
>
> curq = LQL_NEXT(curq);
>
>I'm not sure what do these checks do. Code around is uncommented and
>puzzled. But could we guarantee the same invariant on the stage of
>ltree/lquery parsing?
>
Unfortunately, the current code is somewhat undercommented :-(
Anyway, I don't quite understand why we need these caps. It kinda seems
like a band-aid for potential overflow.
Why should it be OK for the values to even get past the maximum, with
sane input data? And isn't there a better upper limit (e.g. based on
how much space we actually allocated)?
regards
--
Tomas Vondra http://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
В списке pgsql-hackers по дате отправления: