Received: from maia.hub.org (maia-2.hub.org [200.46.204.251]) by mail.postgresql.org (Postfix) with ESMTP id 8194E632924 for ; Thu, 13 May 2010 07:51:47 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.251]) (amavisd-maia, port 10024) with ESMTP id 80143-08 for ; Thu, 13 May 2010 10:51:39 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from smtpcorp.com (smtpcorp.com [67.192.120.76]) by mail.postgresql.org (Postfix) with ESMTP id 2C7A563289D for ; Thu, 13 May 2010 07:51:40 -0300 (ADT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=smtpcorp.com; s=main; h=Content-Transfer-Encoding:Content-Type:Mime-Version:References:Message-ID:Date:Subject:From:To; bh=rN18hiF3z7t1V0BFkfv6NnV/oJ0KAwAzOdm1x1aCLx8=; b=LlzDWin7qeMaupx0BWa2PolTBkl6XYg0QzcpumFDidHl1EkO0Tk2Z1F8GFdguzwtgWrn1TVcvOP/xbC7kQSZp9gfCEfgmsK3SOOOaHGiNKVgU/doRc5jAaMr6jDYtblO; Received: from ip-118-90-137-155.xdsl.xnet.co.nz ([118.90.137.155] helo=gonzo) by smtpcorp.com with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.70) id 1OCW0w-0006a3-Bh; mid 144 for pgsql-sql@postgresql.org; Thu, 13 May 2010 10:51:14 +0000 Received: from news by gonzo with local (Exim 4.69) (envelope-from ) id 1OCW0g-0006We-N9 for pgsql-sql@postgresql.org; Thu, 13 May 2010 22:51:22 +1200 To: pgsql-sql@postgresql.org Path: not-for-mail From: Jasen Betts Newsgroups: gmane.comp.db.postgresql.sql Subject: Re: [Trigger] Help needed with NEW.* and TG_TABLE_NAME Date: 13 May 2010 10:51:22 GMT Organization: Dis (not Dat) Organisation Lines: 67 Message-ID: References: NNTP-Posting-Host: localhost Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Trace: reversiblemaps.ath.cx 1273747882 25086 127.0.0.1 (13 May 2010 10:51:22 GMT) X-Face: ?)Aw4rXwN5u0~$nqKj`xPz>xHCwgi^q+^?Ri*+R(&uv2=E1Q0Zk(>h!~o2ID@6{uf8s; a +M[5[U[QT7xFN%^gR"=tuJw%TXXR'Fp~W; (T"1(739R%m0Yyyv*gkGoPA.$b,D.w:z+<'"=-lVT?6 {T?=R^:W5g|E2#EhjKCa+nt":4b}dU7GYB*HBxn&Td$@f%.kl^:7X8rQWd[NTc"P"u6nkisze/Q; 8 "9Z{peQF,w)7UjV$c|RO/mQW/NMgWfr5*$-Z%u46"/00mx-,\R'fLPe.)^ User-Agent: slrn/pre1.0.0-2 (Linux) X-Smtpcorp-Track: 2581945.1.44025735 X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-0.5 tagged_above=-5 required=5 tests=BAYES_05=-0.5 X-Spam-Level: X-Archive-Number: 201005/61 X-Sequence-Number: 34109 On 2010-05-11, Torsten Zühlsdorff wrote: > Hello, > > i have a problem with a trigger written in pl/pgsql. > > It looks like this: > > CREATE OR REPLACE FUNCTION versionize() > RETURNS TRIGGER > AS $$ > BEGIN > > NEW.revision := addContentRevision (OLD.content_id, OLD.revision); > > /* not working line, just a stub: > EXECUTE 'INSERT INTO ' || TG_TABLE_NAME || ' SELECT $1 ' USING NEW; > */ > > RETURN NULL; > > END; > $$ LANGUAGE 'plpgsql' VOLATILE; > > The function should be used at different tables and is invoked before > UPDATEs. Everything what happens is the function call of > addContentRevision. After this call all data (with the updated revision > column) should be stored in the table as a new row. What many people have missed is that you want to INSERT when the DML comnabd UPDATE is used. for things like that usually a rule is used instead, but I can see where that may be unsuitable for your needs. I found the following to work on a simple test case. The problem is that INSERT in PLPGSQL needs a fixed table-name, and that "EXECUTE" can't use variable-names, and further that quote_literal doesn't convert ROW variables into something that can be used in a VALUES clause. so, Here's what I did. CREATE OR REPLACE FUNCTION versionize() RETURNS TRIGGER AS $$ BEGIN -- Not havign a definition for addContentRevision -- I had this line commented out during testing. NEW.revision := addContentRevision (OLD.content_id, OLD.revision); EXECUTE 'INSERT INTO '||TG_TABLE_NAME||' SELECT (' || QUOTE_LITERAL(NEW) || '::' || TG_TABLE_NAME ||').*' ; RETURN NULL; END; $$ LANGUAGE PLPGSQL VOLATILE; I take NEW, convert it to a quoted literal so I can use it in EXECUTE, cast it to the apreopreiate row type and split it into columns using SELECT and .*. That gets inserted. you should probably use QUOTE_IDENT on the TG_TABLE_NAME and possibly also use similarly quoted TG_SCHEMA_NAME