Changeset: 1bdd5b492adc for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1bdd5b492adc
Added Files:
        gdk/gdk_analytic.c
        gdk/gdk_analytic.h
        sql/backends/monet5/sql_rank.mal.sh
        sql/backends/monet5/sql_rank_hge.mal
        sql/backends/monet5/sql_rank_hge.mal.sh
Modified Files:
        gdk/Makefile.ag
        sql/backends/monet5/Makefile.ag
        sql/backends/monet5/sql_rank.c
        sql/backends/monet5/sql_rank.h
        sql/backends/monet5/sql_rank.mal
        sql/common/sql_types.c
        sql/test/analytics/Tests/analytics00.sql
        sql/test/analytics/Tests/analytics00.stable.out
Branch: analytics
Log Message:

First implementation for sum analytical function over a window. Also moved 
analytical functions implementation to the GDK layer.

Still missing floating-point sum implementation, it's complex :(


diffs (truncated from 1432 to 300 lines):

diff --git a/gdk/Makefile.ag b/gdk/Makefile.ag
--- a/gdk/Makefile.ag
+++ b/gdk/Makefile.ag
@@ -34,6 +34,7 @@ lib_gdk = {
                gdk_unique.c \
                gdk_interprocess.c gdk_interprocess.h \
                gdk_firstn.c \
+               gdk_analytic.c gdk_analytic.h \
                libbat.rc
        LIBS = ../common/options/libmoptions \
                ../common/utils/libmutils \
@@ -52,6 +53,7 @@ headers_h = {
        HEADERS = h
        SOURCES = \
                gdk.h \
+               gdk_analytic.h \
                gdk_atomic.h \
                gdk_atoms.h \
                gdk_bbp.h \
diff --git a/gdk/gdk_analytic.c b/gdk/gdk_analytic.c
new file mode 100644
--- /dev/null
+++ b/gdk/gdk_analytic.c
@@ -0,0 +1,441 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ */
+
+#include "monetdb_config.h"
+#include "gdk.h"
+#include "gdk_analytic.h"
+
+#define ANALYTICAL_LIMIT_IMP(TPE, OP)                        \
+       do {                                                     \
+               TPE *rp, *rb, *bp, curval;                           \
+               rb = rp = (TPE*)Tloc(r, 0);                          \
+               bp = (TPE*)Tloc(b, 0);                               \
+               curval = *bp;                                        \
+               if (p) {                                             \
+                       if (o) {                                         \
+                               np = (bit*)Tloc(p, 0);                       \
+                               for(i=0; i<cnt; i++, np++, rp++, bp++) {     \
+                                       if (*np) {                              
 \
+                                               if(is_##TPE##_nil(curval))      
     \
+                                                       has_nils = true;        
         \
+                                               for (;rb < rp; rb++)            
     \
+                                                       *rb = curval;           
         \
+                                               curval = *bp;                   
     \
+                                       }                                       
 \
+                                       if(!is_##TPE##_nil(*bp)) {              
 \
+                                               if(is_##TPE##_nil(curval))      
     \
+                                                       curval = *bp;           
         \
+                                               else                            
     \
+                                                       curval = OP(*bp, 
curval);        \
+                                       }                                       
 \
+                               }                                            \
+                               if(is_##TPE##_nil(curval))                   \
+                                       has_nils = true;                        
 \
+                               for (;rb < rp; rb++)                         \
+                                       *rb = curval;                           
 \
+                       } else { /* single value, ie no ordering */      \
+                               np = (bit*)Tloc(p, 0);                       \
+                               for(i=0; i<cnt; i++, np++, rp++, bp++) {     \
+                                       if (*np) {                              
 \
+                                               if(is_##TPE##_nil(curval))      
     \
+                                                       has_nils = true;        
         \
+                                               for (;rb < rp; rb++)            
     \
+                                                       *rb = curval;           
         \
+                                               curval = *bp;                   
     \
+                                       }                                       
 \
+                                       if(!is_##TPE##_nil(*bp)) {              
 \
+                                               if(is_##TPE##_nil(curval))      
     \
+                                                       curval = *bp;           
         \
+                                               else                            
     \
+                                                       curval = OP(*bp, 
curval);        \
+                                       }                                       
 \
+                               }                                            \
+                               if(is_##TPE##_nil(curval))                   \
+                                       has_nils = true;                        
 \
+                               for (;rb < rp; rb++)                         \
+                                       *rb = curval;                           
 \
+                       }                                                \
+               } else if (o) { /* single value, ie no partitions */ \
+                       for(i=0; i<cnt; i++, rp++, bp++) {               \
+                               if(!is_##TPE##_nil(*bp)) {                   \
+                                       if(is_##TPE##_nil(curval))              
 \
+                                               curval = *bp;                   
     \
+                                       else                                    
 \
+                                               curval = OP(*bp, curval);       
     \
+                               }                                            \
+                       }                                                \
+                       if(is_##TPE##_nil(curval))                       \
+                               has_nils = true;                             \
+                       for(;rb < rp; rb++)                              \
+                               *rb = curval;                                \
+               } else { /* single value, ie no ordering */          \
+                       if(is_##TPE##_nil(*bp))                          \
+                               has_nils = true;                             \
+                       for(i=0; i<cnt; i++, rp++, bp++)                 \
+                               *rp = *bp;                                   \
+               }                                                    \
+       } while(0);
+
+#ifdef HAVE_HUGE
+#define ANALYTICAL_LIMIT_IMP_HUGE(IMP) \
+       case TYPE_hge:                     \
+               ANALYTICAL_LIMIT_IMP(hge, IMP) \
+       break;
+#else
+#define ANALYTICAL_LIMIT_IMP_HUGE(IMP)
+#endif
+
+#define ANALYTICAL_LIMIT(OP, IMP, SIGN_OP)                                     
             \
+gdk_return                                                                     
             \
+GDKanalytical##OP(BAT *r, BAT *b, BAT *p, BAT *o, int tpe)                     
             \
+{                                                                              
             \
+       int (*atomcmp)(const void *, const void *);                             
                \
+       const void *nil;                                                        
                \
+       bool has_nils = false;                                                  
                \
+       BUN i, j, cnt = BATcount(b);                                            
                \
+       bit *np;                                                                
                \
+       gdk_return gdk_res = GDK_SUCCEED;                                       
                \
+                                                                               
             \
+       switch(ATOMstorage(tpe)) {                                              
                \
+               case TYPE_bit:                                                  
                    \
+                       ANALYTICAL_LIMIT_IMP(bit, IMP)                          
                        \
+                       break;                                                  
                        \
+               case TYPE_bte:                                                  
                    \
+                       ANALYTICAL_LIMIT_IMP(bte, IMP)                          
                        \
+                       break;                                                  
                        \
+               case TYPE_sht:                                                  
                    \
+                       ANALYTICAL_LIMIT_IMP(sht, IMP)                          
                        \
+                       break;                                                  
                        \
+               case TYPE_int:                                                  
                    \
+                       ANALYTICAL_LIMIT_IMP(int, IMP)                          
                        \
+                       break;                                                  
                        \
+               case TYPE_lng:                                                  
                    \
+                       ANALYTICAL_LIMIT_IMP(lng, IMP)                          
                        \
+                       break;                                                  
                        \
+               ANALYTICAL_LIMIT_IMP_HUGE(IMP)                                  
                    \
+               case TYPE_flt:                                                  
                    \
+                       ANALYTICAL_LIMIT_IMP(flt, IMP)                          
                        \
+                       break;                                                  
                        \
+               case TYPE_dbl:                                                  
                    \
+                       ANALYTICAL_LIMIT_IMP(dbl, IMP)                          
                        \
+                       break;                                                  
                        \
+               default: {                                                      
                    \
+                       BATiter bpi = bat_iterator(b);                          
                        \
+                       void *curval = BUNtail(bpi, 0);                         
                        \
+                       nil = ATOMnilptr(tpe);                                  
                        \
+                       atomcmp = ATOMcompare(tpe);                             
                        \
+                       if (p) {                                                
                        \
+                               if (o) {                                        
                            \
+                                       np = (bit*)Tloc(p, 0);                  
                                \
+                                       for(i=0,j=0; i<cnt; i++, np++) {        
                                \
+                                               if (*np) {                      
                                    \
+                                                       if((*atomcmp)(curval, 
nil) == 0)                                \
+                                                               has_nils = 
true;                                            \
+                                                       for (;j < i; j++) {     
                                        \
+                                                               if ((gdk_res = 
BUNappend(r, curval, false)) != GDK_SUCCEED) \
+                                                                       goto 
finish;                                            \
+                                                       }                       
                                        \
+                                                       curval = BUNtail(bpi, 
i);                                       \
+                                               }                               
                                    \
+                                               void *next = BUNtail(bpi, i);   
                                    \
+                                               if((*atomcmp)(next, nil) != 0) 
{                                    \
+                                                       if((*atomcmp)(curval, 
nil) == 0)                                \
+                                                               curval = next;  
                                            \
+                                                       else                    
                                        \
+                                                               curval = 
atomcmp(next, curval) SIGN_OP 0 ? curval : next;   \
+                                               }                               
                                    \
+                                       }                                       
                                \
+                                       if((*atomcmp)(curval, nil) == 0)        
                                \
+                                               has_nils = true;                
                                    \
+                                       for (;j < i; j++) {                     
                                \
+                                                  if ((gdk_res = BUNappend(r, 
curval, false)) != GDK_SUCCEED)      \
+                                                          goto finish;         
                                        \
+                                       }                                       
                                \
+                               } else { /* single value, ie no ordering */     
                            \
+                                       np = (bit*)Tloc(p, 0);                  
                                \
+                                       for(i=0,j=0; i<cnt; i++, np++) {        
                                \
+                                               if (*np) {                      
                                    \
+                                                       if((*atomcmp)(curval, 
nil) == 0)                                \
+                                                               has_nils = 
true;                                            \
+                                                       for (;j < i; j++) {     
                                        \
+                                                               if ((gdk_res = 
BUNappend(r, curval, false)) != GDK_SUCCEED) \
+                                                                       goto 
finish;                                            \
+                                                       }                       
                                        \
+                                                       curval = BUNtail(bpi, 
i);                                       \
+                                               }                               
                                    \
+                                               void *next = BUNtail(bpi, i);   
                                    \
+                                               if((*atomcmp)(next, nil) != 0) 
{                                    \
+                                                       if((*atomcmp)(curval, 
nil) == 0)                                \
+                                                               curval = next;  
                                            \
+                                                       else                    
                                        \
+                                                               curval = 
atomcmp(next, curval) SIGN_OP 0 ? curval : next;   \
+                                               }                               
                                    \
+                                       }                                       
                                \
+                                       if((*atomcmp)(curval, nil) == 0)        
                                \
+                                               has_nils = true;                
                                    \
+                                       for (;j < i; j++) {                     
                                \
+                                               if ((gdk_res = BUNappend(r, 
curval, false)) != GDK_SUCCEED)         \
+                                                       goto finish;            
                                        \
+                                       }                                       
                                \
+                               }                                               
                            \
+                       } else if (o) { /* single value, ie no partitions */    
                        \
+                               for(i=0; i<cnt; i++) {                          
                            \
+                                       void *next = BUNtail(bpi, i);           
                                \
+                                               if((*atomcmp)(next, nil) != 0) 
{                                    \
+                                                       if((*atomcmp)(curval, 
nil) == 0)                                \
+                                                               curval = next;  
                                            \
+                                                       else                    
                                        \
+                                                               curval = 
atomcmp(next, curval) SIGN_OP 0 ? curval : next;   \
+                                               }                               
                                    \
+                               }                                               
                            \
+                               if((*atomcmp)(curval, nil) == 0)                
                            \
+                                       has_nils = true;                        
                                \
+                               for (j=0; j < i; j++) {                         
                            \
+                                       if ((gdk_res = BUNappend(r, curval, 
false)) != GDK_SUCCEED)             \
+                                               goto finish;                    
                                    \
+                               }                                               
                            \
+                       } else { /* single value, ie no ordering */             
                        \
+                               if((*atomcmp)(curval, nil) == 0)                
                            \
+                                       has_nils = true;                        
                                \
+                               for(i=0; i<cnt; i++)                            
                            \
+                                       if ((gdk_res = BUNappend(r, curval, 
false)) != GDK_SUCCEED)             \
+                                               goto finish;                    
                                    \
+                       }                                                       
                        \
+               }                                                               
                    \
+       }                                                                       
                \
+finish:                                                                        
             \
+       BATsetcount(r, cnt);                                                    
                \
+       r->tnonil = !has_nils;                                                  
                \
+       r->tnil = has_nils;                                                     
                \
+       return gdk_res;                                                         
                \
+}
+
+ANALYTICAL_LIMIT(min, MIN, >)
+ANALYTICAL_LIMIT(max, MAX, <)
+
+#undef ANALYTICAL_LIMIT
+#undef ANALYTICAL_LIMIT_IMP_HUGE
+#undef ANALYTICAL_LIMIT_IMP
+
+#define ANALYTICAL_ADD_WITH_CHECK(lft, rgt, TPE2, dst, max, on_overflow) \
+       do {                                                            \
+               if ((rgt) < 1) {                                        \
+                       if (-(max) - (rgt) > (lft)) {                   \
+                               on_overflow;                    \
+                       } else {                                        \
+                               (dst) = (TPE2) (lft) + (rgt);           \
+                       }                                               \
+               } else {                                                \
+                       if ((max) - (rgt) < (lft)) {                    \
+                               on_overflow;                    \
+                       } else {                                        \
+                               (dst) = (TPE2) (lft) + (rgt);           \
+                       }                                               \
+               }                                                       \
+       } while (0);
+
+#define ANALYTICAL_SUM_IMP(TPE1, TPE2)                              \
+       do {                                                            \
+               TPE1 *bp;                                                   \
+               TPE2 *rp, *rb, curval;                                      \
+               bp = (TPE1*)Tloc(b, 0);                                     \
+               rb = rp = (TPE2*)Tloc(r, 0);                                \
+               curval = TPE2##_nil;                                        \
+               if (p) {                                                    \
+                       if (o) {                                                
\
+                               np = (bit*)Tloc(p, 0);                          
    \
+                               for(i=0; i<cnt; i++, np++, rp++, bp++) {        
    \
+                                       if (*np) {                              
        \
+                                               if(is_##TPE2##_nil(curval))     
            \
+                                                       has_nils = true;        
                \
+                                               for (;rb < rp; rb++)            
            \
+                                                       *rb = curval;           
                \
+                                               curval = TPE2##_nil;            
            \
+                                       }                                       
        \
+                                       if (!is_##TPE1##_nil(*bp)) {            
        \
+                                               if(is_##TPE2##_nil(curval))     
            \
+                                                       curval = (TPE2) *bp;    
                \
+                                               else                            
            \
+                                                       
ANALYTICAL_ADD_WITH_CHECK(*bp, curval,  \
+                                                                               
   TPE2, curval,            \
+                                                                               
   GDK_##TPE2##_max,        \
+                                                                               
   goto calc_overflow);     \
+                                       }                                       
        \
+                               }                                               
    \
+                               if(is_##TPE2##_nil(curval))                     
    \
+                                       has_nils = true;                        
        \
+                               for (;rb < rp; rb++)                            
    \
+                                       *rb = curval;                           
        \
+                       } else { /* single value, ie no ordering */             
\
+                               np = (bit*)Tloc(p, 0);                          
    \
+                               for(i=0; i<cnt; i++, np++, rp++, bp++) {        
    \
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to