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