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