CREATE OR REPLACE FUNCTION permute(lst) as table ( WITH RECURSIVE permute(perm, remaining) as ( -- base case SELECT [] as perm, lst as remaining UNION ALL -- recursive case: add one element from remaining to perm and remove it from remaining SELECT (perm || [element]) AS perm, (remaining[1:i-1] || remaining[i+1:]) AS remaining FROM (select *, unnest(remaining) AS element, generate_subscripts(remaining,1) as i FROM permute) ) SELECT perm FROM permute WHERE length(remaining) = 0 );