Changeset: 4fb611bd75cb for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=4fb611bd75cb Modified Files: sql/backends/monet5/sql_execute.c sql/backends/monet5/sql_gencode.c sql/backends/monet5/sql_scenario.c sql/backends/monet5/wlr.c sql/include/sql_catalog.h sql/server/rel_psm.c sql/server/sql_mvc.h sql/server/sql_qc.c sql/storage/bat/bat_storage.c sql/storage/bat/bat_storage.h sql/storage/bat/bat_table.c sql/storage/bat/bat_utils.c sql/storage/bat/bat_utils.h sql/storage/sql_catalog.c sql/storage/store.c Branch: nospare Log Message:
reworked the temp tables (now split in global and localtmps (is transaction local changeset)) as we now have a single multiversion-transaction tree functions are shared as well, ie use module 'sql' to register the mal function, instead of 'user'. For prepare and current query mal plans we still need to use a private ('user') module. diffs (truncated from 1129 to 300 lines): diff --git a/sql/backends/monet5/sql_execute.c b/sql/backends/monet5/sql_execute.c --- a/sql/backends/monet5/sql_execute.c +++ b/sql/backends/monet5/sql_execute.c @@ -459,7 +459,7 @@ SQLstatementIntern(Client c, const char * optimize and produce code. * We don't search the cache for a previous incarnation yet. */ - if((msg = MSinitClientPrg(c, "user", nme)) != MAL_SUCCEED) { + if((msg = MSinitClientPrg(c, sql_private_module_name, nme)) != MAL_SUCCEED) { goto endofcompile; } oldvtop = c->curprg->def->vtop; @@ -774,7 +774,7 @@ RAstatement(Client c, MalBlkPtr mb, MalS if (*opt && rel) rel = sql_processrelation(m, rel, 1, 1); - if ((msg = MSinitClientPrg(c, "user", "test")) != MAL_SUCCEED) { + if ((msg = MSinitClientPrg(c, sql_private_module_name, "test")) != MAL_SUCCEED) { rel_destroy(rel); return msg; } diff --git a/sql/backends/monet5/sql_gencode.c b/sql/backends/monet5/sql_gencode.c --- a/sql/backends/monet5/sql_gencode.c +++ b/sql/backends/monet5/sql_gencode.c @@ -787,9 +787,9 @@ backend_dumpproc(backend *be, Client c, if (argc < MAXARG) argc = MAXARG; if (cq) - c->curprg = newFunctionArgs(userRef, putName(cq->name), FUNCTIONsymbol, argc); + c->curprg = newFunctionArgs(putName(sql_private_module_name), putName(cq->name), FUNCTIONsymbol, argc); else - c->curprg = newFunctionArgs(userRef, "tmp", FUNCTIONsymbol, argc); + c->curprg = newFunctionArgs(putName(sql_private_module_name), "tmp", FUNCTIONsymbol, argc); if (c->curprg == NULL) { sql_error(m, 001, SQLSTATE(HY013) MAL_MALLOC_FAIL); return NULL; @@ -801,7 +801,7 @@ backend_dumpproc(backend *be, Client c, curInstr = getInstrPtr(mb, 0); /* we do not return anything */ setVarType(mb, 0, TYPE_void); - setModuleId(curInstr, userRef); + setModuleId(curInstr, putName(sql_private_module_name)); if (m->params) { /* needed for prepare statements */ @@ -1154,7 +1154,7 @@ backend_create_sql_func(backend *be, sql } backup = c->curprg; - curPrg = c->curprg = newFunctionArgs(userRef, putName(f->base.name), FUNCTIONsymbol, (f->res && f->type == F_UNION ? list_length(f->res) : 1) + (f->vararg && ops ? list_length(ops) : f->ops ? list_length(f->ops) : 0)); + curPrg = c->curprg = newFunctionArgs(putName(sql_shared_module_name), putName(f->base.name), FUNCTIONsymbol, (f->res && f->type == F_UNION ? list_length(f->res) : 1) + (f->vararg && ops ? list_length(ops) : f->ops ? list_length(f->ops) : 0)); if( curPrg == NULL) { sql_error(m, 001, SQLSTATE(HY013) MAL_MALLOC_FAIL); goto cleanup; diff --git a/sql/backends/monet5/sql_scenario.c b/sql/backends/monet5/sql_scenario.c --- a/sql/backends/monet5/sql_scenario.c +++ b/sql/backends/monet5/sql_scenario.c @@ -417,10 +417,12 @@ SQLinit(Client c) /* check whether table sys.systemfunctions exists: if * it doesn't, this is probably a restart of the * server after an incomplete initialization */ - sql_schema *s = mvc_bind_schema(m, "sys"); - sql_table *t = s ? mvc_bind_table(m, s, "systemfunctions") : NULL; - if (t == NULL) - store->first = 1; + if ((msg = SQLtrans(m)) == MAL_SUCCEED) { + sql_schema *s = mvc_bind_schema(m, "sys"); + sql_table *t = s ? mvc_bind_table(m, s, "systemfunctions") : NULL; + if (t == NULL) + store->first = 1; + } } if (store->first > 0) { store->first = 0; diff --git a/sql/backends/monet5/wlr.c b/sql/backends/monet5/wlr.c --- a/sql/backends/monet5/wlr.c +++ b/sql/backends/monet5/wlr.c @@ -244,7 +244,7 @@ WLRprocessBatch(Client cntxt) } /* Cook a log file into a concreate MAL function for multiple transactions */ - prev = newFunction(putName("user"), putName("wlr"), FUNCTIONsymbol); + prev = newFunction(putName(sql_private_module_name), putName("wlr"), FUNCTIONsymbol); if(prev == NULL) { MCcloseClient(c); throw(MAL, "wlr.batch", "Could not create user for WLR process\n"); diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h --- a/sql/include/sql_catalog.h +++ b/sql/include/sql_catalog.h @@ -312,6 +312,7 @@ typedef struct sql_trans { sql_catalog *cat; sql_schema *tmp; /* each session has its own tmp schema */ + changeset localtmps; sql_allocator *sa; /* transaction allocator */ struct sql_trans *parent; /* multilevel transaction support */ diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c --- a/sql/server/rel_psm.c +++ b/sql/server/rel_psm.c @@ -985,7 +985,7 @@ rel_create_func(sql_query *query, dlist if (create) { /* needed for recursive functions */ q = query_cleaned(sql->ta, q); - sql->forward = f = mvc_create_func(sql, sql->sa, s, fname, l, restype, type, lang, "user", q, q, FALSE, vararg, FALSE); + sql->forward = f = mvc_create_func(sql, sql->sa, s, fname, l, restype, type, lang, sql_shared_module_name, q, q, FALSE, vararg, FALSE); } sql->session->schema = s; b = sequential_block(query, (ra)?&ra->type:NULL, ra?NULL:restype, body, NULL, is_func); diff --git a/sql/server/sql_mvc.h b/sql/server/sql_mvc.h --- a/sql/server/sql_mvc.h +++ b/sql/server/sql_mvc.h @@ -68,6 +68,9 @@ /* locked needs unlocking */ #define mod_locked 16 +#define sql_shared_module_name "sql" +#define sql_private_module_name "user" + typedef struct sql_groupby_expression { symbol *sdef; tokens token; diff --git a/sql/server/sql_qc.c b/sql/server/sql_qc.c --- a/sql/server/sql_qc.c +++ b/sql/server/sql_qc.c @@ -151,7 +151,7 @@ qc_insert(qc *cache, sql_allocator *sa, } *f = (sql_func) { - .mod = "user", + .mod = sql_private_module_name, .type = F_PROC, .query = cmd, .ops = params, 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 @@ -22,6 +22,21 @@ static int log_create_col(sql_trans *tr, static int log_create_idx(sql_trans *tr, sql_change *change, ulng commit_ts, ulng oldest); static int log_create_del(sql_trans *tr, sql_change *change, ulng commit_ts, ulng oldest); + +/* + * The sql data is stored using 2 structure + * sql_delta and sql_dbat. The dbat keeps the deleted rows and + * the delta structure the column content consisting of a stable bat, + * inserts and updates. + * + * The monetdb sql part uses MVCC, where the multiple versions of a these + * structures keep timestamps (ts). + * + * The code needs too handle 3 cases of tables/transactions, + * global persistent tables in normal transactions (ie those a chain of versions). + * temporary tables, the chain holds a version per transaction. + * save points these need too look at the parent transaction (and are private too one transaction). + */ static int tr_merge_delta( sql_trans *tr, sql_delta *obat); static int @@ -33,17 +48,74 @@ tr_version_of_parent(sql_trans *tr, ulng return 0; } -sql_delta * -timestamp_delta( sql_trans *tr, sql_delta *d) +static sql_delta * +temp_dup_delta(ulng tid, int type) +{ + sql_delta *bat = ZNEW(sql_delta); + BAT *b = bat_new(type, 1024, TRANSIENT); + bat->bid = temp_create(b); + bat_destroy(b); + bat->ibid = e_bat(type); + bat->uibid = e_bat(TYPE_oid); + bat->uvbid = e_bat(type); + bat->ibase = 0; + bat->ucnt = bat->cnt = 0; + bat->cleared = 0; + bat->ts = tid; + return bat; +} + +static sql_delta * +get_delta(sql_delta *d, ulng tid, int type, int is_temp) { + if (is_temp) { + while (d && d->ts != tid) + d = d->next; + if (!d) + return temp_dup_delta(tid, type); + } + return d; +} + +static sql_dbat * +temp_dup_dbat(ulng tid) +{ + sql_dbat *bat = ZNEW(sql_dbat); + BAT *b = bat_new(TYPE_oid, 1024, TRANSIENT); + bat->dbid = temp_create(b); + bat_destroy(b); + bat->cnt = 0; + bat->ts = tid; + return bat; +} + +static sql_dbat * +get_dbat(sql_dbat *d, ulng tid, int is_temp) +{ + if (is_temp) { + while (d && d->ts != tid) + d = d->next; + if (!d) + return temp_dup_dbat(tid); + } + return d; +} + +static sql_delta * +timestamp_delta( sql_trans *tr, sql_delta *d, int type, int is_temp) +{ + if (is_temp) + return get_delta(d, tr->tid, type, is_temp); while (d->next && d->ts != tr->tid && (tr->parent && !tr_version_of_parent(tr, d->ts)) && d->ts > tr->ts) d = d->next; return d; } -sql_dbat * -timestamp_dbat( sql_trans *tr, sql_dbat *d) +static sql_dbat * +timestamp_dbat( sql_trans *tr, sql_dbat *d, int is_temp) { + if (is_temp) + return get_dbat(d, tr->tid, is_temp); while (d->next && d->ts != tr->tid && (tr->parent && !tr_version_of_parent(tr, d->ts)) && d->ts > tr->ts) d = d->next; return d; @@ -102,11 +174,8 @@ static BAT * bind_del(sql_trans *tr, sql_table *t, int access) { assert(access == QUICK || tr->active); - if (!t->data) { - sql_table *ot = tr_find_table(tr->parent, t); - t->data = timestamp_dbat(tr, ot->data); - } - return delta_bind_del(t->data, access); + sql_dbat *d = timestamp_dbat(tr, t->data, isTempTable(t)); + return delta_bind_del(d, access); } static BAT * @@ -141,37 +210,18 @@ delta_bind_ubat(sql_delta *bat, int acce static BAT * bind_ucol(sql_trans *tr, sql_column *c, int access) { - BAT *u = NULL; - assert(tr->active); - if (!c->data) { - sql_column *oc = tr_find_column(tr->parent, c); - c->data = timestamp_delta(tr, oc->data); - } - if (!c->t->data) { - sql_table *ot = tr_find_table(tr->parent, c->t); - c->t->data = timestamp_dbat(tr, ot->data); - } - u = delta_bind_ubat(c->data, access, c->type.type->localtype); - return u; + sql_delta *d = timestamp_delta(tr, c->data, c->type.type->localtype, isTempTable(c->t)); + return delta_bind_ubat(d, access, c->type.type->localtype); } static BAT * bind_uidx(sql_trans *tr, sql_idx * i, int access) { - BAT *u = NULL; - + int type = oid_index(i->type)?TYPE_oid:TYPE_lng; assert(tr->active); - if (!i->data) { - sql_idx *oi = tr_find_idx(tr->parent, i); - i->data = timestamp_delta(tr, oi->data); - } - if (!i->t->data) { - sql_table *ot = tr_find_table(tr->parent, i->t); - i->t->data = timestamp_dbat(tr, ot->data); - } - u = delta_bind_ubat(i->data, access, (oid_index(i->type))?TYPE_oid:TYPE_lng); - return u; + sql_delta *d = timestamp_delta(tr, i->data, type, isTempTable(i->t)); + return delta_bind_ubat(d, access, type); } static BAT * @@ -249,13 +299,11 @@ bind_col(sql_trans *tr, sql_column *c, i assert(access == QUICK || tr->active); if (!isTable(c->t)) return NULL; - if (!c->data) { _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list