Changeset: 830922be8989 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/830922be8989
Added Files:
        sql/server/rel_optimize_exps.c
        sql/server/rel_optimize_others.c
        sql/server/rel_optimize_proj.c
        sql/server/rel_optimize_sel.c
        sql/server/rel_optimizer_private.h
Modified Files:
        sql/server/CMakeLists.txt
        sql/server/rel_optimizer.c
        sql/server/rel_optimizer.h
        sql/server/rel_rewriter.c
        sql/server/rel_rewriter.h
        sql/server/rel_unnest.c
        sql/test/Tests/keys.test
Branch: sqloptimizer
Log Message:

Splitting different SQL optimizers into different groups across multiple 
translation units.

Creating a framework that will be used to time the SQL optimizers later.
More is still needed.


diffs (truncated from 18884 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
@@ -46,6 +46,10 @@ target_sources(sqlserver
   rel_rewriter.c
   rel_unnest.c
   rel_optimizer.c
+  rel_optimize_exps.c
+  rel_optimize_others.c
+  rel_optimize_proj.c
+  rel_optimize_sel.c
   rel_partition.c
   rel_planner.c rel_planner.h
   rel_distribute.c
@@ -58,6 +62,7 @@ target_sources(sqlserver
   rel_basetable.h
   rel_unnest.h
   rel_optimizer.h
+  rel_optimizer_private.h
   rel_partition.h
   rel_distribute.h
   rel_prop.h
diff --git a/sql/server/rel_optimize_exps.c b/sql/server/rel_optimize_exps.c
new file mode 100644
--- /dev/null
+++ b/sql/server/rel_optimize_exps.c
@@ -0,0 +1,793 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2022 MonetDB B.V.
+ */
+
+#include "monetdb_config.h"
+#include "rel_optimizer.h"
+#include "rel_optimizer_private.h"
+#include "rel_rel.h"
+#include "rel_basetable.h"
+#include "rel_select.h"
+#include "rel_exp.h"
+#include "rel_prop.h"
+#include "rel_dump.h"
+#include "rel_rewriter.h"
+#include "sql_mvc.h"
+
+static inline int
+str_ends_with(const char *s, const char *suffix)
+{
+       size_t slen = strlen(s), suflen = strlen(suffix);
+       if (suflen > slen)
+               return 1;
+       return strncmp(s + slen - suflen, suffix, suflen);
+}
+
+static sql_exp *
+exp_simplify_math( mvc *sql, sql_exp *e, int *changes)
+{
+       if (e->type == e_func || e->type == e_aggr) {
+               list *l = e->l;
+               sql_subfunc *f = e->f;
+               node *n;
+               sql_exp *le;
+
+               if (list_length(l) < 1)
+                       return e;
+
+               /* if the function has no null semantics we can return NULL if 
one of the arguments is NULL */
+               if (!f->func->semantics && f->func->type != F_PROC) {
+                       for (node *n = l->h ; n ; n = n->next) {
+                               sql_exp *arg = n->data;
+
+                               if (exp_is_atom(arg) && exp_is_null(arg)) {
+                                       sql_exp *ne = exp_null(sql->sa, 
exp_subtype(e));
+                                       (*changes)++;
+                                       if (exp_name(e))
+                                               exp_prop_alias(sql->sa, ne, e);
+                                       return ne;
+                               }
+                       }
+               }
+               if (!f->func->s && list_length(l) == 2 && 
str_ends_with(sql_func_imp(f->func), "_no_nil") == 0) {
+                       sql_exp *le = l->h->data;
+                       sql_exp *re = l->h->next->data;
+
+                       /* if "_no_nil" is in the name of the
+                        * implementation function (currently either
+                        * min_no_nil or max_no_nil), in which case we
+                        * ignore the NULL and return the other value */
+
+                       if (exp_is_atom(le) && exp_is_null(le)) {
+                               (*changes)++;
+                               if (exp_name(e))
+                                       exp_prop_alias(sql->sa, re, e);
+                               return re;
+                       }
+                       if (exp_is_atom(re) && exp_is_null(re)) {
+                               (*changes)++;
+                               if (exp_name(e))
+                                       exp_prop_alias(sql->sa, le, e);
+                               return le;
+                       }
+               }
+
+               le = l->h->data;
+               if (!EC_COMPUTE(exp_subtype(le)->type->eclass) && 
exp_subtype(le)->type->eclass != EC_DEC)
+                       return e;
+
+               if (!f->func->s && !strcmp(f->func->base.name, "sql_mul") && 
list_length(l) == 2) {
+                       sql_exp *le = l->h->data;
+                       sql_exp *re = l->h->next->data;
+                       sql_subtype *et = exp_subtype(e);
+
+                       /* 0*a = 0 */
+                       if (exp_is_atom(le) && exp_is_zero(le) && 
exp_is_atom(re) && exp_is_not_null(re)) {
+                               (*changes)++;
+                               le = exp_zero(sql->sa, et);
+                               if (subtype_cmp(exp_subtype(e), 
exp_subtype(le)) != 0)
+                                       le = exp_convert(sql->sa, le, 
exp_subtype(le), exp_subtype(e));
+                               if (exp_name(e))
+                                       exp_prop_alias(sql->sa, le, e);
+                               return le;
+                       }
+                       /* a*0 = 0 */
+                       if (exp_is_atom(re) && exp_is_zero(re) && 
exp_is_atom(le) && exp_is_not_null(le)) {
+                               (*changes)++;
+                               re = exp_zero(sql->sa, et);
+                               if (subtype_cmp(exp_subtype(e), 
exp_subtype(re)) != 0)
+                                       re = exp_convert(sql->sa, re, 
exp_subtype(re), exp_subtype(e));
+                               if (exp_name(e))
+                                       exp_prop_alias(sql->sa, re, e);
+                               return re;
+                       }
+                       if (exp_is_atom(le) && exp_is_atom(re)) {
+                               atom *la = exp_flatten(sql, true, le);
+                               atom *ra = exp_flatten(sql, true, re);
+
+                               if (la && ra && subtype_cmp(atom_type(la), 
atom_type(ra)) == 0 && subtype_cmp(atom_type(la), exp_subtype(e)) == 0) {
+                                       atom *a = atom_mul(sql->sa, la, ra);
+
+                                       if (a && (a = atom_cast(sql->sa, a, 
exp_subtype(e)))) {
+                                               sql_exp *ne = exp_atom(sql->sa, 
a);
+                                               if (subtype_cmp(exp_subtype(e), 
exp_subtype(ne)) != 0)
+                                                       ne = 
exp_convert(sql->sa, ne, exp_subtype(ne), exp_subtype(e));
+                                               (*changes)++;
+                                               if (exp_name(e))
+                                                       exp_prop_alias(sql->sa, 
ne, e);
+                                               return ne;
+                                       }
+                               }
+                       }
+                       /* change a*pow(a,n) or pow(a,n)*a into pow(a,n+1) */
+                       if (is_func(le->type)) {
+                               list *l = le->l;
+                               sql_subfunc *f = le->f;
+
+                               if (!f->func->s && !strcmp(f->func->base.name, 
"power") && list_length(l) == 2) {
+                                       sql_exp *lle = l->h->data;
+                                       sql_exp *lre = l->h->next->data;
+                                       if (exp_equal(re, lle)==0) {
+                                               atom *a = exp_value(sql, lre);
+                                               if (a && (a = atom_inc(sql->sa, 
a))) {
+                                                       lre->l = a;
+                                                       lre->r = NULL;
+                                                       if 
(subtype_cmp(exp_subtype(e), exp_subtype(le)) != 0)
+                                                               le = 
exp_convert(sql->sa, le, exp_subtype(le), exp_subtype(e));
+                                                       (*changes)++;
+                                                       if (exp_name(e))
+                                                               
exp_prop_alias(sql->sa, le, e);
+                                                       return le;
+                                               }
+                                       }
+                               }
+                               if (!f->func->s && !strcmp(f->func->base.name, 
"sql_mul") && list_length(l) == 2) {
+                                       sql_exp *lle = l->h->data;
+                                       sql_exp *lre = l->h->next->data;
+                                       if (!exp_is_atom(lle) && 
exp_is_atom(lre) && exp_is_atom(re)) {
+                                               /* (x*c1)*c2 -> x * (c1*c2) */
+                                               sql_exp *ne = NULL;
+
+                                               if (!(le = rel_binop_(sql, 
NULL, lre, re, "sys", "sql_mul", card_value))) {
+                                                       sql->session->status = 
0;
+                                                       sql->errstr[0] = '\0';
+                                                       return e; /* error, 
fallback to original expression */
+                                               }
+                                               if (!(ne = rel_binop_(sql, 
NULL, lle, le, "sys", "sql_mul", card_value))) {
+                                                       sql->session->status = 
0;
+                                                       sql->errstr[0] = '\0';
+                                                       return e; /* error, 
fallback to original expression */
+                                               }
+                                               if (subtype_cmp(exp_subtype(e), 
exp_subtype(ne)) != 0)
+                                                       ne = 
exp_convert(sql->sa, ne, exp_subtype(ne), exp_subtype(e));
+                                               (*changes)++;
+                                               if (exp_name(e))
+                                                       exp_prop_alias(sql->sa, 
ne, e);
+                                               return ne;
+                                       }
+                               }
+                       }
+               }
+               if (!f->func->s && !strcmp(f->func->base.name, "sql_add") && 
list_length(l) == 2) {
+                       sql_exp *le = l->h->data;
+                       sql_exp *re = l->h->next->data;
+                       if (exp_is_atom(le) && exp_is_zero(le)) {
+                               if (subtype_cmp(exp_subtype(e), 
exp_subtype(re)) != 0)
+                                       re = exp_convert(sql->sa, re, 
exp_subtype(re), exp_subtype(e));
+                               (*changes)++;
+                               if (exp_name(e))
+                                       exp_prop_alias(sql->sa, re, e);
+                               return re;
+                       }
+                       if (exp_is_atom(re) && exp_is_zero(re)) {
+                               if (subtype_cmp(exp_subtype(e), 
exp_subtype(le)) != 0)
+                                       le = exp_convert(sql->sa, le, 
exp_subtype(le), exp_subtype(e));
+                               (*changes)++;
+                               if (exp_name(e))
+                                       exp_prop_alias(sql->sa, le, e);
+                               return le;
+                       }
+                       if (exp_is_atom(le) && exp_is_atom(re)) {
+                               atom *la = exp_flatten(sql, true, le);
+                               atom *ra = exp_flatten(sql, true, re);
+
+                               if (la && ra) {
+                                       atom *a = atom_add(sql->sa, la, ra);
+
+                                       if (a) {
+                                               sql_exp *ne = exp_atom(sql->sa, 
a);
+                                               if (subtype_cmp(exp_subtype(e), 
exp_subtype(ne)) != 0)
+                                                       ne = 
exp_convert(sql->sa, ne, exp_subtype(ne), exp_subtype(e));
+                                               (*changes)++;
+                                               if (exp_name(e))
+                                                       exp_prop_alias(sql->sa, 
ne, e);
+                                               return ne;
+                                       }
+                               }
+                       }
+                       if (is_func(le->type)) {
+                               list *ll = le->l;
+                               sql_subfunc *f = le->f;
+                               if (!f->func->s && !strcmp(f->func->base.name, 
"sql_add") && list_length(ll) == 2) {
+                                       sql_exp *lle = ll->h->data;
+                                       sql_exp *lre = ll->h->next->data;
+
+                                       if (exp_is_atom(lle) && 
exp_is_atom(lre))
+                                               return e;
+                                       if (!exp_is_atom(re) && 
exp_is_atom(lre)) {
+                                               /* (x+c1)+y -> (x+y) + c1 */
+                                               ll->h->next->data = re;
+                                               l->h->next->data = lre;
+                                               if (!(l->h->data = 
exp_simplify_math(sql, le, changes)))
+                                                       return NULL;
+                                               (*changes)++;
+                                               return e;
+                                       }
+                                       if (exp_is_atom(re) && 
exp_is_atom(lre)) {
+                                               /* (x+c1)+c2 -> (c2+c1) + x */
+                                               ll->h->data = re;
+                                               l->h->next->data = lle;
+                                               if (!(l->h->data = 
exp_simplify_math(sql, le, changes)))
+                                                       return NULL;
+                                               (*changes)++;
+                                               return e;
+                                       }
+                               }
+                       }
+               }
+               if (!f->func->s && !strcmp(f->func->base.name, "sql_sub") && 
list_length(l) == 2) {
+                       sql_exp *le = l->h->data;
+                       sql_exp *re = l->h->next->data;
+
+                       if (exp_is_atom(le) && exp_is_atom(re)) {
+                               atom *la = exp_flatten(sql, true, le);
+                               atom *ra = exp_flatten(sql, true, re);
+
+                               if (la && ra) {
+                                       atom *a = atom_sub(sql->sa, la, ra);
+
+                                       if (a) {
+                                               sql_exp *ne = exp_atom(sql->sa, 
a);
+                                               if (subtype_cmp(exp_subtype(e), 
exp_subtype(ne)) != 0)
+                                                       ne = 
exp_convert(sql->sa, ne, exp_subtype(ne), exp_subtype(e));
+                                               (*changes)++;
+                                               if (exp_name(e))
+                                                       exp_prop_alias(sql->sa, 
ne, e);
+                                               return ne;
+                                       }
+                               }
+                       }
+                       if (exp_is_not_null(le) && exp_is_not_null(re) && 
exp_equal(le,re) == 0) { /* a - a = 0 */
+                               atom *a;
+                               sql_exp *ne;
+
+                               if (exp_subtype(le)->type->eclass == EC_NUM) {
+                                       a = atom_int(sql->sa, exp_subtype(le), 
0);
+                               } else if (exp_subtype(le)->type->eclass == 
EC_FLT) {
+                                       a = atom_float(sql->sa, 
exp_subtype(le), 0);
+                               } else {
+                                       return e;
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to