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 -- [email protected]
To unsubscribe send an email to [email protected]