Skip site navigation (1) Skip section navigation (2)

Re: [HACKERS] Help with pl/pgsql, triggers, and foreign keys

From: Ed Loehr <eloehr(at)austin(dot)rr(dot)com>
To: roberts(at)panix(dot)com
Cc: pgsql-hackers(at)postgresql(dot)org, pgsql-sql(at)postgresql(dot)org
Subject: Re: [HACKERS] Help with pl/pgsql, triggers, and foreign keys
Date: 2000-01-29 08:37:21
Message-ID: 3892A6C1.264C62B7@austin.rr.com (view raw or flat)
Thread:
Lists: pgsql-hackerspgsql-sql
Roland Roberts wrote:
> 
> The Postgres guide says that foreign keys can be partially emulated
> via triggers.  Just how "partial" is this.  I can't seem to get the
> following to work.  Would it work if I wrote it in C?  Would I need to
> open a second connection to the database?  Would it work if my second
> key was really in another table?
> 
> project=> CREATE FUNCTION check_task_pid () RETURNS OPAQUE AS '
> project'>     BEGIN
> project'>         IF NEW.task_pid IS NOT NULL THEN
> project'>             SELECT task_id FROM task WHERE task_id = NEW.task_pid;
> project'>             IF NOT FOUND THEN
> project'>                 RAISE EXCEPTION ''FOREIGN KEY constraint task_pid not found'';
> project'>             END IF;
> project'>         END IF;
> project'>         RETURN NEW;
> project'>     END;
> project'> ' LANGUAGE 'plpgsql';
> CREATE
> project=> CREATE TRIGGER iu_btrig_check_task_pid BEFORE INSERT OR UPDATE ON task
> project->     FOR EACH ROW EXECUTE PROCEDURE check_task_pid();

At least in 6.5.2, you can definitely implement referential integrity
(RI) via pl/pgsql.  As someone noted earlier, RI is to be released in
7.0, but I suspect it will take a subsequent release or two to
stabilize before it's fit for consumption by the more conservative
reliability-focused users among us...

As for your failing SELECT query, the following tweak to your function
makes it work as expected:

CREATE FUNCTION check_task_pid () RETURNS OPAQUE AS '
    DECLARE
        tmp RECORD;
    BEGIN
        IF NEW.task_pid IS NOT NULL THEN
            SELECT INTO tmp task_id FROM task WHERE task_id =
NEW.task_pid;
            IF NOT FOUND THEN
                RAISE EXCEPTION ''FOREIGN KEY constraint task_pid not
found'';
            END IF;
        END IF;
        RETURN NEW;
    END;
' LANGUAGE 'plpgsql';


Cheers,
Ed Loehr

In response to

Responses

pgsql-hackers by date

Next:From: Michael MeskesDate: 2000-01-29 09:36:55
Subject: Re: [HACKERS] Copyright
Previous:From: Tom LaneDate: 2000-01-29 07:55:56
Subject: Re: [HACKERS] Copyright

pgsql-sql by date

Next:From: Peter EisentrautDate: 2000-01-29 11:14:13
Subject: Re: [SQL] transaction aborted
Previous:From: rootDate: 2000-01-29 07:53:24
Subject: Re: [SQL] transaction aborted

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group