Changeset: d0327c77a9a3 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d0327c77a9a3
Modified Files:
        gdk/gdk_analytic_bounds.c
        monetdb5/modules/atoms/mtime_analytic.c
        sql/backends/monet5/sql_rank.c
        sql/server/rel_select.c
        sql/server/sql_atom.c
        sql/server/sql_atom.h
        sql/test/analytics/Tests/analytics03.stable.err
        sql/test/analytics/Tests/analytics03.stable.out
        sql/test/analytics/Tests/analytics07.stable.err
        sql/test/analytics/Tests/analytics07.stable.out
Branch: window-tunning
Log Message:

Avoid iterating bounds input, by moving bounds validation to the GDK. I had to 
undo another change because I didn't remember the code well. On the unbounded 
case, generate the max width of the interval rather than NULL, because NULL is 
an invalid bound


diffs (truncated from 1111 to 300 lines):

diff --git a/gdk/gdk_analytic_bounds.c b/gdk/gdk_analytic_bounds.c
--- a/gdk/gdk_analytic_bounds.c
+++ b/gdk/gdk_analytic_bounds.c
@@ -134,46 +134,57 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *p
        return GDK_SUCCEED;
 }
 
-#define ANALYTICAL_WINDOW_BOUNDS_ROWS_PRECEDING(LIMIT)                 \
+#define ANALYTICAL_WINDOW_BOUNDS_ROWS_PRECEDING(TPE, LIMIT, UPCAST)            
        \
        do {                                                            \
-               lng calc1, calc2;                                       \
+               lng calc1 = 0, calc2 = 0, rlimit = 0;                           
        \
                j = k;                                                  \
                for (; k < i; k++) {                            \
-                       lng rlimit = LIMIT;                             \
+                       TPE olimit = LIMIT;     \
+                       if (is_##TPE##_nil(olimit) || olimit < 0)       \
+                               goto invalid_bound;     \
+                       rlimit = UPCAST;        \
                        SUB_WITH_CHECK(k, rlimit, lng, calc1, GDK_lng_max, goto 
calc_overflow); \
                        ADD_WITH_CHECK(calc1, !first_half, lng, calc2, 
GDK_lng_max, goto calc_overflow); \
                        rb[k] = MAX(calc2, j);                          \
                }                                                       \
        } while (0)
 
-#define ANALYTICAL_WINDOW_BOUNDS_ROWS_FOLLOWING(LIMIT)                 \
+#define ANALYTICAL_WINDOW_BOUNDS_ROWS_FOLLOWING(TPE, LIMIT, UPCAST)            
        \
        do {                                                            \
-               lng calc1, calc2;                                       \
+               lng calc1 = 0, calc2 = 0, rlimit = 0;                           
        \
                for (; k < i; k++) {                            \
-                       lng rlimit = LIMIT;                             \
+                       TPE olimit = LIMIT;     \
+                       if (is_##TPE##_nil(olimit) || olimit < 0)       \
+                               goto invalid_bound;     \
+                       rlimit = UPCAST;        \
                        ADD_WITH_CHECK(rlimit, k, lng, calc1, GDK_lng_max, goto 
calc_overflow); \
                        ADD_WITH_CHECK(calc1, !first_half, lng, calc2, 
GDK_lng_max, goto calc_overflow); \
                        rb[k] = MIN(calc2, i);                          \
                }                                                       \
        } while (0)
 
-#define ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(IMP, LIMIT)             \
+#define ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(IMP, TPE, LIMIT, UPCAST)        
\
        do {                                                            \
                if (p) {                                                \
                        for (; i < cnt; i++) {                  \
                                if (np[i])                      \
-                                       
ANALYTICAL_WINDOW_BOUNDS_ROWS##IMP(LIMIT); \
+                                       ANALYTICAL_WINDOW_BOUNDS_ROWS##IMP(TPE, 
LIMIT, UPCAST); \
                        }                                               \
                }               \
                i = cnt;                                        \
-               ANALYTICAL_WINDOW_BOUNDS_ROWS##IMP(LIMIT);      \
+               ANALYTICAL_WINDOW_BOUNDS_ROWS##IMP(TPE, LIMIT, UPCAST); \
        } while (0)
 
-#define ANALYTICAL_WINDOW_BOUNDS_GROUPS_PRECEDING(LIMIT) \
+#define ANALYTICAL_WINDOW_BOUNDS_GROUPS_PRECEDING(TPE, LIMIT, UPCAST)          
        \
        do {                                                            \
-               lng m = k - 1;                                          \
+               lng m = k - 1, rlimit = 0;                                      
        \
                for (; k < i; k++) {            \
-                       lng rlimit = LIMIT;             \
+                       TPE olimit = LIMIT;     \
+                       if (is_##TPE##_nil(olimit) || olimit < 0)       \
+                               goto invalid_bound;     \
+                       rlimit = UPCAST;        \
+                       if (is_lng_nil(rlimit) || rlimit < 0)   \
+                               goto invalid_bound;     \
                        for (j = k; ; j--) {            \
                                if (j == m) {           \
                                        j++; \
@@ -189,10 +200,14 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *p
                }                                       \
        } while (0)
 
-#define ANALYTICAL_WINDOW_BOUNDS_GROUPS_FOLLOWING(LIMIT) \
+#define ANALYTICAL_WINDOW_BOUNDS_GROUPS_FOLLOWING(TPE, LIMIT, UPCAST)          
        \
        do {                                                            \
+               lng rlimit = 0; \
                for (; k < i; k++) {            \
-                       lng rlimit = LIMIT;             \
+                       TPE olimit = LIMIT;     \
+                       if (is_##TPE##_nil(olimit) || olimit < 0)       \
+                               goto invalid_bound;     \
+                       rlimit = UPCAST;        \
                        for (j = k + 1; j < i; j++) {   \
                                if (bp[j]) {            \
                                        if (rlimit == 0)                \
@@ -204,16 +219,16 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *p
                }               \
        } while (0)
 
-#define ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(IMP, LIMIT)           \
+#define ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(IMP, TPE, LIMIT, UPCAST)      
\
        do {                                                            \
                if (p) {                                                \
                        for (; i < cnt; i++) {                  \
                                if (np[i])                      \
-                                       
ANALYTICAL_WINDOW_BOUNDS_GROUPS##IMP(LIMIT); \
+                                       
ANALYTICAL_WINDOW_BOUNDS_GROUPS##IMP(TPE, LIMIT, UPCAST);       \
                        }                                               \
                }                               \
                i = cnt;                                        \
-               ANALYTICAL_WINDOW_BOUNDS_GROUPS##IMP(LIMIT);    \
+               ANALYTICAL_WINDOW_BOUNDS_GROUPS##IMP(TPE, LIMIT, UPCAST);       
\
        } while (0)
 
 #define ANALYTICAL_WINDOW_BOUNDS_FIXED_RANGE_PRECEDING(TPE1, LIMIT, TPE2) \
@@ -223,7 +238,10 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *p
                TPE2 rlimit;                                            \
                if (b->tnonil) {                                        \
                        for (; k < i; k++) {                    \
-                               rlimit = (TPE2) LIMIT;                  \
+                               TPE1 olimit = LIMIT;    \
+                               if (is_##TPE1##_nil(olimit) || olimit < 0)      
\
+                                       goto invalid_bound;     \
+                               rlimit = (TPE2) olimit;                 \
                                v = bp[k];                              \
                                for (j = k; ; j--) {                    \
                                        if (j == m)                     \
@@ -236,7 +254,10 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *p
                        }                                               \
                } else {                                                \
                        for (; k < i; k++) {                    \
-                               rlimit = (TPE2) LIMIT;                  \
+                               TPE1 olimit = LIMIT;    \
+                               if (is_##TPE1##_nil(olimit) || olimit < 0)      
\
+                                       goto invalid_bound;     \
+                               rlimit = (TPE2) olimit;                 \
                                v = bp[k];                              \
                                if (is_##TPE1##_nil(v)) {               \
                                        for (j = k; ; j--) {            \
@@ -267,7 +288,10 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *p
                TPE2 rlimit;                                            \
                if (b->tnonil) {                                        \
                        for (; k < i; k++) {                    \
-                               rlimit = (TPE2) LIMIT;                  \
+                               TPE1 olimit = LIMIT;    \
+                               if (is_##TPE1##_nil(olimit) || olimit < 0)      
\
+                                       goto invalid_bound;     \
+                               rlimit = (TPE2) olimit;                 \
                                v = bp[k];                              \
                                for (j = k + 1; j < i; j++) {           \
                                        SUB_WITH_CHECK(v, bp[j], TPE1, calc, 
GDK_##TPE1##_max, goto calc_overflow); \
@@ -278,7 +302,10 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *p
                        }                                               \
                } else {                                                \
                        for (; k < i; k++) {                    \
-                               rlimit = (TPE2) LIMIT;                  \
+                               TPE1 olimit = LIMIT;    \
+                               if (is_##TPE1##_nil(olimit) || olimit < 0)      
\
+                                       goto invalid_bound;     \
+                               rlimit = (TPE2) olimit;                 \
                                v = bp[k];                              \
                                if (is_##TPE1##_nil(v)) {               \
                                        for (j =k + 1; j < i; j++) {    \
@@ -315,21 +342,30 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *p
 #define ANALYTICAL_WINDOW_BOUNDS_VARSIZED_RANGE_PRECEDING(LIMIT, TPE)  \
        do {                                                            \
                lng m = k - 1;                                          \
+               TPE rlimit = 0;         \
                if (b->tnonil) {                                        \
                        for (; k < i; k++) {                    \
+                               TPE olimit = LIMIT;     \
+                               if (is_##TPE##_nil(olimit) || olimit < 0)       
\
+                                       goto invalid_bound;     \
+                               rlimit = (TPE) olimit;                  \
                                void *v = BUNtail(bpi, (BUN) k);        \
                                for (j = k; ; j--) {                    \
                                        void *next;                     \
                                        if (j == m)                     \
                                                break;                  \
                                        next = BUNtail(bpi, (BUN) j);   \
-                                       if (ABSOLUTE((TPE) atomcmp(v, next)) > 
(TPE) LIMIT) \
+                                       if (ABSOLUTE((TPE) atomcmp(v, next)) > 
olimit) \
                                                break;                  \
                                }                                       \
                                rb[k] = ++j;                                    
\
                        }                                               \
                } else {                                                \
                        for (; k < i; k++) {                    \
+                               TPE olimit = LIMIT;     \
+                               if (is_##TPE##_nil(olimit) || olimit < 0)       
\
+                                       goto invalid_bound;     \
+                               rlimit = (TPE) olimit;                  \
                                void *v = BUNtail(bpi, (BUN) k);        \
                                if (atomcmp(v, nil) == 0) {             \
                                        for (j = k; ; j--) {            \
@@ -346,7 +382,7 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *p
                                                next = BUNtail(bpi, (BUN) j); \
                                                if (atomcmp(next, nil) == 0) \
                                                        break;          \
-                                               if (ABSOLUTE((TPE) atomcmp(v, 
next)) > (TPE) LIMIT) \
+                                               if (ABSOLUTE((TPE) atomcmp(v, 
next)) > rlimit) \
                                                        break;          \
                                        }                               \
                                }                                       \
@@ -530,40 +566,42 @@ GDKanalyticalrowbounds(BAT *r, BAT *b, B
        int abort_on_error = 1;
 
        if (l) {                /* dynamic bounds */
+               if (l->tnil)
+                       goto invalid_bound;
                switch (tp2) {
                case TYPE_bte:{
                        bte *restrict limit = (bte *) Tloc(l, 0);
                        if (preceding) {
-                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, (lng) limit[k]);
+                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, bte, limit[k], (lng) olimit);
                        } else {
-                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, (lng) limit[k]);
+                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, bte, limit[k], (lng) olimit);
                        }
                        break;
                }
                case TYPE_sht:{
                        sht *restrict limit = (sht *) Tloc(l, 0);
                        if (preceding) {
-                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, (lng) limit[k]);
+                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, sht, limit[k], (lng) olimit);
                        } else {
-                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, (lng) limit[k]);
+                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, sht, limit[k], (lng) olimit);
                        }
                        break;
                }
                case TYPE_int:{
                        int *restrict limit = (int *) Tloc(l, 0);
                        if (preceding) {
-                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, (lng) limit[k]);
+                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, int, limit[k], (lng) olimit);
                        } else {
-                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, (lng) limit[k]);
+                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, int, limit[k], (lng) olimit);
                        }
                        break;
                }
                case TYPE_lng:{
                        lng *restrict limit = (lng *) Tloc(l, 0);
                        if (preceding) {
-                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, (lng) limit[k]);
+                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, lng, limit[k], olimit);
                        } else {
-                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, (lng) limit[k]);
+                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, lng, limit[k], olimit);
                        }
                        break;
                }
@@ -571,9 +609,9 @@ GDKanalyticalrowbounds(BAT *r, BAT *b, B
                case TYPE_hge:{
                        hge *restrict limit = (hge *) Tloc(l, 0);
                        if (preceding) {
-                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, (limit[k] > (hge) 
GDK_lng_max) ? GDK_lng_max : (lng) limit[k]);
+                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, hge, limit[k], (olimit > 
(hge) GDK_lng_max) ? GDK_lng_max : (lng) olimit);
                        } else {
-                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, (limit[k] > (hge) 
GDK_lng_max) ? GDK_lng_max : (lng) limit[k]);
+                               
ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, hge, limit[k], (olimit > 
(hge) GDK_lng_max) ? GDK_lng_max : (lng) olimit);
                        }
                        break;
                }
@@ -606,12 +644,14 @@ GDKanalyticalrowbounds(BAT *r, BAT *b, B
                default:
                        goto bound_not_supported;
                }
-               if (is_lng_nil(limit)) {
+               if (limit == GDK_lng_max) {
                        return GDKanalyticalallbounds(r, b, p, preceding);
+               } else if (is_lng_nil(limit) || limit < 0) {
+                       goto invalid_bound;     
                } else if (preceding) {
-                       ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, 
limit);
+                       ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, lng, 
limit, olimit);
                } else {
-                       ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, 
limit);
+                       ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, lng, 
limit, olimit);
                }
        }
 
@@ -620,11 +660,14 @@ GDKanalyticalrowbounds(BAT *r, BAT *b, B
        r->tnil = (nils > 0);
        return GDK_SUCCEED;
       bound_not_supported:
-       GDKerror("rows frame bound type %s not supported.\n", ATOMname(tp2));
+       GDKerror("42000!rows frame bound type %s not supported.\n", 
ATOMname(tp2));
        return GDK_FAIL;
       calc_overflow:
        GDKerror("22003!overflow in calculation.\n");
        return GDK_FAIL;
+      invalid_bound:
+       GDKerror("42000!row frame bound must be non negative and non null.\n");
+       return GDK_FAIL;
 }
 
 static gdk_return
@@ -638,6 +681,8 @@ GDKanalyticalrangebounds(BAT *r, BAT *b,
        int abort_on_error = 1;
 
        if (l) {                /* dynamic bounds */
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to