X-Original-To: pgsql-general-postgresql.org@localhost.postgresql.org Received: from localhost (neptune.hub.org [200.46.204.2]) by svr1.postgresql.org (Postfix) with ESMTP id 25D43D1D903 for ; Thu, 11 Dec 2003 19:49:35 +0000 (GMT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (neptune.hub.org [200.46.204.2]) (amavisd-new, port 10024) with ESMTP id 01313-03 for ; Thu, 11 Dec 2003 15:49:04 -0400 (AST) Received: from infosys-1.ofc.findlaw.com (dhcp-users.findlaw.com [64.94.79.45]) by svr1.postgresql.org (Postfix) with ESMTP id E66FDD1BB74 for ; Thu, 11 Dec 2003 15:49:02 -0400 (AST) Received: from findlaw.com. (sam.ofc.findlaw.com [10.223.234.165]) by infosys-1.ofc.findlaw.com (8.11.6/8.11.6) with ESMTP id hBBJn3T05343 for ; Thu, 11 Dec 2003 11:49:03 -0800 Received: from sam.ofc.findlaw.com (jrogers@localhost) by findlaw.com. (8.11.6/8.11.6) with ESMTP id hBBJn3X10554 for ; Thu, 11 Dec 2003 11:49:03 -0800 Message-Id: <200312111949.hBBJn3X10554@findlaw.com.> X-Authentication-Warning: sam.ofc.findlaw.com: jrogers owned process doing -bs X-Mailer: exmh version 2.4 06/23/2000 with nmh-1.0.4 From: Jeff Rogers To: pgsql-general@postgresql.org Subject: set returning functions Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Date: Thu, 11 Dec 2003 11:49:03 -0800 X-Virus-Scanned: by amavisd-new at postgresql.org X-Archive-Number: 200312/819 X-Sequence-Number: 54212 I have a set-returning function that takes a text string and returns multiple values from it. Its a small hack on the pgxml_xpath function from contrib/xml that returns all matching nodes from an xml document rather than just a single specified node. I currently use it as follows: create table xml_files (file text, doc text) ; create view xnodes as select file, pgxml_xpath(doc, '/top/node') from xml_files; select * from xnodes ; This gives me a table of all the matching nodes in all the documents. However, the documentation says that using a SRF in the select list of a query, but this capability is deprecated. I can't figure out how to call this function in the from clause with it referring to a column in a table, I get an error like ERROR: FROM function expression may not refer to other relations of same query level. Is there another way to accomplish this? Another useful way to call my function would be select file from xml_files where 'foo' in pgxml_xpath(doc,'/top/node') but that gives be a parse error. select file from xml_files where 'foo' in (select pgxml_xpath(doc,'/top/node')) parses, but it doesn't seem to give correct results. Thanks -J PS: Here's the function. This goes with pgxml.c, not pgxml_dom.c, bt could probably be modified to work there as well. PG_FUNCTION_INFO_V1(pgxml_xpath_all); Datum pgxml_xpath_all(PG_FUNCTION_ARGS) { /* called as pgxml_xpath(document,pathstr) */ /* returns set of all matching results */ XPath_Results *xpresults; text *restext; MemoryContext oldContext; FuncCallContext *funcctx; text *t = PG_GETARG_TEXT_P(0); /* document buffer */ text *t2 = PG_GETARG_TEXT_P(1); int32 ind; if (SRF_IS_FIRSTCALL()) { funcctx=SRF_FIRSTCALL_INIT(); oldContext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); xpresults = build_xpath_results(t, t2); funcctx->user_fctx=xpresults; MemoryContextSwitchTo(oldContext); } funcctx = SRF_PERCALL_SETUP(); xpresults=funcctx->user_fctx; ind=funcctx->call_cntr; if (xpresults == NULL || ind >= xpresults->rescount) { if (xpresults != NULL) { pfree(xpresults->resbuf); pfree(xpresults); } SRF_RETURN_DONE(funcctx); } restext = (text *) palloc(xpresults->reslens[ind] + VARHDRSZ); memcpy(VARDATA(restext), xpresults->results[ind], xpresults->reslens[ind]); VARATT_SIZEP(restext) = xpresults->reslens[ind] + VARHDRSZ; SRF_RETURN_NEXT(funcctx,restext); }