Changeset: 96373e9a31ff for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/96373e9a31ff
Modified Files:
        sql/backends/monet5/sql_upgrades.c
        sql/server/rel_optimizer.c
Branch: properties
Log Message:

Merged with default


diffs (truncated from 538 to 300 lines):

diff --git a/gdk/ChangeLog b/gdk/ChangeLog
--- a/gdk/ChangeLog
+++ b/gdk/ChangeLog
@@ -1,3 +1,8 @@
 # ChangeLog file for GDK
 # This file is updated with Maddlog
 
+* Tue Jan 25 2022 Sjoerd Mullender <[email protected]>
+- When adding or subtracting months from a date or timestamp value,
+  clamp the result to the calculated month instead of wrapping to the
+  beginning of the next month.  See bug 7227.
+
diff --git a/gdk/gdk_time.c b/gdk/gdk_time.c
--- a/gdk/gdk_time.c
+++ b/gdk/gdk_time.c
@@ -172,12 +172,7 @@ date_add_month(date dt, int months)
                m = (m - 1) % 12 + 1;
        }
        if (d > monthdays(y, m)) {
-               d -= monthdays(y, m);
-               if (++m > 12) {
-                       m = 1;
-                       if (++y > YEAR_MAX)
-                               return date_nil;
-               }
+               d = monthdays(y, m);
        }
        return mkdate(y, m, d);
 }
diff --git a/sql/backends/monet5/dict.c b/sql/backends/monet5/dict.c
--- a/sql/backends/monet5/dict.c
+++ b/sql/backends/monet5/dict.c
@@ -720,7 +720,7 @@ DICTthetaselect(Client cntxt, MalBlkPtr 
                        } else
                                assert(0);
                } else {
-                       bn = BATdense(0, 0, 0);
+                       bn = BATdense(0, 0, op[0] == '!' ? BATcount(lv) : 0); 
/* for '!' if it didn't find, then all are different */
                }
        } else { /* select + intersect */
                if (ATOMextern(lv->ttype))
diff --git a/sql/backends/monet5/sql_upgrades.c 
b/sql/backends/monet5/sql_upgrades.c
--- a/sql/backends/monet5/sql_upgrades.c
+++ b/sql/backends/monet5/sql_upgrades.c
@@ -674,12 +674,12 @@ sql_update_nov2019_missing_dependencies(
        ppos = pos; /* later check if found updatable database objects */
 
        os_iterator(&si, sql->session->tr->cat->schemas, sql->session->tr, 
NULL);
-       for (sql_base *b = oi_next(&si); b; oi_next(&si)) {
+       for (sql_base *b = oi_next(&si); b; b = oi_next(&si)) {
                sql_schema *s = (sql_schema*)b;
 
                struct os_iter oi;
                os_iterator(&oi, s->funcs, sql->session->tr, NULL);
-               for (sql_base *b = oi_next(&oi); b; oi_next(&oi)) {
+               for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
                        sql_func *f = (sql_func*)b;
 
                        if (f->query && f->lang == FUNC_LANG_SQL) {
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -7473,6 +7473,57 @@ rel_select_order(visitor *v, sql_rel *re
        return rel;
 }
 
+/*
+ * Casting decimal values on both sides of a compare expression is expensive,
+ * both in preformance (cpu cost) and memory requirements (need for large
+ * types).
+ */
+
+#define reduce_scale_tpe(tpe, uval) \
+       do { \
+               tpe v = uval; \
+               if (v != 0) { \
+                       while( (v/10)*10 == v ) { \
+                               i++; \
+                               v /= 10; \
+                       } \
+                       nval = v; \
+               } \
+       } while (0)
+
+static atom *
+reduce_scale(mvc *sql, atom *a)
+{
+       int i = 0;
+       atom *na = a;
+#ifdef HAVE_HGE
+       hge nval = 0;
+#else
+       lng nval = 0;
+#endif
+
+#ifdef HAVE_HGE
+       if (a->data.vtype == TYPE_hge) {
+               reduce_scale_tpe(hge, a->data.val.hval);
+       } else
+#endif
+       if (a->data.vtype == TYPE_lng) {
+               reduce_scale_tpe(lng, a->data.val.lval);
+       } else if (a->data.vtype == TYPE_int) {
+               reduce_scale_tpe(int, a->data.val.ival);
+       } else if (a->data.vtype == TYPE_sht) {
+               reduce_scale_tpe(sht, a->data.val.shval);
+       } else if (a->data.vtype == TYPE_bte) {
+               reduce_scale_tpe(bte, a->data.val.btval);
+       }
+       if (i) {
+               na = atom_int(sql->sa, &a->tpe, nval);
+               if (na->tpe.scale)
+                       na->tpe.scale -= i;
+       }
+       return na;
+}
+
 static inline sql_exp *
 rel_simplify_predicates(visitor *v, sql_rel *rel, sql_exp *e)
 {
@@ -7550,9 +7601,67 @@ rel_simplify_predicates(visitor *v, sql_
                                list *r = e->r;
                                e = exp_compare(v->sql->sa, l->h->data, 
r->h->data, is_anti(e) ? cmp_notequal : cmp_equal);
                                v->changes++;
-                               return e;
-                       }
-                       return e;
+                       }
+               }
+               /* rewrite e if left or right is a cast */
+               if (is_compare(e->type) && !e->f && is_theta_exp(e->flag) && 
(((sql_exp*)e->l)->type == e_convert || ((sql_exp*)e->r)->type == e_convert)) {
+                       sql_rel *r = rel->r;
+                       sql_exp *le = e->l, *re = e->r;
+
+                       /* if convert on left then find mul or div on right 
which increased scale! */
+                       if (le->type == e_convert && re->type == e_column && 
(e->flag == cmp_lt || e->flag == cmp_gt) && r && is_project(r->op)) {
+                               sql_exp *nre = rel_find_exp(r, re);
+                               sql_subtype *tt = exp_totype(le), *ft = 
exp_fromtype(le);
+
+                               if (nre && nre->type == e_func) {
+                                       sql_subfunc *f = nre->f;
+
+                                       if (!f->func->s && 
!strcmp(f->func->base.name, "sql_mul")) {
+                                               list *args = nre->l;
+                                               sql_exp *ce = args->t->data;
+                                               sql_subtype *fst = 
exp_subtype(args->h->data);
+
+                                               if (fst->scale && fst->scale == 
ft->scale && is_atom(ce->type) && ce->l) {
+                                                       atom *a = ce->l;
+                                                       int anti = is_anti(e);
+                                                       sql_exp *arg1, *arg2;
+#ifdef HAVE_HGE
+                                                       hge val = 1;
+#else
+                                                       lng val = 1;
+#endif
+                                                       /* multiply with 
smallest value, then scale and (round) */
+                                                       int scale = (int) 
tt->scale - (int) ft->scale, rs = 0;
+                                                       atom *na = 
reduce_scale(v->sql, a);
+
+                                                       if (na != a) {
+                                                               rs = 
a->tpe.scale - na->tpe.scale;
+                                                               ce->l = na;
+                                                       }
+                                                       scale -= rs;
+
+                                                       while (scale > 0) {
+                                                               scale--;
+                                                               val *= 10;
+                                                       }
+                                                       arg1 = re;
+#ifdef HAVE_HGE
+                                                       arg2 = 
exp_atom_hge(v->sql->sa, val);
+#else
+                                                       arg2 = 
exp_atom_lng(v->sql->sa, val);
+#endif
+                                                       if ((nre = 
rel_binop_(v->sql, NULL, arg1, arg2, "sys", "scale_down", card_value))) {
+                                                               e = 
exp_compare(v->sql->sa, le->l, nre, e->flag);
+                                                               if (anti) 
set_anti(e);
+                                                               v->changes++;
+                                                       } else {
+                                                               
v->sql->session->status = 0;
+                                                               
v->sql->errstr[0] = '\0';
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
                }
                if (is_compare(e->type) && is_semantics(e) && (e->flag == 
cmp_equal || e->flag == cmp_notequal) && exp_is_null(e->r)) {
                        /* simplify 'is null' predicates on constants */
@@ -8169,57 +8278,6 @@ exp_merge_range(visitor *v, sql_rel *rel
        return exps;
 }
 
-/*
- * Casting decimal values on both sides of a compare expression is expensive,
- * both in preformance (cpu cost) and memory requirements (need for large
- * types).
- */
-
-#define reduce_scale_tpe(tpe, uval) \
-       do { \
-               tpe v = uval; \
-               if (v != 0) { \
-                       while( (v/10)*10 == v ) { \
-                               i++; \
-                               v /= 10; \
-                       } \
-                       nval = v; \
-               } \
-       } while (0)
-
-static atom *
-reduce_scale(mvc *sql, atom *a)
-{
-       int i = 0;
-       atom *na = a;
-#ifdef HAVE_HGE
-       hge nval = 0;
-#else
-       lng nval = 0;
-#endif
-
-#ifdef HAVE_HGE
-       if (a->data.vtype == TYPE_hge) {
-               reduce_scale_tpe(hge, a->data.val.hval);
-       } else
-#endif
-       if (a->data.vtype == TYPE_lng) {
-               reduce_scale_tpe(lng, a->data.val.lval);
-       } else if (a->data.vtype == TYPE_int) {
-               reduce_scale_tpe(int, a->data.val.ival);
-       } else if (a->data.vtype == TYPE_sht) {
-               reduce_scale_tpe(sht, a->data.val.shval);
-       } else if (a->data.vtype == TYPE_bte) {
-               reduce_scale_tpe(bte, a->data.val.btval);
-       }
-       if (i) {
-               na = atom_int(sql->sa, &a->tpe, nval);
-               if (na->tpe.scale)
-                       na->tpe.scale -= i;
-       }
-       return na;
-}
-
 static sql_rel *
 rel_project_reduce_casts(visitor *v, sql_rel *rel)
 {
@@ -8266,88 +8324,6 @@ rel_project_reduce_casts(visitor *v, sql
        return rel;
 }
 
-static inline sql_rel *
-rel_reduce_casts(visitor *v, sql_rel *rel)
-{
-       list *exps = rel->exps;
-       assert(!list_empty(rel->exps));
-
-       for (node *n=exps->h; n; n = n->next) {
-               sql_exp *e = n->data;
-               sql_exp *le = e->l;
-               sql_exp *re = e->r;
-
-               /* handle the and's in the or lists */
-               if (e->type != e_cmp || !is_theta_exp(e->flag) || e->f)
-                       continue;
-               /* rewrite e if left or right is a cast */
-               if (le->type == e_convert || re->type == e_convert) {
-                       sql_rel *r = rel->r;
-
-                       /* if convert on left then find
-                        * mul or div on right which increased
-                        * scale!
-                        */
-                       if (le->type == e_convert && re->type == e_column && 
(e->flag == cmp_lt || e->flag == cmp_gt) && r && is_project(r->op)) {
-                               sql_exp *nre = rel_find_exp(r, re);
-                               sql_subtype *tt = exp_totype(le);
-                               sql_subtype *ft = exp_fromtype(le);
-
-                               if (nre && nre->type == e_func) {
-                                       sql_subfunc *f = nre->f;
-
-                                       if (!f->func->s && 
!strcmp(f->func->base.name, "sql_mul")) {
-                                               list *args = nre->l;
-                                               sql_exp *ce = args->t->data;
-                                               sql_subtype *fst = 
exp_subtype(args->h->data);
-
-                                               if (fst->scale && fst->scale == 
ft->scale && is_atom(ce->type) && ce->l) {
-                                                       atom *a = ce->l;
-                                                       int anti = is_anti(e);
-                                                       sql_exp *arg1, *arg2;
-#ifdef HAVE_HGE
-                                                       hge val = 1;
-#else
-                                                       lng val = 1;
-#endif
-                                                       /* multiply with 
smallest value, then scale and (round) */
-                                                       int scale = (int) 
tt->scale - (int) ft->scale, rs = 0;
-                                                       atom *na = 
reduce_scale(v->sql, a);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to