Обсуждение: rules / triggers on insert. why after?
Hi,
I have the following things in my database:
CREATE SEQUENCE "REO_ID_seq" INCREMENT 1 MINVALUE 1 MAXVALUE 2147483647
CACHE 1;
CREATE TABLE reo ( "REO_ID" int4 DEFAULT nextval('"REO_ID_seq"'::text) NOT NULL, "TYPE" varchar(64) NOT NULL,
CONSTRAINT"REO_ID_reo_ukey" UNIQUE ("REO_ID"), CONSTRAINT reo_pkey PRIMARY KEY ("REO_ID")
);
CREATE TABLE lreo ( "CITY" varchar(64), "STREET" varchar(64), "PRICE" int4, "REO_ID" int4 DEFAULT
currval('"REO_ID_seq"'::text), CONSTRAINT "REO_ID_land_reo_ukey" UNIQUE ("REO_ID"), CONSTRAINT "fk_LREO_REO_ID"
FOREIGNKEY ("REO_ID") REFERENCES reo
("REO_ID") ON DELETE NO ACTION ON UPDATE NO ACTION NOT DEFERRABLE
INITIALLY IMMEDIATE
);
---- either this
-- the rule won't work in 7.2.x, because it is done AFTER the Insert has
-- executed :(
CREATE RULE "rule_lreo_INSERT" AS ON INSERT TO lreo DO INSTEAD INSERT INTO reo("TYPE") values ('lreo');
---- or this
-- but why does not this work ???
CREATE FUNCTION insert_lreo() Returns opaque As '
BeginINSERT INTO reo ("TYPE") VALUES (''lreo'');Return Null;
End;
' language 'plpgsql';
CREATE TRIGGER on_insert_lreoBEFORE INSERT ON lreo FOR EACH ROWEXECUTE PROCEDURE insert_lreo();
---- end
On postgres 7.1.3 it was OK to do this:
INSERT INTO "lreo" ("STREET", "PRICE", "CITY")
VALUES ('street', 1234, 'the city');
but on postgres 7.2 and 7.2.1 I get an error that "REO_ID_seq.currval is
not yet defined for this session." The trigger should execute *before*
the insert, right?
Does anyone know why since postgres 7.2 the rules are executed *after*
the insert?
Hope you can help me:)
--
Ahti Legonkov
Ahti Legonkov wrote: > Does anyone know why since postgres 7.2 the rules are executed *after* > the insert? Because people where still complaining that they changed to execute *before* in v6.4. Jan -- #======================================================================# # It's easier to get forgiveness for being wrong than for being right. # # Let's break this rule - forgive me. # #================================================== JanWieck@Yahoo.com #
Ahti Legonkov <lego@127.0.0.1> writes:
> CREATE TABLE reo (
> "REO_ID" int4 DEFAULT nextval('"REO_ID_seq"'::text) NOT NULL,
> "TYPE" varchar(64) NOT NULL,
> CONSTRAINT "REO_ID_reo_ukey" UNIQUE ("REO_ID"),
> CONSTRAINT reo_pkey PRIMARY KEY ("REO_ID")
> );
> CREATE TABLE lreo (
> "CITY" varchar(64),
> "STREET" varchar(64),
> "PRICE" int4,
> "REO_ID" int4 DEFAULT currval('"REO_ID_seq"'::text),
> CONSTRAINT "REO_ID_land_reo_ukey" UNIQUE ("REO_ID"),
> CONSTRAINT "fk_LREO_REO_ID" FOREIGN KEY ("REO_ID") REFERENCES reo
> ("REO_ID") ON DELETE NO ACTION ON UPDATE NO ACTION NOT DEFERRABLE
> INITIALLY IMMEDIATE
> );
That default for reo_id is too fragile to consider using in any case.
You are making way too many assumptions about when defaults will be
evaluated relative to other actions (such as rule/trigger firings).
I'd suggest that you have no default for column reo_id, and instead
have a BEFORE INSERT trigger for lreo that (a) inserts a row into reo
and (b) sets new.reo_id to the inserted key (which you could get from
currval at that point).
regards, tom lane