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

Distinguish window exclusive functions from aggregation functions.


diffs (truncated from 1189 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
@@ -103,12 +103,12 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *c
 
 #define NTILE_CALC(TPE)               \
        do {                              \
-               if((BUN)val >= cnt) {         \
+               if((BUN)val >= ncnt) {        \
                        i = 1;                    \
                        for(; rb<rp; i++, rb++)   \
                                *rb = i;              \
-               } else if(cnt % val == 0) {   \
-                       buckets = cnt / val;      \
+               } else if(ncnt % val == 0) {  \
+                       buckets = ncnt / val;     \
                        for(; rb<rp; i++, rb++) { \
                                if(i == buckets) {    \
                                        j++;              \
@@ -117,7 +117,7 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *c
                                *rb = j;              \
                        }                         \
                } else {                      \
-                       buckets = cnt / val;      \
+                       buckets = ncnt / val;     \
                        for(; rb<rp; i++, rb++) { \
                                *rb = j;              \
                                if(i == buckets) {    \
@@ -145,14 +145,14 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *c
                                if (*np) {                   \
                                        i = 0;                   \
                                        j = 1;                   \
-                                       cnt = np - pnp;          \
+                                       ncnt = np - pnp;         \
                                        pnp = np;                \
                                        NTILE_CALC(TPE)          \
                                }                            \
                        }                                \
                        i = 0;                           \
                        j = 1;                           \
-                       cnt = np - pnp;                  \
+                       ncnt = np - pnp;                 \
                        NTILE_CALC(TPE)                  \
                } else {                             \
                        rp = rb + cnt;                   \
@@ -164,13 +164,14 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *c
 gdk_return
 GDKanalyticalntile(BAT *r, BAT *b, BAT *p, BAT *o, int tpe, const void* 
restrict ntile)
 {
-       BUN cnt = BATcount(b);
+       BUN cnt = BATcount(b), ncnt = cnt;
        bit *np, *pnp;
        bool has_nils = false;
        gdk_return gdk_res = GDK_SUCCEED;
 
        assert(ntile);
 
+       (void) o;
        switch (tpe) {
                case TYPE_bte:
                        ANALYTICAL_NTILE_IMP(bte)
@@ -200,13 +201,6 @@ finish:
        BATsetcount(r, cnt);
        r->tnonil = !has_nils;
        r->tnil = has_nils;
-       if(o) {
-               r->tsorted = o->tsorted;
-               r->trevsorted = o->trevsorted;
-       } else if(!p) {
-               r->tsorted = true;
-               r->trevsorted = false;
-       }
        return gdk_res;
 }
 
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
@@ -613,27 +613,47 @@ SQLanalytics_args(BAT **r, BAT **b, BAT 
        return MAL_SUCCEED;
 }
 
-/* we will keep the ordering bat here although is not needed, but maybe later 
with varied sized windows */
 static str
-SQLanalytical_func(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, 
const str op, const str err,
-                                       gdk_return (*func)(BAT *, BAT *, BAT *, 
BAT *, int))
+do_limit_value(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, const 
str op, const str err,
+                          gdk_return (*func)(BAT *, BAT *, BAT *, BAT *, int))
 {
-       BAT *r, *b, *p, *o;
-       str msg = SQLanalytics_args(&r, &b, &p, &o, cntxt, mb, stk, pci, 0, op, 
err);
-       int tpe = getArgType(mb, pci, 1);
-       int unit = *getArgReference_int(stk, pci, 4);
-       int start = *getArgReference_int(stk, pci, 5);
-       int end = *getArgReference_int(stk, pci, 6);
-       int excl = *getArgReference_int(stk, pci, 7);
+       BAT *r = NULL, *b = NULL, *p = NULL, *o = NULL;
+       int tpe;
        gdk_return gdk_res;
 
-       if (unit != 0 || excl != 0)
-               throw(SQL, op, SQLSTATE(42000) "OVER currently only supports 
frame extends with unit ROWS (and none of the excludes)");
-       (void)start;
-       (void)end;
+       (void) cntxt;
+       if (pci->argc != 4 ||
+               (getArgType(mb, pci, 2) != TYPE_bit && 
getBatType(getArgType(mb, pci, 2)) != TYPE_bit) ||
+               (getArgType(mb, pci, 3) != TYPE_bit && 
getBatType(getArgType(mb, pci, 3)) != TYPE_bit)){
+               throw(SQL, op, "%s", err);
+       }
+       tpe = getArgType(mb, pci, 1);
+       if (isaBatType(tpe)) {
+               b = BATdescriptor(*getArgReference_bat(stk, pci, 1));
+               if (!b)
+                       throw(SQL, op, SQLSTATE(HY005) "Cannot access column 
descriptor");
+       }
+       if (b) {
+               voidresultBAT(r, b->ttype, BATcount(b), b, op);
+       }
+       if (isaBatType(getArgType(mb, pci, 2))) {
+               p = BATdescriptor(*getArgReference_bat(stk, pci, 2));
+               if (!p) {
+                       if (b) BBPunfix(b->batCacheid);
+                       if (r) BBPunfix(r->batCacheid);
+                       throw(SQL, op, SQLSTATE(HY005) "Cannot access column 
descriptor");
+               }
+       }
+       if (isaBatType(getArgType(mb, pci, 3))) {
+               o = BATdescriptor(*getArgReference_bat(stk, pci, 3));
+               if (!o) {
+                       if (b) BBPunfix(b->batCacheid);
+                       if (r) BBPunfix(r->batCacheid);
+                       if (p) BBPunfix(p->batCacheid);
+                       throw(SQL, op, SQLSTATE(HY005) "Cannot access column 
descriptor");
+               }
+       }
 
-       if (msg)
-               return msg;
        if (isaBatType(tpe))
                tpe = getBatType(tpe);
 
@@ -653,19 +673,19 @@ SQLanalytical_func(Client cntxt, MalBlkP
                ptr *in = getArgReference(stk, pci, 1);
                *res = *in;
        }
-       return msg;
+       return MAL_SUCCEED;
 }
 
 str
 SQLfirst_value(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
-       return SQLanalytical_func(cntxt, mb, stk, pci, "sql.first_value", 
SQLSTATE(42000) "first_value(:any_1,:bit,:bit)", GDKanalyticalfirst);
+       return do_limit_value(cntxt, mb, stk, pci, "sql.first_value", 
SQLSTATE(42000) "first_value(:any_1,:bit,:bit)", GDKanalyticalfirst);
 }
 
 str
 SQLlast_value(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
-       return SQLanalytical_func(cntxt, mb, stk, pci, "sql.last_value", 
SQLSTATE(42000) "last_value(:any_1,:bit,:bit)", GDKanalyticallast);
+       return do_limit_value(cntxt, mb, stk, pci, "sql.last_value", 
SQLSTATE(42000) "last_value(:any_1,:bit,:bit)", GDKanalyticallast);
 }
 
 #define NTH_VALUE_IMP(TPE)                                                     
                 \
@@ -710,7 +730,7 @@ SQLnth_value(Client cntxt, MalBlkPtr mb,
        int tp1, tp2;
 
        (void)cntxt;
-       if (pci->argc != 9 || (getArgType(mb, pci, 3) != TYPE_bit && 
getBatType(getArgType(mb, pci, 3)) != TYPE_bit) ||
+       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.nth_value", SQLSTATE(42000) 
"nth_value(:any_1,:number,:bit,:bit)");
        }
@@ -807,12 +827,12 @@ do_lead_lag(Client cntxt, MalBlkPtr mb, 
        size_t default_value_size = 0;
 
        (void)cntxt;
-       if (pci->argc < 8 || pci->argc > 10)
+       if (pci->argc < 4 || pci->argc > 6)
                throw(SQL, op, SQLSTATE(42000) "%s called with invalid number 
of arguments", desc);
 
        tp1 = getArgType(mb, pci, 1);
 
-       if (pci->argc > 8) { //contains (lag or lead) value;
+       if (pci->argc > 4) { //contains (lag or lead) value;
                tp2 = getArgType(mb, pci, 2);
                if (isaBatType(tp2))
                        throw(SQL, op, SQLSTATE(42000) "%s second argument must 
a single atom", desc);
@@ -840,7 +860,7 @@ do_lead_lag(Client cntxt, MalBlkPtr mb, 
                base = 3;
        }
 
-       if (pci->argc > 9) { //contains default value;
+       if (pci->argc > 5) { //contains default value;
                ValRecord *vin = &(stk)->stk[(pci)->argv[3]];
                tp3 = getArgType(mb, pci, 3);
                if (isaBatType(tp3))
@@ -919,6 +939,49 @@ SQLlead(Client cntxt, MalBlkPtr mb, MalS
        return do_lead_lag(cntxt, mb, stk, pci, "sql.lead", "lead", 
GDKanalyticallead);
 }
 
+/* we will keep the ordering bat here although is not needed, but maybe later 
with varied sized windows */
+static str
+SQLanalytical_func(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, 
const str op, const str err,
+                                  gdk_return (*func)(BAT *, BAT *, BAT *, BAT 
*, int))
+{
+       BAT *r, *b, *p, *o;
+       str msg = SQLanalytics_args(&r, &b, &p, &o, cntxt, mb, stk, pci, 0, op, 
err);
+       int tpe = getArgType(mb, pci, 1);
+       int unit = *getArgReference_int(stk, pci, 4);
+       int start = *getArgReference_int(stk, pci, 5);
+       int end = *getArgReference_int(stk, pci, 6);
+       int excl = *getArgReference_int(stk, pci, 7);
+       gdk_return gdk_res;
+
+       if (unit != 0 || excl != 0)
+               throw(SQL, op, SQLSTATE(42000) "OVER currently only supports 
frame extends with unit ROWS (and none of the excludes)");
+       (void)start;
+       (void)end;
+
+       if (msg)
+               return msg;
+       if (isaBatType(tpe))
+               tpe = getBatType(tpe);
+
+       if (b) {
+               bat *res = getArgReference_bat(stk, pci, 0);
+
+               gdk_res = func(r, b, p, o, tpe);
+               BBPunfix(b->batCacheid);
+               if (p) BBPunfix(p->batCacheid);
+               if (o) BBPunfix(o->batCacheid);
+               if (gdk_res == GDK_SUCCEED)
+                       BBPkeepref(*res = r->batCacheid);
+               else
+                       return createException(SQL, op, SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
+       } else {
+               ptr *res = getArgReference(stk, pci, 0);
+               ptr *in = getArgReference(stk, pci, 1);
+               *res = *in;
+       }
+       return msg;
+}
+
 str
 SQLmin(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
@@ -70,22 +70,174 @@ address SQLcume_dist
 comment "return the accumulated distribution of the number of rows per group 
to the total number of partition rows";
 
 
-pattern sql.first_value(b:any_1, p:bit, o:bit, unit:int, s:int, e:int, 
excl:int) :any_1
+pattern sql.first_value(b:any_1, p:bit, o:bit) :any_1
 address SQLfirst_value
 comment "return the first value of groups";
 
-pattern batsql.first_value(b:bat[:any_1], p:any_2, o:any_3, unit:int, s:int, 
e:int, exl:int) :bat[:any_1]
+pattern batsql.first_value(b:bat[:any_1], p:any_2, o:any_3) :bat[:any_1]
 address SQLfirst_value
 comment "return the first value of groups";
 
 
-pattern sql.last_value(b:any_1, p:bit, o:bit, unit:int, s:int, e:int, 
excl:int) :any_1
+pattern sql.last_value(b:any_1, p:bit, o:bit) :any_1
+address SQLlast_value
+comment "return the last value of groups";
+
+pattern batsql.last_value(b:bat[:any_1], p:any_2, o:any_3) :bat[:any_1]
 address SQLlast_value
 comment "return the last value of groups";
 
-pattern batsql.last_value(b:bat[:any_1], p:any_2, o:any_3, unit:int, s:int, 
e:int, exl:int) :bat[:any_1]
-address SQLlast_value
-comment "return the last value of groups";
+
+pattern sql.lag(b:any_1, p:any_3, o:any_4) :any_1
+address SQLlag
+comment "return the value in the previous row in the partition or NULL if non 
existent";
+
+pattern batsql.lag(b:bat[:any_1], p:any_3, o:any_4) :bat[:any_1]
+address SQLlag
+comment "return the value in the previous row in the partition or NULL if non 
existent";
+
+
+pattern sql.lag(b:any_1, l:any_2, p:any_3, o:any_4) :any_1
+address SQLlag
+comment "return the value in the previous 'l' row in the partition or NULL if 
non existent";
+
+pattern batsql.lag(b:bat[:any_1], l:any_2, p:any_3, o:any_4) :bat[:any_1]
+address SQLlag
+comment "return the value in the previous 'l' row in the partition or NULL if 
non existent";
+
+pattern sql.lag(b:any_1, l:bat[:any_2], p:any_3, o:any_4) :any_1
+address SQLlag
+comment "return the value in the previous 'l' row in the partition or NULL if 
non existent";
+
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to