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