Changeset: ed58de6194b5 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ed58de6194b5
Added Files:
        sql/test/merge-partitions/Tests/mergepart29.py
        sql/test/merge-partitions/Tests/mergepart29.stable.err
        sql/test/merge-partitions/Tests/mergepart29.stable.out
Modified Files:
        configure.ag
        monetdb5/NT/M5server.bat
        monetdb5/modules/atoms/xml.c
        sql/backends/monet5/sql_cat.c
        sql/server/rel_schema.c
        sql/server/sql_partition.c
        sql/server/sql_privileges.c
        
sql/test/BugDay_2005-11-09_2.9.3/Tests/grant_public.SF-1114580.stable.err
        
sql/test/BugDay_2005-11-09_2.9.3/Tests/schema_change_grant_crash.SF-963620.stable.err
        sql/test/BugTracker-2010/Tests/crashonschema.Bug-2547.stable.err
        
sql/test/BugTracker-2016/Tests/create_merge_table_withdata.Bug-4041.stable.err
        sql/test/Users/Tests/grantPrivilegesNonDefaultRole.Bug-3365.stable.err
        sql/test/merge-partitions/Tests/All
        sql/test/merge-partitions/Tests/mergepart01.sql
        sql/test/merge-partitions/Tests/mergepart01.stable.err
        sql/test/merge-partitions/Tests/mergepart01.stable.out
        sql/test/merge-partitions/Tests/mergepart02.stable.err
        sql/test/merge-partitions/Tests/mergepart16.stable.err
        sql/test/merge-partitions/Tests/mergepart21.sql
        sql/test/merge-partitions/Tests/mergepart21.stable.err
        sql/test/merge-partitions/Tests/mergepart21.stable.out
        sql/test/merge-partitions/Tests/mergepart27.sql
        sql/test/merge-partitions/Tests/mergepart27.stable.err
        sql/test/merge-partitions/Tests/mergepart27.stable.out
        testing/Mtest.py.in
        tools/mserver/mserver5.1.in
Branch: default
Log Message:

Merge with Apr2019 branch.


diffs (truncated from 1722 to 300 lines):

diff --git a/configure.ag b/configure.ag
--- a/configure.ag
+++ b/configure.ag
@@ -1473,7 +1473,7 @@ AS_VAR_IF([have_pthread], [no], [], [
                        LIBS="$LIBS $PTHREAD_LIBS"],
                [
                        # ok, do old-fashioned stuff
-                       CPPFLAGS="$CPPFLAGS $PTHREAD_INCS" # in case user did 
--with-pthreads
+                       CPPFLAGS="$CPPFLAGS $PTHREAD_INCS" # in case user did 
--with-pthread
                        LIBS="$LIBS $PTHREAD_LIBS"
                        pthread_found=yes
                        AC_SEARCH_LIBS([sem_init], [pthreadGC2 pthreadGC1 
pthreadGC pthread],
@@ -1519,7 +1519,7 @@ AS_VAR_IF([have_pthread], [no],
        [PTHREAD_LIBS=""
         PTHREAD_INCS=""
         AC_MSG_RESULT([no])
-        AC_MSG_ERROR([MonetDB requires libpthread (try --with-pthreada)])],
+        AC_MSG_ERROR([MonetDB requires libpthread (try --with-pthread)])],
        [AC_DEFINE([HAVE_LIBPTHREAD], 1, [Define if you have the pthread 
library])
         PTHREAD_INCS="$PTHREAD_INCS $PTHREAD_EXTRA"
         # CPPFLAGS="$CPPFLAGS $PTHREAD_INCS"
diff --git a/monetdb5/NT/M5server.bat b/monetdb5/NT/M5server.bat
--- a/monetdb5/NT/M5server.bat
+++ b/monetdb5/NT/M5server.bat
@@ -43,8 +43,8 @@ set MONETDBPYTHONUDF=embedded_py=false
 
 if not exist "%MONETDB%\pyapi_locatepython3.bat" goto skippython3
 call "%MONETDB%\pyapi_locatepython3.bat"
+if not "%MONETDBPYTHONUDF%" == "embedded_py=false" goto skippython2
 :skippython3
-if not "%MONETDBPYTHONUDF%" == "embedded_py=false" goto skippython2
 if not exist "%MONETDB%\pyapi_locatepython2.bat" goto skippython2
 call "%MONETDB%\pyapi_locatepython2.bat"
 :skippython2
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
@@ -154,6 +154,8 @@ validate_alter_table_add_table(mvc *sql,
                node *n = cs_find_id(&rmt->members, rpt->base.id);
                const char *errtable = TABLE_TYPE_DESCRIPTION(rmt->type, 
rmt->properties);
 
+               if (ms->base.id != ps->base.id)
+                       throw(SQL,call,SQLSTATE(42000) "ALTER TABLE: all 
partitions of '%s.%s' must be part of schema '%s'", msname, mtname, msname);
                if (n && !update)
                        throw(SQL,call,SQLSTATE(42S02) "ALTER TABLE: table 
'%s.%s' is already part of the %s '%s.%s'", psname, ptname, errtable, msname, 
mtname);
                if (!n && update)
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
@@ -668,9 +668,14 @@ create_column(mvc *sql, symbol *s, sql_s
        dlist *opt_list = NULL;
        int res = SQL_OK;
 
-(void)ss;
-       if (alter && !isTable(t)) {
-               sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: cannot add 
column to VIEW '%s'\n", t->base.name);
+       (void) ss;
+       if (alter && !(isTable(t) || (isMergeTable(t) && cs_size(&t->members) 
== 0))) {
+               sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: cannot add 
column to %s '%s'%s\n",
+                                 isMergeTable(t)?"MERGE TABLE":
+                                 isRemote(t)?"REMOTE TABLE":
+                                 isStream(t)?"STREAM TABLE":
+                                 isReplicaTable(t)?"REPLICA TABLE":"VIEW",
+                                 t->base.name, (isMergeTable(t) && 
cs_size(&t->members)>0) ? " while it has partitions" : "");
                return SQL_ERR;
        }
        if (l->h->next->next)
@@ -741,12 +746,14 @@ table_element(mvc *sql, symbol *s, sql_s
                        sql_error(sql, 02, SQLSTATE(M0M03) "Unknown table 
element (%p)->token = %s\n", s, token2string(s->token));
                        return SQL_ERR;
                }
-               sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: cannot %s %s 
'%s'\n",
+               sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: cannot %s %s 
'%s'%s\n",
                                msg, 
                                isPartition(t)?"a PARTITION of a MERGE or 
REPLICA TABLE":
                                isMergeTable(t)?"MERGE TABLE":
+                               isRemote(t)?"REMOTE TABLE":
+                               isStream(t)?"STREAM TABLE":
                                isReplicaTable(t)?"REPLICA TABLE":"VIEW",
-                               t->base.name);
+                               t->base.name, (isMergeTable(t) && 
cs_size(&t->members)>0) ? " while it has partitions" : "");
                return SQL_ERR;
        }
 
@@ -917,7 +924,8 @@ table_element(mvc *sql, symbol *s, sql_s
                }
        }       break;
        case SQL_DROP_CONSTRAINT:
-               assert(0);
+               res = SQL_OK;
+               break;
        default:
                res = SQL_ERR;
        }
@@ -1087,7 +1095,7 @@ rel_create_table(mvc *sql, sql_schema *s
                        return NULL;
 
                if ((tt == tt_merge_table || tt == tt_remote || tt == 
tt_replica_table) && with_data)
-                       return sql_error(sql, 02, SQLSTATE(42000) "CREATE 
TABLE: cannot create %s table 'with data'",
+                       return sql_error(sql, 02, SQLSTATE(42000) "CREATE 
TABLE: cannot create %s 'with data'",
                                                         
TABLE_TYPE_DESCRIPTION(tt, properties));
 
                /* create table */
@@ -1457,15 +1465,6 @@ sql_alter_table(mvc *sql, dlist *dl, dli
                sql_exp ** updates, *e;
 
                assert(te);
-               if (t && te && te->token == SQL_DROP_CONSTRAINT) {
-                       dlist *l = te->data.lval;
-                       char *kname = l->h->data.sval;
-                       int drop_action = l->h->next->data.i_val;
-                       
-                       sname = get_schema_name(sql, sname, tname);
-                       return rel_drop(sql->sa, DDL_DROP_CONSTRAINT, sname, 
kname, drop_action, 0);
-               }
-
                if (t->persistence != SQL_DECLARED_TABLE)
                        sname = s->base.name;
 
@@ -1490,45 +1489,49 @@ sql_alter_table(mvc *sql, dlist *dl, dli
                        if (te->token == SQL_TABLE) {
                                symbol *extra = 
dl->h->next->next->next->data.sym;
 
-                               if(!extra)
-                                       return rel_alter_table(sql->sa, 
DDL_ALTER_TABLE_ADD_TABLE, sname, tname, sname, ntname, 0);
+                               if (strcmp(sname, nsname) != 0)
+                                       return sql_error(sql, 02, 
SQLSTATE(42000) "ALTER TABLE: all partitions of '%s.%s' must be part of "
+                                                                        
"schema '%s'", sname, tname, sname);
+                               if (!extra)
+                                       return rel_alter_table(sql->sa, 
DDL_ALTER_TABLE_ADD_TABLE, sname, tname, nsname, ntname, 0);
 
                                if ((isMergeTable(pt) || isReplicaTable(pt)) && 
list_empty(pt->members.set))
-                                       return sql_error(sql, 02, 
SQLSTATE(42000) "The %s table %s.%s should have at least one table associated",
+                                       return sql_error(sql, 02, 
SQLSTATE(42000) "The %s %s.%s should have at least one table associated",
                                                                         
TABLE_TYPE_DESCRIPTION(pt->type, pt->properties), spt->base.name, 
pt->base.name);
 
-                               if(extra->token == SQL_MERGE_PARTITION) { 
//partition to hold null values only
+                               if (extra->token == SQL_MERGE_PARTITION) { 
//partition to hold null values only
                                        dlist* ll = extra->data.lval;
                                        int update = 
ll->h->next->next->next->data.i_val;
 
-                                       if(isRangePartitionTable(t)) {
-                                               return 
rel_alter_table_add_partition_range(sql, t, pt, sname, tname, sname, ntname, 
NULL, NULL, 1, update);
-                                       } else if(isListPartitionTable(t)) {
-                                               return 
rel_alter_table_add_partition_list(sql, t, pt, sname, tname, sname, ntname, 
NULL, 1, update);
+                                       if (isRangePartitionTable(t)) {
+                                               return 
rel_alter_table_add_partition_range(sql, t, pt, sname, tname, nsname, ntname, 
NULL, NULL, 1, update);
+                                       } else if (isListPartitionTable(t)) {
+                                               return 
rel_alter_table_add_partition_list(sql, t, pt, sname, tname, nsname, ntname, 
NULL, 1, update);
                                        } else {
-                                               return sql_error(sql, 
02,SQLSTATE(42000) "ALTER TABLE: cannot add a partition into a merge table");
+                                               return sql_error(sql, 02, 
SQLSTATE(42000) "ALTER TABLE: cannot add a partition into a %s",
+                                                                               
 TABLE_TYPE_DESCRIPTION(t->type, t->properties));
                                        }
-                               } else if(extra->token == SQL_PARTITION_RANGE) {
+                               } else if (extra->token == SQL_PARTITION_RANGE) 
{
                                        dlist* ll = extra->data.lval;
                                        symbol* min = ll->h->data.sym, *max = 
ll->h->next->data.sym;
                                        int nills = 
ll->h->next->next->data.i_val, update = ll->h->next->next->next->data.i_val;
 
-                                       if(!isRangePartitionTable(t)) {
-                                               return sql_error(sql, 
02,SQLSTATE(42000) "ALTER TABLE: cannot add a range partition into a %s table",
-                                                                               
 isListPartitionTable(t)?"list partition":"merge");
+                                       if (!isRangePartitionTable(t)) {
+                                               return sql_error(sql, 
02,SQLSTATE(42000) "ALTER TABLE: cannot add a range partition into a %s",
+                                                                               
 TABLE_TYPE_DESCRIPTION(t->type, t->properties));
                                        }
 
-                                       return 
rel_alter_table_add_partition_range(sql, t, pt, sname, tname, sname, ntname, 
min, max, nills, update);
-                               } else if(extra->token == SQL_PARTITION_LIST) {
+                                       return 
rel_alter_table_add_partition_range(sql, t, pt, sname, tname, nsname, ntname, 
min, max, nills, update);
+                               } else if (extra->token == SQL_PARTITION_LIST) {
                                        dlist* ll = extra->data.lval, *values = 
ll->h->data.lval;
                                        int nills = ll->h->next->data.i_val, 
update = ll->h->next->next->data.i_val;
 
-                                       if(!isListPartitionTable(t)) {
-                                               return sql_error(sql, 
02,SQLSTATE(42000) "ALTER TABLE: cannot add a value partition into a %s table",
-                                                                               
 isRangePartitionTable(t)?"range partition":"merge");
+                                       if (!isListPartitionTable(t)) {
+                                               return sql_error(sql, 
02,SQLSTATE(42000) "ALTER TABLE: cannot add a value partition into a %s",
+                                                                               
 TABLE_TYPE_DESCRIPTION(t->type, t->properties));
                                        }
 
-                                       return 
rel_alter_table_add_partition_list(sql, t, pt, sname, tname, sname, ntname, 
values, nills, update);
+                                       return 
rel_alter_table_add_partition_list(sql, t, pt, sname, tname, nsname, ntname, 
values, nills, update);
                                }
                                assert(0);
                        } else {
@@ -1555,6 +1558,15 @@ sql_alter_table(mvc *sql, dlist *dl, dli
                if (!nt || (te && table_element(sql, te, s, nt, 1) == SQL_ERR)) 
                        return NULL;
 
+               if (te->token == SQL_DROP_CONSTRAINT) {
+                       dlist *l = te->data.lval;
+                       char *kname = l->h->data.sval;
+                       int drop_action = l->h->next->data.i_val;
+
+                       sname = get_schema_name(sql, sname, tname);
+                       return rel_drop(sql->sa, DDL_DROP_CONSTRAINT, sname, 
kname, drop_action, 0);
+               }
+
                if (t->s && !nt->s)
                        nt->s = t->s;
 
diff --git a/sql/server/sql_partition.c b/sql/server/sql_partition.c
--- a/sql/server/sql_partition.c
+++ b/sql/server/sql_partition.c
@@ -32,41 +32,50 @@ table_column_colnr(int *colnr)
 str
 sql_partition_validate_key(mvc *sql, sql_table *nt, sql_key *k, const char* op)
 {
-       if(isPartitionedByColumnTable(nt)) {
-               assert(nt->part.pcol);
-               if(list_length(k->columns) != 1) {
-                       throw(SQL, "sql.partition", SQLSTATE(42000) "%s TABLE: 
%s.%s: in a partitioned table the keys must match "
-                                                                          "the 
columns used in the partition definition", op, nt->s->base.name, nt->base.name);
-               } else {
-                       sql_kc *kcol = k->columns->h->data;
-                       if(kcol->c->colnr != nt->part.pcol->colnr)
-                               throw(SQL, "sql.partition", SQLSTATE(42000) "%s 
TABLE: %s.%s: in a partitioned table the keys must "
-                                                                          
"match the columns used in the partition definition", op, nt->s->base.name, 
nt->base.name);
-               }
-       } else if(isPartitionedByExpressionTable(nt)) {
-               list *kcols, *pcols;
-               sql_allocator *p1, *p2;
+       if (k->type != fkey) {
+               const char *keys = (k->type == pkey) ? "primary" : "unique";
+               assert(k->type == pkey || k->type == ukey);
+
+               if (isPartitionedByColumnTable(nt)) {
+                       assert(nt->part.pcol);
+                       if (list_length(k->columns) != 1) {
+                               throw(SQL, "sql.partition", SQLSTATE(42000) "%s 
TABLE: %s.%s: in a partitioned table, the %s key's "
+                                         "columns must match the columns used 
in the partition definition", op, nt->s->base.name,
+                                         nt->base.name, keys);
+                       } else {
+                               sql_kc *kcol = k->columns->h->data;
+                               if (kcol->c->colnr != nt->part.pcol->colnr)
+                                       throw(SQL, "sql.partition", 
SQLSTATE(42000) "%s TABLE: %s.%s: in a partitioned table, the %s key's "
+                                                 "columns must match the 
columns used in the partition definition", op, nt->s->base.name,
+                                                 nt->base.name, keys);
+                       }
+               } else if (isPartitionedByExpressionTable(nt)) {
+                       list *kcols, *pcols;
+                       sql_allocator *p1, *p2;
 
-               assert(nt->part.pexp->cols);
-               if(list_length(k->columns) != list_length(nt->part.pexp->cols))
-                       throw(SQL, "sql.partition", SQLSTATE(42000) "%s TABLE: 
%s.%s: in a partitioned table the keys must match "
-                                                                          "the 
columns used in the partition definition", op, nt->s->base.name, nt->base.name);
+                       assert(nt->part.pexp->cols);
+                       if (list_length(k->columns) != 
list_length(nt->part.pexp->cols))
+                               throw(SQL, "sql.partition", SQLSTATE(42000) "%s 
TABLE: %s.%s: in a partitioned table, the %s key's "
+                                         "columns must match the columns used 
in the partition definition", op, nt->s->base.name,
+                                         nt->base.name, keys);
 
-               p1 = k->columns->sa; /* save the original sql allocators */
-               p2 = nt->part.pexp->cols->sa;
-               k->columns->sa = sql->sa;
-               nt->part.pexp->cols->sa = sql->sa;
-               kcols = list_sort(k->columns, (fkeyvalue)&key_column_colnr, 
NULL);
-               pcols = list_sort(nt->part.pexp->cols, 
(fkeyvalue)&table_column_colnr, NULL);
-               k->columns->sa = p1;
-               nt->part.pexp->cols->sa = p2;
+                       p1 = k->columns->sa; /* save the original sql 
allocators */
+                       p2 = nt->part.pexp->cols->sa;
+                       k->columns->sa = sql->sa;
+                       nt->part.pexp->cols->sa = sql->sa;
+                       kcols = list_sort(k->columns, 
(fkeyvalue)&key_column_colnr, NULL);
+                       pcols = list_sort(nt->part.pexp->cols, 
(fkeyvalue)&table_column_colnr, NULL);
+                       k->columns->sa = p1;
+                       nt->part.pexp->cols->sa = p2;
 
-               for (node *nn = kcols->h, *mm = pcols->h; nn && mm; nn = 
nn->next, mm = mm->next) {
-                       sql_kc *kcol = nn->data;
-                       int *colnr = mm->data;
-                       if (kcol->c->colnr != *colnr)
-                               throw(SQL, "sql.partition", SQLSTATE(42000) "%s 
TABLE: %s.%s: in a partitioned table the keys must match "
-                                                                          "the 
columns used in the partition definition", op, nt->s->base.name, nt->base.name);
+                       for (node *nn = kcols->h, *mm = pcols->h; nn && mm; nn 
= nn->next, mm = mm->next) {
+                               sql_kc *kcol = nn->data;
+                               int *colnr = mm->data;
+                               if (kcol->c->colnr != *colnr)
+                                       throw(SQL, "sql.partition", 
SQLSTATE(42000) "%s TABLE: %s.%s: in a partitioned table, the %s key's "
+                                                 "columns must match the 
columns used in the partition definition", op, nt->s->base.name,
+                                                 nt->base.name, keys);
+                       }
                }
        }
        return NULL;
diff --git a/sql/server/sql_privileges.c b/sql/server/sql_privileges.c
--- a/sql/server/sql_privileges.c
+++ b/sql/server/sql_privileges.c
@@ -67,60 +67,60 @@ sql_insert_all_privs(mvc *sql, sqlid aut
        sql_insert_priv(sql, auth_id, obj_id, PRIV_TRUNCATE, grantor, 
grantable);
 }
 
-static int
+static bool
 admin_privs(sqlid grantor)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to