Changeset: 253d4c864a86 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/253d4c864a86 Modified Files: gdk/gdk_calc.c gdk/gdk_calc_private.h sql/server/rel_exp.c sql/server/rel_exp.h sql/server/rel_select.c Branch: default Log Message:
Merged with Jan2022 diffs (truncated from 564 to 300 lines): diff --git a/gdk/gdk_calc_private.h b/gdk/gdk_calc_private.h --- a/gdk/gdk_calc_private.h +++ b/gdk/gdk_calc_private.h @@ -659,7 +659,6 @@ typedef double ldouble; #ifdef TRUNCATE_NUMBERS #define rounddbl(x) (x) #else -#define rounddbl(x) roundl(x) #define rounddbl(x) round(x) #endif #else @@ -667,7 +666,13 @@ typedef long double ldouble; #ifdef TRUNCATE_NUMBERS #define rounddbl(x) (x) #else +#ifdef HAVE_HGE +/* can't round to hge via lng since we might loose significant bits, so + * just keep it long double */ +#define rounddbl(x) roundl(x) +#else /* round long double to long long int in one go */ #define rounddbl(x) llroundl(x) #endif #endif +#endif diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c --- a/sql/server/rel_exp.c +++ b/sql/server/rel_exp.c @@ -3023,13 +3023,56 @@ exps_reset_freevar(list *exps) } } -int -rel_set_type_param(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp *rel_exp, int upcast) +static int rel_find_parameter(mvc *sql, sql_subtype *type, sql_rel *rel, const char *relname, const char *expname); + +static int +set_exp_type(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp *e) { - sql_rel *r = rel; - int is_rel = exp_is_rel(rel_exp); - - if (!type || !rel_exp || (rel_exp->type != e_atom && rel_exp->type != e_column && !is_rel)) + if (mvc_highwater(sql)) { + (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space"); + return -1; + } + if (e->tpe.type) + return 0; + + if (e->type == e_column) { + const char *nrname = (const char*) e->l, *nename = (const char*) e->r; + /* find all the column references and set the type */ + if (rel_find_parameter(sql, type, rel, nrname, nename) < 0) + return -1; + e->tpe = *type; + } else if (e->type == e_atom && e->f) { + list *atoms = e->f; + if (!list_empty(atoms)) + for (node *n = atoms->h; n; n = n->next) + if (set_exp_type(sql, type, rel, n->data) < 0) /* set recursively */ + return -1; + e->tpe = *type; + } else if (e->type == e_atom && !e->l && !e->r && !e->f) { + if (set_type_param(sql, type, e->flag) != 0) + return -1; + e->tpe = *type; + } else if (exp_is_rel(e)) { /* for relation expressions, restart cycle */ + rel = (sql_rel*) e->l; + /* limiting to these cases */ + if (!is_project(rel->op) || list_length(rel->exps) != 1) + return 0; + sql_exp *re = rel->exps->h->data; + + if (set_exp_type(sql, type, rel, re) < 0) /* set recursively */ + return -1; + e->tpe = *type; + } + return 0; +} + +int +rel_set_type_param(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp *exp, int upcast) +{ + sql_exp *e = exp; + int is_rel = exp_is_rel(exp); + + if (!type || !exp || (exp->type != e_atom && exp->type != e_column && !is_rel)) return -1; /* use largest numeric types */ @@ -3039,22 +3082,10 @@ rel_set_type_param(mvc *sql, sql_subtype #else type = sql_bind_localtype("lng"); #endif - if (upcast && type->type->eclass == EC_FLT) + else if (upcast && type->type->eclass == EC_FLT) type = sql_bind_localtype("dbl"); - if (is_rel) - r = (sql_rel*) rel_exp->l; - - if ((rel_exp->type == e_atom && (rel_exp->l || rel_exp->r || rel_exp->f)) || rel_exp->type == e_column || is_rel) { - /* it's not a parameter set possible parameters below */ - const char *relname = exp_relname(rel_exp), *expname = exp_name(rel_exp); - if (rel_set_type_recurse(sql, type, r, &relname, &expname) < 0) - return -1; - } else if (set_type_param(sql, type, rel_exp->flag) != 0) - return -1; - - rel_exp->tpe = *type; - return 0; + return set_exp_type(sql, type, rel, e); } /* try to do an in-place conversion @@ -3207,199 +3238,89 @@ exp_values_set_supertype(mvc *sql, sql_e } static int -exp_set_list_recurse(mvc *sql, sql_subtype *type, sql_exp *e, const char **relname, const char** expname) -{ - if (mvc_highwater(sql)) { - (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space"); - return -1; - } - assert(*relname && *expname); - if (!e) - return 0; - - if (exp_is_rel(e)) { - /* Try to set parameters on the list of projections of the subquery. For now I won't go any further, ugh */ - sql_rel *r = exp_rel_get_rel(sql->sa, e); - if ((is_simple_project(r->op) || is_groupby(r->op)) && list_length(r->exps) == 1) { - for (node *n = r->exps->h; n; n = n->next) - if (exp_set_list_recurse(sql, type, (sql_exp *) n->data, relname, expname) < 0) - return -1; - } - } else if (e->type == e_atom) { - if (e->f) { - const char *next_rel = exp_relname(e), *next_exp = exp_name(e); - if (next_rel && next_exp && !strcmp(next_rel, *relname) && !strcmp(next_exp, *expname)) - for (node *n = ((list *) e->f)->h; n; n = n->next) - if (exp_set_list_recurse(sql, type, (sql_exp *) n->data, relname, expname) < 0) - return -1; - } - if (e->f && !e->tpe.type) { - e->tpe = *type; - } else if (!e->l && !e->r && !e->f && !e->tpe.type) { - if (set_type_param(sql, type, e->flag) == 0) - e->tpe = *type; - else - return -1; - } - } - return 0; -} - -static int -exp_set_type_recurse(mvc *sql, sql_subtype *type, sql_exp *e, const char **relname, const char** expname) +rel_find_parameter(mvc *sql, sql_subtype *type, sql_rel *rel, const char *relname, const char *expname) { if (mvc_highwater(sql)) { (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space"); return -1; } - assert(*relname && *expname); - if (!e) - return 0; - - switch (e->type) { - case e_atom: { - const char *next_exp = exp_name(e); - if (e->f || !next_exp || !strcmp(next_exp, *expname)) { - if (!e->f && next_exp) - *expname = next_exp; - return exp_set_list_recurse(sql, type, e, relname, expname); - } - } break; - case e_convert: - case e_column: { - /* if the column pretended is found, set its type */ - const char *next_rel = exp_relname(e), *next_exp = exp_name(e); - if (next_rel && *relname && !strcmp(next_rel, *relname)) { - *relname = (e->type == e_column && e->l) ? (const char*) e->l : next_rel; - if (next_exp && !strcmp(next_exp, *expname)) { - *expname = (e->type == e_column && e->r) ? (const char*) e->r : next_exp; - if (e->type == e_column && !e->tpe.type) { - if (set_type_param(sql, type, e->flag) == 0) - e->tpe = *type; - else - return -1; - } - } - } - if (e->type == e_convert) - exp_set_type_recurse(sql, type, e->l, relname, expname); - } break; - case e_psm: { - if (e->flag & PSM_RETURN) { - for(node *n = ((list*)e->r)->h ; n ; n = n->next) - exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); - } else if (e->flag & PSM_WHILE) { - exp_set_type_recurse(sql, type, e->l, relname, expname); - for(node *n = ((list*)e->r)->h ; n ; n = n->next) - exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); - } else if (e->flag & PSM_IF) { - exp_set_type_recurse(sql, type, e->l, relname, expname); - for(node *n = ((list*)e->r)->h ; n ; n = n->next) - exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); - if (e->f) - for(node *n = ((list*)e->f)->h ; n ; n = n->next) - exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); - } else if (e->flag & PSM_REL) { - rel_set_type_recurse(sql, type, e->l, relname, expname); - } else if (e->flag & PSM_EXCEPTION) { - exp_set_type_recurse(sql, type, e->l, relname, expname); - } - } break; - case e_aggr: - case e_func: { - if (e->l) - for(node *n = ((list*)e->l)->h ; n ; n = n->next) - exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); - if (e->type == e_func && e->r) - for(node *n = ((list*)e->r)->h ; n ; n = n->next) - exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); - } break; - case e_cmp: { - if (e->flag == cmp_in || e->flag == cmp_notin) { - exp_set_type_recurse(sql, type, e->l, relname, expname); - for(node *n = ((list*)e->r)->h ; n ; n = n->next) - exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); - } else if (e->flag == cmp_or || e->flag == cmp_filter) { - for(node *n = ((list*)e->l)->h ; n ; n = n->next) - exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); - for(node *n = ((list*)e->r)->h ; n ; n = n->next) - exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); - } else { - if(e->l) - exp_set_type_recurse(sql, type, e->l, relname, expname); - if(e->r) - exp_set_type_recurse(sql, type, e->r, relname, expname); - if(e->f) - exp_set_type_recurse(sql, type, e->f, relname, expname); - } - } break; - } - return 0; -} - -int -rel_set_type_recurse(mvc *sql, sql_subtype *type, sql_rel *rel, const char **relname, const char **expname) -{ - if (mvc_highwater(sql)) { - (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space"); - return -1; - } - assert(*relname && *expname); if (!rel) return 0; - if (rel->exps) - for (node *n = rel->exps->h; n; n = n->next) - exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); + const char *nrname = relname, *nename = expname; + if ((is_simple_project(rel->op) || is_groupby(rel->op)) && !list_empty(rel->exps)) { + sql_exp *e = NULL; + + if (nrname && nename) { /* find the column reference and propagate type setting */ + e = exps_bind_column2(rel->exps, nrname, nename, NULL); + } else if (nename) { + e = exps_bind_column(rel->exps, nename, NULL, NULL, 1); + } + if (!e) + return 0; + /* set order by column types */ + if (is_simple_project(rel->op) && !list_empty(rel->r)) { + sql_exp *ordere = NULL; + if (nrname && nename) { + ordere = exps_bind_column2(rel->r, nrname, nename, NULL); + } else if (nename) { + ordere = exps_bind_column(rel->r, nename, NULL, NULL, 1); + } + if (ordere && ordere->type == e_column) + ordere->tpe = *type; + } + if (e->type == e_column) { + nrname = (const char*) e->l; + nename = (const char*) e->r; + e->tpe = *type; + } else if ((e->type == e_atom || exp_is_rel(e)) && set_exp_type(sql, type, rel, e) < 0) { + return -1; /* don't search further */ + } + /* group by columns can have aliases! */ + if (is_groupby(rel->op) && !list_empty(rel->r)) { + if (nrname && nename) { + e = exps_bind_column2(rel->r, nrname, nename, NULL); + } else if (nename) { + e = exps_bind_column(rel->r, nename, NULL, NULL, 1); _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org