Обсуждение: Issue with past commit: Allow fractional input values for integer GUCs ...

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

Issue with past commit: Allow fractional input values for integer GUCs ...

От
Greg Nancarrow
Дата:
Hi Hackers,

I may be wrong, but an issue seems to have been introduced by the
following commit (March 11, 2019):

    Allow fractional input values for integer GUCs, and improve rounding logic
    https://github.com/postgres/postgres/commit/1a83a80a2fe5b559f85ed4830acb92d5124b7a9a

The changes made allow fractional input for some cases where I believe
it shouldn't be allowed (i.e. when the setting does not accept a
unit).
For example,

log_file_mode = 384.234
max_connections = 1.0067e2
port = 5432.123

(Is it intentional - or indeed useful - to allow such settings, for
integer options?)

Also, the modified parse_int() function is used for parsing other
options, such as the integer storage parameters for CREATE TABLE and
CREATE INDEX. For example, the following integer parameter settings
are currently allowed but I don't believe that they should be:

CREATE TABLE ... WITH (fillfactor = 23.45);
CREATE TABLE ... WITH (parallel_workers = 5.4);


I have attached a patch with a proposed correction, keeping it a
simple change to the existing parse_int() function, rather than making
further changes for more optimal integer parsing code. The patch also
updates a couple of test cases (reverting one to its original state
before the commit mentioned above).

Let me know what you think.

Regards,
Greg Nancarrow
Fujitsu Australia

Вложения

Re: Issue with past commit: Allow fractional input values for integer GUCs ...

От
Tom Lane
Дата:
Greg Nancarrow <gregn4422@gmail.com> writes:
> The changes made allow fractional input for some cases where I believe
> it shouldn't be allowed (i.e. when the setting does not accept a
> unit).
> ...
> (Is it intentional - or indeed useful - to allow such settings, for
> integer options?)

Given that the commit included a test case exercising exactly that,
I'm not sure why you might think it was unintentional.  IIRC, the
reasoning was that we ought to hide whether any given GUC is int or
float underneath, in anticipation of future changes like caf626b2c.
Another argument is that in regular SQL, you can assign a fractional
value to an integer column and the system will let you do it; so
why not in SET?

In any case, we already shipped that behavior in v12, so I don't think
we can take it away now.  People don't appreciate formerly valid
settings suddenly not working any more.

            regards, tom lane



Re: Issue with past commit: Allow fractional input values for integer GUCs ...

От
Greg Nancarrow
Дата:
> Given that the commit included a test case exercising exactly that,
> I'm not sure why you might think it was unintentional.

Well, maybe not exercising exactly that. No positive test case was
added. The commit replaced a CREATE TABLE fillfactor test case testing
that "30.5" is invalid, with a test case testing that "-30.1" is
out-of-range. I guess that does indirectly test that "-30.1" is not an
improper value, though the out-of-range error means that test case
should really be put in the "-- Fail min/max values check" section and
not in the "-- Fail while setting improper values" section.

My point was that allowing the fractional input really only makes
sense if the "integer" option/GUC has an associated unit. That's why I
questioned whether allowing it in this case (when the integer
option/GUC has no associated unit, like "port" or "max_connections")
was intentional or useful.


>  IIRC, the
> reasoning was that we ought to hide whether any given GUC is int or
> float underneath, in anticipation of future changes like caf626b2c.
> Another argument is that in regular SQL, you can assign a fractional
> value to an integer column and the system will let you do it; so
> why not in SET?
>
> In any case, we already shipped that behavior in v12, so I don't think
> we can take it away now.  People don't appreciate formerly valid
> settings suddenly not working any more.
>

I guess we'll have to live with the current behaviour then.


Regards,
Greg Nancarrow
Fujitsu Australia



Re: Issue with past commit: Allow fractional input values for integer GUCs ...

От
Robert Haas
Дата:
On Mon, Aug 24, 2020 at 5:32 AM Greg Nancarrow <gregn4422@gmail.com> wrote:
> For example,
>
> log_file_mode = 384.234
> max_connections = 1.0067e2
> port = 5432.123
> CREATE TABLE ... WITH (fillfactor = 23.45);
> CREATE TABLE ... WITH (parallel_workers = 5.4);

I don't think any of these cases should be allowed. Surely if we
allowed 384.234 to be inserted into an integer column, everyone would
say that we'd lost our minds. These cases seem no different. The
discussion to which the commit links is mainly about allowing 0.2s to
work like 200ms, or something of that sort, when the value is
specified as a fraction but works out to an integer when converted to
the base unit. That is a completely different thing from letting
people configure 5.4 parallel workers.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: Issue with past commit: Allow fractional input values for integer GUCs ...

От
Tom Lane
Дата:
Robert Haas <robertmhaas@gmail.com> writes:
> I don't think any of these cases should be allowed. Surely if we
> allowed 384.234 to be inserted into an integer column, everyone would
> say that we'd lost our minds.

regression=# create table itable (f1 int);
CREATE TABLE
regression=# insert into itable values (384.234);
INSERT 0 1
regression=# table itable;
 f1  
-----
 384
(1 row)

It's always worked like that, and nobody's complained about it.
I suspect, in fact, that one could find chapter and verse in the
SQL spec that requires it, just like "numeric" values should get
rounded if you write too many digits.

            regards, tom lane



Re: Issue with past commit: Allow fractional input values for integer GUCs ...

От
Robert Haas
Дата:
On Wed, Aug 26, 2020 at 4:47 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
> regression=# create table itable (f1 int);
> CREATE TABLE
> regression=# insert into itable values (384.234);
> INSERT 0 1
> regression=# table itable;
>  f1
> -----
>  384
> (1 row)
>
> It's always worked like that, and nobody's complained about it.
> I suspect, in fact, that one could find chapter and verse in the
> SQL spec that requires it, just like "numeric" values should get
> rounded if you write too many digits.

That is a bit different from what I had in mind, because it does not
involve a call to int4in(). Instead, it involves a cast. I was
imagining that you would put quotation marks around 384.234, which
does indeed fail:

ERROR:  invalid input syntax for type integer: "384.234"

So the question is whether users who supply values for integer-valued
reloptions, or integer-valued GUCs, expect that they will be parsed as
integers, or whether they expect that they will be parsed as float
values and the cast to integers.

While the new behavior seems fine -- and indeed convenient -- for GUCs
that are numeric with a unit, it does not seem very nice at all for
GUCs that are unitless integers. Why do you think that anyone would be
pleased to discover that they can set port = 543.2? We must decide
whether it is more likely that such a setting is the result of a user
error about which we should issue some complaint, or on the other hand
whether the user is hoping that we will be good enough to round the
value off so as to spare them the trouble. My own view is that the
former is vastly more probably than the latter.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: Issue with past commit: Allow fractional input values for integer GUCs ...

От
Tom Lane
Дата:
Robert Haas <robertmhaas@gmail.com> writes:
> While the new behavior seems fine -- and indeed convenient -- for GUCs
> that are numeric with a unit, it does not seem very nice at all for
> GUCs that are unitless integers.

I find that distinction to be entirely without merit; not least because
we also have unitless float GUCs.  I think the fact that we have some
float and some integer GUCs is an implementation detail more than a
fundamental property --- especially since SQL considers integers
to be just the scale-zero subset of numerics.  I recognize that your
opinion is different, but to me it seems fine as-is.

            regards, tom lane