Changeset: 541a4f582a92 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/541a4f582a92
Modified Files:
        sql/server/rel_optimize_sel.c
        sql/server/rel_schema.c
        sql/storage/store.c
        sql/test/BugTracker-2025/Tests/7674-rel_find_designated_index_crash.test
        sql/test/BugTracker-2025/Tests/All
        testing/Mtest.py.in
Branch: default
Log Message:

Merge with Mar2025 branch.


diffs (233 lines):

diff --git a/sql/server/rel_optimize_sel.c b/sql/server/rel_optimize_sel.c
--- a/sql/server/rel_optimize_sel.c
+++ b/sql/server/rel_optimize_sel.c
@@ -3824,27 +3824,24 @@ rel_push_select_down(visitor *v, sql_rel
                                list_destroy(keyColumns);
                        }
                        /* also push (rewrite) limits on output of 
row_number/(*)rank like window functions */
-                       if (is_simple_project(r->op) /*&& 
is_simple_project(pl->op)*/) { /* possible window functions */
+                       if (is_simple_project(r->op)) { /* possible window 
functions */
                                for (n = exps->h; n; n = n->next) {
                                        sql_exp *e = n->data;
 
-                                       if (e->type == e_cmp && (e->flag == 
cmp_lt || e->flag == cmp_lte) && exp_is_atom(e->r)) { /* simple limit */
+                                       if (e->type == e_cmp && (e->flag == 
cmp_lt || e->flag == cmp_lte) && exp_is_atom(e->r) && !e->f) { /* simple limit 
*/
                                                sql_exp *ranke = 
rel_find_exp(r, e->l);
 
                                                if (ranke && ranke->type == 
e_func) {
                                                        sql_subfunc *rankf = 
ranke->f;
                                                        if (rankf->func->type 
== F_ANALYTIC) { /* rank functions cannot have a frame */
-                                                               // For now only 
for rank/row_number without partition by
                                                                sql_rel *tn = 
NULL;
-                                                               if 
(strcmp(rankf->func->base.name, "rank") == 0 && is_simple_project(pl->op) && 
pl->r /* &&
-                                                                               
!rank_exp_has_partition_key(ranke)*/) {
+                                                               if 
(strcmp(rankf->func->base.name, "rank") == 0 && is_simple_project(pl->op) && 
pl->r) {
                                                                        tn = 
r->l = rel_topn(v->sql->sa, r->l, append(sa_list(v->sql->sa), e->r));
                                                                        
tn->grouped = 1;
                                                                        
v->changes++;
                                                                        break;
                                                                }
-                                                               if 
(strcmp(rankf->func->base.name, "row_number") == 0 && list_empty(r->r) && 
!is_topn(pl->op) /*&&
-                                                                               
!rank_exp_has_partition_key(ranke)*/) {
+                                                               if 
(strcmp(rankf->func->base.name, "row_number") == 0 && list_empty(r->r) && 
!is_topn(pl->op)) {
                                                                        tn = 
r->l = rel_topn(v->sql->sa, r->l, append(sa_list(v->sql->sa), e->r));
                                                                        
tn->grouped = 1;
                                                                        
v->changes++;
diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c
--- a/sql/server/rel_schema.c
+++ b/sql/server/rel_schema.c
@@ -2038,22 +2038,31 @@ sql_alter_table(sql_query *query, dlist 
 
                if (!(pt = find_table_or_view_on_scope(sql, t->s, nsname, 
ntname, "ALTER TABLE", false)))
                        return NULL;
+               const char *errt = TABLE_TYPE_DESCRIPTION(t->type, 
t->properties);
+               const char *errpt = TABLE_TYPE_DESCRIPTION(pt->type, 
pt->properties);
                if (isView(pt))
-                       return sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: 
can't add/drop a view into a %s",
-                                                       
TABLE_TYPE_DESCRIPTION(t->type, t->properties));
+                       return sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: 
can't add/drop a view into a %s", errt);
                if (isDeclaredTable(pt))
-                       return sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: 
can't add/drop a declared table into a %s",
-                                                       
TABLE_TYPE_DESCRIPTION(t->type, t->properties));
+                       return sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: 
can't add/drop a declared table into a %s", errt);
                if (isTempSchema(pt->s))
-                       return sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: 
can't add/drop a temporary table into a %s",
-                                                       
TABLE_TYPE_DESCRIPTION(t->type, t->properties));
+                       return sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: 
can't add/drop a temporary table into a %s", errt);
                if (isReplicaTable(t) && isMergeTable(pt))
-                       return sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: 
can't add/drop a %s table into a %s",
-                                                       
TABLE_TYPE_DESCRIPTION(pt->type, pt->properties), 
TABLE_TYPE_DESCRIPTION(t->type, t->properties));
+                       return sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: 
can't add/drop a %s table into a %s", errpt, errt);
                nsname = pt->s->base.name;
                if (strcmp(sname, nsname) != 0)
-                       return sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: 
all children tables of '%s.%s' must be part of schema '%s'",
-                                               sname, tname, sname);
+                       return sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: 
all children tables of '%s.%s' must be part of schema '%s'", sname, tname, 
sname);
+
+               if (ol_length(t->columns) != ol_length(pt->columns))
+                       return sql_error(sql, 02, SQLSTATE(3F000) "ALTER %s: to 
be added table doesn't match %s definition", errt, errt);
+               for (node *n = ol_first_node(t->columns), *m = 
ol_first_node(pt->columns); n && m; n = n->next, m = m->next) {
+                       sql_column *nc = n->data;
+                       sql_column *mc = m->data;
+
+                       if (subtype_cmp(&nc->type, &mc->type) != 0)
+                       return sql_error(sql, 02, SQLSTATE(3F000) "ALTER %s: to 
be added table column type doesn't match %s definition", errt, errt);
+                       if (nc->null != mc->null)
+                               return sql_error(sql, 02, SQLSTATE(3F000) 
"ALTER %s: to be added table column NULL check doesn't match %s definition", 
errt, errt);
+               }
 
                if (te->token == SQL_TABLE) {
                        symbol *extra = dl->h->next->next->next->data.sym;
diff --git a/sql/server/rel_semantic.c b/sql/server/rel_semantic.c
--- a/sql/server/rel_semantic.c
+++ b/sql/server/rel_semantic.c
@@ -30,6 +30,8 @@
 sql_rel *
 rel_parse(mvc *m, sql_schema *s, const char *query, char emode)
 {
+       if (mvc_highwater(m))
+        return sql_error(m, 10, SQLSTATE(42000) "Query too complex: running 
out of stack space");
        sql_rel *rel = NULL;
        buffer *b;
        bstream *bs;
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -3767,13 +3767,10 @@ sql_trans_copy_key( sql_trans *tr, sql_t
                if (nk->type == fkey) {
                        if ((res = sql_trans_create_dependency(tr, 
kc->c->base.id, nk->base.id, FKEY_DEPENDENCY)))
                                return res;
-               } else if (nk->type == ukey || nk->type == ckey) {
+               } else if (nk->type == pkey || nk->type == ukey || nk->type == 
unndkey || nk->type == ckey) {
                        if ((res = sql_trans_create_dependency(tr, 
kc->c->base.id, nk->base.id, KEY_DEPENDENCY)))
                                return res;
-               } else if (nk->type == pkey) {
-                       if ((res = sql_trans_create_dependency(tr, 
kc->c->base.id, nk->base.id, KEY_DEPENDENCY)))
-                               return res;
-                       if ((res = sql_trans_alter_null(tr, kc->c, 0)))
+                       if (nk->type == pkey && (res = sql_trans_alter_null(tr, 
kc->c, 0)))
                                return res;
                }
 
@@ -6056,6 +6053,35 @@ sql_trans_add_value_partition(sql_trans 
        return res;
 }
 
+/* here we should delete also all tables idxs, keys and triggers from the 
schema */
+static int
+cleanup_schema_objects( sql_table *t, sql_trans *tr)
+{
+       int res = LOG_OK;
+       if (ol_length(t->idxs))
+               for (node *n = ol_first_node(t->idxs); n; n = n->next) {
+                       sql_idx *i = n->data;
+
+                       if ((res = os_del(i->t->s->idxs, tr, i->base.name, 
dup_base(&i->base))))
+                               return res;
+               }
+       if (ol_length(t->keys))
+               for (node *n = ol_first_node(t->keys); n; n = n->next) {
+                       sql_key *k = n->data;
+
+                       if ((res = os_del(k->t->s->keys, tr, k->base.name, 
dup_base(&k->base))))
+                               return res;
+               }
+       if (ol_length(t->triggers))
+               for (node *n = ol_first_node(t->triggers); n; n = n->next) {
+                       sql_key *t = n->data;
+
+                       if ((res = os_del(t->t->s->triggers, tr, t->base.name, 
dup_base(&t->base))))
+                               return res;
+               }
+       return res;
+}
+
 int
 sql_trans_rename_table(sql_trans *tr, sql_schema *s, sqlid id, const char 
*new_name)
 {
@@ -6086,6 +6112,8 @@ sql_trans_rename_table(sql_trans *tr, sq
 
        if ((res = table_dup(tr, t, t->s, new_name, &dup, true)))
                return res;
+       if (isGlobal(t))
+               res = cleanup_schema_objects(t, tr);
        return res;
 }
 
@@ -6108,7 +6136,11 @@ sql_trans_set_table_schema(sql_trans *tr
                return res;
        if ((res = os_del(os->tables, tr, t->base.name, dup_base(&t->base))))
                return res;
-       return table_dup(tr, t, ns, NULL, &dup, true);
+       if ((res = table_dup(tr, t, ns, NULL, &dup, true)))
+               return res;
+       if (isGlobal(t))
+               res = cleanup_schema_objects(t, tr);
+       return res;
 }
 
 int
@@ -6973,10 +7005,10 @@ sql_trans_create_kc(sql_trans *tr, sql_k
        if (k->idx && (res = sql_trans_create_ic(tr, k->idx, c)))
                return res;
 
-       if (k->type == pkey) {
+       if (k->type == pkey || k->type == ukey || k->type == unndkey || k->type 
== ckey) {
                if ((res = sql_trans_create_dependency(tr, c->base.id, 
k->base.id, KEY_DEPENDENCY)))
                        return res;
-               if ((res = sql_trans_alter_null(tr, c, 0))) /* should never 
trigger error */
+               if (k->type == pkey && (res = sql_trans_alter_null(tr, c, 0))) 
/* should never trigger error */
                        return res;
        }
 
diff --git a/sql/test/BugTracker-2025/Tests/7668-missing-key-dependency.test 
b/sql/test/BugTracker-2025/Tests/7668-missing-key-dependency.test
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2025/Tests/7668-missing-key-dependency.test
@@ -0,0 +1,8 @@
+statement ok
+CREATE TABLE table1 (column1 INT, column2 INT, CONSTRAINT constraint1 UNIQUE 
NULLS NOT DISTINCT (column1, column2));
+
+statement ok
+ALTER TABLE table1 DROP COLUMN column2 CASCADE
+
+statement error 42000!ALTER TABLE: no such constraint 'constraint1'
+ALTER TABLE table1 DROP CONSTRAINT constraint1 CASCADE
diff --git 
a/sql/test/BugTracker-2025/Tests/7670-missing-table-compatibility-checks.test 
b/sql/test/BugTracker-2025/Tests/7670-missing-table-compatibility-checks.test
new file mode 100644
--- /dev/null
+++ 
b/sql/test/BugTracker-2025/Tests/7670-missing-table-compatibility-checks.test
@@ -0,0 +1,8 @@
+statement ok
+CREATE TABLE table1 (column1 STRING, column2 INT)
+
+statement ok
+CREATE MERGE TABLE table2 (column3 INT, column4 VARCHAR(100)) PARTITION BY 
VALUES USING (UPPER(column4))
+
+statement error 3F000!ALTER LIST PARTITION TABLE: to be added table column 
type doesn't match LIST PARTITION TABLE definition
+ALTER TABLE table2 SET TABLE table1 AS PARTITION IN (4, 5, 6)
diff --git 
a/sql/test/BugTracker-2025/Tests/7674-rel_find_designated_index_crash.test 
b/sql/test/BugTracker-2025/Tests/7674-rel_find_designated_index_crash.test
--- a/sql/test/BugTracker-2025/Tests/7674-rel_find_designated_index_crash.test
+++ b/sql/test/BugTracker-2025/Tests/7674-rel_find_designated_index_crash.test
@@ -13,8 +13,7 @@ ALTER TABLE table1 SET SCHEMA schema1
 statement error 42000!syntax error, unexpected IDENT, expecting INSERT or READ 
or SCHEMA or TABLE in: "alter table table1 set access"
 ALTER TABLE table1 SET ACCESS READ ONLY
 
-skipif knownfail
-statement ok
+statement error 42S12!COMMENT ON: no such index 'index1'
 COMMENT ON INDEX index1 IS 'Index created for analytical queries'
 
 statement error 42S02!ALTER TABLE: no such table 'table1'
diff --git a/sql/test/BugTracker-2025/Tests/All 
b/sql/test/BugTracker-2025/Tests/All
--- a/sql/test/BugTracker-2025/Tests/All
+++ b/sql/test/BugTracker-2025/Tests/All
@@ -27,6 +27,8 @@ 7661_trigger_crash
 7662-drop-role-user
 7663-alter-user-role
 7664-session-user
+7668-missing-key-dependency
+7670-missing-table-compatibility-checks
 7671-lag-over-empty-bat
 7674-rel_find_designated_index_crash
 7680-union-all
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to