Is it possible to perform a bitwise group function?
MySQL:
SELECT user_id, BIT_OR(permissions) as all_permsFROM permissionsGROUP BY user_id
Ah, another one of those questions where I find the answer 5 minutes after asking... Accepted answer will go to the MySQL implementation though...
Here's how to do it with Oracle, as I discovered on Radino's blog
You create an object...
CREATE OR REPLACE TYPE bitor_impl AS OBJECT( bitor NUMBER, STATIC FUNCTION ODCIAggregateInitialize(ctx IN OUT bitor_impl) RETURN NUMBER, MEMBER FUNCTION ODCIAggregateIterate(SELF IN OUT bitor_impl, VALUE IN NUMBER) RETURN NUMBER, MEMBER FUNCTION ODCIAggregateMerge(SELF IN OUT bitor_impl, ctx2 IN bitor_impl) RETURN NUMBER, MEMBER FUNCTION ODCIAggregateTerminate(SELF IN OUT bitor_impl, returnvalue OUT NUMBER, flags IN NUMBER) RETURN NUMBER)/CREATE OR REPLACE TYPE BODY bitor_impl IS STATIC FUNCTION ODCIAggregateInitialize(ctx IN OUT bitor_impl) RETURN NUMBER IS BEGIN ctx := bitor_impl(0); RETURN ODCIConst.Success; END ODCIAggregateInitialize; MEMBER FUNCTION ODCIAggregateIterate(SELF IN OUT bitor_impl, VALUE IN NUMBER) RETURN NUMBER IS BEGIN SELF.bitor := SELF.bitor + VALUE - bitand(SELF.bitor, VALUE); RETURN ODCIConst.Success; END ODCIAggregateIterate; MEMBER FUNCTION ODCIAggregateMerge(SELF IN OUT bitor_impl, ctx2 IN bitor_impl) RETURN NUMBER IS BEGIN SELF.bitor := SELF.bitor + ctx2.bitor - bitand(SELF.bitor, ctx2.bitor); RETURN ODCIConst.Success; END ODCIAggregateMerge; MEMBER FUNCTION ODCIAggregateTerminate(SELF IN OUT bitor_impl, returnvalue OUT NUMBER, flags IN NUMBER) RETURN NUMBER IS BEGIN returnvalue := SELF.bitor; RETURN ODCIConst.Success; END ODCIAggregateTerminate;END;/
...and then define your own aggregate function
CREATE OR REPLACE FUNCTION bitoragg(x IN NUMBER) RETURN NUMBERPARALLEL_ENABLEAGGREGATE USING bitor_impl;/
Usage:
SELECT user_id, bitoragg(permissions) FROM perms GROUP BY user_id
And you can do a bitwise or with...
FUNCTION BITOR(x IN NUMBER, y IN NUMBER)RETURN NUMBERASBEGIN RETURN x + y - BITAND(x,y);END;