Changeset: 50fa819b01c1 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=50fa819b01c1
Modified Files:
        monetdb5/optimizer/opt_prelude.c
        monetdb5/optimizer/opt_prelude.h
        monetdb5/optimizer/opt_support.c
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_rank.c
        sql/backends/monet5/sql_rank.h
        sql/backends/monet5/sql_rank.mal
        sql/backends/monet5/sql_rank.mal.sh
        sql/backends/monet5/sql_rank_hge.mal
        sql/backends/monet5/sql_rank_hge.mal.sh
        sql/common/sql_types.c
        sql/include/sql_catalog.h
        sql/server/rel_select.c
        sql/test/analytics/Tests/analytics07.sql
        sql/test/analytics/Tests/analytics07.stable.out
Branch: analytics
Log Message:

Cleaned code generation for window bounds, because the range bound with CURRENT 
ROW has a different meaning, and the current implementation was incompatible 
for temporal types.

Now instead of having separate MAL calls for FOLLOWING and PRECEDING bounds, 
join both together.


diffs (truncated from 1393 to 300 lines):

diff --git a/monetdb5/optimizer/opt_prelude.c b/monetdb5/optimizer/opt_prelude.c
--- a/monetdb5/optimizer/opt_prelude.c
+++ b/monetdb5/optimizer/opt_prelude.c
@@ -310,8 +310,7 @@ str unpinRef;
 str updateRef;
 str userRef;
 str vectorRef;
-str window_following_boundRef;
-str window_preceding_boundRef;
+str window_boundRef;
 str wlcRef;
 str wlrRef;
 str zero_or_oneRef;
@@ -617,8 +616,7 @@ void optimizerInit(void)
        updateRef = putName("update");
        userRef = putName("user");
        vectorRef = putName("vector");
-       window_following_boundRef = putName("window_following_bound");
-       window_preceding_boundRef = putName("window_preceding_bound");
+       window_boundRef = putName("window_bound");
        wlcRef = putName("wlc");
        wlrRef = putName("wlr");
        zero_or_oneRef = putName("zero_or_one");
diff --git a/monetdb5/optimizer/opt_prelude.h b/monetdb5/optimizer/opt_prelude.h
--- a/monetdb5/optimizer/opt_prelude.h
+++ b/monetdb5/optimizer/opt_prelude.h
@@ -310,8 +310,7 @@ mal_export  str unpinRef;
 mal_export  str updateRef;
 mal_export  str userRef;
 mal_export  str vectorRef;
-mal_export  str window_following_boundRef;
-mal_export  str window_preceding_boundRef;
+mal_export  str window_boundRef;
 mal_export  str wlcRef;
 mal_export  str wlrRef;
 mal_export  str zero_or_oneRef;
diff --git a/monetdb5/optimizer/opt_support.c b/monetdb5/optimizer/opt_support.c
--- a/monetdb5/optimizer/opt_support.c
+++ b/monetdb5/optimizer/opt_support.c
@@ -521,8 +521,7 @@ isOrderDepenent(InstrPtr p)
        if( getModuleId(p) != batsqlRef)
                return 0;
        if ( getFunctionId(p) == differenceRef ||
-               getFunctionId(p) == window_following_boundRef ||
-               getFunctionId(p) == window_preceding_boundRef ||
+               getFunctionId(p) == window_boundRef ||
                getFunctionId(p) == row_numberRef ||
                getFunctionId(p) == rankRef ||
                getFunctionId(p) == dense_rankRef ||
diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -499,7 +499,7 @@ exp_bin(backend *be, sql_exp *e, stmt *l
                                else if(f->func->type == F_ANALYTIC && 
es->nrcols == 0) {
                                        if(en == exps->h)
                                                es = stmt_const(be, 
bin_first_column(be, left), es); /* ensure the first argument is a column */
-                                       if((!strcmp(f->func->base.name, 
"window_preceding_bound") || !strcmp(f->func->base.name, 
"window_following_bound"))
+                                       if((!strcmp(f->func->base.name, 
"window_bound"))
                                                && exps->h->next && 
list_length(f->func->ops) == 6 && en == exps->h->next)
                                                es = stmt_const(be, 
bin_first_column(be, left), es);
                                }
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
@@ -73,47 +73,56 @@ SQLdiff(Client cntxt, MalBlkPtr mb, MalS
        is_negative = vlimit->val.MEMBER < 0; \
        limit = &vlimit->val.MEMBER; \
 
-static str
-doSQLwindowbound(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, bool 
preceding, const str mod)
+str
+SQLwindow_bound(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
-       bool has_partitions = (pci->argc > 6);
-       lng first_half = *getArgReference_lng(stk, pci, has_partitions ? 5 : 4);
        str msg = MAL_SUCCEED;
+       bool preceding;
+       lng first_half;
+       int unit, bound, excl, part_offset = (pci->argc > 6);
+
+       if ((pci->argc != 6 && pci->argc != 7) || getArgType(mb, pci, 
part_offset + 2) != TYPE_int ||
+               getArgType(mb, pci, part_offset + 3) != TYPE_int || 
getArgType(mb, pci, part_offset + 4) != TYPE_int) {
+               throw(SQL, "sql.window_bound", SQLSTATE(42000) "Invalid 
arguments");
+       }
+
+       unit = *getArgReference_int(stk, pci, part_offset + 2);
+       bound = *getArgReference_int(stk, pci, part_offset + 3);
+       excl = *getArgReference_int(stk, pci, part_offset + 4);
+
+       assert(unit >= 0 && unit <= 3);
+       assert(bound >= 0 && bound <= 5);
+       assert(excl >= 0 && excl <= 2);
+       preceding = (bound % 2 == 0);
+       first_half = (bound < 2 || bound == 4);
 
        (void)cntxt;
        if (isaBatType(getArgType(mb, pci, 1))) {
                bat *res = getArgReference_bat(stk, pci, 0);
-               BAT *b = BATdescriptor(*getArgReference_bat(stk, pci, 
has_partitions ? 2 : 1)), *p = NULL, *r, *l = NULL;
-               int unit = *getArgReference_int(stk, pci, has_partitions ? 3 : 
2),
-                       excl = *getArgReference_int(stk, pci, has_partitions ? 
4 : 3),
-                       limit_pos = has_partitions ? 6 : 5,
-                       tp1 = getBatType(getArgType(mb, pci, has_partitions ? 2 
: 1)),
-                       tp2 = getArgType(mb, pci, limit_pos);
+               BAT *b = BATdescriptor(*getArgReference_bat(stk, pci, 
part_offset + 1)), *p = NULL, *r, *l = NULL;
+               int tp1 = getBatType(getArgType(mb, pci, part_offset + 1)), tp2 
= getArgType(mb, pci, part_offset + 5);
                void* limit = NULL;
                bool is_negative = false, is_null = false, is_a_bat;
                gdk_return gdk_code;
 
-               assert(unit >= 0 && unit <= 3);
-               assert(excl >= 0 && excl <= 2);
-
                if (!b)
-                       throw(SQL, mod, SQLSTATE(HY005) "Cannot access column 
descriptor");
+                       throw(SQL, "sql.window_bound", SQLSTATE(HY005) "Cannot 
access column descriptor");
 
                if (excl != 0) {
                        BBPunfix(b->batCacheid);
-                       throw(SQL, mod, SQLSTATE(42000) "Only EXCLUDE NO OTHERS 
exclusion is currently implemented");
+                       throw(SQL, "sql.window_bound", SQLSTATE(42000) "Only 
EXCLUDE NO OTHERS exclusion is currently implemented");
                }
 
                is_a_bat = isaBatType(tp2);
                if(is_a_bat)
                        tp2 = getBatType(tp2);
 
-               voidresultBAT(r, TYPE_lng, BATcount(b), b, mod);
-               if(is_a_bat) {
-                       l = BATdescriptor(*getArgReference_bat(stk, pci, 
limit_pos));
+               voidresultBAT(r, TYPE_lng, BATcount(b), b, "sql.window_bound");
+               if(is_a_bat) { //SQL_CURRENT_ROW shall never fall in limit 
validation
+                       l = BATdescriptor(*getArgReference_bat(stk, pci, 
part_offset + 5));
                        if (!l) {
                                BBPunfix(b->batCacheid);
-                               throw(SQL, mod, SQLSTATE(HY005) "Cannot access 
column descriptor");
+                               throw(SQL, "sql.window_bound", SQLSTATE(HY005) 
"Cannot access column descriptor");
                        }
                        switch (tp2) {
                                case TYPE_bte:
@@ -142,18 +151,18 @@ doSQLwindowbound(Client cntxt, MalBlkPtr
                                default: {
                                        BBPunfix(b->batCacheid);
                                        BBPunfix(l->batCacheid);
-                                       throw(SQL, mod, SQLSTATE(42000) "%s 
limit not available for %s", mod, ATOMname(tp2));
+                                       throw(SQL, "sql.window_bound", 
SQLSTATE(42000) "%s limit not available for %s", "sql.window_bound", 
ATOMname(tp2));
                                }
                        }
                        if(is_null || is_negative) {
                                BBPunfix(b->batCacheid);
                                BBPunfix(l->batCacheid);
                                if(is_null)
-                                       throw(SQL, mod, SQLSTATE(HY005) "All 
values on %s boundary must be non-null", preceding ? "PRECEDING" : "FOLLOWING");
-                               throw(SQL, mod, SQLSTATE(HY005) "All values on 
%s boundary must be non-negative", preceding ? "PRECEDING" : "FOLLOWING");
+                                       throw(SQL, "sql.window_bound", 
SQLSTATE(HY005) "All values on %s boundary must be non-null", preceding ? 
"PRECEDING" : "FOLLOWING");
+                               throw(SQL, "sql.window_bound", SQLSTATE(HY005) 
"All values on %s boundary must be non-negative", preceding ? "PRECEDING" : 
"FOLLOWING");
                        }
                } else {
-                       ValRecord *vlimit = &(stk)->stk[(pci)->argv[limit_pos]];
+                       ValRecord *vlimit = &(stk)->stk[(pci)->argv[part_offset 
+ 5]];
 
                        switch (tp2) {
                                case TYPE_bte:
@@ -181,24 +190,25 @@ doSQLwindowbound(Client cntxt, MalBlkPtr
 #endif
                                default: {
                                        BBPunfix(b->batCacheid);
-                                       throw(SQL, mod, SQLSTATE(42000) "%s 
limit is not available for %s", mod, ATOMname(tp2));
+                                       throw(SQL, "sql.window_bound", 
SQLSTATE(42000) "%s limit is not available for %s", "sql.window_bound", 
ATOMname(tp2));
                                }
                        }
                        if(is_null)
-                               throw(SQL, mod, SQLSTATE(42000) "The %s 
boundary must be non-null", preceding ? "PRECEDING" : "FOLLOWING");
+                               throw(SQL, "sql.window_bound", SQLSTATE(42000) 
"The %s boundary must be non-null", preceding ? "PRECEDING" : "FOLLOWING");
                        if(is_negative)
-                               throw(SQL, mod, SQLSTATE(42000) "The %s 
boundary must be non-negative", preceding ? "PRECEDING" : "FOLLOWING");
+                               throw(SQL, "sql.window_bound", SQLSTATE(42000) 
"The %s boundary must be non-negative", preceding ? "PRECEDING" : "FOLLOWING");
                }
-               if (has_partitions) {
+               if (part_offset) {
                        p = BATdescriptor(*getArgReference_bat(stk, pci, 1));
                        if (!p) {
                                if(l) BBPunfix(l->batCacheid);
                                BBPunfix(b->batCacheid);
-                               throw(SQL, mod, SQLSTATE(HY005) "Cannot access 
column descriptor");
+                               throw(SQL, "sql.window_bound", SQLSTATE(HY005) 
"Cannot access column descriptor");
                        }
                }
 
-               if((tp1 == TYPE_daytime || tp1 == TYPE_date || tp1 == 
TYPE_timestamp) && unit == 1) { //only for RANGE frame
+               //On RANGE frame, when "CURRENT ROW" is not specified, the 
ranges are calculated with SQL intervals in mind
+               if((tp1 == TYPE_daytime || tp1 == TYPE_date || tp1 == 
TYPE_timestamp) && unit == 1 && bound < 4) {
                        msg = MTIMEanalyticalrangebounds(r, b, p, l, limit, 
tp1, tp2, preceding, first_half);
                        if(msg == MAL_SUCCEED)
                                BBPkeepref(*res = r->batCacheid);
@@ -207,7 +217,7 @@ doSQLwindowbound(Client cntxt, MalBlkPtr
                        if(gdk_code == GDK_SUCCEED)
                                BBPkeepref(*res = r->batCacheid);
                        else
-                               msg = createException(SQL, mod, GDK_EXCEPTION);
+                               msg = createException(SQL, "sql.window_bound", 
GDK_EXCEPTION);
                }
                if(l) BBPunfix(l->batCacheid);
                if(p) BBPunfix(p->batCacheid);
@@ -220,18 +230,6 @@ doSQLwindowbound(Client cntxt, MalBlkPtr
        return msg;
 }
 
-str
-SQLwindow_preceding_bound(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci)
-{
-       return doSQLwindowbound(cntxt, mb, stk, pci, true, 
"sql.window_preceding_bound");
-}
-
-str
-SQLwindow_following_bound(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci)
-{
-       return doSQLwindowbound(cntxt, mb, stk, pci, false, 
"sql.window_following_bound");
-}
-
 str 
 SQLrow_number(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
diff --git a/sql/backends/monet5/sql_rank.h b/sql/backends/monet5/sql_rank.h
--- a/sql/backends/monet5/sql_rank.h
+++ b/sql/backends/monet5/sql_rank.h
@@ -12,8 +12,7 @@
 #include "sql.h"
 
 sql5_export str SQLdiff(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci);
-sql5_export str SQLwindow_preceding_bound(Client cntxt, MalBlkPtr mb, 
MalStkPtr stk, InstrPtr pci);
-sql5_export str SQLwindow_following_bound(Client cntxt, MalBlkPtr mb, 
MalStkPtr stk, InstrPtr pci);
+sql5_export str SQLwindow_bound(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 sql5_export str SQLrow_number(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 sql5_export str SQLrank(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci);
 sql5_export str SQLdense_rank(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
@@ -24,299 +24,155 @@ pattern batsql.diff(p:bat[:bit], b:bat[:
 address SQLdiff
 comment "return true if cur != prev row";
 
-pattern sql.window_preceding_bound(b:any_1, unit:int, excl:int, fh:lng, 
start:bte) :lng
-address SQLwindow_preceding_bound
-comment "computes the start ranges for each row";
+pattern sql.window_bound(b:any_1, unit:int, bound:int, excl:int, limit:bte) 
:lng
+address SQLwindow_bound
+comment "computes window ranges for each row";
 
-pattern batsql.window_preceding_bound(b:bat[:any_1], unit:int, excl:int, 
fh:lng, start:bte) :bat[:lng]
-address SQLwindow_preceding_bound
-comment "computes the start ranges for each row";
+pattern batsql.window_bound(b:bat[:any_1], unit:int, bound:int, excl:int, 
limit:bte) :bat[:lng]
+address SQLwindow_bound
+comment "computes window ranges for each row";
 
-pattern sql.window_preceding_bound(p:bit, b:any_1, unit:int, excl:int, fh:lng, 
start:bte) :lng
-address SQLwindow_preceding_bound
-comment "computes the start ranges for each row";
+pattern sql.window_bound(p:bit, b:any_1, unit:int, bound:int, excl:int, 
limit:bte) :lng
+address SQLwindow_bound
+comment "computes window ranges for each row";
 
-pattern batsql.window_preceding_bound(p:bat[:bit], b:bat[:any_1], unit:int, 
excl:int, fh:lng, start:bte) :bat[:lng]
-address SQLwindow_preceding_bound
-comment "computes the start ranges for each row";
+pattern batsql.window_bound(p:bat[:bit], b:bat[:any_1], unit:int, bound:int, 
excl:int, limit:bte) :bat[:lng]
+address SQLwindow_bound
+comment "computes window ranges for each row";
 
-pattern batsql.window_preceding_bound(b:bat[:any_1], unit:int, excl:int, 
fh:lng, start:bat[:bte]) :bat[:lng]
-address SQLwindow_preceding_bound
-comment "computes the start ranges for each row";
+pattern batsql.window_bound(b:bat[:any_1], unit:int, bound:int, excl:int, 
limit:bat[:bte]) :bat[:lng]
+address SQLwindow_bound
+comment "computes window ranges for each row";
 
-pattern batsql.window_preceding_bound(p:bat[:bit], b:bat[:any_1], unit:int, 
excl:int, fh:lng, start:bat[:bte]) :bat[:lng]
-address SQLwindow_preceding_bound
-comment "computes the start ranges for each row";
+pattern batsql.window_bound(p:bat[:bit], b:bat[:any_1], unit:int, bound:int, 
excl:int, limit:bat[:bte]) :bat[:lng]
+address SQLwindow_bound
+comment "computes window ranges for each row";
 
 
-pattern sql.window_following_bound(b:any_1, unit:int, excl:int, fh:lng, 
end:bte) :lng
-address SQLwindow_following_bound
-comment "computes the end ranges for each row";
-
-pattern batsql.window_following_bound(b:bat[:any_1], unit:int, excl:int, 
fh:lng, end:bte) :bat[:lng]
-address SQLwindow_following_bound
-comment "computes the end ranges for each row";
-
-pattern sql.window_following_bound(p:bit, b:any_1, unit:int, excl:int, fh:lng, 
end:bte) :lng
-address SQLwindow_following_bound
-comment "computes the end ranges for each row";
+pattern sql.window_bound(b:any_1, unit:int, bound:int, excl:int, limit:sht) 
:lng
+address SQLwindow_bound
+comment "computes window ranges for each row";
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to