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

Reply via email to