From: | "W(dot) Trevor King" <wking(at)tremily(dot)us> |
---|---|
To: | "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com> |
Cc: | pgsql-general(at)postgresql(dot)org |
Subject: | Re: Dynamically filtering a CTE? |
Date: | 2018-04-20 16:22:32 |
Message-ID: | 20180420162232.GM27577@valgrind.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
On Thu, Apr 19, 2018 at 05:28:00PM -0700, David G. Johnston wrote:
> On Thursday, April 19, 2018, W. Trevor King wrote:
> > Is there an idiomatic way to approach this problem?
>
> I would use pl/pgsql as the language and build a query using a
> combination of text literals and the format() function - invoking
> via pl/pgsql's EXECUTE command.
That works. I've ended up with:
CREATE OR REPLACE FUNCTION ancestors(condition text)
RETURNS TABLE(id integer, ancestors integer[]) AS
$$
BEGIN
RETURN QUERY EXECUTE format('
WITH RECURSIVE _ancestors(id, ancestors) AS (
SELECT
item.id AS id,
ARRAY[item.ancestor_id] AS ancestors
FROM items AS item
%s
UNION ALL
SELECT
descendant.id AS id,
descendant.ancestors || ancestor.ancestor_id AS ancestors
FROM _ancestors AS descendant
JOIN items as ancestor
ON descendant.ancestors[array_length(descendant.ancestors, 1)] = ancestor.id
)
SELECT
id,
ancestors[1:array_length(ancestors, 1) - 1] AS ancestors -- drop the trailing NULL
FROM _ancestors
WHERE ancestors[array_length(ancestors, 1)] IS NULL -- remove non-terminal recursion
', condition);
END
$$ LANGUAGE plpgsql STABLE;
which you can use like:
SELECT * FROM ancestors('WHERE item.id = 62324721');
or (without filtering, for the full, slow CTE):
SELECT * FROM ancestors('');
Thanks,
Trevor
--
This email may be signed or encrypted with GnuPG (http://www.gnupg.org)
For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy
From | Date | Subject | |
---|---|---|---|
Next Message | David G. Johnston | 2018-04-20 16:33:22 | Re: Dynamically filtering a CTE? |
Previous Message | Tatsuo Ishii | 2018-04-20 16:14:30 | Re: Postgresql database encryption |