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