Changeset: 0237b8aad4ed for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=0237b8aad4ed
Modified Files:
        gdk/gdk_analytic.c
        gdk/gdk_analytic.h
        sql/backends/monet5/sql_rank.c
        sql/backends/monet5/sql_rank.h
        sql/backends/monet5/sql_rank.mal
        sql/backends/monet5/sql_rank.mal.sh
        sql/backends/monet5/sql_rank_hge.mal
        sql/backends/monet5/sql_rank_hge.mal.sh
        sql/common/sql_types.c
        sql/server/rel_select.c
        sql/server/sql_parser.y
        sql/server/sql_scan.c
        sql/test/analytics/Tests/analytics01.sql
        sql/test/analytics/Tests/analytics01.stable.out
Branch: analytics
Log Message:

Implemented ntile(n) over a window.

Now it's time for a cleanup.


diffs (truncated from 1071 to 300 lines):

diff --git a/gdk/gdk_analytic.c b/gdk/gdk_analytic.c
--- a/gdk/gdk_analytic.c
+++ b/gdk/gdk_analytic.c
@@ -101,6 +101,110 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *c
 
 #undef ANALYTICAL_DIFF_IMP
 
+#define NTILE_CALC(TPE)               \
+       do {                              \
+               TPE val =  *(TPE *)ntile;     \
+               if((BUN)val >= cnt) {         \
+                       i = 1;                    \
+                       for(; rb<rp; i++, rb++)   \
+                               *rb = i;              \
+               } else if(cnt % val == 0) {   \
+                       buckets = cnt / val;      \
+                       for(; rb<rp; i++, rb++) { \
+                               if(i == buckets) {    \
+                                       j++;              \
+                                       i = 0;            \
+                               }                     \
+                               *rb = j;              \
+                       }                         \
+               } else {                      \
+                       buckets = cnt / val;      \
+                       for(; rb<rp; i++, rb++) { \
+                               *rb = j;              \
+                               if(i == buckets) {    \
+                                       j++;              \
+                                       i = 0;            \
+                               }                     \
+                       }                         \
+               }                             \
+       } while(0);
+
+#define ANALYTICAL_NTILE_IMP(TPE)            \
+       do {                                     \
+               TPE i = 0, j = 1, *rp, *rb, buckets; \
+               rb = rp = (TPE*)Tloc(r, 0);          \
+               if(p) {                              \
+                       pnp = np = (bit*)Tloc(p, 0);     \
+                       TPE *end = rp + cnt;             \
+                       for(; rp<end; np++, rp++) {      \
+                               if (*np) {                   \
+                                       i = 0;                   \
+                                       j = 1;                   \
+                                       cnt = np - pnp;          \
+                                       pnp = np;                \
+                                       NTILE_CALC(TPE)          \
+                               }                            \
+                       }                                \
+                       i = 0;                           \
+                       j = 1;                           \
+                       cnt = np - pnp;                  \
+                       NTILE_CALC(TPE)                  \
+               } else {                             \
+                       rp = rb + cnt;                   \
+                       NTILE_CALC(TPE)                  \
+               }                                    \
+               goto finish;                         \
+       } while(0);
+
+gdk_return
+GDKanalyticalntile(BAT *r, BAT *b, BAT *p, BAT *o, int tpe, ptr ntile)
+{
+       BUN cnt = BATcount(b);
+       bit *np, *pnp;
+       gdk_return gdk_res = GDK_SUCCEED;
+
+       switch (tpe) {
+               case TYPE_bte:
+                       ANALYTICAL_NTILE_IMP(bte)
+                       break;
+               case TYPE_sht:
+                       ANALYTICAL_NTILE_IMP(sht)
+                       break;
+               case TYPE_int:
+                       ANALYTICAL_NTILE_IMP(int)
+                       break;
+               case TYPE_lng:
+                       ANALYTICAL_NTILE_IMP(lng)
+                       break;
+#ifdef HAVE_HGE
+               case TYPE_hge:
+                       ANALYTICAL_NTILE_IMP(hge)
+                       break;
+#endif
+               default: {
+                       goto nosupport;
+               }
+       }
+nosupport:
+       GDKerror("ntile: type %s not supported.\n", ATOMname(tpe));
+       return GDK_FAIL;
+finish:
+       BATsetcount(r, cnt);
+       r->tnonil = true;
+       r->tnil = false;
+       if(o) {
+               r->tsorted = o->tsorted;
+               r->trevsorted = o->trevsorted;
+       } else if(!p) {
+               r->tsorted = true;
+               r->trevsorted = false;
+       }
+       return gdk_res;
+}
+
+#undef ANALYTICAL_NTILE_IMP
+#undef NTILE_CALC
+
 #define ANALYTICAL_LIMIT_IMP(TPE, OP)                        \
        do {                                                     \
                TPE *rp, *rb, *restrict bp, *end, curval;            \
diff --git a/gdk/gdk_analytic.h b/gdk/gdk_analytic.h
--- a/gdk/gdk_analytic.h
+++ b/gdk/gdk_analytic.h
@@ -17,6 +17,7 @@
 #include "gdk.h"
 
 gdk_export gdk_return GDKanalyticaldiff(BAT *r, BAT *b, BAT *c, int tpe);
+gdk_export gdk_return GDKanalyticalntile(BAT *r, BAT *b, BAT *p, BAT *o, int 
tpe, ptr ntile);
 gdk_export gdk_return GDKanalyticalmin(BAT *r, BAT *b, BAT *p, BAT *o, int 
tpe);
 gdk_export gdk_return GDKanalyticalmax(BAT *r, BAT *b, BAT *p, BAT *o, int 
tpe);
 gdk_export gdk_return GDKanalyticalcount(BAT *r, BAT *b, BAT *p, BAT *o, const 
bit *ignore_nils, int tpe);
diff --git a/sql/backends/monet5/sql_rank.c b/sql/backends/monet5/sql_rank.c
--- a/sql/backends/monet5/sql_rank.c
+++ b/sql/backends/monet5/sql_rank.c
@@ -399,7 +399,7 @@ SQLcume_dist(Client cntxt, MalBlkPtr mb,
                                p = BATdescriptor(*getArgReference_bat(stk, 
pci, 2));
                                if (!p) {
                                        BBPunfix(b->batCacheid);
-                                       throw(SQL, "sql.percent_rank", 
SQLSTATE(HY005) "Cannot access column descriptor");
+                                       throw(SQL, "sql.cume_dist", 
SQLSTATE(HY005) "Cannot access column descriptor");
                                }
                                np = (bit*)Tloc(p, 0);
                                for(j=0; rp<end; j++, np++, rp++) {
@@ -414,7 +414,7 @@ SQLcume_dist(Client cntxt, MalBlkPtr mb,
                                p = BATdescriptor(*getArgReference_bat(stk, 
pci, 2));
                                if (!p) {
                                        BBPunfix(b->batCacheid);
-                                       throw(SQL, "sql.percent_rank", 
SQLSTATE(HY005) "Cannot access column descriptor");
+                                       throw(SQL, "sql.cume_dist", 
SQLSTATE(HY005) "Cannot access column descriptor");
                                }
                                np = (bit*)Tloc(p, 0);
                                for(j=0; rp<end; j++, np++, rp++) {
@@ -442,6 +442,89 @@ SQLcume_dist(Client cntxt, MalBlkPtr mb,
        return MAL_SUCCEED;
 }
 
+#define NTILE_IMP(TPE)                                                         
             \
+       do {                                                                    
                \
+               TPE *ntile = getArgReference_##TPE(stk, pci, 2);                
                    \
+               if(*ntile < 1) {                                                
                    \
+                       BBPunfix(b->batCacheid);                                
                        \
+                       throw(SQL, "sql.ntile", SQLSTATE(42000) "ntile must be 
greater than zero");     \
+               }                                                               
                    \
+               voidresultBAT(r, TYPE_##TPE, cnt, b, "sql.ntile");              
                    \
+               if (isaBatType(getArgType(mb, pci, 3))) {                       
                    \
+                       p = BATdescriptor(*getArgReference_bat(stk, pci, 3));   
                        \
+                       if (!p) {                                               
                        \
+                               BBPunfix(b->batCacheid);                        
                            \
+                               throw(SQL, "sql.ntile", SQLSTATE(HY005) "Cannot 
access column descriptor"); \
+                       }                                                       
                        \
+               }                                                               
                    \
+               if (isaBatType(getArgType(mb, pci, 4))) {                       
                    \
+                       o = BATdescriptor(*getArgReference_bat(stk, pci, 4));   
                        \
+                       if (!o) {                                               
                        \
+                               BBPunfix(b->batCacheid);                        
                            \
+                               BBPunfix(p->batCacheid);                        
                            \
+                               throw(SQL, "sql.ntile", SQLSTATE(HY005) "Cannot 
access column descriptor"); \
+                       }                                                       
                        \
+               }                                                               
                    \
+               gdk_code = GDKanalyticalntile(r, b, p, o, TYPE_##TPE, ntile);   
                    \
+       } while(0);
+
+str
+SQLntile(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
+{
+       (void)cntxt;
+       if (pci->argc != 5 || (getArgType(mb, pci, 3) != TYPE_bit && 
getBatType(getArgType(mb, pci, 3)) != TYPE_bit) ||
+               (getArgType(mb, pci, 4) != TYPE_bit && 
getBatType(getArgType(mb, pci, 4)) != TYPE_bit)) {
+               throw(SQL, "sql.ntile", SQLSTATE(42000) 
"ntile(:any_1,:number,:bit,:bit)");
+       }
+       if (isaBatType(getArgType(mb, pci, 1))) {
+               BUN cnt;
+               bat *res = getArgReference_bat(stk, pci, 0);
+               BAT *b = BATdescriptor(*getArgReference_bat(stk, pci, 1)), *p = 
NULL, *o = NULL, *r;
+               if (!b)
+                       throw(SQL, "sql.ntile", SQLSTATE(HY005) "Cannot access 
column descriptor");
+               cnt = BATcount(b);
+               gdk_return gdk_code;
+
+               switch (getArgType(mb, pci, 2)) {
+                       case TYPE_bte:
+                               NTILE_IMP(bte)
+                               break;
+                       case TYPE_sht:
+                               NTILE_IMP(sht)
+                               break;
+                       case TYPE_int:
+                               NTILE_IMP(int)
+                               break;
+                       case TYPE_lng:
+                               NTILE_IMP(lng)
+                               break;
+#ifdef HAVE_HGE
+                       case TYPE_hge:
+                               NTILE_IMP(hge)
+                               break;
+#endif
+                       default: {
+                               BBPunfix(b->batCacheid);
+                               throw(SQL, "sql.ntile", SQLSTATE(42000) "ntile 
not available for %s", ATOMname(getArgType(mb, pci, 2)));
+                       }
+               }
+
+               BATsetcount(r, cnt);
+               BBPunfix(b->batCacheid);
+               if(gdk_code == GDK_SUCCEED)
+                       BBPkeepref(*res = r->batCacheid);
+               else
+                       throw(SQL, "sql.ntile", SQLSTATE(HY001) "Unknown GDK 
error");
+       } else {
+               int *res = getArgReference_int(stk, pci, 0);
+
+               *res = 1;
+       }
+       return MAL_SUCCEED;
+}
+
+#undef NTILE_IMP
+
 static str
 SQLanalytics_args(BAT **r, BAT **b, BAT **p, BAT **o, Client cntxt, MalBlkPtr 
mb, MalStkPtr stk, InstrPtr pci,
                                  int rtype, const str mod, const str err)
@@ -459,7 +542,7 @@ SQLanalytics_args(BAT **r, BAT **b, BAT 
                if (!*b)
                        throw(SQL, mod, SQLSTATE(HY005) "Cannot access column 
descriptor");
        }
-       if (b) {
+       if (b && *b) {
                size_t cnt = BATcount(*b);
                voidresultBAT((*r), rtype ? rtype : (*b)->ttype, cnt, (*b), 
mod);
                if (!*r && *b)
@@ -545,12 +628,10 @@ SQLcount(Client cntxt, MalBlkPtr mb, Mal
 {
        BAT *r = NULL, *p = NULL, *o = NULL, *cr;
        str msg = MAL_SUCCEED;
-       int tpe, unit, start, end, excl;
+       int tpe, unit, excl;
        bit ignore_nils = 0;
        gdk_return gdk_res;
 
-       (void)start;
-       (void)end;
        (void)cntxt;
        if (pci->argc != 7 || (getArgType(mb, pci, 1) != TYPE_bit && 
getBatType(getArgType(mb, pci, 1)) != TYPE_bit) ||
                (getArgType(mb, pci, 2) != TYPE_bit && 
getBatType(getArgType(mb, pci, 2)) != TYPE_bit)){
diff --git a/sql/backends/monet5/sql_rank.h b/sql/backends/monet5/sql_rank.h
--- a/sql/backends/monet5/sql_rank.h
+++ b/sql/backends/monet5/sql_rank.h
@@ -17,6 +17,7 @@ sql5_export str SQLrank(Client cntxt, Ma
 sql5_export str SQLdense_rank(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 sql5_export str SQLpercent_rank(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 sql5_export str SQLcume_dist(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
+sql5_export str SQLntile(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci);
 sql5_export str SQLmin(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci);
 sql5_export str SQLmax(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci);
 sql5_export str SQLcount(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci);
diff --git a/sql/backends/monet5/sql_rank.mal b/sql/backends/monet5/sql_rank.mal
--- a/sql/backends/monet5/sql_rank.mal
+++ b/sql/backends/monet5/sql_rank.mal
@@ -96,6 +96,38 @@ pattern batsql.count(b:bat[:any_1], p:an
 address SQLcount_no_nil
 comment "return count of groups";
 
+pattern sql.ntile(b:bat[:any_1], n:bte, p:any_2, o:any_3) :bte
+address SQLntile
+comment "return the groups divided as equally as possible";
+
+pattern batsql.ntile(b:bat[:any_1], n:bte, p:any_2, o:any_3) :bat[:bte]
+address SQLntile
+comment "return the groups divided as equally as possible";
+
+pattern sql.ntile(b:bat[:any_1], n:sht, p:any_2, o:any_3) :sht
+address SQLntile
+comment "return the groups divided as equally as possible";
+
+pattern batsql.ntile(b:bat[:any_1], n:sht, p:any_2, o:any_3) :bat[:sht]
+address SQLntile
+comment "return the groups divided as equally as possible";
+
+pattern sql.ntile(b:bat[:any_1], n:int, p:any_2, o:any_3) :int
+address SQLntile
+comment "return the groups divided as equally as possible";
+
+pattern batsql.ntile(b:bat[:any_1], n:int, p:any_2, o:any_3) :bat[:int]
+address SQLntile
+comment "return the groups divided as equally as possible";
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to