(expert) "insert into VIEW returning" inside an instead of trigger returns nothing

Поиск
Список
Период
Сортировка
От Rémi Cura
Тема (expert) "insert into VIEW returning" inside an instead of trigger returns nothing
Дата
Msg-id CAJvUf_tuGGTYJO1sm1MvFD0=RHseGhTO29-bQ3Z8hL82R0gb9Q@mail.gmail.com
обсуждение исходный текст
Ответы Re: (expert) "insert into VIEW returning" inside an instead of trigger returns nothing
Список pgsql-general
Hey list,
I'm stuck on a problem that I can't figure out (postgres 9.3).
In short, using an
INSERT INTO __view_with_trigger__ ...  RETURNING gid INTO _gid;
returns nothing.
I need this feature because I use views on tables as user interface.

​This must have to do with the postgres order of execution,
because inserting into a table instead of the view of the table returns the expected result.

Here is a synthetic example (of course the real use really requires this kind of architecture),
any help is much appreciated,
because I don't see any work-around (except not using view at all, which would be terrible data duplication in my case)

Cheers,
Rémi-C​



------------------------------------------------
-- test inserting and instead of trigger --
-----------------------------------------------

CREATE SCHEMA IF NOT EXISTS test ;
SET search_path to test, public ;

DROP TABLE IF EXISTS generic_object CASCADE;
CREATE TABLE generic_object (
    gid SERIAL PRIMARY KEY
    , orientation float
) ;

DROP VIEW IF EXISTS editing_generic_object ;
CREATE VIEW editing_generic_object AS(
    SELECT gid,
        degrees(orientation) AS orientation
        FROM generic_object
) ;


DROP TABLE IF EXISTS specific_object CASCADE ;
CREATE TABLE specific_object (
    gid int references generic_object (gid) ON DELETE CASCADE
    , width float
) ;

DROP VIEW IF EXISTS editing_specific_object ;
CREATE VIEW editing_specific_object AS(
    SELECT g.gid    
        , g.orientation
        , so.width
        FROM specific_object AS so LEFT OUTER JOIN
            generic_object AS g USING (gid)
) ;




DROP FUNCTION IF EXISTS test.rc_editing_generic_object() CASCADE ;
CREATE OR REPLACE FUNCTION test.rc_editing_generic_object(  )
RETURNS  trigger  AS $BODY$
/** @brief : this trigger deals with editing generic object*/
    DECLARE      
    BEGIN
        IF TG_OP = 'DELETE' THEN DELETE FROM test.generic_object WHERE gid = OLD.gid ; RETURN OLD ;
        ELSIF TG_OP = 'INSERT' THEN INSERT INTO test.generic_object (orientation) VALUES (radians(NEW.orientation) ) ;
        ELSE UPDATE test.generic_object SET orientation = radians(NEW.orientation) ;
        END IF ;
       
        RETURN NEW ;
    END ;
$BODY$  LANGUAGE plpgsql VOLATILE;
 

DROP TRIGGER IF EXISTS rc_editing_generic_object ON test.editing_generic_object ;
CREATE TRIGGER rc_edit_street_object_pedestrian INSTEAD OF UPDATE OR INSERT OR DELETE
ON test.editing_generic_object
FOR ROW  EXECUTE PROCEDURE rc_editing_generic_object(  ) ;




DROP FUNCTION IF EXISTS test.rc_editing_specific_object() CASCADE ;
CREATE OR REPLACE FUNCTION test.rc_editing_specific_object(  )
RETURNS  trigger  AS $BODY$
/** @brief : this trigger deals with editing specific object*/
    DECLARE
        _gid int;
    BEGIN
        IF TG_OP = 'DELETE' THEN DELETE FROM test.generic_object WHERE gid = OLD.gid ; RETURN OLD ;
        ELSIF TG_OP = 'INSERT' THEN
            --does not works
            INSERT INTO test.editing_generic_object (orientation) VALUES ( NEW.orientation)  RETURNING gid INTO _gid;
            --does works
            --INSERT INTO test.generic_object (orientation) VALUES ( radians(NEW.orientation) )  RETURNING gid INTO _gid;
           
            RAISE WARNING 'here is the gid deduced after insertion : %', _gid ;
            INSERT INTO test.specific_object (gid, width) VALUES (_gid, NEW.width) ;
        ELSE
            UPDATE test.editing_generic_object  AS e SET orientation = NEW.orientation WHERE e.gid = NEW.gid;
            UPDATE test.specific_object AS s SET width = NEW.width WHERE s.gid = NEW.gid;
        END IF ;
        RETURN NEW ;
    END ;
$BODY$  LANGUAGE plpgsql VOLATILE;
 

DROP TRIGGER IF EXISTS rc_editing_specific_object ON test.editing_specific_object ;
CREATE TRIGGER rc_editing_specific_object INSTEAD OF UPDATE OR INSERT OR DELETE
ON test.editing_specific_object
FOR ROW  EXECUTE PROCEDURE rc_editing_specific_object(  ) ;

--testing

    --inserting into generic : works
    INSERT INTO editing_generic_object ( orientation) VALUES (180) ;
    SELECT *
    FROM generic_object ;
  
    -- insert into specific : don't work
    INSERT INTO editing_specific_object ( orientation,width) VALUES (180, 123) ;
    SELECT *
    FROM specific_object ; 

В списке pgsql-general по дате отправления:

Предыдущее
От: Willy-Bas Loos
Дата:
Сообщение: Re: FDW and BDR
Следующее
От: Rémi Cura
Дата:
Сообщение: Re: (expert) "insert into VIEW returning" inside an instead of trigger returns nothing