Re: BUG #15668: Server crash in transformPartitionRangeBounds

Amit Langote <langote_amit_f8@lab.ntt.co.jp>

From: Amit Langote <Langote_Amit_f8@lab.ntt.co.jp>
To: Tom Lane <tgl@sss.pgh.pa.us>, Robert Haas <robertmhaas@gmail.com>
Cc: Michael Paquier <michael@paquier.xyz>, Amit Langote <amitlangote09@gmail.com>, Alexander Lakhin <exclusion@gmail.com>, PostgreSQL mailing lists <pgsql-bugs@lists.postgresql.org>, PostgreSQL-development <pgsql-hackers@postgresql.org>, Peter Eisentraut <peter.eisentraut@2ndquadrant.com>
Date: 2019-03-13T04:08:01Z
Lists: pgsql-bugs, pgsql-hackers
On 2019/03/13 1:35, Tom Lane wrote:
> Robert Haas <robertmhaas@gmail.com> writes:
>> On Mon, Mar 11, 2019 at 2:45 AM Amit Langote
>> <Langote_Amit_f8@lab.ntt.co.jp> wrote:
>>> I noticed another issue with the code -- it's using strcmp() to compare
>>> specified string against "minvalue" and "maxvalue", which causes the
>>> following silly error:
>>>
>>> create table q2 partition of q for values from ("MINVALUE") to (maxvalue);
>>> ERROR:  column "MINVALUE" does not exist
>>> LINE 1: create table q2 partition of q for values from ("MINVALUE") ...
>>>
>>> It should be using pg_strncasecmp().
> 
>> Uh, why?  Generally, an unquoted keyword is equivalent to a quoted
>> lowercase version of that same keyword, not anything else.  Like
>> CREATE TABLE "foo" = CREATE TABLE FOO <> CREATE TABLE "FOO".

OK.  Perhaps, I reacted too strongly to encountering the following
behavior with HEAD:

create table p1 partition of p for values from ("minValue") to (1);
ERROR:  column "minValue" does not exist

but,

create table p1 partition of p for values from ("minvalue") to (1);
\d p1
                 Table "public.p1"
 Column │  Type   │ Collation │ Nullable │ Default
────────┼─────────┼───────────┼──────────┼─────────
 a      │ integer │           │          │
Partition of: p FOR VALUES FROM (MINVALUE) TO (1)

But as you and Tom have pointed out, maybe it's normal.

> Yeah.  The behavior shown above is entirely correct, and accepting the
> statement would be flat out wrong; it would cause trouble if somebody
> created a table containing multiple case-variations of MINVALUE.

Sorry, I didn't understand this last part.  Different case-variations will
all be interpreted as a minvalue (negative infinity) range bound and
flagged if the resulting range bound constraint would be invalid.

Did you mean something like the following:

create table p1 partition of ... from ("minValue") to ("MINVALUE");


which using pg_strncasecmp() comparisons gives:

create table p1 partition of p for values from ("minValue") to ("MINVALUE");
ERROR:  empty range bound specified for partition "p1"
DETAIL:  Specified lower bound (MINVALUE) is greater than or equal to
upper bound (MINVALUE).

which is same as the behavior with unquoted keyword syntax:

create table p1 partition of p for values from (minValue) to (MINVALUE);
ERROR:  empty range bound specified for partition "p1"
DETAIL:  Specified lower bound (MINVALUE) is greater than or equal to
upper bound (MINVALUE).

whereas quoted identifier syntax on HEAD gives:

create table p1 partition of p for values from ("minValue") to ("MINVALUE");
ERROR:  column "minValue" does not exist
LINE 1: create table p1 partition of p for values from ("minValue") ...

However, as you guys said, HEAD is behaving sanely.

Thanks,
Amit



Commits

  1. Fix crash when using partition bound expressions

  2. Allow generalized expression syntax for partition bounds