From: | Samuel Gilbert <samuel(dot)gilbert(at)ec(dot)gc(dot)ca> |
---|---|
To: | pgsql-general(at)postgresql(dot)org |
Subject: | Re: Issues with patitionning and triggers |
Date: | 2014-02-19 16:54:46 |
Message-ID: | 36656139.rbatI8Y9LY@yamium |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
Hello everyone,
Here is a complete example demonstrating the issue I am encountering :
CREATE TABLE parent (
split INTEGER NOT NULL,
happiness INTEGER NOT NULL,
modificationDate TIMESTAMP NOT NULL
);
CREATE TABLE child_split1 ( CHECK (split = 1) ) INHERITS (parent);
CREATE TABLE child_split2 ( CHECK (split = 2) ) INHERITS (parent);
CREATE OR REPLACE FUNCTION parent_dispatcher_trigger()
RETURNS TRIGGER AS $$
BEGIN
CASE NEW.split
WHEN 1 THEN INSERT INTO child_split1 VALUES (NEW.*);
WHEN 2 THEN INSERT INTO child_split2 VALUES (NEW.*);
ELSE RAISE EXCEPTION 'Partition for % does not exist!',NEW.split;
END CASE;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_insert_00
BEFORE INSERT ON parent
FOR EACH ROW EXECUTE PROCEDURE parent_dispatcher_trigger();
CREATE OR REPLACE FUNCTION set_modificationDate_debug() RETURNS TRIGGER AS $$
BEGIN
NEW.modificationDate := now();
RAISE NOTICE 'NEW row is now : (%, %, %)',
NEW.split, NEW.happiness, NEW.modificationDate;
RETURN NEW;
END;
$$ LANGUAGE 'plpgsql';
CREATE TRIGGER trigger_insert_00
BEFORE INSERT ON child_split1
FOR EACH ROW EXECUTE PROCEDURE set_modificationdate_debug();
CREATE TRIGGER trigger_insert_00
BEFORE INSERT ON child_split2
FOR EACH ROW EXECUTE PROCEDURE set_modificationdate_debug();
INSERT INTO parent (split, happiness) VALUES (1, 42);
-- NOTICE: NEW row is now : (1, 42, 2014-02-19 16:31:07.384151)
-- CONTEXT: SQL statement "INSERT INTO child_split1 VALUES (NEW.*)"
-- PL/pgSQL function parent_dispatcher_trigger() line 4 at SQL statement
-- ERROR: null value in column "modificationdate" violates not-null
constraint
-- DETAIL: Failing row contains (1, 42, null).
INSERT INTO child_split1 (split, happiness) VALUES (1, 42);
-- NOTICE: NEW row is now : (1, 42, 2014-02-19 16:37:27.134194)
-- INSERT 0 1
So, we clearly see that trigger_insert_00 is called in both cases. I don't
understand why the query fails on the parent, but works when the INSERT
targets the child table directly.
Regards,
Samuel Gilbert
On 2014-02-18 23:16:31 Samuel Gilbert wrote:
> On 2014-02-18 17:59:35 Tom Lane wrote:
> > Samuel Gilbert <samuel(dot)gilbert(at)ec(dot)gc(dot)ca> writes:
> > > All of this was done on PostgreSQL 9.2.0 64-bit compiled from the
> > > official
> >
> > > source. Significant changes in postgresql.conf :
> > Why in the world are you using 9.2.0? You're missing a year and a half
> > worth of bug fixes, some of them quite serious.
>
> Yes. I know and I bear the pain and shame not running at least the latest
> revision of the 9.2 branch. Unfortunately, it's hard to get my manager to
> view the update of software that "just works" as something to prioritize.
>
> The good news is that your reply is a good argument to do so! :)
>
> Cheers!
>
> > > INSERT ... RETURNING does not work with partitioned tables, since the
> > > trigger function on the parent that dispatches new rows to the children
> > > tables, must return NULL. If the trigger function on the parent ends
> > > with "RETURN NEW", INSERT ... RETURNING works, but new rows are
> > > duplicated; they are inserted both in the parent and child tables.
> > >
> > > Is there a way to make INSERT ... RETURNING work without duplicating the
> > > rows?
> >
> > Fraid not --- it only shows what got inserted into the parent table, which
> > is nothing if you're using this technique.
> >
> > > The modification date must be updated if any row is modified in any way.
> > > I
> > > first tried to define the triggers on the parent table. This worked,
> > > but
> > > I
> > > realized that if a queries targets explicitly a child table, it could
> > > modify a row without the date being updated. I therefore dropped the
> > > triggers on the parent table and defined them for every child. To my
> > > great surprise, the insert below failed with a message saying that NULLs
> > > are not allowed in the modificationdate column.
> >
> > You'd have to provide a self-contained example for anyone to help you with
> > that. The most obvious explanation is that you forgot to attach the
> > trigger to the specific child table ...
> >
> > regards, tom lane
From | Date | Subject | |
---|---|---|---|
Next Message | Joshua D. Drake | 2014-02-19 17:14:23 | Re: Support for Alert |
Previous Message | Alejandro Carrillo | 2014-02-19 16:49:19 | Support for Alert |