Changeset: 5c6a19af8f86 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5c6a19af8f86
Modified Files:
        sql/server/rel_select.c
        sql/test/Tests/window_functions.stable.out
        sql/test/analytics/Tests/analytics02.sql
        sql/test/analytics/Tests/analytics02.stable.err
Branch: Oct2020
Log Message:

Backport window-tunning fixes into Oct2020


diffs (184 lines):

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
@@ -4407,26 +4407,26 @@ generate_window_bound_call(mvc *sql, sql
        return e; /* return something to say there were no errors */
 }
 
+#define EC_NUMERIC(e) (e==EC_NUM||EC_INTERVAL(e)||e==EC_DEC||e==EC_FLT)
+
 static sql_exp*
 calculate_window_bound(sql_query *query, sql_rel *p, tokens token, symbol 
*bound, sql_exp *ie, int frame_type, int f)
 {
        mvc *sql = query->sql;
        sql_subtype *bt, *it = sql_bind_localtype("int"), *lon = 
sql_bind_localtype("lng"), *iet;
-       sql_class bclass = EC_ANY;
        sql_exp *res = NULL;
 
        if ((bound->token == SQL_PRECEDING || bound->token == SQL_FOLLOWING || 
bound->token == SQL_CURRENT_ROW) && bound->type == type_int) {
                atom *a = NULL;
                bt = (frame_type == FRAME_ROWS || frame_type == FRAME_GROUPS) ? 
lon : exp_subtype(ie);
-               bclass = bt->type->eclass;
 
                if ((bound->data.i_val == UNBOUNDED_PRECEDING_BOUND || 
bound->data.i_val == UNBOUNDED_FOLLOWING_BOUND)) {
-                       if (EC_NUMBER(bclass))
+                       if (EC_NUMBER(bt->type->eclass))
                                a = atom_general(sql->sa, bt, NULL);
                        else
                                a = atom_general(sql->sa, it, NULL);
                } else if (bound->data.i_val == CURRENT_ROW_BOUND) {
-                       if (EC_NUMBER(bclass))
+                       if (EC_NUMBER(bt->type->eclass))
                                a = atom_zero_value(sql->sa, bt);
                        else
                                a = atom_zero_value(sql->sa, it);
@@ -4451,40 +4451,24 @@ calculate_window_bound(sql_query *query,
                                return NULL;
                        bt = exp_subtype(res);
                }
-               bclass = bt->type->eclass;
-               if (!(bclass == EC_NUM || EC_INTERVAL(bclass) || bclass == 
EC_DEC || bclass == EC_FLT))
+               if (!EC_NUMERIC(bt->type->eclass))
                        return sql_error(sql, 02, SQLSTATE(42000) "%s offset 
must be of a countable SQL type", bound_desc);
-               if ((frame_type == FRAME_ROWS || frame_type == FRAME_GROUPS) && 
bclass != EC_NUM) {
-                       char *err = subtype2string2(sql->ta, bt);
-                       if (!err)
-                               return sql_error(sql, 02, SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
-                       (void) sql_error(sql, 02, SQLSTATE(42000) "Values on %s 
boundary on %s frame can't be %s type", bound_desc,
-                                                        (frame_type == 
FRAME_ROWS) ? "rows":"groups", err);
-                       sa_reset(sql->ta);
+               if (exp_is_null(res))
+                       return sql_error(sql, 02, SQLSTATE(42000) "%s offset 
must not be NULL", bound_desc);
+               if ((frame_type == FRAME_ROWS || frame_type == FRAME_GROUPS) && 
bt->type->eclass != EC_NUM && !(res = exp_check_type(sql, lon, p, res, 
type_equal)))
                        return NULL;
-               }
                if (frame_type == FRAME_RANGE) {
-                       if (bclass == EC_FLT && iet->type->eclass != EC_FLT)
-                               return sql_error(sql, 02, SQLSTATE(42000) 
"Values in input aren't floating-point while on %s boundary are", bound_desc);
-                       if (bclass != EC_FLT && iet->type->eclass == EC_FLT)
-                               return sql_error(sql, 02, SQLSTATE(42000) 
"Values on %s boundary aren't floating-point while on input are", bound_desc);
-                       if (bclass == EC_DEC && iet->type->eclass != EC_DEC)
-                               return sql_error(sql, 02, SQLSTATE(42000) 
"Values in input aren't decimals while on %s boundary are", bound_desc);
-                       if (bclass != EC_DEC && iet->type->eclass == EC_DEC)
-                               return sql_error(sql, 02, SQLSTATE(42000) 
"Values on %s boundary aren't decimals while on input are", bound_desc);
-                       if (bclass != EC_SEC && iet->type->eclass == EC_TIME) {
-                               char *err = subtype2string2(sql->ta, iet);
-                               if (!err)
-                                       return sql_error(sql, 02, 
SQLSTATE(HY013) MAL_MALLOC_FAIL);
-                               (void) sql_error(sql, 02, SQLSTATE(42000) "For 
%s input the %s boundary must be an interval type up to the day", err, 
bound_desc);
+                       sql_class iet_class = iet->type->eclass;
+
+                       if (EC_NUMERIC(iet_class) && !(res = 
exp_check_type(sql, iet, p, res, type_equal)))
+                               return NULL;
+                       if ((iet_class == EC_TIME || iet_class == EC_TIME_TZ) 
&& bt->type->eclass != EC_SEC) {
+                               (void) sql_error(sql, 02, SQLSTATE(42000) "For 
%s input the %s boundary must be an interval type up to the day", 
subtype2string2(sql->ta, iet), bound_desc);
                                sa_reset(sql->ta);
                                return NULL;
                        }
-                       if (EC_INTERVAL(bclass) && !EC_TEMP(iet->type->eclass)) 
{
-                               char *err = subtype2string2(sql->ta, iet);
-                               if (!err)
-                                       return sql_error(sql, 02, 
SQLSTATE(HY013) MAL_MALLOC_FAIL);
-                               (void) sql_error(sql, 02, SQLSTATE(42000) "For 
%s input the %s boundary must be an interval type", err, bound_desc);
+                       if (EC_TEMP(iet->type->eclass) && 
!EC_INTERVAL(bt->type->eclass)) {
+                               (void) sql_error(sql, 02, SQLSTATE(42000) "For 
%s input the %s boundary must be an interval type", subtype2string2(sql->ta, 
iet), bound_desc);
                                sa_reset(sql->ta);
                                return NULL;
                        }
@@ -4810,6 +4794,20 @@ rel_rankop(sql_query *query, sql_rel **r
        if (frame_clause || supports_frames)
                ie = exp_copy(sql, obe ? (sql_exp*) obe->t->data : in);
 
+       if (!supports_frames) {
+               append(fargs, pe);
+               append(fargs, oe);
+       }
+
+       types = exp_types(sql->sa, fargs);
+       if (!(wf = bind_func_(sql, s, aname, types, F_ANALYTIC))) {
+               wf = find_func(sql, s, aname, list_length(types), F_ANALYTIC, 
NULL);
+               if (!wf || (!(fargs = 
check_arguments_and_find_largest_any_type(sql, NULL, fargs, wf, 0)))) {
+                       char *arg_list = nfargs ? 
window_function_arg_types_2str(sql, types, nfargs) : NULL;
+                       return sql_error(sql, 02, SQLSTATE(42000) "SELECT: 
window function '%s(%s)' not found", aname, arg_list ? arg_list : "");
+               }
+       }
+
        /* Frame */
        if (frame_clause) {
                dnode *d = frame_clause->data.lval->h;
@@ -4859,7 +4857,7 @@ rel_rankop(sql_query *query, sql_rel **r
 
                bt = (frame_type == FRAME_ROWS || frame_type == FRAME_GROUPS) ? 
lon : exp_subtype(ie);
                sclass = bt->type->eclass;
-               if (sclass == EC_POS || sclass == EC_NUM || sclass == EC_DEC || 
EC_INTERVAL(sclass)) {
+               if (EC_NUMERIC(sclass)) {
                        fstart = exp_null(sql->sa, bt);
                        if (order_by_clause)
                                fend = exp_atom(sql->sa, 
atom_zero_value(sql->sa, bt));
@@ -4892,19 +4890,6 @@ rel_rankop(sql_query *query, sql_rel **r
        if (eend && !exp_name(eend))
                exp_label(sql->sa, eend, ++sql->label);
 
-       if (!supports_frames) {
-               append(fargs, pe);
-               append(fargs, oe);
-       }
-
-       types = exp_types(sql->sa, fargs);
-       if (!(wf = bind_func_(sql, s, aname, types, F_ANALYTIC))) {
-               wf = find_func(sql, s, aname, list_length(types), F_ANALYTIC, 
NULL);
-               if (!wf || (!(fargs = 
check_arguments_and_find_largest_any_type(sql, NULL, fargs, wf, 0)))) {
-                       char *arg_list = nfargs ? 
window_function_arg_types_2str(sql, types, nfargs) : NULL;
-                       return sql_error(sql, 02, SQLSTATE(42000) "SELECT: 
window function '%s(%s)' not found", aname, arg_list ? arg_list : "");
-               }
-       }
        args = sa_list(sql->sa);
        for (node *n = fargs->h ; n ; n = n->next)
                append(args, n->data);
diff --git a/sql/test/Tests/window_functions.stable.out 
b/sql/test/Tests/window_functions.stable.out
--- a/sql/test/Tests/window_functions.stable.out
+++ b/sql/test/Tests/window_functions.stable.out
@@ -166,11 +166,11 @@ stdout of test 'window_functions` in dir
 % 20,  10,     9,      9 # length
 [ 3.000,       "Management",   4000.00,        4000.00 ]
 [ 2.000,       "Management",   4400.00,        4400.00 ]
-[ 1.000,       "Management",   4500.00,        4500.00 ]
+[ 1.000,       "Management",   4500.00,        8900.00 ]
 [ 5.000,       "Production",   3500.00,        3500.00 ]
-[ 6.000,       "Production",   3600.00,        3600.00 ]
-[ 4.000,       "Production",   3700.00,        3700.00 ]
-[ 7.000,       "Production",   3800.00,        3800.00 ]
+[ 6.000,       "Production",   3600.00,        7100.00 ]
+[ 4.000,       "Production",   3700.00,        7300.00 ]
+[ 7.000,       "Production",   3800.00,        7500.00 ]
 [ 8.000,       "Production",   4000.00,        4000.00 ]
 [ 11.000,      "Sales",        4100.00,        4100.00 ]
 [ 10.000,      "Sales",        4300.00,        4300.00 ]
diff --git a/sql/test/analytics/Tests/analytics02.sql 
b/sql/test/analytics/Tests/analytics02.sql
--- a/sql/test/analytics/Tests/analytics02.sql
+++ b/sql/test/analytics/Tests/analytics02.sql
@@ -163,6 +163,8 @@ select dense_rank() over (rows 200 prece
 select ntile(1) over (rows 200 preceding) from analytics; --error
 select lead(aa) over (partition by bb order by bb rows between 2 preceding and 
0 following) from analytics; --error
 
+select last_value() over () from analytics; --error, function not found
+
 prepare select count(*) over (partition by ?) from analytics; --error
 
 drop table analytics;
diff --git a/sql/test/analytics/Tests/analytics02.stable.err 
b/sql/test/analytics/Tests/analytics02.stable.err
--- a/sql/test/analytics/Tests/analytics02.stable.err
+++ b/sql/test/analytics/Tests/analytics02.stable.err
@@ -44,7 +44,11 @@ MAPI  = (monetdb) /var/tmp/mtest-13031/.
 QUERY = select lead(aa) over (partition by bb order by bb rows between 2 
preceding and 0 following) from analytics; --error
 ERROR = !OVER: frame extend only possible with aggregation and first_value, 
last_value and nth_value functions
 CODE  = 42000
-MAPI  = (monetdb) /var/tmp/mtest-193075/.s.monetdb.38205
+MAPI  = (monetdb) /var/tmp/mtest-157754/.s.monetdb.38461
+QUERY = select last_value() over () from analytics; --error, function not found
+ERROR = !SELECT: window function 'last_value()' not found
+CODE  = 42000
+MAPI  = (monetdb) /var/tmp/mtest-157754/.s.monetdb.38461
 QUERY = prepare select count(*) over (partition by ?) from analytics; --error
 ERROR = !SELECT: parameters not allowed at PARTITION BY clause from window 
functions
 CODE  = 42000
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to