Changeset: 6a76eda3f5d1 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6a76eda3f5d1 Modified Files: clients/mapiclient/mhelp.c gdk/gdk_analytic_func.c sql/backends/monet5/sql_rank.c sql/common/sql_types.c sql/server/rel_select.c Branch: analytics Log Message:
Added missing SQL function prototypes, cleaned bounds type checking and compilation fixes. diffs (truncated from 336 to 300 lines): diff --git a/clients/mapiclient/mhelp.c b/clients/mapiclient/mhelp.c --- a/clients/mapiclient/mhelp.c +++ b/clients/mapiclient/mhelp.c @@ -788,7 +788,7 @@ SQLhelp sqlhelp[] = { NULL}, {"window_aggregate_function", NULL, - "{ AVG '(' query_expression ')' | COUNT '(' [ '*' | query_expression ] ')' | MAX '(' query_expression ')'\n" + "{ AVG '(' query_expression ')' | COUNT '(' { '*' | query_expression } ')' | MAX '(' query_expression ')'\n" "| MIN '(' query_expression ')' | PROD '(' query_expression ')' | SUM '(' query_expression ')' }", "query_expression", NULL}, @@ -818,7 +818,7 @@ SQLhelp sqlhelp[] = { NULL}, {"window_specification", NULL, - "[ PARTITION BY column_ref ... ]\n" + "[ PARTITION BY column_ref [ ',' ... ] ]\n" "[ ORDER BY sort_spec ]\n" "[ { ROWS | RANGE | GROUPS } { window_frame_start | BETWEEN window_bound AND window_bound }\n" " [ EXCLUDING { CURRENT ROW | GROUP | TIES | NO OTHERS } ] ]", diff --git a/gdk/gdk_analytic_func.c b/gdk/gdk_analytic_func.c --- a/gdk/gdk_analytic_func.c +++ b/gdk/gdk_analytic_func.c @@ -258,7 +258,7 @@ GDKanalyticalfirst(BAT *r, BAT *b, BAT * void *curval; for(; i<cnt; i++) { - curval = (end[i] > start[i]) ? BUNtail(bpi, start[i]) : (void*) nil; + curval = (end[i] > start[i]) ? BUNtail(bpi, (BUN)start[i]) : (void*) nil; if (BUNappend(r, curval, false) != GDK_SUCCEED) goto allocation_error; if (atomcmp(curval, nil) == 0) @@ -335,7 +335,7 @@ GDKanalyticallast(BAT *r, BAT *b, BAT *s void *curval; for(; i<cnt; i++) { - curval = (end[i] > start[i]) ? BUNtail(bpi, end[i] - 1) : (void*) nil; + curval = (end[i] > start[i]) ? BUNtail(bpi, (BUN)(end[i] - 1)) : (void*) nil; if (BUNappend(r, curval, false) != GDK_SUCCEED) goto allocation_error; if (atomcmp(curval, nil) == 0) 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 @@ -104,19 +104,6 @@ doSQLwindowbound(Client cntxt, MalBlkPtr is_a_bat = isaBatType(tpe); if(is_a_bat) tpe = getBatType(tpe); - if((unit == FRAME_ROWS || unit == FRAME_GROUPS) && (tpe == TYPE_flt || tpe == TYPE_dbl)) { - BBPunfix(b->batCacheid); - throw(SQL, mod, SQLSTATE(42000) "Values on %s boundary on %s frame can't be a floating-point type", - preceding ? "PRECEDING" : "FOLLOWING", (unit == FRAME_ROWS) ? "rows":"groups"); - } else if(unit == FRAME_RANGE && (tpe == TYPE_flt || tpe == TYPE_dbl) && (tp1 != TYPE_flt && tp1 != TYPE_dbl)) { - BBPunfix(b->batCacheid); - throw(SQL, mod, SQLSTATE(42000) "Values in the input column aren't floating-point while on %s boundary are", - preceding ? "PRECEDING" : "FOLLOWING"); - } else if(unit == FRAME_RANGE && (tp1 == TYPE_flt || tp1 == TYPE_dbl) && (tpe != TYPE_flt && tpe != TYPE_dbl)) { - BBPunfix(b->batCacheid); - throw(SQL, mod, SQLSTATE(42000) "Values on %s boundary aren't floating-point while on input column are", - preceding ? "PRECEDING" : "FOLLOWING"); - } voidresultBAT(r, TYPE_lng, BATcount(b), b, mod); if(is_a_bat) { diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c --- a/sql/common/sql_types.c +++ b/sql/common/sql_types.c @@ -1656,6 +1656,31 @@ sqltypeinit( sql_allocator *sa) sql_create_analytic5(sa, "window_preceding_bound", "sql", "window_preceding_bound", ANY, INT, INT, LNG, DBL, LNG, SCALE_NONE); sql_create_analytic6(sa, "window_preceding_bound", "sql", "window_preceding_bound", BIT, ANY, INT, INT, LNG, DBL, LNG, SCALE_NONE); + t = decimals; /* BTE */ + sql_create_analytic5(sa, "window_preceding_bound", "sql", "window_preceding_bound", ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + sql_create_analytic6(sa, "window_preceding_bound", "sql", "window_preceding_bound", BIT, ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + t++; /* SHT */ + sql_create_analytic5(sa, "window_preceding_bound", "sql", "window_preceding_bound", ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + sql_create_analytic6(sa, "window_preceding_bound", "sql", "window_preceding_bound", BIT, ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + t++; /* INT */ + sql_create_analytic5(sa, "window_preceding_bound", "sql", "window_preceding_bound", ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + sql_create_analytic6(sa, "window_preceding_bound", "sql", "window_preceding_bound", BIT, ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + t++; /* LNG */ + sql_create_analytic5(sa, "window_preceding_bound", "sql", "window_preceding_bound", ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + sql_create_analytic6(sa, "window_preceding_bound", "sql", "window_preceding_bound", BIT, ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); +#ifdef HAVE_HGE + if (have_hge) { + t++; /* HGE */ + sql_create_analytic5(sa, "window_preceding_bound", "sql", "window_preceding_bound", ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + sql_create_analytic6(sa, "window_preceding_bound", "sql", "window_preceding_bound", BIT, ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + } +#endif + + sql_create_analytic5(sa, "window_preceding_bound", "sql", "window_preceding_bound", ANY, INT, INT, LNG, MONINT, LNG, SCALE_NONE); + sql_create_analytic6(sa, "window_preceding_bound", "sql", "window_preceding_bound", BIT, ANY, INT, INT, LNG, MONINT, LNG, SCALE_NONE); + sql_create_analytic5(sa, "window_preceding_bound", "sql", "window_preceding_bound", ANY, INT, INT, LNG, SECINT, LNG, SCALE_NONE); + sql_create_analytic6(sa, "window_preceding_bound", "sql", "window_preceding_bound", BIT, ANY, INT, INT, LNG, SECINT, LNG, SCALE_NONE); + sql_create_analytic5(sa, "window_following_bound", "sql", "window_following_bound", ANY, INT, INT, LNG, BTE, LNG, SCALE_NONE); sql_create_analytic6(sa, "window_following_bound", "sql", "window_following_bound", BIT, ANY, INT, INT, LNG, BTE, LNG, SCALE_NONE); sql_create_analytic5(sa, "window_following_bound", "sql", "window_following_bound", ANY, INT, INT, LNG, SHT, LNG, SCALE_NONE); @@ -1669,6 +1694,31 @@ sqltypeinit( sql_allocator *sa) sql_create_analytic5(sa, "window_following_bound", "sql", "window_following_bound", ANY, INT, INT, LNG, DBL, LNG, SCALE_NONE); sql_create_analytic6(sa, "window_following_bound", "sql", "window_following_bound", BIT, ANY, INT, INT, LNG, DBL, LNG, SCALE_NONE); + t = decimals; /* BTE */ + sql_create_analytic5(sa, "window_following_bound", "sql", "window_following_bound", ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + sql_create_analytic6(sa, "window_following_bound", "sql", "window_following_bound", BIT, ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + t++; /* SHT */ + sql_create_analytic5(sa, "window_following_bound", "sql", "window_following_bound", ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + sql_create_analytic6(sa, "window_following_bound", "sql", "window_following_bound", BIT, ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + t++; /* INT */ + sql_create_analytic5(sa, "window_following_bound", "sql", "window_following_bound", ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + sql_create_analytic6(sa, "window_following_bound", "sql", "window_following_bound", BIT, ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + t++; /* LNG */ + sql_create_analytic5(sa, "window_following_bound", "sql", "window_following_bound", ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + sql_create_analytic6(sa, "window_following_bound", "sql", "window_following_bound", BIT, ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); +#ifdef HAVE_HGE + if (have_hge) { + t++; /* HGE */ + sql_create_analytic5(sa, "window_following_bound", "sql", "window_following_bound", ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + sql_create_analytic6(sa, "window_following_bound", "sql", "window_following_bound", BIT, ANY, INT, INT, LNG, *(t), LNG, SCALE_NONE); + } +#endif + + sql_create_analytic5(sa, "window_following_bound", "sql", "window_following_bound", ANY, INT, INT, LNG, MONINT, LNG, SCALE_NONE); + sql_create_analytic6(sa, "window_following_bound", "sql", "window_following_bound", BIT, ANY, INT, INT, LNG, MONINT, LNG, SCALE_NONE); + sql_create_analytic5(sa, "window_following_bound", "sql", "window_following_bound", ANY, INT, INT, LNG, SECINT, LNG, SCALE_NONE); + sql_create_analytic6(sa, "window_following_bound", "sql", "window_following_bound", BIT, ANY, INT, INT, LNG, SECINT, LNG, SCALE_NONE); + sql_create_analytic3(sa, "rank", "sql", "rank", ANY, BIT, BIT, INT, SCALE_NONE); sql_create_analytic3(sa, "dense_rank", "sql", "dense_rank", ANY, BIT, BIT, INT, SCALE_NONE); sql_create_analytic3(sa, "row_number", "sql", "row_number", ANY, BIT, BIT, INT, SCALE_NONE); @@ -1803,6 +1853,22 @@ sqltypeinit( sql_allocator *sa) if (have_hge) sql_create_analytic(sa, "avg", "sql", "avg", HGE, DBL, SCALE_NONE); #endif + + t = decimals; // BTE + sql_create_analytic(sa, "avg", "sql", "avg", *(t), DBL, SCALE_NONE); + t++; // SHT + sql_create_analytic(sa, "avg", "sql", "avg", *(t), DBL, SCALE_NONE); + t++; // INT + sql_create_analytic(sa, "avg", "sql", "avg", *(t), DBL, SCALE_NONE); + t++; // LNG + sql_create_analytic(sa, "avg", "sql", "avg", *(t), DBL, SCALE_NONE); +#ifdef HAVE_HGE + if (have_hge) { + t++; // HGE + sql_create_analytic(sa, "avg", "sql", "avg", *(t), DBL, SCALE_NONE); + } +#endif + sql_create_analytic(sa, "avg", "sql", "avg", FLT, DBL, SCALE_NONE); sql_create_analytic(sa, "avg", "sql", "avg", DBL, DBL, SCALE_NONE); 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 @@ -4429,7 +4429,7 @@ rel_order_by(mvc *sql, sql_rel **R, symb /* window functions */ static sql_exp* -calculate_window_bounds(mvc *sql, sql_exp **estart, sql_exp **eend, sql_schema *s, sql_exp *pe, sql_exp *e, +generate_window_bound_call(mvc *sql, sql_exp **estart, sql_exp **eend, sql_schema *s, sql_exp *pe, sql_exp *e, sql_exp *start, sql_exp *fend, int frame_type, int excl, int t1, int t2) { list *rargs1 = sa_list(sql->sa), *rargs2 = sa_list(sql->sa), *targs1 = sa_list(sql->sa), *targs2 = sa_list(sql->sa); @@ -4477,6 +4477,68 @@ calculate_window_bounds(mvc *sql, sql_ex return e; //return something to say there were no errors b:any_1, unit:int, excl:int, start:int } +static sql_exp* +calculate_window_bound(mvc *sql, sql_rel *p, int token, symbol *bound, sql_exp *ie, int frame_type, int f) +{ + sql_subtype *bt, *it = sql_bind_localtype("int"), *iet; + unsigned char bclass = 0; + 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 = 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)) + a = atom_absolute_max(sql->sa, exp_subtype(ie)); + else + a = atom_absolute_max(sql->sa, it); + } else if(bound->data.i_val == CURRENT_ROW_BOUND) { + if(EC_NUMBER(bclass)) + a = atom_zero_value(sql->sa, exp_subtype(ie)); + else + a = atom_zero_value(sql->sa, it); + } else { + assert(0); + } + res = exp_atom(sql->sa, a); + } else { //arbitrary expression case + int is_last = 0; + exp_kind ek = {type_value, card_column, FALSE}; + const char* bound_desc = (token == SQL_PRECEDING) ? "PRECEDING" : "FOLLOWING"; + iet = exp_subtype(ie); + + assert(token == SQL_PRECEDING || token == SQL_FOLLOWING); + res = rel_value_exp2(sql, &p, bound, f, ek, &is_last); + if(!res) + return NULL; + bt = exp_subtype(res); + if(bt) + bclass = bt->type->eclass; + if(!bt || !(bclass == EC_NUM || EC_INTERVAL(bclass) || bclass == EC_DEC || bclass == EC_FLT)) + 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) + return 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", subtype2string(bt)); + 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) + return sql_error(sql, 02, SQLSTATE(42000) "For %s input the %s boundary must be an interval type", subtype2string(iet), bound_desc); + if(EC_INTERVAL(bclass) && !EC_TEMP(iet->type->eclass)) + return sql_error(sql, 02, SQLSTATE(42000) "For %s input the %s boundary must be an interval type", subtype2string(iet), bound_desc); + } + } + return res; +} + /* * select x, y, rank_op() over (partition by x order by y) as, ... aggr_op(z) over (partition by y order by x) as, ... @@ -4730,12 +4792,9 @@ rel_rankop(mvc *sql, sql_rel **rel, symb /* Frame */ if(window_specification->h->next->next->data.sym) { dnode *d = window_specification->h->next->next->data.sym->data.lval->h; - exp_kind ek = {type_value, card_column, FALSE}; symbol *wstart = d->data.sym, *wend = d->next->data.sym, *rstart = wstart->data.lval->h->data.sym, *rend = wend->data.lval->h->data.sym; int excl = d->next->next->next->data.i_val; - sql_subtype* st, *et, *it = sql_bind_localtype("int"); - unsigned char sclass = 0, eclass = 0; frame_type = d->next->next->data.i_val; sql_exp *ie = obe ? obe->t->data : in; @@ -4766,70 +4825,11 @@ rel_rankop(mvc *sql, sql_rel **rel, symb frame_type = FRAME_ALL; //special case, iterate the entire partition } - //SQL keyword case - if((rstart->token == SQL_PRECEDING || rstart->token == SQL_FOLLOWING || rstart->token == SQL_CURRENT_ROW) && rstart->type == type_int) { - atom *a = NULL; - st = exp_subtype(ie); - sclass = st->type->eclass; - - if((rstart->data.i_val == UNBOUNDED_PRECEDING_BOUND || rstart->data.i_val == UNBOUNDED_FOLLOWING_BOUND)) { - if(sclass == EC_POS || sclass == EC_NUM || sclass == EC_DEC || EC_INTERVAL(sclass)) - a = atom_absolute_max(sql->sa, exp_subtype(ie)); - else - a = atom_absolute_max(sql->sa, it); - } else if(rstart->data.i_val == CURRENT_ROW_BOUND) { - if(sclass == EC_POS || sclass == EC_NUM || sclass == EC_DEC || EC_INTERVAL(sclass)) - a = atom_zero_value(sql->sa, exp_subtype(ie)); - else - a = atom_zero_value(sql->sa, it); - } else { - assert(0); - } - fstart = exp_atom(sql->sa, a); - } else { //arbitrary expression case - is_last = 0; - fstart = rel_value_exp2(sql, &p, rstart, f, ek, &is_last); - if(!fstart) - return NULL; - st = exp_subtype(fstart); - if(st) - sclass = st->type->eclass; - if(!st || !(sclass == EC_POS || sclass == EC_NUM || sclass == EC_DEC || EC_INTERVAL(sclass))) - return sql_error(sql, 02, SQLSTATE(42000) "PRECEDING offset must be of a countable SQL type"); - } - - if((rend->token == SQL_PRECEDING || rend->token == SQL_FOLLOWING || rend->token == SQL_CURRENT_ROW) && rend->type == type_int) { - atom *a = NULL; - et = exp_subtype(ie); - eclass = et->type->eclass; - - if((rend->data.i_val == UNBOUNDED_PRECEDING_BOUND || rend->data.i_val == UNBOUNDED_FOLLOWING_BOUND)) { - if(eclass == EC_POS || eclass == EC_NUM || eclass == EC_DEC || EC_INTERVAL(eclass)) - a = atom_absolute_max(sql->sa, exp_subtype(ie)); - else - a = atom_absolute_max(sql->sa, it); - } else if(rend->data.i_val == CURRENT_ROW_BOUND) { - if(eclass == EC_POS || eclass == EC_NUM || eclass == EC_DEC || EC_INTERVAL(eclass)) - a = atom_zero_value(sql->sa, exp_subtype(ie)); - else - a = atom_zero_value(sql->sa, it); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list