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

Reply via email to