Is it possible to perform a bitwise group function? Is it possible to perform a bitwise group function? oracle oracle

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;