Re: EXECUTE tab completion

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Alvaro Herrera <alvherre(at)commandprompt(dot)com>
Cc: Josh Kupershmidt <schmiddy(at)gmail(dot)com>, Andreas Karlsson <andreas(at)proxel(dot)se>, Pg Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: EXECUTE tab completion
Date: 2011-10-20 14:36:43
Message-ID: 24183.1319121403@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Alvaro Herrera <alvherre(at)commandprompt(dot)com> writes:
> Excerpts from Josh Kupershmidt's message of mi oct 19 23:50:58 -0300 2011:
>> I assume this is an accepted quirk of previous_word() since we have
>> this existing similar code:

> Maybe both are wrong, though the DROP case seems to work so maybe it's
> just dead code.

I looked at the code more closely and I now see what Josh saw and why
this code is like this. If you take a desultory look at previous_word()
you will come away with the impression that it returns NULL when asked
for a word before the first word on the line. But in reality, it
returns NULL only if there is nothing before the current point.
Otherwise, you get duplicates of the first word on the line. For
example in "DROP TABLE <tab>" we'll get
prev_wd = TABLE
prev2_wd = DROP
prev3_wd = DROP
prev4_wd = DROP
prev5_wd = DROP
prev6_wd = DROP
I think this is just a plain old coding bug: the stop-test assumes that
end is reset to -1 each time through the outer loop, but it isn't.

However, we can't just fix the bug, because if previous_word() actually
starts to return NULLs like its author seems to have intended, the
strcasecmp calls that use its output will dump core.

What I suggest is that we redefine previous_word() as returning an empty
string, not NULL, anytime there is no such preceding word. This is
better than the current behavior because (a) it's less surprising and
(b) it's not ambiguous. Right now the caller can't tell the difference
between "DROP" and "DROP DROP DROP".

With that change, the correct test at line 795 would become

else if (pg_strcasecmp(prev_wd, "DROP") == 0 &&
prev2_wd[0] == '\0')

(or any other way you care to write a test for empty string). It looks
like there is only one place in the file that is actually expecting a
null result in prev_wd, so there wouldn't be much collateral damage
to fix.

regards, tom lane

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Kohei KaiGai 2011-10-20 14:49:19 Re: [v9.2] DROP statement reworks
Previous Message Alvaro Herrera 2011-10-20 13:23:31 Re: EXECUTE tab completion