Changeset: 538ab4144c72 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=538ab4144c72 Modified Files: sql/server/rel_select.c sql/test/analytics/Tests/analytics01.sql sql/test/analytics/Tests/analytics01.stable.err sql/test/analytics/Tests/analytics01.stable.out Branch: analytics Log Message:
Fix for lag and lead analytical functions calls where the 3rd argument must have the same type as the 1st argument. diffs (114 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 @@ -4726,15 +4726,19 @@ rel_rankop(mvc *sql, sql_rel **rel, symb fargs = sa_list(sql->sa); if (window_function->token == SQL_RANK) { //rank function call dlist* dnn = window_function->data.lval->h->next->data.lval; - bool is_ntile = (strcmp(s->base.name, "sys") == 0 && strcmp(aname, "ntile") == 0); - - if(!dnn || is_ntile) { + 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(!dnn || is_ntile) { //pass an input column for analytic functions that don't require it sql_rel *lr = p->l; in = lr->exps->h->data; in = exp_column(sql->sa, exp_relname(in), exp_name(in), exp_subtype(in), exp_card(in), has_nil(in), is_intern(in)); if(!in) return NULL; append(fargs, in); + nfargs++; } if(dnn) { for(dnode *nn = dnn->h ; nn ; nn = nn->next) { @@ -4743,22 +4747,26 @@ rel_rankop(mvc *sql, sql_rel **rel, symb in = rel_value_exp2(sql, &p, nn->data.sym, f, ek, &is_last); if(!in) return NULL; - - if(is_ntile) { /* ntile only has one argument and in null case this cast should be done */ + if(is_ntile && nfargs == 1) { //ntile first argument null handling case sql_subtype *empty = sql_bind_localtype("void"); if(subtype_cmp(&(in->tpe), empty) == 0) { sql_subtype *to = sql_bind_localtype("bte"); in = exp_convert(sql->sa, in, empty, to); } - } else if(is_nth_value && dnn->h && nn == dnn->h->next) { /* corner case for nth_value */ + } else if(is_nth_value && nfargs == 1) { //nth_value second argument null handling case sql_subtype *empty = sql_bind_localtype("void"); if(subtype_cmp(&(in->tpe), empty) == 0) { sql_rel *lr = p->l; sql_exp *ep = lr->exps->h->data; in = exp_convert(sql->sa, in, empty, &(ep->tpe)); } + } else if((is_lag || is_lead) && nfargs == 2) { //lag and lead 3rd arg must have same type as 1st arg + sql_exp *first = (sql_exp*) fargs->h->data; + if(!(in = rel_check_type(sql, &first->tpe, in, type_equal))) + return NULL; } append(fargs, in); + nfargs++; } } } else { //aggregation function call diff --git a/sql/test/analytics/Tests/analytics01.sql b/sql/test/analytics/Tests/analytics01.sql --- a/sql/test/analytics/Tests/analytics01.sql +++ b/sql/test/analytics/Tests/analytics01.sql @@ -202,6 +202,8 @@ select lead(bb) over (partition by aa or select lead(bb) over (order by aa) from stressme; select lead(bb) over (order by aa desc) from stressme; +select aa, bb, lead(aa, 2, 100) over (partition by bb), lead(aa, 1, '100') over (partition by bb) from analytics; + select nth_value(aa, aa) over () from analytics; select nth_value(1, aa) over () from analytics; @@ -212,5 +214,6 @@ select lag(null, aa) over () from analyt select lag(null, null, aa) over () from analytics; --error select lead(null, aa) over () from analytics; --error select lead(null, null, aa) over () from analytics; --error +select lead(aa, 34, 1000000000000) over (partition by bb) from analytics; --error drop table analytics; diff --git a/sql/test/analytics/Tests/analytics01.stable.err b/sql/test/analytics/Tests/analytics01.stable.err --- a/sql/test/analytics/Tests/analytics01.stable.err +++ b/sql/test/analytics/Tests/analytics01.stable.err @@ -48,6 +48,10 @@ MAPI = (monetdb) /var/tmp/mtest-1980/.s QUERY = select lead(null, null, aa) over () from analytics; --error ERROR = !types int(32,0) and any(0,0) are not equal for column 'aa' CODE = 42000 +MAPI = (monetdb) /var/tmp/mtest-21352/.s.monetdb.32874 +QUERY = select lead(aa, 34, 1000000000000) over (partition by bb) from analytics; --error +ERROR = !overflow in conversion of 1000000000000 to int. +CODE = 22003 # 16:22:53 > # 16:22:53 > "Done." diff --git a/sql/test/analytics/Tests/analytics01.stable.out b/sql/test/analytics/Tests/analytics01.stable.out --- a/sql/test/analytics/Tests/analytics01.stable.out +++ b/sql/test/analytics/Tests/analytics01.stable.out @@ -2461,6 +2461,21 @@ Ready. [ 2 ] [ 4 ] [ NULL ] +#select aa, bb, lead(aa, 2, 100) over (partition by bb), lead(aa, 1, '100') over (partition by bb) from analytics; +% sys.analytics, sys.analytics, sys.L6, sys.L12 # table_name +% aa, bb, L6, L12 # name +% int, int, int, int # type +% 2, 1, 3, 3 # length +[ 3, 1, 4, 2 ] +[ 2, 1, 100, 4 ] +[ 4, 1, 100, 100 ] +[ NULL, 2, 8, 3 ] +[ 3, 2, 100, 8 ] +[ 8, 2, 100, 100 ] +[ 15, 3, 6, 5 ] +[ 5, 3, 100, 6 ] +[ 6, 3, 100, 100 ] +[ NULL, 4, 100, 100 ] #select nth_value(aa, aa) over () from analytics; % sys.L4 # table_name % L4 # name _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list