Changeset: 74e82cef418e for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=74e82cef418e Modified Files: gdk/gdk_analytic.h gdk/gdk_analytic_func.c sql/backends/monet5/sql_rank.c sql/test/analytics/Tests/analytics01.sql sql/test/analytics/Tests/analytics01.stable.err sql/test/analytics/Tests/analytics01.stable.out Branch: analytics Log Message:
nth_value analytic function with column nth parameter. diffs (truncated from 544 to 300 lines): diff --git a/gdk/gdk_analytic.h b/gdk/gdk_analytic.h --- a/gdk/gdk_analytic.h +++ b/gdk/gdk_analytic.h @@ -27,7 +27,7 @@ gdk_export gdk_return GDKanalyticalwindo gdk_export gdk_return GDKanalyticalfirst(BAT *r, BAT *b, BAT *s, BAT *e, int tpe); gdk_export gdk_return GDKanalyticallast(BAT *r, BAT *b, BAT *s, BAT *e, int tpe); -gdk_export gdk_return GDKanalyticalnthvalue(BAT *r, BAT *b, BAT *s, BAT *e, BUN nth, int tpe); +gdk_export gdk_return GDKanalyticalnthvalue(BAT *r, BAT *b, BAT *s, BAT *e, BAT *l, const void* restrict bound, int tp1, int tp2); gdk_export gdk_return GDKanalyticalmin(BAT *r, BAT *b, BAT *s, BAT *e, int tpe); gdk_export gdk_return GDKanalyticalmax(BAT *r, BAT *b, BAT *s, BAT *e, int tpe); gdk_export gdk_return GDKanalyticalcount(BAT *r, BAT *b, BAT *s, BAT *e, const bit* restrict ignore_nils, int tpe); diff --git a/gdk/gdk_analytic_func.c b/gdk/gdk_analytic_func.c --- a/gdk/gdk_analytic_func.c +++ b/gdk/gdk_analytic_func.c @@ -352,84 +352,208 @@ allocation_error: return GDK_FAIL; } -#define ANALYTICAL_NTHVALUE_IMP(TPE) \ - do { \ - TPE *bp, *bs, *be, curval, *restrict rb; \ - bp = (TPE*)Tloc(b, 0); \ - rb = (TPE*)Tloc(r, 0); \ - if (nth == BUN_NONE) { \ - has_nils = true; \ - for(; i<cnt; i++, rb++) \ - *rb = TPE##_nil; \ - } else { \ - for(; i<cnt; i++, rb++) { \ - bs = bp + start[i]; \ - be = bp + end[i]; \ - curval = (be > bs && nth < (BUN)(end[i] - start[i])) ? *(bs + nth) : TPE##_nil; \ - *rb = curval; \ - if (is_##TPE##_nil(curval)) \ - has_nils = true; \ - } \ - } \ +#define ANALYTICAL_NTHVALUE_IMP_SINGLE_FIXED(TPE1) \ + do { \ + TPE1 *bp = (TPE1*)Tloc(b, 0), *bs, *be, curval, *restrict rb = (TPE1*)Tloc(r, 0); \ + if (is_lng_nil(nth)) { \ + has_nils = true; \ + for (; i<cnt; i++, rb++) \ + *rb = TPE1##_nil; \ + } else { \ + nth--; \ + for (; i<cnt; i++, rb++) { \ + bs = bp + start[i]; \ + be = bp + end[i]; \ + curval = (be > bs && nth < (end[i] - start[i])) ? *(bs + nth) : TPE1##_nil; \ + *rb = curval; \ + if (is_##TPE1##_nil(curval)) \ + has_nils = true; \ + } \ + } \ + } while(0) + +#define ANALYTICAL_NTHVALUE_IMP_MULTI_FIXED(TPE1, TPE2) \ + do { \ + TPE2 *restrict lp = (TPE2*)Tloc(l, 0); \ + for (; i<cnt; i++, rb++) { \ + TPE2 lnth = lp[i]; \ + bs = bp + start[i]; \ + be = bp + end[i]; \ + if (is_##TPE2##_nil(lnth) || be <= bs || (lng)(lnth - 1) > (end[i] - start[i])) \ + curval = TPE1##_nil; \ + else \ + curval = *(bs + lnth - 1); \ + *rb = curval; \ + if (is_##TPE1##_nil(curval)) \ + has_nils = true; \ + } \ + } while(0) + +#define ANALYTICAL_NTHVALUE_CALC_FIXED(TPE1) \ + do { \ + TPE1 *bp, *bs, *be, curval, *restrict rb; \ + bp = (TPE1*)Tloc(b, 0); \ + rb = (TPE1*)Tloc(r, 0); \ + switch (tp2) { \ + case TYPE_bte: \ + ANALYTICAL_NTHVALUE_IMP_MULTI_FIXED(TPE1, bte); \ + break; \ + case TYPE_sht: \ + ANALYTICAL_NTHVALUE_IMP_MULTI_FIXED(TPE1, sht); \ + break; \ + case TYPE_int: \ + ANALYTICAL_NTHVALUE_IMP_MULTI_FIXED(TPE1, int); \ + break; \ + case TYPE_lng: \ + ANALYTICAL_NTHVALUE_IMP_MULTI_FIXED(TPE1, lng); \ + break; \ + default: \ + goto nosupport; \ + } \ + } while(0) + +#define ANALYTICAL_NTHVALUE_IMP_MULTI_VARSIZED(TPE2) \ + do { \ + TPE2 *restrict lp = (TPE2*)Tloc(l, 0); \ + for (; i < cnt; i++) { \ + TPE2 lnth = lp[i]; \ + if (is_##TPE2##_nil(lnth) || end[i] <= start[i] || (lng)(lnth - 1) > (end[i] - start[i])) \ + curval = (void *) nil; \ + else \ + curval = BUNtail(bpi, (BUN) start[i] + lnth - 1); \ + if (BUNappend(r, curval, false) != GDK_SUCCEED) \ + goto allocation_error; \ + if (atomcmp(curval, nil) == 0) \ + has_nils = true; \ + } \ } while(0) gdk_return -GDKanalyticalnthvalue(BAT *r, BAT *b, BAT *s, BAT *e, BUN nth, int tpe) +GDKanalyticalnthvalue(BAT *r, BAT *b, BAT *s, BAT *e, BAT *l, const void* restrict bound, int tp1, int tp2) { BUN i = 0, cnt = BATcount(b); - lng *restrict start, *restrict end; + lng *restrict start, *restrict end, nth = 0; bool has_nils = false; + const void* restrict nil = ATOMnilptr(tp1); + int (*atomcmp)(const void *, const void *) = ATOMcompare(tp1); + void *curval; - assert(s && e); + assert(s && e && ((l && !bound) || (!l && bound))); start = (lng*)Tloc(s, 0); end = (lng*)Tloc(e, 0); - switch (tpe) { - case TYPE_bit: - ANALYTICAL_NTHVALUE_IMP(bit); - break; - case TYPE_bte: - ANALYTICAL_NTHVALUE_IMP(bte); - break; - case TYPE_sht: - ANALYTICAL_NTHVALUE_IMP(sht); - break; - case TYPE_int: - ANALYTICAL_NTHVALUE_IMP(int); - break; - case TYPE_lng: - ANALYTICAL_NTHVALUE_IMP(lng); - break; + if(bound) { + switch (tp2) { + case TYPE_bte: { + bte val = *(bte *) bound; + nth = !is_bte_nil(val) ? (lng) val : lng_nil; + } break; + case TYPE_sht: { + sht val = *(sht *) bound; + nth = !is_sht_nil(val) ? (lng) val : lng_nil; + } break; + case TYPE_int: { + int val = *(int *) bound; + nth = !is_int_nil(val) ? (lng) val : lng_nil; + } break; + case TYPE_lng: { + nth = *(lng *) bound; + } break; + default: + goto nosupport; + } + switch (tp1) { + case TYPE_bit: + ANALYTICAL_NTHVALUE_IMP_SINGLE_FIXED(bit); + break; + case TYPE_bte: + ANALYTICAL_NTHVALUE_IMP_SINGLE_FIXED(bte); + break; + case TYPE_sht: + ANALYTICAL_NTHVALUE_IMP_SINGLE_FIXED(sht); + break; + case TYPE_int: + ANALYTICAL_NTHVALUE_IMP_SINGLE_FIXED(int); + break; + case TYPE_lng: + ANALYTICAL_NTHVALUE_IMP_SINGLE_FIXED(lng); + break; #ifdef HAVE_HGE - case TYPE_hge: - ANALYTICAL_NTHVALUE_IMP(hge); - break; + case TYPE_hge: + ANALYTICAL_NTHVALUE_IMP_SINGLE_FIXED(hge); + break; #endif - case TYPE_flt: - ANALYTICAL_NTHVALUE_IMP(flt); - break; - case TYPE_dbl: - ANALYTICAL_NTHVALUE_IMP(dbl); - break; - default: { - const void* restrict nil = ATOMnilptr(tpe); - int (*atomcmp)(const void *, const void *) = ATOMcompare(tpe); - BATiter bpi = bat_iterator(b); - void *curval; - - if (nth == BUN_NONE) { - has_nils = true; - for(; i<cnt; i++) - if (BUNappend(r, nil, false) != GDK_SUCCEED) - goto allocation_error; - } else { - for (; i < cnt; i++) { - curval = (end[i] > start[i] && nth < (BUN) (end[i] - start[i])) ? - BUNtail(bpi, (BUN) start[i] + nth) : (void *) nil; - if (BUNappend(r, curval, false) != GDK_SUCCEED) - goto allocation_error; - if (atomcmp(curval, nil) == 0) - has_nils = true; + case TYPE_flt: + ANALYTICAL_NTHVALUE_IMP_SINGLE_FIXED(flt); + break; + case TYPE_dbl: + ANALYTICAL_NTHVALUE_IMP_SINGLE_FIXED(dbl); + break; + default: { + BATiter bpi = bat_iterator(b); + if (is_lng_nil(nth)) { + has_nils = true; + for(; i<cnt; i++) + if (BUNappend(r, nil, false) != GDK_SUCCEED) + goto allocation_error; + } else { + nth--; + for (; i < cnt; i++) { + curval = (end[i] > start[i] && nth < (end[i] - start[i])) ? + BUNtail(bpi, (BUN) start[i] + nth) : (void *) nil; + if (BUNappend(r, curval, false) != GDK_SUCCEED) + goto allocation_error; + if (atomcmp(curval, nil) == 0) + has_nils = true; + } + } + } + } + } else { + switch (tp1) { + case TYPE_bit: + ANALYTICAL_NTHVALUE_CALC_FIXED(bit); + break; + case TYPE_bte: + ANALYTICAL_NTHVALUE_CALC_FIXED(bte); + break; + case TYPE_sht: + ANALYTICAL_NTHVALUE_CALC_FIXED(sht); + break; + case TYPE_int: + ANALYTICAL_NTHVALUE_CALC_FIXED(int); + break; + case TYPE_lng: + ANALYTICAL_NTHVALUE_CALC_FIXED(lng); + break; +#ifdef HAVE_HGE + case TYPE_hge: + ANALYTICAL_NTHVALUE_CALC_FIXED(hge); + break; +#endif + case TYPE_flt: + ANALYTICAL_NTHVALUE_CALC_FIXED(flt); + break; + case TYPE_dbl: + ANALYTICAL_NTHVALUE_CALC_FIXED(dbl); + break; + default: { + BATiter bpi = bat_iterator(b); + switch (tp2) { + case TYPE_bte: + ANALYTICAL_NTHVALUE_IMP_MULTI_VARSIZED(bte); + break; + case TYPE_sht: + ANALYTICAL_NTHVALUE_IMP_MULTI_VARSIZED(sht); + break; + case TYPE_int: + ANALYTICAL_NTHVALUE_IMP_MULTI_VARSIZED(int); + break; + case TYPE_lng: + ANALYTICAL_NTHVALUE_IMP_MULTI_VARSIZED(lng); + break; + default: + goto nosupport; } } } @@ -441,6 +565,9 @@ GDKanalyticalnthvalue(BAT *r, BAT *b, BA allocation_error: GDKerror("GDKanalyticalnthvalue: malloc failure\n"); return GDK_FAIL; +nosupport: + GDKerror("GDKanalyticalnthvalue: type %s not supported for the nth_value.\n", ATOMname(tp2)); + return GDK_FAIL; } #define ANALYTICAL_LAG_CALC(TPE) \ _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list