X-Original-To: pgsql-sql@postgresql.org Received: from localhost (postgresql.org [64.49.215.8]) by postgresql.org (Postfix) with ESMTP id 2A78B4770CB for ; Fri, 31 Jan 2003 01:36:58 -0500 (EST) Received: from candle.pha.pa.us (momjian.navpoint.com [207.106.42.251]) by postgresql.org (Postfix) with ESMTP id A700B476D91 for ; Fri, 31 Jan 2003 01:36:56 -0500 (EST) Received: (from pgman@localhost) by candle.pha.pa.us (8.11.6/8.10.1) id h0V5W4G11349; Fri, 31 Jan 2003 00:32:04 -0500 (EST) From: Bruce Momjian Message-Id: <200301310532.h0V5W4G11349@candle.pha.pa.us> Subject: Re: checking data integrity in a recursive table In-Reply-To: <019801c2c31c$c8d63fa0$3200000a@K2> To: Luke Pascoe Date: Fri, 31 Jan 2003 00:32:04 -0500 (EST) Cc: pgsql-sql@postgresql.org X-Mailer: ELM [version 2.4ME+ PL99 (25)] MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII X-Virus-Scanned: by AMaViS new-20020517 X-Archive-Number: 200301/518 X-Sequence-Number: 11383 Luke Pascoe wrote: > Hi, I have a table that references itself to create a tree-like structure, > eg: > CREATE TABLE tree ( > id SERIAL NOT NULL, > name VARCHAR(255) NOT NULL, > parent INT NULL, > customer IN NOT NULL, > CONSTRAINT parent_key... > CONSTRAINT customer_fk FOREIGN KEY (customer) REFERENCES customer > ); > ALTER TABLE tree ADD CONSTRAINT FOREIGN KEY (parent) REFERENCES tree; > > As you can see tree also references the customer table. > > What I need is a CHECK that will ensuer that any given "tree" row has the > same customer as its parent. > Remember that "parent" can also be NULL. > > Or would this be better done as a trigger? Good question. I don't think you can do actualy SQL lookups in a CHECK. I think you will need a trigger, either in pl/pgsql or in C using SPI to issue the lookup queries. You can have a CHECK clause that deals with multiple columns: CREATE TABLE friend2 ( firstname CHAR(15), lastname CHAR(20), city CHAR(15), state CHAR(2) CHECK (length(trim(state)) = 2), age INTEGER CHECK (age >= 0), gender CHAR(1) CHECK (gender IN ('M','F')), last_met DATE CHECK (last_met BETWEEN '1950-01-01' AND CURRENT_DATE), CHECK (upper(trim(firstname)) != 'ED' OR upper(trim(lastname)) != 'RIVERS') ); However, that doesn't help you because you can't reference a column in another row of the same table. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073