Обсуждение: Spurious errors relating to escaped single quotes

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

Spurious errors relating to escaped single quotes

От
Gavin Flower
Дата:
Hi,

Using pg 9.1beta3, I was found that running a function generated an
error relating to escaped single quotes, yet still produced the answer I
expected!

/////////////// part000.sql script ///////////

DROP TABLE IF EXISTS measurement CASCADE;

CREATE TABLE measurement
(
city_id int not null,
logdate date not null,
peaktemp int,
unitsales int
);


CREATE TABLE measurement_y2010m11
(
CHECK (logdate >= '2010-11-01' AND logdate < '2010-12-01')
) INHERITS (measurement);

CREATE TABLE measurement_y2010m12(
CHECK (logdate >= '2010-12-01' AND logdate < '2011-01-01')
) INHERITS (measurement);

CREATE TABLE measurement_y2011m01
(
CHECK (logdate >= '2011-01-01' AND logdate < '2011-02-01')
) INHERITS (measurement);

CREATE TABLE measurement_y2011m02
(
CHECK (logdate >= '2011-02-01' AND logdate < '2011-03-01')
) INHERITS (measurement);


CREATE INDEX ON measurement_y2010m11 (logdate);
CREATE INDEX ON measurement_y2010m12 (logdate);
CREATE INDEX ON measurement_y2011m01 (logdate);
CREATE INDEX ON measurement_y2011m02 (logdate);


DROP FUNCTION IF EXISTS measurement_insert_trigger() CASCADE;

CREATE OR REPLACE FUNCTION measurement_insert_trigger()
RETURNS TRIGGER AS $$
DECLARE
v_yyyy int;
v_mm int;
v_sql text;
BEGIN
v_yyyy := extract('year' FROM NEW.logdate);
v_mm := extract('month' FROM NEW.logdate) ;
v_sql := 'INSERT INTO measurement_y' ||
v_yyyy ||
'm' ||
v_mm ||
' VALUES (' ||
NEW.city_id || ', ' ||
''\' || NEW.logdate || '\', ' ||
NEW.peaktemp || ', ' ||
NEW.unitsales ||
')';
EXECUTE v_sql;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;


CREATE TRIGGER insert_measurement_trigger
BEFORE INSERT ON measurement
FOR EACH ROW EXECUTE PROCEDURE measurement_insert_trigger();

INSERT INTO measurement
(
city_id,
logdate,
peaktemp,
unitsales
)
VALUES
(3, '2011-01-07', 34, 4000);

TABLE measurement;

////////////// output follows ////////////////

gavin=> \c gcf_db
You are now connected to database "gcf_db" as user "gavin"

gcf_db=> \i part000.sql
psql:part000.sql:1: NOTICE: table "measurement" does not exist, skipping
DROP TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
psql:part000.sql:38: NOTICE: function measurement_insert_trigger() does
not exist, skipping
DROP FUNCTION
psql:part000.sql:63: ERROR: syntax error at or near "\"
LINE 16: ''\' || NEW.logdate || '\', ' ||
^

psql:part000.sql:68: ERROR: function measurement_insert_trigger() does
not exist
INSERT 0 1
city_id | logdate | peaktemp | unitsales
---------+------------+----------+-----------
3 | 2011-01-07 | 34 | 4000
(1 row)

gcf_db=>


Cheers,
Gavin

Re: Spurious errors relating to escaped single quotes

От
Alvaro Herrera
Дата:
Excerpts from Gavin Flower's message of jue jul 14 07:45:00 -0400 2011:
> Hi,
>
> Using pg 9.1beta3, I was found that running a function generated an
> error relating to escaped single quotes, yet still produced the answer I
> expected!

The errors are not spurious.  The function doesn't exist now because it
didn't get created.  What happened is that now your inserts are going
into the parent table, not the partitions as your script intended.

--
Álvaro Herrera <alvherre@commandprompt.com>
The PostgreSQL Company - Command Prompt, Inc.
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

Re: Spurious errors relating to escaped single quotes

От
Tom Lane
Дата:
Alvaro Herrera <alvherre@commandprompt.com> writes:
> Excerpts from Gavin Flower's message of jue jul 14 07:45:00 -0400 2011:
>> Using pg 9.1beta3, I was found that running a function generated an
>> error relating to escaped single quotes, yet still produced the answer I
>> expected!

> The errors are not spurious.  The function doesn't exist now because it
> didn't get created.  What happened is that now your inserts are going
> into the parent table, not the partitions as your script intended.

Possibly a more useful answer is "your function appears to be assuming
that standard_conforming_strings is OFF.  As of 9.1 it's ON by default".

            regards, tom lane

Re: Spurious errors relating to escaped single quotes

От
Gavin Flower
Дата:
On 15/07/11 07:14, Tom Lane wrote:
> Alvaro Herrera<alvherre@commandprompt.com>  writes:
>> Excerpts from Gavin Flower's message of jue jul 14 07:45:00 -0400 2011:
>>> Using pg 9.1beta3, I was found that running a function generated an
>>> error relating to escaped single quotes, yet still produced the answer I
>>> expected!
>> The errors are not spurious.  The function doesn't exist now because it
>> didn't get created.  What happened is that now your inserts are going
>> into the parent table, not the partitions as your script intended.
> Possibly a more useful answer is "your function appears to be assuming
> that standard_conforming_strings is OFF.  As of 9.1 it's ON by default".
>
>             regards, tom lane
Thanks Tom (& Alvera),

I checked my postgresql.conf:
standard_conforming_strings = off

I had forgotten I had changed this, and had simply reussed it from earlier!

The silly thing is, that I had been treading up on partitioned tables
and had come across a comment about mistakes could lead to populating
the parent table!

If I could change the sunject of thread, I would change it to start with
'Misleading...'.

My lawyer siuggests defences of 'tiredness due ti it being late at
night' and 'poor eyesight'!  :-)
(You  can tell I've been reading groklaw.net way too much))

More seriously:
Could a hint be put in after the error message:
'psql:part000.sql:68: ERROR:  function measurement_insert_trigger() does
not exist'
when the table has been partitioned, along the lines that 'this might
cause inserts to go into the parent table, is this intended?' or some
such? I am sure many others also get caught.  This was purely an
exercise for me, but it would be more serious in production code (yes I
know things 'should' be tested properly first...).


Cheers,
Gavin

Re: Spurious errors relating to escaped single quotes

От
Gavin Flower
Дата:
On 15/07/11 08:00, Gavin Flower wrote:
> On 15/07/11 07:14, Tom Lane wrote:
>> Alvaro Herrera<alvherre@commandprompt.com>  writes:
>>> Excerpts from Gavin Flower's message of jue jul 14 07:45:00 -0400 2011:
>>>> Using pg 9.1beta3, I was found that running a function generated an
>>>> error relating to escaped single quotes, yet still produced the
>>>> answer I
>>>> expected!
>>> The errors are not spurious.  The function doesn't exist now because it
>>> didn't get created.  What happened is that now your inserts are going
>>> into the parent table, not the partitions as your script intended.
>> Possibly a more useful answer is "your function appears to be assuming
>> that standard_conforming_strings is OFF.  As of 9.1 it's ON by default".
>>
>>             regards, tom lane
> Thanks Tom (& Alvera),
>
> I checked my postgresql.conf:
> standard_conforming_strings = off
>
> I had forgotten I had changed this, and had simply reussed it from
> earlier!
>
> The silly thing is, that I had been treading up on partitioned tables
> and had come across a comment about mistakes could lead to populating
> the parent table!
>
> If I could change the sunject of thread, I would change it to start
> with 'Misleading...'.
>
> My lawyer siuggests defences of 'tiredness due ti it being late at
> night' and 'poor eyesight'!  :-)
> (You  can tell I've been reading groklaw.net way too much))
>
> More seriously:
> Could a hint be put in after the error message:
> 'psql:part000.sql:68: ERROR:  function measurement_insert_trigger()
> does not exist'
> when the table has been partitioned, along the lines that 'this might
> cause inserts to go into the parent table, is this intended?' or some
> such? I am sure many others also get caught.  This was purely an
> exercise for me, but it would be more serious in production code (yes
> I know things 'should' be tested properly first...).
>
>
> Cheers,
> Gavin
I think it should be possible to put a constraint on the master table to
prevent rows being inserted.

I was able to do this with a nasty hack:

    CREATE TABLE measurement
    (
         city_id         int not null,
         logdate         date not null,
         peaktemp        int,
         unitsales       int,
         CONSTRAINT nothing_allowed_in_master CHECK (city_id::text =
    logdate::text)
    );

But I think it would be better if the EXCLUDE' clause could take a value
'ALL' or 'EVERYTHING', to exclude everything - this would be simpler,
more universally valid (convenient columns for such a nasty hack may not
always be available), and be better documentation.  If that was
implented, I could then rewrite the above as:

    CREATE TABLE measurement
    (
         city_id         int not null,
         logdate         date not null,
         peaktemp        int,
         unitsales       int,
         CONSTRAINT nothing_allowed_in_master EXCLUDE EVERYTHING
    );

Cheers,
Gavin

Re: Spurious errors relating to escaped single quotes

От
Gavin Flower
Дата:
On 15/07/11 11:25, Gavin Flower wrote:
> On 15/07/11 08:00, Gavin Flower wrote:
>> On 15/07/11 07:14, Tom Lane wrote:
>>> Alvaro Herrera<alvherre@commandprompt.com>  writes:
>>>> Excerpts from Gavin Flower's message of jue jul 14 07:45:00 -0400
>>>> 2011:
>>>>> Using pg 9.1beta3, I was found that running a function generated an
>>>>> error relating to escaped single quotes, yet still produced the
>>>>> answer I
>>>>> expected!
>>>> The errors are not spurious.  The function doesn't exist now
>>>> because it
>>>> didn't get created.  What happened is that now your inserts are going
>>>> into the parent table, not the partitions as your script intended.
>>> Possibly a more useful answer is "your function appears to be assuming
>>> that standard_conforming_strings is OFF.  As of 9.1 it's ON by
>>> default".
>>>
>>>             regards, tom lane
>> Thanks Tom (& Alvera),
>>
>> I checked my postgresql.conf:
>> standard_conforming_strings = off
>>
>> I had forgotten I had changed this, and had simply reussed it from
>> earlier!
>>
>> The silly thing is, that I had been treading up on partitioned tables
>> and had come across a comment about mistakes could lead to populating
>> the parent table!
>>
>> If I could change the sunject of thread, I would change it to start
>> with 'Misleading...'.
>>
>> My lawyer siuggests defences of 'tiredness due ti it being late at
>> night' and 'poor eyesight'!  :-)
>> (You  can tell I've been reading groklaw.net way too much))
>>
>> More seriously:
>> Could a hint be put in after the error message:
>> 'psql:part000.sql:68: ERROR:  function measurement_insert_trigger()
>> does not exist'
>> when the table has been partitioned, along the lines that 'this might
>> cause inserts to go into the parent table, is this intended?' or some
>> such? I am sure many others also get caught.  This was purely an
>> exercise for me, but it would be more serious in production code (yes
>> I know things 'should' be tested properly first...).
>>
>>
>> Cheers,
>> Gavin
> I think it should be possible to put a constraint on the master table
> to prevent rows being inserted.
>
> I was able to do this with a nasty hack:
>
>     CREATE TABLE measurement
>     (
>         city_id         int not null,
>         logdate         date not null,
>         peaktemp        int,
>         unitsales       int,
>         CONSTRAINT nothing_allowed_in_master CHECK (city_id::text =
>     logdate::text)
>     );
>
> But I think it would be better if the EXCLUDE' clause could take a
> value 'ALL' or 'EVERYTHING', to exclude everything - this would be
> simpler, more universally valid (convenient columns for such a nasty
> hack may not always be available), and be better documentation.  If
> that was implented, I could then rewrite the above as:
>
>     CREATE TABLE measurement
>     (
>         city_id         int not null,
>         logdate         date not null,
>         peaktemp        int,
>         unitsales       int,
>         CONSTRAINT nothing_allowed_in_master EXCLUDE EVERYTHING
>     );
>
> Cheers,
> Gavin
>
Of course, minutes after I sent the above - I realized these constraints
are inherited, so the above is nonsense!  :-(

Re: Spurious errors relating to escaped single quotes

От
Tom Lane
Дата:
Gavin Flower <GavinFlower@archidevsys.co.nz> writes:
> On 15/07/11 11:25, Gavin Flower wrote:
>> I think it should be possible to put a constraint on the master table
>> to prevent rows being inserted.

> Of course, minutes after I sent the above - I realized these constraints
> are inherited, so the above is nonsense!  :-(

Yeah.  I think there's been some discussion of inventing a non-inherited
variety of check constraint, so that you could put something like
"CHECK (false) NO INHERIT" on the parent table.  There's not really
consensus for this though.

IMO we'd be better advised to spend our time on building an explicit
partitioning mechanism to handle the common cases more simply and
efficiently, instead of continuing to add frammishes to the inheritance
mechanism.

            regards, tom lane

Re: Spurious errors relating to escaped single quotes

От
Gavin Flower
Дата:
On 16/07/11 05:21, Tom Lane wrote:
> Gavin Flower<GavinFlower@archidevsys.co.nz>  writes:
>> On 15/07/11 11:25, Gavin Flower wrote:
>>> I think it should be possible to put a constraint on the master table
>>> to prevent rows being inserted.
>> Of course, minutes after I sent the above - I realized these constraints
>> are inherited, so the above is nonsense!  :-(
> Yeah.  I think there's been some discussion of inventing a non-inherited
> variety of check constraint, so that you could put something like
> "CHECK (false) NO INHERIT" on the parent table.  There's not really
> consensus for this though.
>
> IMO we'd be better advised to spend our time on building an explicit
> partitioning mechanism to handle the common cases more simply and
> efficiently, instead of continuing to add frammishes to the inheritance
> mechanism.
>
>             regards, tom lane

How about being able to mark individual columns, and optionally the
table itself, as ABSTRACT?

Though, I agree that a proper partitioning mechanism would be better.

Cheers,
Gavin