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

Reply via email to