makesign() broken in tsearch2

Started by Tom Lanealmost 20 years ago4 messages
#1Tom Lane
tgl@sss.pgh.pa.us

I noticed the following code in tsearch2:

typedef uint64 TPQTGist;

static TPQTGist
makesign(QUERYTYPE * a)
{
int i;
ITEM *ptr = GETQUERY(a);
TPQTGist sign = 0;

for (i = 0; i < a->size; i++)
{
if (ptr->type == VAL)
sign |= 1 << (ptr->val % SIGLEN);
ptr++;
}

return sign;
}

This is wrong because "1" is an int constant, not an int64, and
therefore the shift will be done in int width. Correct would be

sign |= ((TPQTGist) 1) << (ptr->val % SIGLEN);

The effect of this is at least that the high-order half of sign
remains always zero. Depending on what the machine does with shifts
exceeding the word width (which is undefined according to ANSI C),
the bottom half might be messed up too. So we are failing to exploit
the full intended "sign" space, which presumably is costing something
in index efficiency.

It looks to me like the values calculated by this routine end up on
disk, and therefore we can't fix it without forcing an initdb, or
at least REINDEX of all affected indexes. Is that correct?

regards, tom lane

#2Teodor Sigaev
teodor@sigaev.ru
In reply to: Tom Lane (#1)
Re: makesign() broken in tsearch2

the bottom half might be messed up too. So we are failing to exploit
the full intended "sign" space, which presumably is costing something
in index efficiency.

You are absolutly right. My fault.

It looks to me like the values calculated by this routine end up on
disk, and therefore we can't fix it without forcing an initdb, or
at least REINDEX of all affected indexes. Is that correct?

No. query_gist.c exists only in HEAD branch. That code is devloped
not a lot time ago, and itsn't tested well yet.

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Teodor Sigaev (#2)
Re: makesign() broken in tsearch2

Teodor Sigaev <teodor@sigaev.ru> writes:

It looks to me like the values calculated by this routine end up on
disk, and therefore we can't fix it without forcing an initdb, or
at least REINDEX of all affected indexes. Is that correct?

No. query_gist.c exists only in HEAD branch.

Oh, good, that makes it easy. Do you want to apply the fix or shall I?

regards, tom lane

#4Teodor Sigaev
teodor@sigaev.ru
In reply to: Tom Lane (#3)
Re: makesign() broken in tsearch2

Oh, good, that makes it easy. Do you want to apply the fix or shall I?

I will have normal access to Internet only on Monday. It can easy wait
for me :)