Changeset: 96178f0350b8 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=96178f0350b8
Modified Files:
        gdk/gdk_logger.c
        monetdb5/optimizer/opt_pushselect.c
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql.c
        sql/backends/monet5/sql_cat.c
        sql/storage/bat/bat_storage.c
        sql/storage/bat/bat_storage.h
        sql/storage/bat/bat_table.c
        sql/storage/store.c
Branch: unlock
Log Message:

the storage is now organised using column_storage
        consisting of a bat for storage and bats for
        updates (id,val).

insert first claims a slot, which marks this slot 'deleted'
in the gtrans (or any intermediate savepoint) and marked as
used localy using the updates on the deleted column.

Deletes are updates on the deleted column.

Updates are like before treated within private bats.


diffs (truncated from 1227 to 300 lines):

diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c
--- a/gdk/gdk_logger.c
+++ b/gdk/gdk_logger.c
@@ -1649,6 +1649,8 @@ logger_load(int debug, const char *fn, c
                }
                for( ; log_id <= lg->saved_id; log_id++)
                        (void)logger_cleanup(lg, log_id);  /* ignore error of 
removing file */
+       } else {
+               lg->id = lg->saved_id+1;
        }
        return GDK_SUCCEED;
   error:
@@ -1698,7 +1700,7 @@ logger_new(int debug, const char *fn, co
                .prefuncp = prefuncp,
                .postfuncp = postfuncp,
 
-               .id = 1,
+               .id = 0,
                .saved_id = getBBPlogno(),              /* get saved log numer 
from bbp */
                .saved_tid = (int)getBBPtransid(),      /* get saved 
transaction id from bbp */
        };
diff --git a/monetdb5/optimizer/opt_pushselect.c 
b/monetdb5/optimizer/opt_pushselect.c
--- a/monetdb5/optimizer/opt_pushselect.c
+++ b/monetdb5/optimizer/opt_pushselect.c
@@ -35,6 +35,16 @@ PushNil(MalBlkPtr mb, InstrPtr p, int po
        return p;
 }
 
+static InstrPtr
+ReplaceWithNil(MalBlkPtr mb, InstrPtr p, int pos, int tpe)
+{
+       p = pushNil(mb, p, tpe); /* push at end */
+       getArg(p, pos) = getArg(p, p->argc-1);
+       p->argc--;
+       return p;
+}
+
+
 #define MAX_TABLES 64
 
 typedef struct subselect_t {
@@ -611,12 +621,12 @@ OPTpushselectImplementation(Client cntxt
                        }
                        if (q && getModuleId(q) == sqlRef && getFunctionId(q) 
== deltaRef) {
                                InstrPtr r = copyInstruction(p);
-                               InstrPtr t = copyInstruction(p);
+                               InstrPtr s = copyInstruction(p);
                                InstrPtr u = copyInstruction(q);
                
-                               if( r == NULL || t== NULL ||u == NULL){
+                               if( r == NULL || s == NULL ||u == NULL){
                                        freeInstruction(r);
-                                       freeInstruction(t);
+                                       freeInstruction(s);
                                        freeInstruction(u);
                                        GDKfree(vars);
                                        GDKfree(nvars);
@@ -631,17 +641,28 @@ OPTpushselectImplementation(Client cntxt
                                getArg(r, 1) = getArg(q, 1); /* column */
                                r->typechk = TYPE_UNKNOWN;
                                pushInstruction(mb,r);
-                               getArg(t, 0) = newTmpVariable(mb, 
newBatType(TYPE_oid));
-                               setVarCList(mb,getArg(t,0));
-                               pushInstruction(mb,t);
+                               getArg(s, 0) = newTmpVariable(mb, 
newBatType(TYPE_oid));
+                               setVarCList(mb,getArg(s,0));
+                               getArg(s, 1) = getArg(q, 3); /* updates */
+                               s = ReplaceWithNil(mb, s, 2, TYPE_bat); /* no 
candidate list */
+                               setArgType(mb, s, 2, newBatType(TYPE_oid));
+                               /* make sure to resolve again */
+                               s->token = ASSIGNsymbol; 
+                               s->typechk = TYPE_UNKNOWN;
+                               s->fcn = NULL;
+                               s->blk = NULL;
+                               pushInstruction(mb,s);
 
                                setFunctionId(u, subdeltaRef);
                                getArg(u, 0) = getArg(p,0);
                                getArg(u, 1) = getArg(r,0);
                                getArg(u, 2) = getArg(p,2); /* pre-cands */
                                getArg(u, 3) = getArg(q,2); /* update ids */
-                               u = pushArgument(mb, u, getArg(t,0));
+                               u = pushArgument(mb, u, getArg(s,0)); /* 
selected updated values ids */
+                               u->token = ASSIGNsymbol; 
                                u->typechk = TYPE_UNKNOWN;
+                               u->fcn = NULL;
+                               u->blk = NULL;
                                pushInstruction(mb,u);  
                                oclean[i] = 1;
                                continue;
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
@@ -5360,7 +5360,7 @@ check_for_foreign_key_references(mvc *sq
                                                if (k->t != t && !cascade) {
                                                        node *n = 
t->columns.set->h;
                                                        sql_column *c = n->data;
-                                                       size_t n_rows = 
store_funcs.count_col(sql->session->tr, c, 1);
+                                                       size_t n_rows = 
store_funcs.count_col(sql->session->tr, c, 0);
                                                        size_t n_deletes = 
store_funcs.count_del(sql->session->tr, c->t, 0);
                                                        assert (n_rows >= 
n_deletes);
                                                        if (n_rows - n_deletes 
> 0) {
diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -2267,7 +2267,7 @@ SQLtid(Client cntxt, MalBlkPtr mb, MalSt
                        d = nd;
                }
                bit *deleted = (bit*)Tloc(d, 0); 
-               for(BUN p = 0; p < nr; p++) {
+               for(BUN p = sb; p < sb+nr; p++) {
                        if (deleted[p]) {
                                oid id = p;
                                if (BUNappend(del_ids, &id, false) != 
GDK_SUCCEED) {
diff --git a/sql/backends/monet5/sql_cat.c b/sql/backends/monet5/sql_cat.c
--- a/sql/backends/monet5/sql_cat.c
+++ b/sql/backends/monet5/sql_cat.c
@@ -63,14 +63,9 @@ table_has_updates(sql_trans *tr, sql_tab
 
        for ( n = t->columns.set->h; !cnt && n; n = n->next) {
                sql_column *c = n->data;
-               BAT *b = store_funcs.bind_col(tr, c, RD_UPD_ID);
-               if ( b == 0)
-                       return -1;
-               cnt |= BATcount(b) > 0;
-               if (isTable(t) && t->access != TABLE_READONLY && (!isNew(t) /* 
alter */ ) &&
-                   t->persistence == SQL_PERSIST && !t->commit_action)
-                       cnt |= store_funcs.count_col(tr, c, 0) > 0;
-               BBPunfix(b->batCacheid);
+
+               size_t upd = store_funcs.count_col( tr, c, 2/* count updates 
*/);
+               cnt |= upd > 0;
        }
        return cnt;
 }
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
@@ -40,13 +40,167 @@ timestamp_dbat( storage *d, int ts)
        return d;
 }
 
+static size_t
+count_col(sql_trans *tr, sql_column *c, int access)
+{
+       storage *d;
+       sql_table *t = c->t;
+
+       if (!isTable(c->t)) 
+               return 0;
+       if (!t->data) {
+               sql_table *ot = tr_find_table(tr->parent, t);
+               t->data = timestamp_dbat(ot->data, t->base.stime);
+       }
+       d = t->data;
+       if (!d)
+               return 0;
+       if (access == 2) 
+               return d->cs.ucnt;
+       if (access == 1) /* TODO improve */
+               return (d->segs.owner == tr)?d->segs.end - d->segs.start:0;
+       return d->segs.end;
+}
+
+static size_t
+dcount_col(sql_trans *tr, sql_column *c)
+{
+       sql_delta *b;
+       assert(0);
+
+       if (!isTable(c->t)) 
+               return 0;
+       if (!c->data) {
+               sql_column *oc = tr_find_column(tr->parent, c);
+               c->data = timestamp_delta(oc->data, c->base.stime);
+       }
+       b = c->data;
+       if (!b)
+               return 1;
+       assert(0);
+       /* TDOO */
+       return 0;
+}
+
+static size_t
+count_idx(sql_trans *tr, sql_idx *i, int access)
+{
+       storage *d;
+       sql_table *t = i->t;
+
+       if (!isTable(i->t) || (hash_index(i->type) && list_length(i->columns) 
<= 1) || !idx_has_column(i->type)) 
+               return 0;
+       if (!t->data) {
+               sql_table *ot = tr_find_table(tr->parent, t);
+               t->data = timestamp_dbat(ot->data, t->base.stime);
+       }
+       d = t->data;
+       if (!d)
+               return 0;
+       if (access == 2) 
+               return d->cs.ucnt;
+       if (access == 1) /* TODO improve */
+               return (d->segs.owner == tr)?d->segs.end - d->segs.start:0;
+       return d->segs.end;
+}
+
+static int
+cs_real_update_bats( column_storage *cs, BAT **Ui, BAT **Uv)
+{
+       BAT *ui = temp_descriptor(cs->uibid);
+       BAT *uv = temp_descriptor(cs->uvbid);
+
+       if (ui == NULL || uv == NULL) {
+               bat_destroy(ui);
+               bat_destroy(uv);
+               return LOG_ERR;
+       }
+       assert(ui && uv);
+       if (isEbat(ui)){
+               temp_destroy(cs->uibid);
+               cs->uibid = temp_copy(ui->batCacheid, false);
+               bat_destroy(ui);
+               if (cs->uibid == BID_NIL ||
+                   (ui = temp_descriptor(cs->uibid)) == NULL) {
+                       bat_destroy(uv);
+                       return LOG_ERR;
+       }
+       }
+       if (isEbat(uv)){
+               temp_destroy(cs->uvbid);
+               cs->uvbid = temp_copy(uv->batCacheid, false);
+               bat_destroy(uv);
+               if (cs->uvbid == BID_NIL ||
+                   (uv = temp_descriptor(cs->uvbid)) == NULL) {
+                       bat_destroy(ui);
+                       return LOG_ERR;
+               }
+       }
+       *Ui = ui;
+       *Uv = uv;
+       return LOG_OK;
+}
+
+static size_t
+count_deletes(storage *d) 
+{
+       /* needs to be optimized */
+       BAT *b = temp_descriptor(d->cs.bid);
+       bit t = TRUE;
+       BAT *s = BATselect(b, NULL, &t, NULL, true, false, false);
+       size_t cnt = 0;
+
+       bat_destroy(b);
+       if (d->cs.ucnt) {
+               BAT *ui, *uv, *cminu;
+
+               if (cs_real_update_bats(&d->cs, &ui, &uv) == LOG_ERR)
+                       return 0;
+               cminu = BATdiff(s, ui, NULL, NULL, false, false, BUN_NONE);
+               BBPunfix(s->batCacheid);
+               BBPunfix(ui->batCacheid);
+               if (!cminu) {
+                       BBPunfix(uv->batCacheid);
+                       return 0;
+               }
+               cnt = BATcount(cminu);
+               BBPunfix(cminu->batCacheid);
+               s = BATselect(uv, NULL, &t, NULL, true, false, false);
+               BBPunfix(uv->batCacheid);
+               if (!s)
+                       return 0;
+       }
+       cnt += BATcount(s);
+       bat_destroy(s);
+       return cnt;
+}
+
+static size_t
+count_del(sql_trans *tr, sql_table *t, int access)
+{
+       storage *d;
+
+       if (!isTable(t))
+               return 0;
+       if (!t->data) {
+               sql_table *ot = tr_find_table(tr->parent, t);
+               t->data = timestamp_dbat(ot->data, t->base.stime);
+       }
+       d = t->data;
+       if (!d)
+               return 0;
+       if (access == 2)
+               return d->cs.ucnt;
+       if (access == 1) /* TODO improve */
+               return (d->segs.owner == tr)?d->segs.end - d->segs.start:0;
+       return count_deletes(d);
+}
+
 static BAT *
 cs_bind_ubat( column_storage *cs, int access, int type)
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to