Received: from localhost (unknown [200.46.204.183]) by mail.postgresql.org (Postfix) with ESMTP id 01B526322AF for ; Sat, 25 Apr 2009 08:06:52 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by localhost (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 46816-08 for ; Sat, 25 Apr 2009 08:06:50 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mail46.e.nsc.no (mail46.e.nsc.no [193.213.115.46]) by mail.postgresql.org (Postfix) with ESMTP id 8A84962E0FE for ; Sat, 25 Apr 2009 08:06:48 -0300 (ADT) Received: from [192.168.0.15] (062016185042.customer.alfanett.no [62.16.185.42]) (authenticated bits=0) by mail46.nsc.no (8.13.8/8.13.5) with ESMTP id n3PB6j60021443 for ; Sat, 25 Apr 2009 13:06:45 +0200 (MEST) From: "Leif B. Kristensen" To: pgsql-sql@postgresql.org Subject: Multiple return values and assignment Date: Sat, 25 Apr 2009 13:06:44 +0200 User-Agent: KMail/1.9.9 X-Face: %iea8o"[SI'kMDS.`hz7lU=?\^lC9J-]CVjo; f{4-C:$?uVUEjyN~uYFn%*aH_c3d09U>=?utf-8?q?x=0A=09TXtaoj=7EMV=2E8PgG7hik9=3BcCT2N6+u?=@Y{wH\p3*_f~FH9k,Wi74e[_l%.7b^'zJ)8S'^G<(=?utf-8?q?=3D=0A=09zw8=5CPMC3=27=7BKl9=2EzL*ks!b6wA?=,c~'F`k&Vq|ELDGa|4 X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0 tagged_above=0 required=5 tests=none X-Spam-Level: X-Archive-Number: 200904/116 X-Sequence-Number: 32462 I've got a function that returns both an integer and a string as a user-defined composite type int_text: -- CREATE TYPE int_text AS (number INTEGER, string TEXT); Basically, the function does some heuristics to extract a sort order number from a text, and conditionally modify the text: CREATE OR REPLACE FUNCTION get_sort(INTEGER, INTEGER, TEXT) RETURNS int_text AS $$ -- parse text to infer sort order; factored out of add_source() below -- because the functionality needs to be accessed directly from PHP as -- well, and this approach eliminates previous duplication of code. -- CREATE TYPE int_text AS (number INTEGER, string TEXT) DECLARE par_id INTEGER = $1; srt INTEGER = $2; txt TEXT = $3; sort_text int_text; BEGIN -- default condition: if nothing is modified, return input values sort_text.number := srt; sort_text.string := txt; -- 1) use page number for sort order -- (low priority, may be overridden) IF srt = 1 THEN -- don't apply this rule unless sort = default IF txt SIMILAR TO E'%side \\d+%' THEN -- use page number as sort order SELECT SUBSTR(SUBSTRING(txt, E'side \\d+'), 5, LENGTH(SUBSTRING(txt, E'side \\d+')) -4)::INTEGER INTO sort_text.number; END IF; END IF; -- 2) use ^#(\d+) for sort order IF txt SIMILAR TO E'#\\d+%' THEN SELECT SUBSTR(SUBSTRING(txt, E'#\\d+'), 2, LENGTH(SUBSTRING(txt, E'#\\d+')) -1)::INTEGER INTO sort_text.number; -- strip #number from text sort_text.string := REGEXP_REPLACE(txt, E'^#\\d+ ', ''); END IF; -- 3) increment from max(sort_order) of source group IF txt LIKE '++ %' THEN SELECT MAX(sort_order) + 1 FROM sources WHERE get_source_gp(source_id) = (SELECT parent_id FROM sources WHERE source_id = par_id) INTO sort_text.number; -- strip symbol from text sort_text.string := REPLACE(txt, '++ ', ''); END IF; RETURN sort_text; END $$ LANGUAGE plpgsql STABLE; To use the two values in an other function where I've declared a variable sort_text of type int_text, I do like this: SELECT number, string FROM get_sort(par_id, srt, txt) INTO sort_text; srt := sort_text.number; txt := sort_text.string; But I feel it's a little awkward. Is there a more elegant way to do it? I can't run the get_sort() function twice, because it modifies its input values. -- Leif Biberg Kristensen | Registered Linux User #338009 Me And My Database: http://solumslekt.org/blog/