Changeset: d7c66455ff97 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d7c66455ff97 Modified Files: sql/server/rel_statistics.c sql/server/rel_statistics_functions.c Branch: properties Log Message:
Some fixes to sql functions and conversions statitistics propagation diffs (298 lines): diff --git a/sql/server/rel_statistics.c b/sql/server/rel_statistics.c --- a/sql/server/rel_statistics.c +++ b/sql/server/rel_statistics.c @@ -28,10 +28,8 @@ static sql_exp * comparison_find_column(sql_exp *input, sql_exp *e) { switch (input->type) { - case e_convert: /* if the conversion is for a different SQL class, the min and max cannot be converted */ - if (((sql_subtype*)exp_fromtype(input))->type->eclass == ((sql_subtype*)exp_totype(input))->type->eclass) - return comparison_find_column(input->l, e); - return NULL; + case e_convert: + return comparison_find_column(input->l, e) ? input : NULL; case e_column: return exp_match(e, input) ? input : NULL; default: @@ -218,11 +216,11 @@ rel_basetable_get_statistics(visitor *v, if (has_nil(e) && mvc_has_no_nil(sql, c)) set_has_no_nil(e); - if ((EC_NUMBER(c->type.type->eclass) || EC_TEMP_NOFRAC(c->type.type->eclass) || c->type.type->eclass == EC_DATE) && (max = mvc_has_max_value(sql, c))) { + if ((max = mvc_has_max_value(sql, c))) { prop *p = e->p = prop_create(sql->sa, PROP_MAX, e->p); p->value = atom_general_ptr(sql->sa, &c->type, max); } - if ((EC_NUMBER(c->type.type->eclass) || EC_TEMP_NOFRAC(c->type.type->eclass) || c->type.type->eclass == EC_DATE) && (min = mvc_has_min_value(sql, c))) { + if ((min = mvc_has_min_value(sql, c))) { prop *p = e->p = prop_create(sql->sa, PROP_MIN, e->p); p->value = atom_general_ptr(sql->sa, &c->type, min); } @@ -261,126 +259,113 @@ rel_propagate_statistics(visitor *v, sql { mvc *sql = v->sql; atom *lval; - sql_subtype *tp = exp_subtype(e); (void) depth; - if (tp && (EC_NUMBER(tp->type->eclass) || EC_TEMP_NOFRAC(tp->type->eclass) || tp->type->eclass == EC_DATE)) { - switch(e->type) { - case e_column: { - switch (rel->op) { - case op_join: - case op_left: - case op_right: - case op_full: { - sql_exp *found = rel_propagate_column_ref_statistics(sql, rel->l, e); - if (!found) - (void) rel_propagate_column_ref_statistics(sql, rel->r, e); - } break; - case op_semi: - case op_select: - case op_project: - case op_groupby: - (void) rel_propagate_column_ref_statistics(sql, rel->l, e); - break; - case op_insert: - case op_update: - case op_delete: + switch(e->type) { + case e_column: { + switch (rel->op) { + case op_join: + case op_left: + case op_right: + case op_full: { + sql_exp *found = rel_propagate_column_ref_statistics(sql, rel->l, e); + if (!found) (void) rel_propagate_column_ref_statistics(sql, rel->r, e); - break; - default: - break; - } } break; - case e_convert: { - sql_subtype *from = exp_fromtype(e), *to = exp_totype(e); + case op_semi: + case op_select: + case op_project: + case op_groupby: + (void) rel_propagate_column_ref_statistics(sql, rel->l, e); + break; + case op_insert: + case op_update: + case op_delete: + (void) rel_propagate_column_ref_statistics(sql, rel->r, e); + break; + default: + break; + } + } break; + case e_convert: { + sql_subtype *to = exp_totype(e); + sql_exp *l = e->l; + + if ((lval = find_prop_and_get(l->p, PROP_MAX))) { + atom *res = atom_dup(sql->sa, lval); + if (atom_cast(sql->sa, res, to)) + set_property(sql, e, PROP_MAX, res); + } + if ((lval = find_prop_and_get(l->p, PROP_MIN))) { + atom *res = atom_dup(sql->sa, lval); + if (atom_cast(sql->sa, res, to)) + set_property(sql, e, PROP_MIN, res); + } + } break; + case e_aggr: + case e_func: { + sql_subfunc *f = e->f; - if (from->type->eclass == to->type->eclass) { - sql_exp *l = e->l; - if ((lval = find_prop_and_get(l->p, PROP_MAX))) { - if (EC_NUMBER(from->type->eclass)) { - atom *res = atom_dup(sql->sa, lval); - if (atom_cast(sql->sa, res, to)) - set_property(sql, e, PROP_MAX, res); + if (!f->func->s) { + int key = hash_key(f->func->base.name); /* Using hash lookup */ + sql_hash_e *he = sql_functions_lookup->buckets[key&(sql_functions_lookup->size-1)]; + lookup_function look = NULL; + + for (; he && !look; he = he->chain) { + struct function_properties* fp = (struct function_properties*) he->value; + + if (!strcmp(f->func->base.name, fp->name)) + look = fp->func; + } + if (look) + look(sql, e); + } + } break; + case e_atom: { + if (e->l) { + atom *a = (atom*) e->l; + if (!a->isnull) { + set_property(sql, e, PROP_MAX, a); + set_property(sql, e, PROP_MIN, a); + } + } else if (e->f) { + list *vals = (list *) e->f; + sql_exp *first = vals->h ? vals->h->data : NULL; + atom *max = NULL, *min = NULL; /* all child values must have a valid min/max */ + + if (first) { + max = ((lval = find_prop_and_get(first->p, PROP_MAX))) ? lval : NULL; + min = ((lval = find_prop_and_get(first->p, PROP_MIN))) ? lval : NULL; + } + + for (node *n = vals->h ? vals->h->next : NULL ; n ; n = n->next) { + sql_exp *ee = n->data; + + if (max) { + if ((lval = find_prop_and_get(ee->p, PROP_MAX))) { + max = atom_cmp(lval, max) > 0 ? lval : max; } else { - set_property(sql, e, PROP_MAX, lval); + max = NULL; } } - if ((lval = find_prop_and_get(l->p, PROP_MIN))) { - if (EC_NUMBER(from->type->eclass)) { - atom *res = atom_dup(sql->sa, lval); - if (atom_cast(sql->sa, res, to)) - set_property(sql, e, PROP_MIN, res); + if (min) { + if ((lval = find_prop_and_get(ee->p, PROP_MIN))) { + min = atom_cmp(min, lval) > 0 ? lval : min; } else { - set_property(sql, e, PROP_MIN, lval); + min = NULL; } } } - } break; - case e_aggr: - case e_func: { - sql_subfunc *f = e->f; - if (!f->func->s) { - int key = hash_key(f->func->base.name); /* Using hash lookup */ - sql_hash_e *he = sql_functions_lookup->buckets[key&(sql_functions_lookup->size-1)]; - lookup_function look = NULL; - - for (; he && !look; he = he->chain) { - struct function_properties* fp = (struct function_properties*) he->value; - - if (!strcmp(f->func->base.name, fp->name)) - look = fp->func; - } - if (look) - look(sql, e); - } - } break; - case e_atom: { - if (e->l) { - atom *a = (atom*) e->l; - if (!a->isnull) { - set_property(sql, e, PROP_MAX, a); - set_property(sql, e, PROP_MIN, a); - } - } else if (e->f) { - list *vals = (list *) e->f; - sql_exp *first = vals->h ? vals->h->data : NULL; - atom *max = NULL, *min = NULL; /* all child values must have a valid min/max */ - - if (first) { - max = ((lval = find_prop_and_get(first->p, PROP_MAX))) ? lval : NULL; - min = ((lval = find_prop_and_get(first->p, PROP_MIN))) ? lval : NULL; - } - - for (node *n = vals->h ? vals->h->next : NULL ; n ; n = n->next) { - sql_exp *ee = n->data; - - if (max) { - if ((lval = find_prop_and_get(ee->p, PROP_MAX))) { - max = atom_cmp(lval, max) > 0 ? lval : max; - } else { - max = NULL; - } - } - if (min) { - if ((lval = find_prop_and_get(ee->p, PROP_MIN))) { - min = atom_cmp(min, lval) > 0 ? lval : min; - } else { - min = NULL; - } - } - } - - if (max) - set_property(sql, e, PROP_MAX, max); - if (min) - set_property(sql, e, PROP_MIN, min); - } - } break; - case e_cmp: /* propagating min and max of booleans is not very worth it */ - case e_psm: - break; + if (max) + set_property(sql, e, PROP_MAX, max); + if (min) + set_property(sql, e, PROP_MIN, min); } + } break; + case e_cmp: /* propagating min and max of booleans is not very worth it */ + case e_psm: + break; } return e; } 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 @@ -142,12 +142,12 @@ sql_neg_propagate_statistics(mvc *sql, s if ((lval = find_prop_and_get(first->p, PROP_MIN))) { atom *res = atom_dup(sql->sa, lval); - if (atom_neg(res)) + if (!atom_neg(res)) set_property(sql, e, PROP_MAX, res); } if ((lval = find_prop_and_get(first->p, PROP_MAX))) { atom *res = atom_dup(sql->sa, lval); - if (atom_neg(res)) + if (!atom_neg(res)) set_property(sql, e, PROP_MIN, res); } } @@ -189,8 +189,8 @@ sql_abs_propagate_statistics(mvc *sql, s atom *omin, *omax; if ((omin = find_prop_and_get(first->p, PROP_MIN)) && (omax = find_prop_and_get(first->p, PROP_MAX))) { - atom *zero1 = atom_zero_value(sql->sa, &(omin->tpe)); - int cmp1 = atom_cmp(omax, zero1), cmp2 = atom_cmp(omin, zero1); + atom *zero = atom_zero_value(sql->sa, &(omin->tpe)); + int cmp1 = atom_cmp(omax, zero), cmp2 = atom_cmp(omin, zero); if (cmp1 >= 0 && cmp2 >= 0) { set_property(sql, e, PROP_MAX, omax); @@ -198,10 +198,17 @@ sql_abs_propagate_statistics(mvc *sql, s } else if (cmp1 < 0 && cmp2 < 0) { atom *res1 = atom_dup(sql->sa, omin), *res2 = atom_dup(sql->sa, omax); - if (atom_absolute(res1) && atom_absolute(res2)) { + if (!atom_absolute(res1) && !atom_absolute(res2)) { set_property(sql, e, PROP_MAX, res1); set_property(sql, e, PROP_MIN, res2); } + } else { + atom *res1 = atom_dup(sql->sa, omin); + + if (!atom_absolute(res1)) { + set_property(sql, e, PROP_MAX, atom_cmp(res1, omax) > 0 ? res1 : omax); + set_property(sql, e, PROP_MIN, zero); + } } } } _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list