X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (av.hub.org [200.46.204.144]) by postgresql.org (Postfix) with ESMTP id 24EEA9DCC17 for ; Sun, 5 Mar 2006 13:48:31 -0400 (AST) Received: from postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 62562-07-2 for ; Sun, 5 Mar 2006 13:48:29 -0400 (AST) X-Greylist: from auto-whitelisted by SQLgrey- Received: from puntd3.cc.uga.edu (puntd3.cc.uga.edu [128.192.1.109]) by postgresql.org (Postfix) with ESMTP id DF0D49DCC25 for ; Sun, 5 Mar 2006 13:48:27 -0400 (AST) Received: from uga.edu (cantor.english.uga.edu [128.192.25.103]) by puntd3.cc.uga.edu (MOS 3.5.9-GR) with SMTP id CON56528 (AUTH via LOGINBEFORESMTP); Sun, 5 Mar 2006 12:48:27 -0500 (EST) Received: by uga.edu (sSMTP sendmail emulation); Sun, 5 Mar 2006 12:48:27 -0500 Date: Sun, 5 Mar 2006 12:48:27 -0500 From: sramsay@uga.edu To: pgsql-sql@postgresql.org Subject: Re: functions in WHERE clause Message-ID: <20060305174827.GA14433@cantor.english.uga.edu> References: <20060305151652.GA14216@cantor.english.uga.edu> <20060305172635.GA77911@winnie.fuhr.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20060305172635.GA77911@winnie.fuhr.org> X-PGP-Key: http://cantor.english.uga.edu/pubkey.asc User-Agent: Mutt/1.5.11 X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, score=0.67 required=5 tests=[AWL=0.120, NO_REAL_NAME=0.55] X-Spam-Score: 0.67 X-Spam-Level: X-Archive-Number: 200603/95 X-Sequence-Number: 24441 On Sun, Mar 05, 2006 at 10:26:35AM -0700, Michael Fuhr wrote: > On Sun, Mar 05, 2006 at 10:16:52AM -0500, sramsay@uga.edu wrote: > > I've got one of these: > > > > SELECT * from some_table WHERE > > test_for_equality_is_syntactically_ugly; > > > > What I'd like to do is encapsulate the WHERE clause in a function, > > but I'm having no end of trouble. > > Would a view work? If not then please provide a more concrete > example that shows what you're trying to do. > > CREATE VIEW foo AS > SELECT * FROM some_table > WHERE test_for_equality_is_syntactically_ugly; Thanks for reply! No, because test_for_equality_is_syntactically_ugly varies. Here's the specifics: I've written an XML database (of sorts) that uses the ltree contrib module to find elements that belong to particular nodes. Right now, if you wanted to find all the word tokens found within the titleStmt element of a set of XML documents, you'd do something like this: SELECT token FROM event WHERE ltree ~ '*.titleStmt.*'; (ltree contains a set of "paths" that together express the hierarchical relationships in the documents, so you can format that bit after the ~ to include any element, and you can also use other kinds of operators to get ancestors, children, etc.). Now, I realize this isn't *really* all that syntactically ugly, but it would be really nice if the user of the db could type in an XPath like so: SELECT token FROM event WHERE xpath("//titleStmt"); This will require some munging inside a function to go from the XPath to the ltree-style regex expression, but I'm finding that I'm having more basic troubles. You can't do this: CREATE FUNCTION xpath(lquery) RETURNS ltree AS $$ SELECT ltree FROM event WHERE ltree ~ $1; $$ LANGUAGE SQL; Because that only returns the first value from the SELECT (and it's not pl-pgsql anyway). But I also can't get this kind of thing to work: CREATE FUNCTION xpath(lquery) RETURNS SETOF ltree AS $$ DECLARE tree record; BEGIN FOR tree IN SELECT ltree FROM event WHERE ltree ~ $1 LOOP RETURN NEXT tree; END LOOP; RETURN; END $$ LANGUAGE plpgsql; Because SETOF won't work in a WHERE context. Part of the problem is that I don't really understand how WHERE constraints work under the hood. The lvalue in the WHERE clause expects a boolean, but I think that really means "evaluate the truth or falsehood of this expression on all rows in the table specified in the FROM clause." So how do you get a function to play nicely with that concept? "The argument of WHERE must not return a set," as the psql shell keeps telling me, but is there anything it would accept that would make this work? Thanks again, Steve -- Stephen Ramsay Assistant Professor Department of English University of Georgia email: sramsay@uga.edu web: http://cantor.english.uga.edu/ PGP Public Key ID: 0xA38D7B11