Changeset: 82a7525eb94a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=82a7525eb94a
Modified Files:
sql/server/rel_statistics.c
sql/server/rel_statistics.h
sql/server/sql_mvc.c
Branch: properties
Log Message:
Use hash lookup for functions statistics propagation. I only added sql_add for
testing. There many other things to fix yet
diffs (185 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
@@ -16,18 +16,6 @@
#include "rel_rewriter.h"
#include "sql_mvc.h"
-static bool
-exps_have_or(list *exps)
-{
- for (node *n = exps->h ; n ; n = n->next) {
- sql_exp *e = n->data;
- assert(e->type == e_cmp);
- if (e->flag == cmp_or)
- return true;
- }
- return false;
-}
-
static inline void
set_max_of_values(mvc *sql, sql_exp *e, rel_prop kind, ValPtr lval, ValPtr
rval)
{
@@ -57,6 +45,73 @@ copy_property(mvc *sql, sql_exp *e, rel_
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)
+{
+ for (node *n = exps->h ; n ; n = n->next) {
+ sql_exp *e = n->data;
+ assert(e->type == e_cmp);
+ if (e->flag == cmp_or)
+ return true;
+ }
+ return false;
+}
+
static sql_exp *
comparison_find_column(sql_exp *input, sql_exp *e)
{
@@ -323,17 +378,51 @@ rel_propagate_statistics(visitor *v, sql
}
} break;
case e_convert: {
- if (((sql_subtype*)exp_fromtype(e))->type->eclass ==
((sql_subtype*)exp_totype(e))->type->eclass) {
+ 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)))
- copy_property(sql, e, PROP_MAX, lval);
- if ((lval = find_prop_and_get(l->p, PROP_MIN)))
- copy_property(sql, e, PROP_MIN, lval);
+ 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);
+ }
+ }
+ 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:
- break;
+ 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;
diff --git a/sql/server/rel_statistics.h b/sql/server/rel_statistics.h
--- a/sql/server/rel_statistics.h
+++ b/sql/server/rel_statistics.h
@@ -12,6 +12,7 @@
#include "sql_relation.h"
#include "sql_mvc.h"
+extern void initialize_sql_functions_lookup(sql_allocator *sa);
extern sql_rel *rel_statistics(mvc *sql, sql_rel *rel);
#endif /*_REL_STATISTICS_H_*/
diff --git a/sql/server/sql_mvc.c b/sql/server/sql_mvc.c
--- a/sql/server/sql_mvc.c
+++ b/sql/server/sql_mvc.c
@@ -24,6 +24,7 @@
#include "rel_semantic.h"
#include "rel_unnest.h"
#include "rel_optimizer.h"
+#include "rel_statistics.h"
#include "wlc.h"
#include "mal_authorize.h"
@@ -137,6 +138,7 @@ mvc_init(sql_allocator *pa, int debug, s
TRC_CRITICAL(SQL_TRANS, "Unable to create system tables\n");
return -1;
}
+ initialize_sql_functions_lookup(pa);
m = mvc_create(pa, 0, 0, NULL, NULL);
if (!m) {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list