Search notes:

Using Oracle Data Cartridge Interface for User Defined Aggragation Functions

With Data Cartridges, it is possible to create user defined aggregate functions.

Example

Specification of a type with the required interface

create or replace type tq84_text_range_t as object (

    min_val varchar2(4000),
    max_val varchar2(4000),

    static function ODCIAggregateInitialize(sctx  in out tq84_text_range_t) 
                    return number,

    member function ODCIAggregateIterate   (self  in out tq84_text_range_t, 
                                            value in varchar2 ) 
                    return number,

    member function ODCIAggregateTerminate (self         in     tq84_text_range_t   , 
                                            return_value    out varchar2, 
                                            flags        in number      )               
                    return number,

    member function ODCIAggregateMerge(self in out tq84_text_range_t, 
                                       ctx2 in tq84_text_range_t    ) 
                    return number
);
/

Implementation of the type

create or replace type body tq84_text_range_t is 


    static function ODCIAggregateInitialize(sctx in out tq84_text_range_t) 
        return number is 
    begin
        sctx := tq84_text_range_t(null, null);
        return ODCIConst.Success;
    end ODCIAggregateInitialize;


    member function ODCIAggregateIterate(
        self in out tq84_text_range_t,
        value in varchar2
    ) 
    return number is
    begin

--      if value is null then
--         return ODCIConst.Success;
--      end if;

        if min_val is null then min_val := value; end if;
        if max_val is null then max_val := value; end if;
          
        if value < min_val then min_val := value; end if;
        if value > max_val then max_val := value; end if;

        return ODCIConst.Success;
    end ODCIAggregateIterate;


    member function ODCIAggregateTerminate(
        self         in  tq84_text_range_t, 
        return_value out varchar2,
        flags        in  number
    )
    return number is
    begin
        return_value := min_val || ' .. ' || max_val;
        return ODCIConst.Success;
    end ODCIAggregateTerminate;


    member function ODCIAggregateMerge(
        self in out tq84_text_range_t, 
        ctx2 in     tq84_text_range_t
    ) return number is
    begin

        if ctx2.min_val < self.min_val then self.min_val := ctx2.min_val; end if;
        if ctx2.max_val > self.max_val then self.max_val := ctx2.max_val; end if;

        return ODCIConst.Success;

    end ODCIAggregateMerge;

end;
/

show errors

The user defined function

create or replace function tq84_text_range(
    value varchar2  -- The value to be aggregated per group
) return varchar2
    parallel_enable
    aggregate
using
  tq84_text_range_t;
/

Test table and data

create table tq84_agg_test (
   a number,
   b varchar2(20)
);

insert into tq84_agg_test values (1, 'colporteur');
insert into tq84_agg_test values (2, 'suedehead');
insert into tq84_agg_test values (1, 'skimmington');
insert into tq84_agg_test values (3, 'xenology');
insert into tq84_agg_test values (1, 'deglutition');
insert into tq84_agg_test values (2, 'omophagy');
insert into tq84_agg_test values (3, 'apoptosis');
insert into tq84_agg_test values (1, 'incunabula');
insert into tq84_agg_test values (2, 'rubricate');
insert into tq84_agg_test values (2, 'bergschrund');

Using the function in a select statement

column b_conc format a30

select
   a,
   tq84_text_range(b) b_conc
from
   tq84_agg_test 
group by
   a;
--
--         A B_CONC
------------ ------------------------------
--         1 colporteur .. skimmington
--         2 bergschrund .. suedehead
--         3 apoptosis .. xenology

Cleaning up

drop table    tq84_agg_test;
drop function tq84_text_range;
drop type     tq84_text_range_t;

See also

Data Cartridge: the interface functions for user defined functions.

Index