Re: Array intersection

From: Josh Trutwin <josh(at)trutwins(dot)homeip(dot)net>
To: pgsql-general(at)postgresql(dot)org
Subject: Re: Array intersection
Date: 2007-10-17 16:28:31
Message-ID: 20071017112831.175bb55e@sinkhole.intrcomm.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general


> This is only going to work for one-dimensional arrays (I'm not sure
> how you would ever fix that with the support postgres has for
> arrays) but the (computational) complexity of having an embedded
> FOR loops looks bad for performance. As you can already use '=ANY'
> syntax to search inside an array, you may as well use that---it's
> probably a bit more faster than the plpgsql work-alike. Leading to
> the following implementation of intersect:

Thanks for the pointers.

> It seems to work for me, but as a side effect will leave the array
> sorted in the same order as the first parameter and with any
> duplicates it has. Even more annoyingly if there is no intersection
> it will return NULL instead of an empty array, how do I fix this?

It's inelegant, but I just did this:

CREATE OR REPLACE FUNCTION array_intersect (array1 INTEGER[],array2
INTEGER[]) RETURNS INTEGER[]
AS $$
DECLARE
out INTEGER[];
return_empty BOOLEAN := TRUE;
BEGIN
IF array1 IS NULL OR array2 IS NULL THEN
RETURN '[]';
END IF;
FOR i IN ARRAY_LOWER(array1,1) .. ARRAY_UPPER(array1,1) LOOP
IF (array1[i] =ANY (array2)) THEN
out := array_append(out,array1[i]);
return_empty := FALSE;
END IF;
END LOOP;

IF return_empty THEN
RETURN '{}';
END IF;

RETURN out;
END;
$$ LANGUAGE PLPGSQL;

psql=> select array_intersect('{1,2,3}', '{6,7,8}');
array_intersect
-----------------
{}
(1 row)

Josh

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Josh Trutwin 2007-10-17 16:31:51 Re: Array intersection
Previous Message Martijn van Oosterhout 2007-10-17 16:21:17 Re: Will UPDATE lock if FROM refers to target table?