Changeset: b7f50478672f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/b7f50478672f
Modified Files:
        sql/include/sql_catalog.h
        sql/storage/sql_storage.h
        sql/storage/store.c
Branch: sql_profiler
Log Message:

Merge with default


diffs (truncated from 838 to 300 lines):

diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -3337,7 +3337,7 @@ dirty_bat(bat *i, bool subcommit)
 static gdk_return
 file_move(int farmid, const char *srcdir, const char *dstdir, const char 
*name, const char *ext)
 {
-       if (GDKmove(farmid, srcdir, name, ext, dstdir, name, ext, true) == 
GDK_SUCCEED) {
+       if (GDKmove(farmid, srcdir, name, ext, dstdir, name, ext, false) == 
GDK_SUCCEED) {
                return GDK_SUCCEED;
        } else {
                char *path;
@@ -3792,7 +3792,7 @@ BBPsync(int cnt, bat *restrict subcommit
                                break;
                        }
                        if (BBP_status(i) & BBPEXISTING) {
-                               if (b != NULL) {
+                               if (b != NULL && b->batInserted > 0) {
                                        if (BBPbackup(b, subcommit != NULL) != 
GDK_SUCCEED) {
                                                if (lock)
                                                        
MT_lock_unset(&GDKswapLock(i));
@@ -3834,6 +3834,7 @@ BBPsync(int cnt, bat *restrict subcommit
                                assert(sizes == NULL || bi.width == 0 || 
(bi.type == TYPE_msk ? ((size + 31) / 32) * 4 : size << bi.shift) <= bi.hfree);
                                if (size > bi.count) /* includes sizes==NULL */
                                        size = bi.count;
+                               bi.b->batInserted = size;
                                if (b && size != 0) {
                                        /* wait for BBPSAVING so that we
                                         * can set it, wait for
diff --git a/gdk/gdk_tm.c b/gdk/gdk_tm.c
--- a/gdk/gdk_tm.c
+++ b/gdk/gdk_tm.c
@@ -43,31 +43,6 @@
  * situation is COLD-abort: quit the server and restart, so you get
  * the recovered disk images.
  */
-/* in the commit prelude, the delta status in the memory image of all
- * bats is commited */
-static gdk_return
-prelude(int cnt, bat *restrict subcommit, BUN *restrict sizes)
-{
-       int i = 0;
-
-       while (++i < cnt) {
-               bat bid = subcommit ? subcommit[i] : i;
-
-               if (BBP_status(bid) & BBPPERSISTENT) {
-                       BAT *b = BBPquickdesc(bid);
-
-                       if (b) {
-                               MT_lock_set(&b->theaplock);
-                               assert(!isVIEW(b));
-                               assert(b->batRole == PERSISTENT);
-                               assert(sizes == NULL || sizes[i] <= 
BATcount(b));
-                               BATcommit(b, sizes ? sizes[i] : BUN_NONE);
-                               MT_lock_unset(&b->theaplock);
-                       }
-               }
-       }
-       return GDK_SUCCEED;
-}
 
 /* in the commit epilogue, the BBP-status of the bats is changed to
  * reflect their presence in the succeeded checkpoint.  Also bats from
@@ -146,8 +121,7 @@ TMcommit(void)
 
        /* commit with the BBP globally locked */
        BBPlock();
-       if (prelude(getBBPsize(), NULL, NULL) == GDK_SUCCEED &&
-           BBPsync(getBBPsize(), NULL, NULL, getBBPlogno(), getBBPtransid()) 
== GDK_SUCCEED) {
+       if (BBPsync(getBBPsize(), NULL, NULL, getBBPlogno(), getBBPtransid()) 
== GDK_SUCCEED) {
                epilogue(getBBPsize(), NULL, true);
                ret = GDK_SUCCEED;
        }
@@ -212,15 +186,13 @@ TMsubcommit_list(bat *restrict subcommit
                        }
                }
        }
-       if (prelude(cnt, subcommit, sizes) == GDK_SUCCEED) {    /* save the new 
bats outside the lock */
-               /* lock just prevents other global (sub-)commits */
-               MT_lock_set(&GDKtmLock);
-               if (BBPsync(cnt, subcommit, sizes, logno, transid) == 
GDK_SUCCEED) { /* write BBP.dir (++) */
-                       epilogue(cnt, subcommit, false);
-                       ret = GDK_SUCCEED;
-               }
-               MT_lock_unset(&GDKtmLock);
+       /* lock just prevents other global (sub-)commits */
+       MT_lock_set(&GDKtmLock);
+       if (BBPsync(cnt, subcommit, sizes, logno, transid) == GDK_SUCCEED) { /* 
write BBP.dir (++) */
+               epilogue(cnt, subcommit, false);
+               ret = GDK_SUCCEED;
        }
+       MT_lock_unset(&GDKtmLock);
        return ret;
 }
 
diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -1262,9 +1262,11 @@ exp_bin(backend *be, sql_exp *e, stmt *l
                }
                assert(!e->r);
                if (strcmp(mod, "") == 0 && strcmp(fimp, "") == 0) {
-                       if (strcmp(f->func->base.name, "star") == 0)
+                       if (strcmp(f->func->base.name, "star") == 0) {
+                               if (!left)
+                                       return const_column(be, stmt_bool(be, 
1));
                                return left->op4.lval->h->data;
-                       if (strcmp(f->func->base.name, "case") == 0)
+                       } if (strcmp(f->func->base.name, "case") == 0)
                                return exp2bin_case(be, e, left, right, sel, 
depth);
                        if (strcmp(f->func->base.name, "casewhen") == 0)
                                return exp2bin_casewhen(be, e, left, right, 
sel, depth);
diff --git a/sql/server/rel_optimize_proj.c b/sql/server/rel_optimize_proj.c
--- a/sql/server/rel_optimize_proj.c
+++ b/sql/server/rel_optimize_proj.c
@@ -2845,21 +2845,32 @@ rel_simplify_count(visitor *v, sql_rel *
                /* With multiple count(*), use exp_ref to reduce the number of 
calls to this aggregate */
                if (ncountstar > 1) {
                        sql_exp *count_star = NULL;
+                       sql_rel *nrel = rel_project(v->sql->sa, rel, NULL);
+                       list *aexps = sa_list(v->sql->sa), *nexps = 
sa_list(v->sql->sa);
+                       nrel->exps = nexps;
                        for (node *n = rel->exps->h; n ; n = n->next) {
                                sql_exp *e = n->data;
 
                                if (exp_aggr_is_count(e) && !need_distinct(e) 
&& list_length(e->l) == 0) {
                                        if (!count_star) {
                                                count_star = e;
+                                               append(aexps, e);
+                                               append(nexps, exp_ref(sql, e));
                                        } else {
                                                sql_exp *ne = exp_ref(sql, 
count_star);
+
                                                if (exp_name(e))
                                                        exp_prop_alias(sql->sa, 
ne, e);
-                                               n->data = ne;
                                                v->changes++;
+                                               append(nexps, ne);
                                        }
+                               } else {
+                                       append(aexps, e);
+                                       append(nexps, exp_ref(sql, e));
                                }
                        }
+                       rel->exps = aexps;
+                       return nrel;
                }
        }
        return rel;
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -4480,7 +4480,7 @@ rel_order_by_column_exp(sql_query *query
        if (!r)
                return e;
 
-       if (is_simple_project(r->op) && is_processed(r)) {
+       if (is_simple_project(r->op) && r->l && is_processed(r)) {
                p = r;
                r = r->l;
        }
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
@@ -729,7 +729,7 @@ rel_get_statistics_(visitor *v, sql_rel 
                                empty_cross = false; /* don't rewrite again */
                        } else if (lv != BUN_NONE && rv != BUN_NONE) {
                                set_count_prop(v->sql->sa, rel, (rv > (BUN_MAX 
- lv)) ? BUN_MAX : (lv + rv)); /* overflow check */
-                       } 
+                       }
                } else if (is_inter(rel->op) || is_except(rel->op)) {
                        BUN lv = need_distinct(rel) ? rel_calc_nuniques(v->sql, 
l, l->exps) : get_rel_count(l),
                                rv = need_distinct(rel) ? 
rel_calc_nuniques(v->sql, r, r->exps) : get_rel_count(r);
@@ -818,10 +818,16 @@ rel_get_statistics_(visitor *v, sql_rel 
                                        } else if (e->type == e_cmp && e->flag 
== cmp_equal) {
                                                /* if one of the sides is 
unique, the cardinality will be that exact number, but look for nulls */
                                                if (!is_semantics(e) || 
!has_nil(el) || !has_nil(er)) {
-                                                       if (is_unique(el)) {
+                                                       BUN lu = 0, ru = 0;
+                                                       prop *p = NULL;
+                                                       if ((p = 
find_prop(el->p, PROP_NUNIQUES)))
+                                                               lu = (BUN) 
p->value.dval;
+                                                       if ((p = 
find_prop(er->p, PROP_NUNIQUES)))
+                                                               ru = (BUN) 
p->value.dval;
+                                                       if (is_unique(el) || lu 
> lv) {
                                                                BUN ncount = 
(is_right(rel->op) || is_full(rel->op)) ? MAX(lv, rv) : lv;
                                                                
uniques_estimate = MIN(uniques_estimate, ncount);
-                                                       } else if 
(is_unique(er)) {
+                                                       } else if 
(is_unique(er) || ru > rv) {
                                                                BUN ncount = 
(is_left(rel->op) || is_full(rel->op)) ? MAX(lv, rv) : rv;
                                                                
uniques_estimate = MIN(uniques_estimate, ncount);
                                                        }
@@ -863,7 +869,24 @@ rel_get_statistics_(visitor *v, sql_rel 
                        if (list_length(rel->exps) == 1 && 
(exp_is_false(rel->exps->h->data) || exp_is_null(rel->exps->h->data))) {
                                set_count_prop(v->sql->sa, rel, 0);
                        } else {
-                               set_count_prop(v->sql->sa, rel, 
get_rel_count(l));
+                               if (!list_empty(rel->exps) && !is_single(rel)) {
+                                       BUN cnt = get_rel_count(l), u = 1;
+                                       for (node *n = rel->exps->h ; n ; n = 
n->next) {
+                                               sql_exp *e = n->data, *el = 
e->l, *er = e->r;
+
+                                               /* simple expressions first */
+                                               if (e->type == e_cmp && e->flag 
== cmp_equal && exp_is_atom(er)) {
+                                                       /* use selectivity */
+                                                       prop *p = NULL;
+                                                       if ((p = 
find_prop(el->p, PROP_NUNIQUES))) {
+                                                               u = (BUN) 
p->value.dval;
+                                                       }
+                                               }
+                                       }
+                                       set_count_prop(v->sql->sa, rel, cnt/u);
+                               } else {
+                                       set_count_prop(v->sql->sa, rel, 
get_rel_count(l));
+                               }
                        }
                } break;
                case op_project: {
@@ -930,8 +953,37 @@ rel_get_statistics_(visitor *v, sql_rel 
                        set_count_prop(v->sql->sa, rel, lv);
                }
        } break;
+       case op_table: {
+               sql_exp *op = rel->r;
+               if (rel->flag != TRIGGER_WRAPPER && op) {
+                       sql_subfunc *f = op->f;
+                       if (f->func->lang == FUNC_LANG_SQL) {
+                               set_count_prop(v->sql->sa, rel, 1000 /* just 
some fallback value */);
+                       } else if (f->func->lang == FUNC_LANG_MAL && 
strcmp(f->func->base.name, "storage") == 0) {
+                               set_count_prop(v->sql->sa, rel, 1000 /* TODO 
get size of catalog */);
+                       } else if (f->func->lang == FUNC_LANG_MAL && 
strcmp(f->func->base.name, "db_users") == 0) {
+                               set_count_prop(v->sql->sa, rel, 1000 /* TODO 
get size of users */);
+                       } else if (f->func->lang == FUNC_LANG_MAL && 
strncmp(f->func->base.name, "querylog", 8) == 0) {
+                               set_count_prop(v->sql->sa, rel, 1000 /* TODO 
get size of querylog */);
+                       } else if (f->func->lang == FUNC_LANG_MAL &&
+                                               (strcmp(f->func->base.name, 
"queue") == 0 ||
+                                                strcmp(f->func->base.name, 
"optimizers") == 0 ||
+                                                strcmp(f->func->base.name, 
"env") == 0 ||
+                                                strcmp(f->func->base.name, 
"keywords") == 0 ||
+                                                strcmp(f->func->base.name, 
"statistics") == 0 ||
+                                                strcmp(f->func->base.name, 
"rejects") == 0 ||
+                                                strcmp(f->func->base.name, 
"schemastorage") == 0 ||
+                                                strncmp(f->func->base.name, 
"storage", 7) == 0 ||
+                                                strcmp(f->func->base.name, 
"sessions") == 0) ) {
+                               set_count_prop(v->sql->sa, rel, 1000 /* TODO 
get size of queue */);
+                       /*} else {
+                               printf("%%func needs stats : %s\n", 
f->func->base.name);
+                               */
+                       }
+               }
+       } break;
        /*These relations are less important for now
-       case op_table: TODO later we can tune it
+       TODO later we can tune it
        case op_insert:
        case op_update:
        case op_delete:
diff --git a/sql/storage/bat/bat_storage.c b/sql/storage/bat/bat_storage.c
--- a/sql/storage/bat/bat_storage.c
+++ b/sql/storage/bat/bat_storage.c
@@ -365,6 +365,7 @@ segments2cs(sql_trans *tr, segments *seg
 static void
 merge_segments(storage *s, sql_trans *tr, sql_change *change, ulng commit_ts, 
ulng oldest)
 {
+       sqlstore* store = tr->store;
        segment *cur = s->segs->h, *seg = NULL;
        for (; cur; cur = cur->next) {
                if (cur->ts == tr->tid) {
@@ -372,24 +373,47 @@ merge_segments(storage *s, sql_trans *tr
                                cur->oldts = 0;
                        cur->ts = commit_ts;
                }
-               if (cur->ts <= oldest && cur->ts < TRANSACTION_ID_BASE) { /* 
possibly merge range */
-                       if (!seg) { /* skip first */
-                               seg = cur;
-                       } else if (seg->end == cur->start && seg->deleted == 
cur->deleted) {
-                               /* merge with previous */
-                               seg->end = cur->end;
-                               seg->next = cur->next;
-                               if (cur == s->segs->t)
-                                       s->segs->t = seg;
-                               if (commit_ts == oldest)
-                                       _DELETE(cur);
-                               else
-                                       mark4destroy(cur, change, commit_ts);
-                               cur = seg;
-                       } else {
-                               seg = cur; /* begin of new merge */
+               if (!seg) {
+                       /* first segment */
+                       seg = cur;
+               }
+               else if (seg->ts < TRANSACTION_ID_BASE) {
+                       /* possible merge since both deleted flags are equal */
+                       if (seg->deleted == cur->deleted && cur->ts < 
TRANSACTION_ID_BASE) {
+                               int merge = 1;
+                               node *n = store->active->h;
+                               for (int i = 0; i < store->active->cnt; i++, n 
= n->next) {
+                                       ulng active = ((sql_trans*)n->data)->ts;
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to