Changeset: 6e21f369e84b for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/6e21f369e84b Modified Files: sql/backends/monet5/sql_cat.c sql/server/rel_basetable.c sql/server/rel_optimizer.c Branch: Jul2021 Log Message:
The 'null' property must be the same between parent and child columns as well key and idx sets. Cleanup, empty indexes can be ignored diffs (168 lines): 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_optimizer.c b/sql/server/rel_optimizer.c --- a/sql/server/rel_optimizer.c +++ b/sql/server/rel_optimizer.c @@ -8759,7 +8759,7 @@ rel_rename_part(mvc *sql, sql_rel *p, sq 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 ((cn = ol_find_name(mt->columns, nname))) { + } 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 */ @@ -8774,9 +8774,8 @@ rel_rename_part(mvc *sql, sql_rel *p, sq set_basecol(e); rel_base_use(sql, p, rc->colnr); list_append(p->exps, e); - } else if (nname[0] && ol_length(mt->idxs) && (ci = ol_find_name(mt->idxs, nname + 1))) { + } else if (nname[0] == '%' && ol_length(mt->idxs) && (ci = ol_find_name(mt->idxs, nname + 1))) { sql_idx *i = ci->data, *ri = NULL; - int has_nils = 0; /* 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) { @@ -8789,16 +8788,10 @@ rel_rename_part(mvc *sql, sql_rel *p, sq } assert((!hash_index(ri->type) || list_length(ri->columns) > 1) && idx_has_column(ri->type)); - for (node *nn = ri->columns->h ; nn && !has_nils; nn = nn->next) { /* check for NULL values */ - sql_kc *kc = nn->data; - - if (kc->c->null) - has_nils = 1; - } 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 *e = exp_alias(sql->sa, mtalias, iname1, pname, iname2, t, CARD_MULTI, has_nils, 1); + sql_exp *e = 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 = e->p = prop_create(sql->sa, PROP_HASHIDX, e->p); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list