Changeset: ca8c7e13eb81 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/ca8c7e13eb81 Modified Files: monetdb5/modules/mal/remote.c sql/server/rel_optimizer.c Branch: default Log Message:
Merged with Jul2021 diffs (truncated from 420 to 300 lines): diff --git a/monetdb5/modules/mal/remote.c b/monetdb5/modules/mal/remote.c --- a/monetdb5/modules/mal/remote.c +++ b/monetdb5/modules/mal/remote.c @@ -596,7 +596,6 @@ typedef struct _binbat_v1 { Tnonil:1, Tdense:1; BUN size; - size_t headsize; size_t tailsize; size_t theapsize; } binbat; @@ -604,7 +603,7 @@ typedef struct _binbat_v1 { static str RMTinternalcopyfrom(BAT **ret, char *hdr, stream *in, bool must_flush) { - binbat bb = { 0, 0, 0, false, false, false, false, false, 0, 0, 0, 0 }; + binbat bb = { 0, 0, 0, false, false, false, false, false, 0, 0, 0 }; char *nme = NULL; char *val = NULL; char tmp; @@ -750,7 +749,6 @@ RMTinternalcopyfrom(BAT **ret, char *hdr if (bb.Ttype == TYPE_str && bb.size) BATsetcapacity(b, (BUN) (bb.tailsize >> b->tshift)); BATsetcount(b, bb.size); - b->batDirtydesc = true; // read blockmode flush while (must_flush && mnstr_read(in, &tmp, 1, 1) > 0) { @@ -1550,7 +1548,7 @@ static str RMTbincopyto(Client cntxt, Ma v->tnonil, BATtdense(v), v->batCount, - (size_t)v->batCount << v->tshift, + BATtvoid(v) ? 0 : (size_t)v->batCount << v->tshift, sendtheap && v->batCount > 0 ? v->tvheap->free : 0 ); 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 @@ -84,44 +84,71 @@ rel_check_tables(mvc *sql, sql_table *nt if (subtype_cmp(&nc->type, &mc->type) != 0) throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table column type doesn't match %s definition", errtable, errtable); + if (nc->null != mc->null) + throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table column NULL check doesn't match %s definition", errtable, errtable); if (isRangePartitionTable(nt) || isListPartitionTable(nt)) { - if (nc->null != mc->null) - throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table column NULL check doesn't match %s definition", errtable, errtable); if ((!nc->def && mc->def) || (nc->def && !mc->def) || (nc->def && mc->def && strcmp(nc->def, mc->def) != 0)) throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table column DEFAULT value doesn't match %s definition", errtable, errtable); } } - if (isNonPartitionedTable(nt)) { - if (ol_length(nt->idxs) != ol_length(nnt->idxs)) - throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table index doesn't match %s definition", errtable, errtable); - if (ol_length(nt->idxs)) - for (n = ol_first_node(nt->idxs), m = ol_first_node(nnt->idxs); n && m; n = n->next, m = m->next) { - sql_idx *ni = n->data; - sql_idx *mi = m->data; + if (ol_length(nt->keys) != ol_length(nnt->keys)) + throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table key doesn't match %s definition", errtable, errtable); + if (ol_length(nt->keys)) + for (n = ol_first_node(nt->keys), m = ol_first_node(nnt->keys); n && m; n = n->next, m = m->next) { + sql_key *ni = n->data; + sql_key *mi = m->data; - if (ni->type != mi->type) - throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table index type doesn't match %s definition", errtable, errtable); + if (ni->type != mi->type) + throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table key type doesn't match %s definition", errtable, errtable); + if (list_length(ni->columns) != list_length(mi->columns)) + throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table key type doesn't match %s definition", errtable, errtable); + for (nn = ni->columns->h, mm = mi->columns->h; nn && mm; nn = nn->next, mm = mm->next) { + sql_kc *nni = nn->data; + sql_kc *mmi = mm->data; + + if (nni->c->colnr != mmi->c->colnr) + throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table key's columns doesn't match %s definition", errtable, errtable); } - } else { //for partitioned tables we allow indexes but the key set must be exactly the same - if (ol_length(nt->keys) != ol_length(nnt->keys)) - throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table key doesn't match %s definition", errtable, errtable); - if (ol_length(nt->keys)) - for (n = ol_first_node(nt->keys), m = ol_first_node(nnt->keys); n && m; n = n->next, m = m->next) { - sql_key *ni = n->data; - sql_key *mi = m->data; + } + + /* For indexes, empty ones can be ignored, which makes validation trickier */ + n = ol_length(nt->idxs) ? ol_first_node(nt->idxs) : NULL; + m = ol_length(nnt->idxs) ? ol_first_node(nnt->idxs) : NULL; + for (; n || m; n = n->next, m = m->next) { + sql_idx *ni, *mi; - if (ni->type != mi->type) - throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table key type doesn't match %s definition", errtable, errtable); - if (list_length(ni->columns) != list_length(mi->columns)) - throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table key type doesn't match %s definition", errtable, errtable); - for (nn = ni->columns->h, mm = mi->columns->h; nn && mm; nn = nn->next, mm = mm->next) { - sql_kc *nni = nn->data; - sql_kc *mmi = mm->data; + while (n) { + ni = n->data; + if ((!hash_index(ni->type) || list_length(ni->columns) > 1) && idx_has_column(ni->type)) + break; + n = n->next; + } + while (m) { + mi = m->data; + if ((!hash_index(mi->type) || list_length(mi->columns) > 1) && idx_has_column(mi->type)) + break; + m = m->next; + } - if (nni->c->colnr != mmi->c->colnr) - throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table key's columns doesn't match %s definition", errtable, errtable); - } - } + if (!n && !m) /* no more idxs to check, done */ + break; + if ((m && !n) || (!m && n)) + throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table index type doesn't match %s definition", errtable, errtable); + + assert(m && n); + ni = n->data; + mi = m->data; + if (ni->type != mi->type) + throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table index type doesn't match %s definition", errtable, errtable); + if (list_length(ni->columns) != list_length(mi->columns)) + throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table key type doesn't match %s definition", errtable, errtable); + for (nn = ni->columns->h, mm = mi->columns->h; nn && mm; nn = nn->next, mm = mm->next) { + sql_kc *nni = nn->data; + sql_kc *mmi = mm->data; + + if (nni->c->colnr != mmi->c->colnr) + throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table index's columns doesn't match %s definition", errtable, errtable); + } } if (nested_mergetable(sql->session->tr, nt/*mergetable*/, nnt->s->base.name, nnt->base.name/*parts*/)) diff --git a/sql/server/rel_basetable.c b/sql/server/rel_basetable.c --- a/sql/server/rel_basetable.c +++ b/sql/server/rel_basetable.c @@ -387,7 +387,7 @@ rewrite_basetable(mvc *sql, sql_rel *rel sql_exp *e; sql_idx *i = cn->data; - sql_subtype *t = sql_bind_localtype("lng"); /* hash "lng" */ + sql_subtype *t; char *iname = NULL; int has_nils = 0; @@ -395,9 +395,7 @@ rewrite_basetable(mvc *sql, sql_rel *rel if ((hash_index(i->type) && list_length(i->columns) <= 1) || !idx_has_column(i->type)) continue; - if (i->type == join_idx) - t = sql_bind_localtype("oid"); - + t = (i->type == join_idx) ? sql_bind_localtype("oid") : sql_bind_localtype("lng"); iname = sa_strconcat( sa, "%", i->base.name); for (node *n = i->columns->h ; n && !has_nils; n = n->next) { /* check for NULL values */ sql_kc *kc = n->data; diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c --- a/sql/server/rel_dump.c +++ b/sql/server/rel_dump.c @@ -814,12 +814,14 @@ read_prop(mvc *sql, sql_exp *exp, char * (*pos)++; if (r[*pos] != '.') return sql_error(sql, -1, SQLSTATE(42000) "JOINIDX: missing '.'\n"); + (*pos)++; tname = r+*pos + 1; skipIdent(r,pos); convertIdent(tname); (*pos)++; if (r[*pos] != '.') return sql_error(sql, -1, SQLSTATE(42000) "JOINIDX: missing '.'\n"); + (*pos)++; iname = r+*pos + 1; skipIdent(r,pos); convertIdent(iname); diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c --- a/sql/server/rel_optimizer.c +++ b/sql/server/rel_optimizer.c @@ -8745,26 +8745,63 @@ static sql_rel * rel_rename_part(mvc *sql, sql_rel *p, sql_rel *mt_rel, const char *mtalias) { sql_table *mt = rel_base_table(mt_rel), *t = rel_base_table(p); - node *n; assert(!p->exps); p->exps = sa_list(sql->sa); const char *pname = t->base.name; if (isRemote(t)) pname = mapiuri_table(t->query, sql->sa, pname); - for (n = mt_rel->exps->h; n; n = n->next) { + for (node *n = mt_rel->exps->h; n; n = n->next) { sql_exp *e = n->data; - if (is_intern(e) || exp_name(e)[0] == '%') /* break on tid/idxs */ - break; - sql_column *c = ol_find_name(mt->columns, exp_name(e))->data; - sql_column *rc = ol_fetch(t->columns, c->colnr); - /* with name find column in merge table, with colnr find column in member */ - list_append(p->exps, exp_alias(sql->sa, mtalias, c->base.name, pname, rc->base.name, &rc->type, CARD_MULTI, rc->null, 0)); - } - if (n) { - sql_exp *e = n->data; - if (strcmp(exp_name(e), TID) == 0) + node *cn = NULL, *ci = NULL; + const char *nname = exp_name(e); + + if (strcmp(nname, TID) == 0) { list_append(p->exps, exp_alias(sql->sa, mtalias, TID, pname, TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1)); + rel_base_use_tid(sql, p); + } else if (nname[0] != '%' && (cn = ol_find_name(mt->columns, nname))) { + sql_column *c = cn->data, *rc = ol_fetch(t->columns, c->colnr); + + /* with name find column in merge table, with colnr find column in member */ + sql_exp *ne = exp_alias(sql->sa, mtalias, c->base.name, pname, rc->base.name, &rc->type, CARD_MULTI, rc->null, 0); + if (rc->t->pkey && ((sql_kc*)rc->t->pkey->k.columns->h->data)->c == rc) { + prop *p = ne->p = prop_create(sql->sa, PROP_HASHCOL, ne->p); + p->value = rc->t->pkey; + } else if (rc->unique == 1) { + prop *p = ne->p = prop_create(sql->sa, PROP_HASHCOL, ne->p); + p->value = NULL; + } + set_basecol(ne); + rel_base_use(sql, p, rc->colnr); + list_append(p->exps, ne); + } else if (nname[0] == '%' && ol_length(mt->idxs) && (ci = ol_find_name(mt->idxs, nname + 1))) { + sql_idx *i = ci->data, *ri = NULL; + + /* indexes don't have a number field like 'colnr', so get the index the old way */ + for (node *nn = mt->idxs->l->h, *mm = t->idxs->l->h; nn && mm ; nn = nn->next, mm = mm->next) { + sql_idx *ii = nn->data; + + if (ii->base.id == i->base.id) { + ri = mm->data; + break; + } + } + + assert((!hash_index(ri->type) || list_length(ri->columns) > 1) && idx_has_column(ri->type)); + sql_subtype *t = (ri->type == join_idx) ? sql_bind_localtype("oid") : sql_bind_localtype("lng"); + char *iname1 = sa_strconcat(sql->sa, "%", i->base.name), *iname2 = sa_strconcat(sql->sa, "%", ri->base.name); + + sql_exp *ne = exp_alias(sql->sa, mtalias, iname1, pname, iname2, t, CARD_MULTI, has_nil(e), 1); + /* index names are prefixed, to make them independent */ + if (hash_index(ri->type)) { + prop *p = ne->p = prop_create(sql->sa, PROP_HASHIDX, ne->p); + p->value = ri; + } else if (ri->type == join_idx) { + prop *p = ne->p = prop_create(sql->sa, PROP_JOINIDX, ne->p); + p->value = ri; + } + list_append(p->exps, ne); + } } rel_base_set_mergetable(p, mt); return p; @@ -9529,8 +9566,8 @@ rel_basecount(visitor *v, sql_rel *rel) if (is_groupby(rel->op) && rel->l && !rel->r && list_length(rel->exps) == 1 && exp_aggr_is_count(rel->exps->h->data)) { sql_rel *bt = rel->l; sql_exp *e = rel->exps->h->data; - if (is_basetable(bt->op) && !e->l) { /* count(*) */ - /* change into select cnt('schema','table') */; + if (is_basetable(bt->op) && list_empty(e->l)) { /* count(*) */ + /* change into select cnt('schema','table') */ sql_table *t = bt->l; /* I need to get the declared table's frame number to make this work correctly for those */ if (!isTable(t) || isDeclaredTable(t)) @@ -9543,9 +9580,9 @@ rel_basecount(visitor *v, sql_rel *rel) ne = exp_propagate(v->sql->sa, ne, e); exp_setname(v->sql->sa, ne, exp_find_rel_name(e), exp_name(e)); - return rel_project(v->sql->sa, NULL, append(sa_list(v->sql->sa), ne)); - } - return rel; + rel = rel_project(v->sql->sa, NULL, append(sa_list(v->sql->sa), ne)); + v->changes++; + } } return rel; } diff --git a/sql/test/BugTracker-2021/Tests/All b/sql/test/BugTracker-2021/Tests/All --- a/sql/test/BugTracker-2021/Tests/All +++ b/sql/test/BugTracker-2021/Tests/All @@ -22,3 +22,4 @@ rollup-distinct-count.Bug-7146 sum-union.Bug-7147 distinct-union.Bug-7148 HAVE_LIBPY3?python-aggregates-empty.Bug-7158 +remote-join-idxs.Bug-7165 diff --git a/sql/test/BugTracker-2021/Tests/remote-join-idxs.Bug-7165.py b/sql/test/BugTracker-2021/Tests/remote-join-idxs.Bug-7165.py new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2021/Tests/remote-join-idxs.Bug-7165.py @@ -0,0 +1,122 @@ +import sys, os, socket, tempfile, pymonetdb + _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list