Обсуждение: Inconsistent error message for varchar(n)

Поиск
Список
Период
Сортировка

Inconsistent error message for varchar(n)

От
Japin Li
Дата:
Hi, hackers

When I try to create table that has a varchar(n) data type, I find an
inconsistent error message for it.

postgres=# CREATE TABLE tbl (s varchar(2147483647));
ERROR:  length for type varchar cannot exceed 10485760
LINE 1: CREATE TABLE tbl (s varchar(2147483647));
                            ^

postgres=# CREATE TABLE tbl (s varchar(2147483648));
ERROR:  syntax error at or near "2147483648"
LINE 1: CREATE TABLE tbl (s varchar(2147483648));
                                    ^

I find that in gram.y the varchar has an integer parameter which
means its value don't exceed 2147483647.

The first error message is reported by anychar_typmodin(), and the later
is reported by gram.y.  IMO, the syntax error for varchar(n) is more
confused.

Any thoughts?

-- 
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.



Re: Inconsistent error message for varchar(n)

От
Tom Lane
Дата:
Japin Li <japinli@hotmail.com> writes:
> postgres=# CREATE TABLE tbl (s varchar(2147483647));
> ERROR:  length for type varchar cannot exceed 10485760
> LINE 1: CREATE TABLE tbl (s varchar(2147483647));
>                             ^

> postgres=# CREATE TABLE tbl (s varchar(2147483648));
> ERROR:  syntax error at or near "2147483648"
> LINE 1: CREATE TABLE tbl (s varchar(2147483648));
>                                     ^

I'm having a very hard time getting excited about that.  We could maybe
switch the grammar production to use generic expr_list syntax for the
typmod, like GenericType does.  But that would just result in this:

regression=# CREATE TABLE tbl (s "varchar"(2147483648));
ERROR:  value "2147483648" is out of range for type integer
LINE 1: CREATE TABLE tbl (s "varchar"(2147483648));
                            ^

which doesn't seem any less confusing for a novice who doesn't know
that typmods are constrained to be integers.

There might be something to be said for switching all the hard-wired
type productions to use opt_type_modifiers and pushing the knowledge
that's in, eg, opt_float out to per-type typmodin routines.  But any
benefit would be in reduction of the grammar size, and I'm dubious
that it'd be worth the trouble.  I suspect that overall, the resulting
error messages would be slightly worse not better --- note for example
the poorer placement of the error cursor above.  A related example is

regression=# CREATE TABLE tbl (s varchar(2,3));
ERROR:  syntax error at or near ","
LINE 1: CREATE TABLE tbl (s varchar(2,3));
                                     ^
regression=# CREATE TABLE tbl (s "varchar"(2,3));
ERROR:  invalid type modifier
LINE 1: CREATE TABLE tbl (s "varchar"(2,3));
                            ^

That's explained by the comment in anychar_typmodin:

     * we're not too tense about good error message here because grammar
     * shouldn't allow wrong number of modifiers for CHAR

and we could surely improve that message, but anychar_typmodin can't give
a really on-point error cursor.

            regards, tom lane



Re: Inconsistent error message for varchar(n)

От
Japin Li
Дата:
On Sat, 13 Nov 2021 at 23:42, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Japin Li <japinli@hotmail.com> writes:
>> postgres=# CREATE TABLE tbl (s varchar(2147483647));
>> ERROR:  length for type varchar cannot exceed 10485760
>> LINE 1: CREATE TABLE tbl (s varchar(2147483647));
>>                             ^
>
>> postgres=# CREATE TABLE tbl (s varchar(2147483648));
>> ERROR:  syntax error at or near "2147483648"
>> LINE 1: CREATE TABLE tbl (s varchar(2147483648));
>>                                     ^
>
> I'm having a very hard time getting excited about that.  We could maybe
> switch the grammar production to use generic expr_list syntax for the
> typmod, like GenericType does.  But that would just result in this:
>
> regression=# CREATE TABLE tbl (s "varchar"(2147483648));
> ERROR:  value "2147483648" is out of range for type integer
> LINE 1: CREATE TABLE tbl (s "varchar"(2147483648));
>                             ^
>
> which doesn't seem any less confusing for a novice who doesn't know
> that typmods are constrained to be integers.
>
> There might be something to be said for switching all the hard-wired
> type productions to use opt_type_modifiers and pushing the knowledge
> that's in, eg, opt_float out to per-type typmodin routines.  But any
> benefit would be in reduction of the grammar size, and I'm dubious
> that it'd be worth the trouble.  I suspect that overall, the resulting
> error messages would be slightly worse not better --- note for example
> the poorer placement of the error cursor above.  A related example is
>
> regression=# CREATE TABLE tbl (s varchar(2,3));
> ERROR:  syntax error at or near ","
> LINE 1: CREATE TABLE tbl (s varchar(2,3));
>                                      ^
> regression=# CREATE TABLE tbl (s "varchar"(2,3));
> ERROR:  invalid type modifier
> LINE 1: CREATE TABLE tbl (s "varchar"(2,3));
>                             ^
>
> That's explained by the comment in anychar_typmodin:
>
>      * we're not too tense about good error message here because grammar
>      * shouldn't allow wrong number of modifiers for CHAR
>
> and we could surely improve that message, but anychar_typmodin can't give
> a really on-point error cursor.
>

Oh! I didn't consider this situation.  Since the max size of varchar cannot
exceed 10485760, however, I cannot find this in documentation [1]. Is there
something I missed? Should we mention this in the documentation?

[1] https://www.postgresql.org/docs/devel/datatype-character.html

-- 
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.



Re: Inconsistent error message for varchar(n)

От
Tom Lane
Дата:
[ Please trim quotes appropriately when replying.  Nobody wants to
  read the whole history of the thread to get to your comment. ]

Japin Li <japinli@hotmail.com> writes:
> Oh! I didn't consider this situation.  Since the max size of varchar cannot
> exceed 10485760, however, I cannot find this in documentation [1]. Is there
> something I missed? Should we mention this in the documentation?
> [1] https://www.postgresql.org/docs/devel/datatype-character.html

I dunno, that section doesn't really get into implementation limits.
For comparison, it doesn't bring up the point that string values are
constrained to 1GB; that's dealt with elsewhere.  Since the limit on
typmod is substantially more than that, I'm not sure there's much point
in mentioning it specifically.  Maybe there's a case for mentioning the
1GB limit here, though.

            regards, tom lane



Re: Inconsistent error message for varchar(n)

От
Tom Lane
Дата:
I wrote:
> For comparison, it doesn't bring up the point that string values are
> constrained to 1GB; that's dealt with elsewhere.  Since the limit on
> typmod is substantially more than that, I'm not sure there's much point
> in mentioning it specifically.

Oh, wait, I was not counting the zeroes in that number :-(

Tracking it a bit further, the actual typmod limit is set by this:

/*
 * MaxAttrSize is a somewhat arbitrary upper limit on the declared size of
 * data fields of char(n) and similar types.  It need not have anything
 * directly to do with the *actual* upper limit of varlena values, which
 * is currently 1Gb (see TOAST structures in postgres.h).  I've set it
 * at 10Mb which seems like a reasonable number --- tgl 8/6/00.
 */
#define MaxAttrSize        (10 * 1024 * 1024)

So maybe that's something we *should* document, though we'd have to
explain that the limit on text and unconstrained varchar is different.

            regards, tom lane

(From the writing style, I suspect the "tgl" here is me not Tom Lockhart.
I'm too lazy to dig in the git history to confirm it though.)



Re: Inconsistent error message for varchar(n)

От
Dagfinn Ilmari Mannsåker
Дата:
Tom Lane <tgl@sss.pgh.pa.us> writes:

> Tracking it a bit further, the actual typmod limit is set by this:
>
> /*
>  * MaxAttrSize is a somewhat arbitrary upper limit on the declared size of
>  * data fields of char(n) and similar types.  It need not have anything
>  * directly to do with the *actual* upper limit of varlena values, which
>  * is currently 1Gb (see TOAST structures in postgres.h).  I've set it
>  * at 10Mb which seems like a reasonable number --- tgl 8/6/00.
>  */
> #define MaxAttrSize        (10 * 1024 * 1024)
>
> So maybe that's something we *should* document, though we'd have to
> explain that the limit on text and unconstrained varchar is different.
>
>             regards, tom lane
>
> (From the writing style, I suspect the "tgl" here is me not Tom Lockhart.
> I'm too lazy to dig in the git history to confirm it though.)

I was bored, and found this:

commit 022417740094620880488dd9b04fbb96ff11694b
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date:   2000-08-07 20:16:13 +0000

    TOAST mop-up work: update comments for tuple-size-related symbols such
    as MaxHeapAttributeNumber.  Increase MaxAttrSize to something more
    reasonable (given what it's used for, namely checking char(n) declarations,
    I didn't make it the full 1G that it could theoretically be --- 10Mb
    seemed a more reasonable number).  Improve calculation of MaxTupleSize.

which added the above comment and changed MaxAttrSize:

-#define MaxAttrSize        (MaxTupleSize - MAXALIGN(sizeof(HeapTupleHeaderData)))
+#define MaxAttrSize        (10 * 1024 * 1024)
  
- ilmari



Re: Inconsistent error message for varchar(n)

От
Bruce Momjian
Дата:
On Sun, Nov 14, 2021 at 10:33:19AM +0800, Japin Li wrote:
> 
> On Sat, 13 Nov 2021 at 23:42, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> > Japin Li <japinli@hotmail.com> writes:
> >> postgres=# CREATE TABLE tbl (s varchar(2147483647));
> >> ERROR:  length for type varchar cannot exceed 10485760
> >> LINE 1: CREATE TABLE tbl (s varchar(2147483647));
> >>                             ^
> >
> >> postgres=# CREATE TABLE tbl (s varchar(2147483648));
> >> ERROR:  syntax error at or near "2147483648"
> >> LINE 1: CREATE TABLE tbl (s varchar(2147483648));
> >>                                     ^
> >
> > I'm having a very hard time getting excited about that.  We could maybe
> > switch the grammar production to use generic expr_list syntax for the
> > typmod, like GenericType does.  But that would just result in this:
> >
> > regression=# CREATE TABLE tbl (s "varchar"(2147483648));
> > ERROR:  value "2147483648" is out of range for type integer
> > LINE 1: CREATE TABLE tbl (s "varchar"(2147483648));
> >                             ^
> >
> > which doesn't seem any less confusing for a novice who doesn't know
> > that typmods are constrained to be integers.
> >
> > There might be something to be said for switching all the hard-wired
> > type productions to use opt_type_modifiers and pushing the knowledge
> > that's in, eg, opt_float out to per-type typmodin routines.  But any
> > benefit would be in reduction of the grammar size, and I'm dubious
> > that it'd be worth the trouble.  I suspect that overall, the resulting
> > error messages would be slightly worse not better --- note for example
> > the poorer placement of the error cursor above.  A related example is
> >
> > regression=# CREATE TABLE tbl (s varchar(2,3));
> > ERROR:  syntax error at or near ","
> > LINE 1: CREATE TABLE tbl (s varchar(2,3));
> >                                      ^
> > regression=# CREATE TABLE tbl (s "varchar"(2,3));
> > ERROR:  invalid type modifier
> > LINE 1: CREATE TABLE tbl (s "varchar"(2,3));
> >                             ^
> >
> > That's explained by the comment in anychar_typmodin:
> >
> >      * we're not too tense about good error message here because grammar
> >      * shouldn't allow wrong number of modifiers for CHAR
> >
> > and we could surely improve that message, but anychar_typmodin can't give
> > a really on-point error cursor.
> >
> 
> Oh! I didn't consider this situation.  Since the max size of varchar cannot
> exceed 10485760, however, I cannot find this in documentation [1]. Is there
> something I missed? Should we mention this in the documentation?
> 
> [1] https://www.postgresql.org/docs/devel/datatype-character.html

Sorry for my long delay in reviewing this issue.  You are correct this
should be documented --- patch attached.

-- 
  Bruce Momjian  <bruce@momjian.us>        https://momjian.us
  EDB                                      https://enterprisedb.com

  Indecision is a decision.  Inaction is an action.  Mark Batterson


Вложения

Re: Inconsistent error message for varchar(n)

От
Bruce Momjian
Дата:
8On Tue, Aug 16, 2022 at 09:56:17PM -0400, Bruce Momjian wrote:
> On Sun, Nov 14, 2021 at 10:33:19AM +0800, Japin Li wrote:
> > Oh! I didn't consider this situation.  Since the max size of varchar cannot
> > exceed 10485760, however, I cannot find this in documentation [1]. Is there
> > something I missed? Should we mention this in the documentation?
> > 
> > [1] https://www.postgresql.org/docs/devel/datatype-character.html
> 
> Sorry for my long delay in reviewing this issue.  You are correct this
> should be documented --- patch attached.

Patch applied back to PG 10.  Thanks for the report.

-- 
  Bruce Momjian  <bruce@momjian.us>        https://momjian.us
  EDB                                      https://enterprisedb.com

  Indecision is a decision.  Inaction is an action.  Mark Batterson