Changeset: d69c8565459b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d69c8565459b
Modified Files:
        sql/server/rel_select.c
        sql/test/analytics/Tests/analytics14.sql
        sql/test/analytics/Tests/analytics14.stable.err
        sql/test/analytics/Tests/analytics14.stable.out
Branch: statistics-analytics
Log Message:

Improved window function not found error message


diffs (214 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
@@ -4431,6 +4431,28 @@ get_window_clauses(mvc *sql, char* ident
        return window_specification; /* return something to say there were no 
errors */
 }
 
+static char*
+window_function_arg_types_2str(list* types, int N)
+{
+       char *arg_list = NULL;
+       int i = 0;
+
+       for (node *n = types->h; n && i < N; n = n->next) {
+               char *tpe = subtype2string((sql_subtype *) n->data);
+               
+               if (arg_list) {
+                       char *t = arg_list;
+                       arg_list = sql_message("%s, %s", arg_list, tpe);
+                       _DELETE(t);
+                       _DELETE(tpe);
+               } else {
+                       arg_list = tpe;
+               }
+               i++;
+       }
+       return arg_list;
+}
+
 /*
  * select x, y, rank_op() over (partition by x order by y) as, ...
                 aggr_op(z) over (partition by y order by x) as, ...
@@ -4460,7 +4482,7 @@ rel_rankop(sql_query *query, sql_rel **r
        list *gbe = NULL, *obe = NULL, *args = NULL, *types = NULL, *fargs = 
NULL;
        sql_schema *s = sql->session->schema;
        dnode *dn = window_function->data.lval->h, *dargs = NULL;
-       int distinct = 0, frame_type, pos, nf = f;
+       int distinct = 0, frame_type, pos, nf = f, nfargs = 0;
        bool is_nth_value, supports_frames;
 
        stack_clear_frame_visited_flag(sql); /* clear visited flags before 
iterating */
@@ -4550,7 +4572,6 @@ rel_rankop(sql_query *query, sql_rel **r
                bool is_ntile = (strcmp(s->base.name, "sys") == 0 && 
strcmp(aname, "ntile") == 0),
                         is_lag = (strcmp(s->base.name, "sys") == 0 && 
strcmp(aname, "lag") == 0),
                         is_lead = (strcmp(s->base.name, "sys") == 0 && 
strcmp(aname, "lead") == 0);
-               int nfargs = 0;
 
                if (!dl || is_ntile) { /* pass an input column for analytic 
functions that don't require it */
                        in = rel_first_column(sql, p);
@@ -4597,17 +4618,15 @@ rel_rankop(sql_query *query, sql_rel **r
                        }
                dargs = dn->next->next;
        } else { /* aggregation function call */
-               bool has_args = false;
-
                for (dargs = dn->next ; dargs->next && dargs->data.sym ; dargs 
= dargs->next) { /* the last dnode is the distinct flag */
                        exp_kind ek = {type_value, card_column, FALSE};
 
-                       has_args = true;
                        in = rel_value_exp2(query, &p, dargs->data.sym, f | 
sql_window, ek);
                        if (!in)
                                return NULL;
 
                        append(fargs, in);
+                       nfargs++;
                        if (strcmp(s->base.name, "sys") == 0 && strcmp(aname, 
"count") == 0) {
                                sql_subtype *empty = 
sql_bind_localtype("void"), *bte = sql_bind_localtype("bte");
                                sql_exp *eo = fargs->h->data;
@@ -4619,7 +4638,7 @@ rel_rankop(sql_query *query, sql_rel **r
                        in = exp_ref_save(sql, in);
                }
 
-               if (!has_args) { /* count(*) */
+               if (!nfargs) { /* count(*) */
                        in = rel_first_column(sql, p);
                        if (!exp_name(in))
                                exp_label(sql->sa, in, ++sql->label);
@@ -4651,7 +4670,7 @@ rel_rankop(sql_query *query, sql_rel **r
                                df = bind_func(sql, s, "diff", exp_subtype(e), 
NULL, F_ANALYTIC);
                        }
                        if (!df)
-                               return sql_error(sql, 02, SQLSTATE(42000) 
"SELECT: function '%s' not found", "diff" );
+                               return sql_error(sql, 02, SQLSTATE(42000) 
"SELECT: function 'diff' not found");
                        append(args, e);
                        pe = exp_op(sql->sa, args, df);
                }
@@ -4675,7 +4694,7 @@ rel_rankop(sql_query *query, sql_rel **r
                                df = bind_func(sql, s, "diff", exp_subtype(e), 
NULL, F_ANALYTIC);
                        }
                        if (!df)
-                               return sql_error(sql, 02, SQLSTATE(42000) 
"SELECT: function '%s' not found", "diff" );
+                               return sql_error(sql, 02, SQLSTATE(42000) 
"SELECT: function 'diff' not found");
                        append(args, e);
                        oe = exp_op(sql->sa, args, df);
                }
@@ -4784,10 +4803,17 @@ rel_rankop(sql_query *query, sql_rel **r
                        }
                        if (wf && list_length(nexps))
                                fargs = nexps;
-                       else
-                               return sql_error(sql, 02, SQLSTATE(42000) 
"SELECT: function '%s' not found", aname );
+                       else {
+                               char *arg_list = 
window_function_arg_types_2str(types, nfargs);
+                               sql_error(sql, 02, SQLSTATE(42000) "SELECT: 
window function '%s(%s)' not found", aname, arg_list);
+                               _DELETE(arg_list);
+                               return NULL;
+                       }
                } else {
-                       return sql_error(sql, 02, SQLSTATE(42000) "SELECT: 
function '%s' not found", aname );
+                       char *arg_list = window_function_arg_types_2str(types, 
nfargs);
+                       sql_error(sql, 02, SQLSTATE(42000) "SELECT: window 
function '%s(%s)' not found", aname, arg_list);
+                       _DELETE(arg_list);
+                       return NULL;
                }
        }
        args = sa_list(sql->sa);
diff --git a/sql/test/analytics/Tests/analytics14.sql 
b/sql/test/analytics/Tests/analytics14.sql
--- a/sql/test/analytics/Tests/analytics14.sql
+++ b/sql/test/analytics/Tests/analytics14.sql
@@ -44,6 +44,12 @@ select var_pop(cc) over (partition by bb
 select var_pop(cc) over (partition by bb order by bb desc) from analytics;
 select var_pop(cc) over (order by bb desc) from analytics;
 
+
+select stddev_samp(aa) over () from analytics;
+select stddev_pop(aa) over () from analytics;
+select var_samp(aa) over () from analytics;
+select var_pop(aa) over () from analytics;
+
 create table stressme (aa varchar(64), bb int);
 insert into stressme values ('one', 1), ('another', 1), ('stress', 1), (NULL, 
2), ('ok', 2), ('check', 3), ('me', 3), ('please', 3), (NULL, 4);
 
diff --git a/sql/test/analytics/Tests/analytics14.stable.err 
b/sql/test/analytics/Tests/analytics14.stable.err
--- a/sql/test/analytics/Tests/analytics14.stable.err
+++ b/sql/test/analytics/Tests/analytics14.stable.err
@@ -27,7 +27,7 @@ stderr of test 'analytics14` in director
 
 MAPI  = (monetdb) /var/tmp/mtest-97238/.s.monetdb.32728
 QUERY = select stddev_samp(aa) over (partition by bb) from stressme; --error, 
stddev_samp not available for string type
-ERROR = !SELECT: function 'stddev_samp' not found
+ERROR = !SELECT: window function 'stddev_samp(varchar(64))' not found
 CODE  = 42000
 
 # 11:24:49 >  
diff --git a/sql/test/analytics/Tests/analytics14.stable.out 
b/sql/test/analytics/Tests/analytics14.stable.out
--- a/sql/test/analytics/Tests/analytics14.stable.out
+++ b/sql/test/analytics/Tests/analytics14.stable.out
@@ -547,6 +547,66 @@ stdout of test 'analytics14` in director
 [ 15.4375      ]
 [ 15.4375      ]
 [ 15.4375      ]
+#select stddev_samp(aa) over () from analytics;
+% sys. # table_name
+% %1 # name
+% double # type
+% 24 # length
+[ 4.200340122  ]
+[ 4.200340122  ]
+[ 4.200340122  ]
+[ 4.200340122  ]
+[ 4.200340122  ]
+[ 4.200340122  ]
+[ 4.200340122  ]
+[ 4.200340122  ]
+[ 4.200340122  ]
+[ 4.200340122  ]
+#select stddev_pop(aa) over () from analytics;
+% sys. # table_name
+% %1 # name
+% double # type
+% 24 # length
+[ 3.929058411  ]
+[ 3.929058411  ]
+[ 3.929058411  ]
+[ 3.929058411  ]
+[ 3.929058411  ]
+[ 3.929058411  ]
+[ 3.929058411  ]
+[ 3.929058411  ]
+[ 3.929058411  ]
+[ 3.929058411  ]
+#select var_samp(aa) over () from analytics;
+% sys. # table_name
+% %1 # name
+% double # type
+% 24 # length
+[ 17.64285714  ]
+[ 17.64285714  ]
+[ 17.64285714  ]
+[ 17.64285714  ]
+[ 17.64285714  ]
+[ 17.64285714  ]
+[ 17.64285714  ]
+[ 17.64285714  ]
+[ 17.64285714  ]
+[ 17.64285714  ]
+#select var_pop(aa) over () from analytics;
+% sys. # table_name
+% %1 # name
+% double # type
+% 24 # length
+[ 15.4375      ]
+[ 15.4375      ]
+[ 15.4375      ]
+[ 15.4375      ]
+[ 15.4375      ]
+[ 15.4375      ]
+[ 15.4375      ]
+[ 15.4375      ]
+[ 15.4375      ]
+[ 15.4375      ]
 #create table stressme (aa varchar(64), bb int);
 #insert into stressme values ('one', 1), ('another', 1), ('stress', 1), (NULL, 
2), ('ok', 2), ('check', 3), ('me', 3), ('please', 3), (NULL, 4);
 [ 9    ]
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to