Changeset: a9f4aa006d3b for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a9f4aa006d3b Modified Files: monetdb5/modules/kernel/algebra.c sql/backends/monet5/sql_statement.c sql/server/rel_unnest.c sql/storage/bat/bat_storage.c sql/storage/store.c sql/test/BugTracker-2016/Tests/storagemodel.stable.out sql/test/mapi/Tests/utf8test.SQL.py sql/test/subquery/Tests/subquery4.sql sql/test/subquery/Tests/subquery4.stable.out sql/test/subquery/Tests/subquery6.sql sql/test/subquery/Tests/subquery6.stable.err sql/test/subquery/Tests/subquery6.stable.out testing/Mtest.py.in testing/process.py Branch: default Log Message:
Merged with Jun2020 diffs (truncated from 983 to 300 lines): diff --git a/monetdb5/modules/kernel/algebra.c b/monetdb5/modules/kernel/algebra.c --- a/monetdb5/modules/kernel/algebra.c +++ b/monetdb5/modules/kernel/algebra.c @@ -1189,9 +1189,17 @@ ALGfetch(ptr ret, const bat *bid, const if ((b = BATdescriptor(*bid)) == NULL) { throw(MAL, "algebra.fetch", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); } - if ((*pos < (lng) 0) || (*pos >= (lng) BUNlast(b))) { + if (*pos < (lng) 0) { + BBPunfix(b->batCacheid); + throw(MAL, "algebra.fetch", ILLEGAL_ARGUMENT ": row index to fetch must be non negative\n"); + } + if (BATcount(b) == 0) { BBPunfix(b->batCacheid); - throw(MAL, "algebra.fetch", ILLEGAL_ARGUMENT " Idx out of range\n"); + throw(MAL, "algebra.fetch", ILLEGAL_ARGUMENT ": cannot fetch a single row from an empty input\n"); + } + if (*pos >= (lng) BUNlast(b)) { + BBPunfix(b->batCacheid); + throw(MAL, "algebra.fetch", ILLEGAL_ARGUMENT ": row index to fetch is out of range\n"); } msg = doALGfetch(ret, b, (BUN) *pos); BBPunfix(b->batCacheid); diff --git a/sql/backends/monet5/sql_statement.c b/sql/backends/monet5/sql_statement.c --- a/sql/backends/monet5/sql_statement.c +++ b/sql/backends/monet5/sql_statement.c @@ -3963,13 +3963,22 @@ const_column(backend *be, stmt *val) stmt * stmt_fetch(backend *be, stmt *val) { - sql_subtype *ct = tail_type(val); + sql_subtype *ct; MalBlkPtr mb = be->mb; InstrPtr q = NULL; - int tt = ct->type->localtype; + int tt; if (val->nr < 0) return NULL; + /* pick from first column on a table case */ + if (val->type == st_table) { + if (list_length(val->op1->op4.lval) > 1) + return NULL; + val = val->op1->op4.lval->h->data; + } + ct = tail_type(val); + tt = ct->type->localtype; + q = newStmt(mb, algebraRef, fetchRef); if (q == NULL) return NULL; diff --git a/sql/server/rel_unnest.c b/sql/server/rel_unnest.c --- a/sql/server/rel_unnest.c +++ b/sql/server/rel_unnest.c @@ -1569,8 +1569,19 @@ rewrite_inner(mvc *sql, sql_rel *rel, sq static sql_exp * rewrite_exp_rel(visitor *v, sql_rel *rel, sql_exp *e, int depth) { - (void)depth; - if (exp_has_rel(e) && !is_ddl(rel->op)) { + if (exp_is_rel(e) && is_ddl(rel->op) && rel->flag == ddl_psm) { + sql_rel *inner = exp_rel_get_rel(v->sql->sa, e); + if (is_single(inner)) { + /* use a dummy projection for the single join */ + sql_rel *nrel = rel_project(v->sql->sa, NULL, append(sa_list(v->sql->sa), exp_atom_bool(v->sql->sa, 1))); + + if (!rewrite_inner(v->sql, nrel, inner, depth?op_left:op_join)) + return NULL; + /* has to apply recursively */ + if (!(e->l = rel_exp_visitor_bottomup(v, nrel, &rewrite_exp_rel))) + return NULL; + } + } else if (exp_has_rel(e) && !is_ddl(rel->op)) { sql_exp *ne = rewrite_inner(v->sql, rel, exp_rel_get_rel(v->sql->sa, e), depth?op_left:op_join); if (!ne) @@ -1586,9 +1597,6 @@ rewrite_exp_rel(visitor *v, sql_rel *rel e = exp_rel_update_exp(v->sql, e); } } - if (exp_is_rel(e) && is_ddl(rel->op)) - if (!(e->l = rel_exp_visitor_bottomup(v, e->l, &rewrite_exp_rel))) - return NULL; return e; } @@ -2104,7 +2112,7 @@ static sql_exp * rewrite_anyequal(mvc *sql, sql_rel *rel, sql_exp *e, int depth) { sql_subfunc *sf; - if (e->type != e_func || is_ddl(rel->op)) + if (e->type != e_func) return e; sf = e->f; @@ -2236,6 +2244,8 @@ rewrite_anyequal(mvc *sql, sql_rel *rel, if (exp_name(e)) exp_prop_alias(sql->sa, le, e); set_processed(lsq); + if (depth == 1 && is_ddl(rel->op)) /* anyequal is at a ddl statment, it must be inside a relation */ + return exp_rel(sql, lsq); return le; } else { if (lsq) @@ -2584,7 +2594,7 @@ static sql_exp * rewrite_exists(visitor *v, sql_rel *rel, sql_exp *e, int depth) { sql_subfunc *sf; - if (e->type != e_func || is_ddl(rel->op)) + if (e->type != e_func) return e; sf = e->f; @@ -2595,8 +2605,12 @@ rewrite_exists(visitor *v, sql_rel *rel, sql_exp *ne = NULL, *ie = l->h->data, *le; sql_rel *sq = NULL; - if (!exp_is_rel(ie)) /* already fine */ + if (!exp_is_rel(ie)) { /* exists over a constant or a single value */ + const char *rname = exp_relname(e), *name = exp_name(e); + e = exp_atom_bool(v->sql->sa, is_exists(sf)?1:0); + exp_setname(v->sql->sa, e, rname, name); return e; + } sq = exp_rel_get_rel(v->sql->sa, ie); /* get subquery */ @@ -2637,6 +2651,8 @@ rewrite_exists(visitor *v, sql_rel *rel, if (exp_name(e)) exp_prop_alias(v->sql->sa, le, e); set_processed(sq); + if (depth == 1 && is_ddl(rel->op)) /* exists is at a ddl statment, it must be inside a relation */ + return exp_rel(v->sql, sq); } else { /* rewrite into semi/anti join */ (void)rewrite_inner(v->sql, rel, sq, is_exists(sf)?op_semi:op_anti); return exp_atom_bool(v->sql->sa, 1); 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 @@ -958,6 +958,39 @@ delta_delete_val( sql_dbat *bat, oid rid return LOG_OK; } +static void +_destroy_dbat(sql_dbat *bat) +{ + assert(bat->r.refcnt == 0); + if (bat->dname) + _DELETE(bat->dname); + if (bat->dbid) + temp_destroy(bat->dbid); + if (bat->cached) { + bat_destroy(bat->cached); + bat->cached = NULL; + } + bat->dbid = 0; + bat->dname = NULL; + _DELETE(bat); +} + +static int +destroy_dbat(sql_trans *tr, sql_dbat *bat) +{ + sql_dbat *n; + + (void)tr; + while(bat) { + n = bat->next; + if (sql_ref_dec(&bat->r) > 0) + return LOG_OK; + _destroy_dbat(bat); + bat = n; + } + return LOG_OK; +} + static int bind_del_data(sql_trans *tr, sql_table *t) { @@ -966,9 +999,12 @@ bind_del_data(sql_trans *tr, sql_table * sql_dbat *bat = ZNEW(sql_dbat), *obat; if(!bat) return LOG_ERR; + if (t->data) + destroy_dbat(tr, t->data); t->data = bat; obat = timestamp_dbat(ot->data, t->base.stime); dup_dbat(tr, obat, bat, isNew(ot), isTempTable(t)); + destroy_dbat(tr, obat); t->base.allocated = 1; } return LOG_OK; @@ -1812,38 +1848,6 @@ log_destroy_idx(sql_trans *tr, sql_idx * return LOG_OK; } -static void -_destroy_dbat(sql_dbat *bat) -{ - if (sql_ref_dec(&bat->r) > 0) - return; - if (bat->dname) - _DELETE(bat->dname); - if (bat->dbid) - temp_destroy(bat->dbid); - if (bat->cached) { - bat_destroy(bat->cached); - bat->cached = NULL; - } - bat->dbid = 0; - bat->dname = NULL; - _DELETE(bat); -} - -static int -destroy_dbat(sql_trans *tr, sql_dbat *bat) -{ - sql_dbat *n; - - (void)tr; - while(bat) { - n = bat->next; - _destroy_dbat(bat); - bat = n; - } - return LOG_OK; -} - static int cleanup(void) { @@ -1885,9 +1889,9 @@ delayed_destroy_dbat(sql_dbat *b) if (!n) return LOG_OK; + MT_lock_set(&destroy_lock); while(n->next) n = n->next; - MT_lock_set(&destroy_lock); n->next = tobe_destroyed_dbat; tobe_destroyed_dbat = b; MT_lock_unset(&destroy_lock); @@ -1899,7 +1903,7 @@ destroy_del(sql_trans *tr, sql_table *t) { int ok = LOG_OK; - if (t->data && t->base.allocated) { + if (t->data /* && t->base.allocated */) { t->base.allocated = 0; ok = destroy_dbat(tr, t->data); } @@ -2700,8 +2704,11 @@ update_table(sql_trans *tr, sql_table *f assert(tt->data); if (tr_merge_dbat(tr, tt->data) != LOG_OK) ok = LOG_ERR; + if (ft->data) + destroy_del(tr, ft); ft->data = NULL; } else if (ft->data) { + assert(!tt->data); tt->data = ft->data; tt->base.allocated = 1; ft->data = NULL; diff --git a/sql/storage/store.c b/sql/storage/store.c --- a/sql/storage/store.c +++ b/sql/storage/store.c @@ -3487,6 +3487,8 @@ table_dup(sql_trans *tr, int flags, sql_ * on savepoints from tr->parent to new tr */ if (flags) { t->base.allocated = ot->base.allocated; + if (ot->data) + (void)store_funcs.destroy_del(tr, ot); t->data = ot->data; ot->base.allocated = 0; ot->data = NULL; @@ -3755,8 +3757,10 @@ trans_init(sql_trans *tr, backend_stack t->base.rtime = t->base.wtime = 0; t->base.stime = pt->base.wtime; - if (!istmp && !t->base.allocated) + if (!istmp && !t->base.allocated) { + (void)store_funcs.destroy_del(tr, t); t->data = NULL; + } assert (istmp || !t->base.allocated); if (pt->base.id == t->base.id) { diff --git a/sql/test/BugTracker-2016/Tests/storagemodel.stable.out b/sql/test/BugTracker-2016/Tests/storagemodel.stable.out --- a/sql/test/BugTracker-2016/Tests/storagemodel.stable.out +++ b/sql/test/BugTracker-2016/Tests/storagemodel.stable.out @@ -83,8 +83,8 @@ stdout of test 'storagemodel` in directo % sys.storagemodel, sys.storagemodel, sys.storagemodel, sys.storagemodel, sys.storagemodel, sys.storagemodel, sys.storagemodel, sys.storagemodel, sys.storagemodel, sys.storagemodel, sys.storagemodel, sys.storagemodel, sys.storagemodel # table_name % schema, table, column, type, count, columnsize, heapsize, hashsize, imprintsize, orderidxsize, sorted, unique, isacolumn # name % varchar, varchar, varchar, varchar, bigint, bigint, bigint, bigint, bigint, bigint, boolean, boolean, boolean # type -% 3, 7, 1, 3, 5, 5, 4, 1, 4, 1, 5, 5, 5 # length -[ "sys", "bug3923", "i", "int", 10000, 10000, 8312, 0, 2000, 0, true, NULL, true ] +% 3, 7, 1, 3, 5, 5, 1, 1, 4, 1, 5, 5, 5 # length +[ "sys", "bug3923", "i", "int", 10000, 40000, 0, 0, 8000, 0, true, NULL, true ] #drop table bug3923; #create table bug3923(i integer); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list