Changeset: 0e24a02a3d8d for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=0e24a02a3d8d Modified Files: sql/server/rel_select.c sql/server/rel_statistics_functions.c Branch: properties Log Message:
Fix min/max propagation for ifthenelse and casewhen functions. Their number of arguments may vary diffs (107 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 @@ -3837,8 +3837,7 @@ rel_case(sql_query *query, sql_rel **rel append(args, result); } assert(res); - if (res) - list_append(args, res); + list_append(args, res); list *types = sa_list(sql->sa); if (!opt_cond_exp) types = append(sa_list(sql->sa), condtype); diff --git a/sql/server/rel_statistics_functions.c b/sql/server/rel_statistics_functions.c --- a/sql/server/rel_statistics_functions.c +++ b/sql/server/rel_statistics_functions.c @@ -270,7 +270,72 @@ static void sql_ifthenelse_propagate_statistics(mvc *sql, sql_exp *e) { list *l = e->l; - sql_extend_min_max(sql, e, l->h->next->data, l->h->next->next->data); + sql_exp *first = l->h->next->data; + atom *curmin = NULL, *curmax = NULL, *lval; + unsigned int i = 0; + + assert(list_length(l) >= 2); + if ((lval = find_prop_and_get(first->p, PROP_MAX))) + curmax = lval; + if ((lval = find_prop_and_get(first->p, PROP_MIN))) + curmin = lval; + for (node *n = l->h->next->next ; n && curmin && curmax ; n = n->next) { + if ((i & 1) || n == l->t) { /* the last expression, ie the result, must be included */ + sql_exp *next = n->data; + if ((lval = find_prop_and_get(next->p, PROP_MAX))) { + curmax = atom_cmp(lval, curmax) > 0 ? lval : curmax; + } else { + curmax = NULL; + } + if ((lval = find_prop_and_get(next->p, PROP_MIN))) { + curmin = atom_cmp(lval, curmin) > 0 ? curmin : lval; + } else { + curmin = NULL; + } + } + i++; + } + + if (curmin && curmax) { + set_property(sql, e, PROP_MAX, curmax); + set_property(sql, e, PROP_MIN, curmin); + } +} + +static void +sql_casewhen_propagate_statistics(mvc *sql, sql_exp *e) +{ + list *l = e->l; + sql_exp *first = l->h->next->next->data; + atom *curmin = NULL, *curmax = NULL, *lval; + unsigned int i = 0; + + assert(list_length(l) >= 3); + if ((lval = find_prop_and_get(first->p, PROP_MAX))) + curmax = lval; + if ((lval = find_prop_and_get(first->p, PROP_MIN))) + curmin = lval; + for (node *n = l->h->next->next->next ; n && curmin && curmax ; n = n->next) { + if ((i & 1) || n == l->t) { /* the last expression, ie the result, must be included */ + sql_exp *next = n->data; + if ((lval = find_prop_and_get(next->p, PROP_MAX))) { + curmax = atom_cmp(lval, curmax) > 0 ? lval : curmax; + } else { + curmax = NULL; + } + if ((lval = find_prop_and_get(next->p, PROP_MIN))) { + curmin = atom_cmp(lval, curmin) > 0 ? curmin : lval; + } else { + curmin = NULL; + } + } + i++; + } + + if (curmin && curmax) { + set_property(sql, e, PROP_MAX, curmax); + set_property(sql, e, PROP_MIN, curmin); + } } static void @@ -618,7 +683,7 @@ sql_min_max_propagate_statistics(mvc *sq } } -static struct function_properties functions_list[33] = { +static struct function_properties functions_list[34] = { /* arithmetic functions */ {"sql_add", &sql_add_propagate_statistics}, {"sql_sub", &sql_sub_propagate_statistics}, @@ -636,6 +701,7 @@ static struct function_properties functi {"ifthenelse", &sql_ifthenelse_propagate_statistics}, {"nullif", &sql_nullif_propagate_statistics}, {"coalesce", &sql_coalesce_propagate_statistics}, + {"casewhen", &sql_casewhen_propagate_statistics}, /* time functions */ {"century", &sql_century_propagate_statistics}, _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list