Changeset: f8f6fb426ed6 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f8f6fb426ed6
Modified Files:
gdk/gdk_analytic.c
gdk/gdk_analytic.h
sql/backends/monet5/sql_rank.c
sql/server/rel_select.c
sql/test/analytics/Tests/analytics00.sql
sql/test/analytics/Tests/analytics00.stable.out
Branch: analytics
Log Message:
When applying an aggregation function on window with no specification: over (),
calculate the aggregate over the entire column.
Also fixed the query: select count(*) over ()
diffs (truncated from 458 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
@@ -957,7 +957,7 @@ finish:
has_nils = true; \
for (;rb < rp; rb++) \
*rb = curval; \
- } else if (o) { /* single value, ie no partitions */ \
+ } else if (o || force_order) { \
for(; rp<end; rp++, bp++) { \
if(!is_##TPE##_nil(*bp)) { \
if(is_##TPE##_nil(curval))
\
@@ -990,7 +990,7 @@ finish:
#define ANALYTICAL_LIMIT(OP, IMP, SIGN_OP)
\
gdk_return
\
-GDKanalytical##OP(BAT *r, BAT *b, BAT *p, BAT *o, int tpe)
\
+GDKanalytical##OP(BAT *r, BAT *b, BAT *p, BAT *o, bit force_order, int tpe)
\
{
\
int (*atomcmp)(const void *, const void *);
\
const void* restrict nil;
\
@@ -1053,7 +1053,7 @@ GDKanalytical##OP(BAT *r, BAT *b, BAT *p
if ((gdk_res = BUNappend(r, curval,
false)) != GDK_SUCCEED) \
goto finish;
\
}
\
- } else if (o) { /* single value, ie no partitions */
\
+ } else if (o || force_order) {
\
for(i=0; i<cnt; i++) {
\
void *next = BUNtail(bpi, i);
\
if((*atomcmp)(next, nil) != 0)
{ \
@@ -1316,7 +1316,7 @@ GDKanalyticalcount(BAT *r, BAT *b, BAT *
has_nils = true;
\
for (;rb < rp; rb++) \
*rb = curval;
\
- } else if (o) { /* single value, ie no partitions */ \
+ } else if (o || force_order) { \
for(; rp<end; rp++, bp++) { \
if(!is_##TPE1##_nil(*bp)) {
\
if(is_##TPE2##_nil(curval))
\
@@ -1379,7 +1379,7 @@ GDKanalyticalcount(BAT *r, BAT *b, BAT *
has_nils = true;
\
for (;rb < rp; rb++)
\
*rb = curval;
\
- } else if (o) { /* single value, ie no partitions */ \
+ } else if (o || force_order) { \
TPE2 *end = rb + cnt;
\
if(dofsum(bp, 0, 0, cnt, rb, 1, TYPE_##TPE1,
TYPE_##TPE2, \
NULL, NULL, NULL, 0, 0, true, false,
true, \
@@ -1406,7 +1406,7 @@ GDKanalyticalcount(BAT *r, BAT *b, BAT *
} while(0);
gdk_return
-GDKanalyticalsum(BAT *r, BAT *b, BAT *p, BAT *o, int tp1, int tp2)
+GDKanalyticalsum(BAT *r, BAT *b, BAT *p, BAT *o, bit force_order, int tp1, int
tp2)
{
bool has_nils = false;
BUN i, j, cnt = BATcount(b), nils = 0;
@@ -1572,7 +1572,7 @@ finish:
has_nils = true;
\
for (;rb < rp; rb++) \
*rb = curval;
\
- } else if (o) { /* single value, ie no partitions */ \
+ } else if (o || force_order) { \
for(; rp<end; rp++, bp++) { \
if(!is_##TPE1##_nil(*bp)) {
\
if(is_##TPE2##_nil(curval))
\
@@ -1631,7 +1631,7 @@ finish:
has_nils = true; \
for (;rb < rp; rb++) \
*rb = curval; \
- } else if (o) { /* single value, ie no partitions */ \
+ } else if (o || force_order) { \
for(; rp<end; rp++, bp++) { \
if(!is_##TPE1##_nil(*bp)) { \
if(is_##TPE2##_nil(curval))
\
@@ -1699,7 +1699,7 @@ finish:
has_nils = true;
\
for (;rb < rp; rb++) \
*rb = curval;
\
- } else if (o) { /* single value, ie no partitions */ \
+ } else if (o || force_order) { \
for(; rp<end; rp++, bp++) { \
if(!is_##TPE1##_nil(*bp)) {
\
if(is_##TPE2##_nil(curval))
\
@@ -1726,7 +1726,7 @@ finish:
} while(0);
gdk_return
-GDKanalyticalprod(BAT *r, BAT *b, BAT *p, BAT *o, int tp1, int tp2)
+GDKanalyticalprod(BAT *r, BAT *b, BAT *p, BAT *o, bit force_order, int tp1,
int tp2)
{
bool has_nils = false;
BUN cnt = BATcount(b), nils = 0;
@@ -1940,7 +1940,7 @@ avg_overflow##TPE:
calc_done##TPE: \
for (;rb < rp; rb++)
\
*rb = curval;
\
- } else if (o) { /* single value, ie no partitions */ \
+ } else if (o || force_order) { \
for(; rp<end; rp++, bp++) {
\
if (!is_##TPE##_nil(*bp)) {
\
ADD_WITH_CHECK(TPE, *bp, lng_hge, sum,
lng_hge, \
@@ -2021,7 +2021,7 @@ single_calc_done##TPE:
has_nils = has_nils || (n == 0); \
for (;rb < rp; rb++) \
*rb = curval; \
- } else if (o) { /* single value, ie no partitions */ \
+ } else if (o || force_order) { \
for(; rp<end; rp++, bp++) { \
if (!is_##TPE##_nil(*bp)) \
AVERAGE_ITER_FLOAT(TPE, *bp, a, n);
\
@@ -2044,7 +2044,7 @@ single_calc_done##TPE:
} while(0);
gdk_return
-GDKanalyticalavg(BAT *r, BAT *b, BAT *p, BAT *o, int tpe)
+GDKanalyticalavg(BAT *r, BAT *b, BAT *p, BAT *o, bit force_order, int tpe)
{
bool has_nils = false;
BUN cnt = BATcount(b), nils = 0, n = 0;
diff --git a/gdk/gdk_analytic.h b/gdk/gdk_analytic.h
--- a/gdk/gdk_analytic.h
+++ b/gdk/gdk_analytic.h
@@ -23,11 +23,11 @@ gdk_export gdk_return GDKanalyticallast(
gdk_export gdk_return GDKanalyticalnthvalue(BAT *r, BAT *b, BAT *p, BAT *o,
BUN nth, int tpe);
gdk_export gdk_return GDKanalyticallag(BAT *r, BAT *b, BAT *p, BAT *o, BUN
lag, const void* restrict default_value, int tpe);
gdk_export gdk_return GDKanalyticallead(BAT *r, BAT *b, BAT *p, BAT *o, BUN
lead, const void* restrict default_value, int tpe);
-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 GDKanalyticalmin(BAT *r, BAT *b, BAT *p, BAT *o, bit
force_order, int tpe);
+gdk_export gdk_return GDKanalyticalmax(BAT *r, BAT *b, BAT *p, BAT *o, bit
force_order, int tpe);
gdk_export gdk_return GDKanalyticalcount(BAT *r, BAT *b, BAT *p, BAT *o, const
bit* restrict ignore_nils, int tpe);
-gdk_export gdk_return GDKanalyticalsum(BAT *r, BAT *b, BAT *p, BAT *o, int
tp1, int tp2);
-gdk_export gdk_return GDKanalyticalprod(BAT *r, BAT *b, BAT *p, BAT *o, int
tp1, int tp2);
-gdk_export gdk_return GDKanalyticalavg(BAT *r, BAT *b, BAT *p, BAT *o, int
tpe);
+gdk_export gdk_return GDKanalyticalsum(BAT *r, BAT *b, BAT *p, BAT *o, bit
force_order, int tp1, int tp2);
+gdk_export gdk_return GDKanalyticalprod(BAT *r, BAT *b, BAT *p, BAT *o, bit
force_order, int tp1, int tp2);
+gdk_export gdk_return GDKanalyticalavg(BAT *r, BAT *b, BAT *p, BAT *o, bit
force_order, int tpe);
#endif //_GDK_ANALYTIC_H_
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
@@ -571,8 +571,8 @@ SQLntile(Client cntxt, MalBlkPtr mb, Mal
#undef NTILE_VALUE_SINGLE_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)
+SQLanalytics_args(BAT **r, BAT **b, BAT **p, BAT **o, bit *force_order, Client
cntxt, MalBlkPtr mb, MalStkPtr stk,
+ InstrPtr pci, int rtype, const str mod, const
str err)
{
*r = *b = *p = *o = NULL;
@@ -609,6 +609,8 @@ SQLanalytics_args(BAT **r, BAT **b, BAT
if (*p) BBPunfix((*p)->batCacheid);
throw(SQL, mod, SQLSTATE(HY005) "Cannot access column
descriptor");
}
+ } else {
+ *force_order = *getArgReference_bit(stk, pci, 3);
}
return MAL_SUCCEED;
}
@@ -942,10 +944,11 @@ SQLlead(Client cntxt, MalBlkPtr mb, MalS
/* 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))
+ gdk_return (*func)(BAT *, BAT *, BAT *, BAT
*, bit, int))
{
BAT *r, *b, *p, *o;
- str msg = SQLanalytics_args(&r, &b, &p, &o, cntxt, mb, stk, pci, 0, op,
err);
+ bit force_order = 0;
+ str msg = SQLanalytics_args(&r, &b, &p, &o, &force_order, 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);
@@ -966,7 +969,7 @@ SQLanalytical_func(Client cntxt, MalBlkP
if (b) {
bat *res = getArgReference_bat(stk, pci, 0);
- gdk_res = func(r, b, p, o, tpe);
+ gdk_res = func(r, b, p, o, force_order, tpe);
BBPunfix(b->batCacheid);
if (p) BBPunfix(p->batCacheid);
if (o) BBPunfix(o->batCacheid);
@@ -1075,10 +1078,11 @@ SQLcount(Client cntxt, MalBlkPtr mb, Mal
static str
do_analytical_sumprod(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
- gdk_return (*func)(BAT *, BAT *, BAT
*, BAT *, int, int), const str op, const str err)
+ gdk_return (*func)(BAT *, BAT *, BAT
*, BAT *, bit, int, int), const str op, const str err)
{
BAT *r = NULL, *b = NULL, *p = NULL, *o = NULL;
int tp1, tp2, unit, start, end, excl;
+ bit force_order = 0;
gdk_return gdk_res;
str msg = MAL_SUCCEED;
@@ -1094,9 +1098,8 @@ do_analytical_sumprod(Client cntxt, MalB
end = *getArgReference_int(stk, pci, 6);
excl = *getArgReference_int(stk, pci, 7);
- if (isaBatType(tp1))
+ if (isaBatType(tp1)) {
tp1 = getBatType(tp1);
- if (isaBatType(getArgType(mb, pci, 1))) {
b = BATdescriptor(*getArgReference_bat(stk, pci, 1));
if (!b)
throw(SQL, op, SQLSTATE(HY005) "Cannot access column
descriptor");
@@ -1125,8 +1128,7 @@ do_analytical_sumprod(Client cntxt, MalB
}
}
if (b) {
- BUN cnt = BATcount(b);
- voidresultBAT(r, tp2, cnt, b, op);
+ voidresultBAT(r, tp2, BATcount(b), b, op);
}
if (isaBatType(getArgType(mb, pci, 2))) {
p = BATdescriptor(*getArgReference_bat(stk, pci, 2));
@@ -1144,6 +1146,8 @@ do_analytical_sumprod(Client cntxt, MalB
if (p) BBPunfix(p->batCacheid);
throw(SQL, op, SQLSTATE(HY005) "Cannot access column
descriptor");
}
+ } else {
+ force_order = *getArgReference_bit(stk, pci, 3);
}
if (unit != 0 || excl != 0)
@@ -1154,7 +1158,7 @@ do_analytical_sumprod(Client cntxt, MalB
if (b) {
bat *res = getArgReference_bat(stk, pci, 0);
- gdk_res = func(r, b, p, o, tp1, tp2);
+ gdk_res = func(r, b, p, o, force_order, tp1, tp2);
BBPunfix(b->batCacheid);
if (p) BBPunfix(p->batCacheid);
if (o) BBPunfix(o->batCacheid);
@@ -1232,7 +1236,8 @@ str
SQLavg(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
BAT *r, *b, *p, *o;
- str msg = SQLanalytics_args(&r, &b, &p, &o, cntxt, mb, stk, pci,
TYPE_dbl, "sql.avg",
+ bit force_order = 0;
+ str msg = SQLanalytics_args(&r, &b, &p, &o, &force_order, cntxt, mb,
stk, pci, TYPE_dbl, "sql.avg",
SQLSTATE(42000)
"avg(:any_1,:bit,:bit)");
int tpe = getArgType(mb, pci, 1);
int unit = *getArgReference_int(stk, pci, 4);
@@ -1254,7 +1259,7 @@ SQLavg(Client cntxt, MalBlkPtr mb, MalSt
if (b) {
bat *res = getArgReference_bat(stk, pci, 0);
- gdk_res = GDKanalyticalavg(r, b, p, o, tpe);
+ gdk_res = GDKanalyticalavg(r, b, p, o, force_order, tpe);
BBPunfix(b->batCacheid);
if (p) BBPunfix(p->batCacheid);
if (o) BBPunfix(o->batCacheid);
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -4577,10 +4577,15 @@ rel_rankop(mvc *sql, sql_rel **rel, symb
if (n) {
if (!n->next->data.sym) { /* count(*) */
- e = p->exps->h->data;
- e = exp_column(sql->sa, exp_relname(e),
exp_name(e), exp_subtype(e), exp_card(e), has_nil(e), is_intern(e));
+ if(!p->exps->h) { //no from clause, use a
constant as the expression to project
+ e = exp_atom_lng(sql->sa, 0);
+ append(p->exps, e);
+ } else {
+ e = p->exps->h->data;
+ e = exp_column(sql->sa, exp_relname(e),
exp_name(e), exp_subtype(e), exp_card(e), has_nil(e), is_intern(e));
+ }
append(fargs, e);
- append(fargs, exp_atom_bool(sql->sa, 0));
+ append(fargs, exp_atom_bool(sql->sa, 0));
//don't ignore nills
} else {
is_last = 0;
exp_kind ek1 = {type_value, card_column, FALSE};
@@ -4588,10 +4593,11 @@ rel_rankop(mvc *sql, sql_rel **rel, symb
distinct = n->data.i_val;
/*
* all aggregations implemented in a window
have 1 and only 1 argument only, so for now no further
+ * checking is needed
*/
append(fargs, rel_value_exp2(sql, &p,
n->next->data.sym, f, ek1, &is_last));
if(strcmp(s->base.name, "sys") == 0 &&
strcmp(aname, "count") == 0)
- append(fargs, exp_atom_bool(sql->sa,
1));
+ append(fargs, exp_atom_bool(sql->sa,
1)); //ignore nills
}
}
}
@@ -4640,6 +4646,9 @@ rel_rankop(mvc *sql, sql_rel **rel, symb
append(args, e);
oe = exp_op(sql->sa, args, df);
}
+ } else if(aggr && !gbe && !obe) {
+ /* when there is no partition and no order by we calculate the
aggregate over the entire column */
+ oe = exp_atom_bool(sql->sa, 1);
} else {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list