Changeset: 5ab030b2a39a for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5ab030b2a39a
Modified Files:
        sql/backends/monet5/sql.mx
        sql/common/sql_types.c
        sql/server/sql_scan.c
Branch: default
Log Message:

added first version of median


diffs (113 lines):

diff --git a/sql/backends/monet5/sql.mx b/sql/backends/monet5/sql.mx
--- a/sql/backends/monet5/sql.mx
+++ b/sql/backends/monet5/sql.mx
@@ -6983,3 +6983,87 @@ freeVariables(Client c, MalBlkPtr mb, Ma
        mb->ptop = j;
 }
 
+/*
+ * Compute the median.
+ * Assume val is id,oid sorted. 
+ */
+@h
+sql_export str SQLmiddle(bat *res,  bat *val, bat *hist);
+@c
+str
+SQLmiddle(bat *res,  bat *val, bat *hist)
+{
+       BAT *r,*v,*h;
+       wrd *sz, cnt, i;
+       oid *gid;
+
+       if( (h = BATdescriptor(*hist)) == NULL )
+               throw(SQL, "sql.middle", "Cannot access descriptor");
+       if( (v = BATdescriptor(*val)) == NULL ) {
+               BBPunfix(h->batCacheid);
+               throw(SQL, "sql.middle", "Cannot access descriptor");
+       }
+       r = BATnew(TYPE_oid, v->ttype, cnt=BATcount(h));
+       if (!r) {
+               BBPunfix(h->batCacheid);
+               BBPunfix(v->batCacheid);
+               throw(SQL, "sql.middle", "Cannot create bat");
+       }
+       sz = (wrd*)Tloc(h,0);
+       gid = (oid*)Tloc(v,0);
+
+       if (v->htype == TYPE_void) {
+               oid id = v->hseqbase;
+
+               for(i=0;i<cnt;i++) {
+                       BUN p = BUNfnd(h, gid);
+                       wrd s = *(sz+p);
+                       oid nid = id + (s-1)/2;
+       
+                       BUNins(r, gid, &nid, FALSE);
+                       gid += s;
+                       id += s;
+               }
+       } else {
+               oid *id = (oid*)Hloc(v,0);
+
+               for(i=0;i<cnt;i++) {
+                       BUN p = BUNfnd(h, gid);
+                       wrd s = *(sz+p);
+       
+                       BUNins(r, gid, id+((s-1)/2), FALSE);
+                       gid += s;
+                       id += s;
+               }
+       }
+
+       BBPunfix(h->batCacheid);
+       BBPunfix(v->batCacheid);
+       BBPkeepref(r->batCacheid);
+       *res = r->batCacheid;
+       return MAL_SUCCEED;
+}
+
+@mal
+command sql.middle( val:bat[:oid,:oid], hist:bat[:oid,:wrd] ):bat[:oid,:oid]
+address SQLmiddle;
+
+function aggr.median(a:bat[:oid,:any_1]):any_1;
+       v := algebra.sortTail(a);
+       c := aggr.count(v);
+       c := calc./(c,2);
+       p := calc.lng(c);
+       return algebra.fetch(v, p);
+end aggr.median;
+
+function 
aggr.median(a:bat[:oid,:any_1],g:bat[:oid,:oid],e:bat[:oid,:any_2]):bat[:oid,:any_1];
+       ng := algebra.sortTail(g);
+       v := group.refine(ng,a);
+       vm := algebra.markT(v, 0:oid);
+       mv := bat.reverse(vm);
+       h := aggr.count(a,g,e);
+       s := algebra.leftjoin(mv,g);
+       id := sql.middle(s,h);
+       sid := algebra.leftjoin(id, mv);
+       return algebra.leftjoin(sid, a);
+end aggr.median;
diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c
--- a/sql/common/sql_types.c
+++ b/sql/common/sql_types.c
@@ -1146,6 +1146,7 @@ sqltypeinit( sql_allocator *sa)
        sql_create_aggr(sa, "max", "aggr", "max", ANY, ANY);
        sql_create_func(sa, "sql_min", "calc", "min", ANY, ANY, ANY, SCALE_FIX);
        sql_create_func(sa, "sql_max", "calc", "max", ANY, ANY, ANY, SCALE_FIX);
+       sql_create_aggr(sa, "median", "aggr", "median", ANY, ANY);
        sql_create_func3(sa, "ifthenelse", "calc", "ifthenelse", BIT, ANY, ANY, 
ANY, SCALE_FIX);
 
        /* sum for numerical and decimals */
diff --git a/sql/server/sql_scan.c b/sql/server/sql_scan.c
--- a/sql/server/sql_scan.c
+++ b/sql/server/sql_scan.c
@@ -45,6 +45,7 @@ scanner_init_keywords(void)
        keywords_insert("ALTER", ALTER);
        keywords_insert("ADD", ADD);
        keywords_insert("AND", AND);
+       keywords_insert("MEDIAN", AGGR);
        keywords_insert("AVG", AGGR);
        keywords_insert("MIN", AGGR);
        keywords_insert("MAX", AGGR);
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to