Changeset: 3d50efb8bee1 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=3d50efb8bee1
Added Files:
        sql/server/rel_statistics_functions.c
Modified Files:
        sql/server/CMakeLists.txt
        sql/server/rel_statistics.c
        sql/server/rel_statistics.h
Branch: properties
Log Message:

Move function statistics propagation to a different translation unit. Limit 
types for min/max propagation to numeric and temporal types


diffs (truncated from 542 to 300 lines):

diff --git a/sql/server/CMakeLists.txt b/sql/server/CMakeLists.txt
--- a/sql/server/CMakeLists.txt
+++ b/sql/server/CMakeLists.txt
@@ -45,7 +45,7 @@ target_sources(sqlserver
   rel_rewriter.c
   rel_unnest.c
   rel_optimizer.c
-  rel_statistics.c
+  rel_statistics.c rel_statistics_functions.c
   rel_partition.c
   rel_planner.c rel_planner.h
   rel_distribute.c
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
@@ -10,95 +10,7 @@
 #include "monetdb_config.h"
 #include "rel_statistics.h"
 #include "rel_optimizer.h"
-#include "rel_rel.h"
-#include "rel_exp.h"
-#include "rel_prop.h"
 #include "rel_rewriter.h"
-#include "sql_mvc.h"
-
-static inline void
-set_max_of_values(mvc *sql, sql_exp *e, rel_prop kind, ValPtr lval, ValPtr 
rval)
-{
-       prop *p;
-       ValRecord res;
-
-       VARcalcgt(&res, lval, rval);
-       p = e->p = prop_create(sql->sa, kind, e->p);
-       p->value = res.val.btval == 1 ? lval : rval;
-}
-
-static inline void
-set_min_of_values(mvc *sql, sql_exp *e, rel_prop kind, ValPtr lval, ValPtr 
rval)
-{
-       prop *p;
-       ValRecord res;
-
-       VARcalcgt(&res, lval, rval);
-       p = e->p = prop_create(sql->sa, kind, e->p);
-       p->value = res.val.btval == 1 ? rval : lval;
-}
-
-static inline void
-copy_property(mvc *sql, sql_exp *e, rel_prop kind, ValPtr val)
-{
-       prop *p = e->p = prop_create(sql->sa, kind, e->p);
-       p->value = val;
-}
-
-static sql_hash *sql_functions_lookup = NULL;
-
-static void
-sql_add_propagate_statistics(mvc *sql, sql_exp *e)
-{
-       list *l = e->l;
-       sql_exp *first = l->h->data, *second = l->h->next->data;
-       ValPtr lval, rval;
-
-       if ((lval = find_prop_and_get(first->p, PROP_MAX)) && (rval = 
find_prop_and_get(second->p, PROP_MAX))) {
-               ValPtr res = (ValPtr) sa_zalloc(sql->sa, sizeof(ValRecord));
-               res->vtype = lval->vtype;
-               if (VARcalcadd(res, lval, rval, true) == GDK_SUCCEED) {
-                       copy_property(sql, e, PROP_MAX, res);
-               } else {
-                       GDKclrerr();
-                       atom *a = atom_max_value(sql->sa, exp_subtype(first));
-                       copy_property(sql, e, PROP_MAX, &a->data);
-               }
-       }
-       if ((lval = find_prop_and_get(first->p, PROP_MIN)) && (rval = 
find_prop_and_get(second->p, PROP_MIN))) {
-               ValPtr res = (ValPtr) sa_zalloc(sql->sa, sizeof(ValRecord));
-               res->vtype = lval->vtype;
-               if (VARcalcadd(res, lval, rval, true) == GDK_SUCCEED) {
-                       copy_property(sql, e, PROP_MIN, res);
-               } else {
-                       GDKclrerr();
-                       atom *a = atom_max_value(sql->sa, exp_subtype(first));
-                       copy_property(sql, e, PROP_MIN, &a->data);
-               }
-       }
-}
-
-typedef void (*lookup_function) (mvc*, sql_exp*);
-
-static struct function_properties {
-       const char *name;
-       lookup_function func;
-} functions_list[1] = {
-       {"sql_add", &sql_add_propagate_statistics}
-};
-
-void
-initialize_sql_functions_lookup(sql_allocator *sa)
-{
-       int nentries = sizeof(functions_list) / sizeof(functions_list[0]);
-
-       sql_functions_lookup = hash_new(sa, nentries, (fkeyvalue)&hash_key);
-       for (int i = 0; i < nentries ; i++) {
-               int key = hash_key(functions_list[i].name);
-
-               hash_add(sql_functions_lookup, key, &(functions_list[i]));
-       }
-}
 
 static bool
 exps_have_or(list *exps)
@@ -153,9 +65,9 @@ rel_propagate_column_ref_statistics(mvc 
 
                                                if ((ne = 
comparison_find_column(le, e)) || (rne = comparison_find_column(re, e))) {
                                                        if 
(is_outerjoin(rel->op)) {
-                                                               if ((lval = 
find_prop_and_get(ne ? ne->p : rne->p, PROP_MAX)))
+                                                               if ((lval = 
find_prop_and_get(le ? le->p : re->p, PROP_MAX)))
                                                                        
copy_property(sql, e, PROP_MAX, lval);
-                                                               if ((lval = 
find_prop_and_get(ne ? ne->p : rne->p, PROP_MIN)))
+                                                               if ((lval = 
find_prop_and_get(le ? le->p : re->p, PROP_MIN)))
                                                                        
copy_property(sql, e, PROP_MIN, lval);
                                                        } else {
                                                                if ((lval = 
find_prop_and_get(le->p, PROP_MAX)) && (rval = find_prop_and_get(re->p, 
PROP_MAX)))
@@ -171,9 +83,9 @@ rel_propagate_column_ref_statistics(mvc 
 
                                                if ((ne = 
comparison_find_column(le, e)) || (rne = comparison_find_column(re, e))) {
                                                        if 
(is_outerjoin(rel->op)) {
-                                                               if ((lval = 
find_prop_and_get(ne ? ne->p : rne->p, PROP_MAX)))
+                                                               if ((lval = 
find_prop_and_get(le ? le->p : re->p, PROP_MAX)))
                                                                        
copy_property(sql, e, PROP_MAX, lval);
-                                                               if ((lval = 
find_prop_and_get(ne ? ne->p : rne->p, PROP_MIN)))
+                                                               if ((lval = 
find_prop_and_get(le ? le->p : re->p, PROP_MIN)))
                                                                        
copy_property(sql, e, PROP_MIN, lval);
                                                        } else {
                                                                if ((lval = 
find_prop_and_get(le->p, PROP_MAX)) && (rval = find_prop_and_get(re->p, 
PROP_MAX)))
@@ -191,9 +103,9 @@ rel_propagate_column_ref_statistics(mvc 
                                                assert(!comp->f);
                                                if ((ne = 
comparison_find_column(le, e)) || (rne = comparison_find_column(re, e))) {
                                                        if 
(is_outerjoin(rel->op)) {
-                                                               if ((lval = 
find_prop_and_get(ne ? ne->p : rne->p, PROP_MAX)))
+                                                               if ((lval = 
find_prop_and_get(le ? le->p : re->p, PROP_MAX)))
                                                                        
copy_property(sql, e, PROP_MAX, lval);
-                                                               if ((lval = 
find_prop_and_get(ne ? ne->p : rne->p, PROP_MIN)))
+                                                               if ((lval = 
find_prop_and_get(le ? le->p : re->p, PROP_MIN)))
                                                                        
copy_property(sql, e, PROP_MIN, lval);
                                                        } else if (ne) {
                                                                if ((lval = 
find_prop_and_get(le->p, PROP_MAX)))
@@ -215,9 +127,9 @@ rel_propagate_column_ref_statistics(mvc 
 
                                                if ((ne = 
comparison_find_column(le, e)) || (rne = comparison_find_column(re, e)) || (fe 
&& (fne = comparison_find_column(fe, e)))) {
                                                        if 
(is_outerjoin(rel->op)) {
-                                                               if ((lval = 
find_prop_and_get(ne ? ne->p : rne ? rne->p : fne->p, PROP_MAX)))
+                                                               if ((lval = 
find_prop_and_get(le ? le->p : re ? re->p : fe->p, PROP_MAX)))
                                                                        
copy_property(sql, e, PROP_MAX, lval);
-                                                               if ((lval = 
find_prop_and_get(ne ? ne->p : rne ? rne->p : fne->p, PROP_MIN)))
+                                                               if ((lval = 
find_prop_and_get(le ? le->p : re ? re->p : fe->p, PROP_MIN)))
                                                                        
copy_property(sql, e, PROP_MIN, lval);
                                                        } else if (ne) {
                                                                if (fe) { /* 
range case */
@@ -305,12 +217,12 @@ rel_basetable_get_statistics(visitor *v,
 
                if (has_nil(e) && mvc_has_no_nil(sql, c))
                        set_has_no_nil(e);
-
-               if ((max = mvc_has_max_value(sql, c))) {
+ 
+               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))) {
                        prop *p = e->p = prop_create(sql->sa, PROP_MAX, e->p);
                        p->value = max;
                }
-               if ((min = mvc_has_min_value(sql, c))) {
+               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))) {
                        prop *p = e->p = prop_create(sql->sa, PROP_MIN, e->p);
                        p->value = min;
                }
@@ -349,128 +261,131 @@ rel_propagate_statistics(visitor *v, sql
 {
        mvc *sql = v->sql;
        ValPtr lval;
+       sql_subtype *tp = exp_subtype(e);
 
        (void) depth;
-       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)
+       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:
                                (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:
-                       (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);
-
-               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)) {
-                                       ValPtr res = (ValPtr) 
sa_zalloc(sql->sa, sizeof(ValRecord));
-                                       VALcopy(res, lval);
-                                       if (VALconvert(to->type->localtype, 
res))
-                                               copy_property(sql, e, PROP_MAX, 
res);
-                               } else {
-                                       copy_property(sql, e, PROP_MAX, lval);
-                               }
+                               break;
+                       default:
+                               break;
                        }
-                       if ((lval = find_prop_and_get(l->p, PROP_MIN))) {
-                               if (EC_NUMBER(from->type->eclass)) {
-                                       ValPtr res = (ValPtr) 
sa_zalloc(sql->sa, sizeof(ValRecord));
-                                       VALcopy(res, lval);
-                                       if (VALconvert(to->type->localtype, 
res))
-                                               copy_property(sql, e, PROP_MIN, 
res);
-                               } else {
-                                       copy_property(sql, e, PROP_MIN, lval);
-                               }
-                       }
-               }
-       } 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;
+               } break;
+               case e_convert: {
+                       sql_subtype *from = exp_fromtype(e), *to = 
exp_totype(e);
 
-                               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) {
-                               copy_property(sql, e, PROP_MAX, &a->data);
-                               copy_property(sql, e, PROP_MIN, &a->data);
-                       }
-               } else if (e->f) {
-                       list *vals = (list *) e->f;
-                       sql_exp *first = vals->h ? vals->h->data : NULL;
-                       ValPtr 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 && 
min && max; n = n->next) {
-                               sql_exp *ee = n->data;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to