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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list