Changeset: 556d4ebf0f83 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=556d4ebf0f83
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/include/sql_catalog.h
        sql/storage/store.c
        
sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.sql
        
sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.stable.err
        
sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.stable.out
        sql/test/BugTracker-2020/Tests/revokeRoleUserLoggedIN.Bug-7026.SQL.py
        
sql/test/BugTracker-2020/Tests/revokeRoleUserLoggedIN.Bug-7026.stable.out
Branch: Oct2020
Log Message:

Fix for bug 7030, ie a sequence may not be created on sys schema


diffs (237 lines):

diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -5314,15 +5314,11 @@ sql_truncate(backend *be, sql_table *t, 
        mvc *sql = be->mvc;
        list *l = sa_list(sql->sa);
        stmt *v, *ret = NULL, *other = NULL;
-       const char *next_value_for = "next value for \"sys\".\"seq_";
-       char *seq_name = NULL;
-       str seq_pos = NULL;
+       const char *next_value_for = "next value for ";
        sql_column *col = NULL;
-       sql_sequence *seq = NULL;
        sql_schema *sche = NULL;
        sql_table *next = NULL;
        sql_trans *tr = sql->session->tr;
-       node *n = NULL;
        int error = 0;
        struct tablelist* new_list = SA_NEW(sql->ta, struct tablelist), 
*list_node;
 
@@ -5343,18 +5339,20 @@ sql_truncate(backend *be, sql_table *t, 
                sche = next->s;
 
                if (restart_sequences) { /* restart the sequences if it's the 
case */
-                       for (n = next->columns.set->h; n; n = n->next) {
+                       for (node *n = next->columns.set->h; n; n = n->next) {
                                col = n->data;
-                               if (col->def && (seq_pos = strstr(col->def, 
next_value_for))) {
-                                       seq_name = sa_strdup(sql->ta, seq_pos + 
(strlen(next_value_for) - strlen("seq_")));
-                                       if (!seq_name) {
-                                               sql_error(sql, 02, 
SQLSTATE(HY013) MAL_MALLOC_FAIL);
-                                               error = 1;
-                                               goto finalize;
-                                       }
-                                       seq_name[strlen(seq_name)-1] = '\0';
-                                       seq = find_sql_sequence(sche, seq_name);
-                                       if (seq) {
+
+                               if (col->def && !strncmp(col->def, 
next_value_for, strlen(next_value_for))) {
+                                       sql_schema *s = NULL;
+                                       sql_sequence *seq = NULL;
+                                       char *schema = NULL, *seq_name = NULL;
+
+                                       
extract_schema_and_sequence_name(sql->ta, col->def + strlen(next_value_for), 
&schema, &seq_name);
+                                       if (!schema || !seq_name || !(s = 
find_sql_schema(tr, schema)))
+                                               continue;
+
+                                       assert(s->base.id == sche->base.id);
+                                       if ((seq = find_sql_sequence(s, 
seq_name))) {
                                                if 
(!sql_trans_sequence_restart(tr, seq, seq->start)) {
                                                        sql_error(sql, 02, 
SQLSTATE(HY005) "Could not restart sequence %s.%s", sche->base.name, seq_name);
                                                        error = 1;
diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -774,4 +774,55 @@ typedef struct {
 extern int nested_mergetable(sql_trans *tr, sql_table *t, const char *sname, 
const char *tname);
 extern sql_part *partition_find_part(sql_trans *tr, sql_table *pt, sql_part 
*pp);
 
+#define outside_str 1
+#define inside_str 2
+
+#define extracting_schema 1
+#define extracting_sequence 2
+
+static inline void
+extract_schema_and_sequence_name(sql_allocator *sa, char *default_value, char 
**schema, char **sequence)
+{
+       int status = outside_str, identifier = extracting_schema;
+       char next_identifier[1024]; /* needs one extra character for null 
terminator */
+       size_t bp = 0;
+
+       for (size_t i = 0; default_value[i]; i++) {
+               char next = default_value[i];
+
+               if (next == '"') {
+                       if (status == inside_str && default_value[i + 1] == 
'"') {
+                               next_identifier[bp++] = '"';
+                               i++; /* has to advance two positions */
+                       } else if (status == inside_str) {
+                               next_identifier[bp++] = '\0';
+                               if (identifier == extracting_schema) {
+                                       *schema = sa_strdup(sa, 
next_identifier);
+                                       identifier = extracting_sequence;
+                               } else if (identifier == extracting_sequence) {
+                                       *sequence = sa_strdup(sa, 
next_identifier);
+                                       break; /* done extracting */
+                               }
+                               bp = 0;
+                               status = outside_str;
+                       } else {
+                               assert(status == outside_str);
+                               status = inside_str;
+                       }
+               } else if (next == '.') {
+                       if (status == outside_str && default_value[i + 1] == 
'"') {
+                               status = inside_str;
+                               i++; /* has to advance two positions */
+                       } else {
+                               assert(status == inside_str);
+                               next_identifier[bp++] = '.'; /* used inside an 
identifier name */
+                       }
+               } else if (status == inside_str) {
+                       next_identifier[bp++] = next;
+               } else {
+                       assert(status == outside_str);
+               }
+       }
+}
+
 #endif /* SQL_CATALOG_H */
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -5512,27 +5512,26 @@ sys_drop_statistics(sql_trans *tr, sql_c
 static int
 sys_drop_default_object(sql_trans *tr, sql_column *col, int drop_action)
 {
-       char *seq_pos = NULL;
-       const char *next_value_for = "next value for \"sys\".\"seq_";
-       sql_schema *syss = find_sql_schema(tr, isGlobal(col->t)?"sys":"tmp");
+       const char *next_value_for = "next value for ";
 
        /* Drop sequence for generated column if it's the case */
-       if (col->def && (seq_pos = strstr(col->def, next_value_for))) {
+       if (col->def && !strncmp(col->def, next_value_for, 
strlen(next_value_for))) {
+               sql_schema *s = NULL;
                sql_sequence *seq = NULL;
-               char *seq_name = _STRDUP(seq_pos + (strlen(next_value_for) - 
strlen("seq_")));
                node *n = NULL;
-
-               if (!seq_name)
+               char *schema = NULL, *seq_name = NULL;
+
+               extract_schema_and_sequence_name(tr->sa, col->def + 
strlen(next_value_for), &schema, &seq_name);
+               if (!schema || !seq_name || !(s = find_sql_schema(tr, schema)))
                        return -1;
-               seq_name[strlen(seq_name)-1] = '\0';
-               n = cs_find_name(&syss->seqs, seq_name);
-               seq = find_sql_sequence(syss, seq_name);
-               if (seq && sql_trans_get_dependency_type(tr, seq->base.id, 
BEDROPPED_DEPENDENCY) > 0) {
+
+               n = cs_find_name(&s->seqs, seq_name);
+               seq = find_sql_sequence(s, seq_name);
+               if (seq && n && sql_trans_get_dependency_type(tr, seq->base.id, 
BEDROPPED_DEPENDENCY) > 0) {
                        sys_drop_sequence(tr, seq, drop_action);
-                       seq->base.wtime = syss->base.wtime = tr->wtime = 
tr->wstime;
-                       cs_del(&syss->seqs, n, seq->base.flags);
-               }
-               _DELETE(seq_name);
+                       seq->base.wtime = s->base.wtime = tr->wtime = 
tr->wstime;
+                       cs_del(&s->seqs, n, seq->base.flags);
+               }
        }
        return 0;
 }
diff --git 
a/sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.sql 
b/sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.sql
--- a/sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.sql
+++ b/sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.sql
@@ -1,4 +1,11 @@
+create local temp table "depend_count" ("a" bigint) on commit preserve rows;
+insert into "depend_count" values ((select count(*) from dependencies, 
sequences));
+
 create schema s1;
 create table s1.t (i int not null auto_increment);
 drop table s1.t;
 drop schema s1;
+
+select cast(count(*) - (select "a" from "depend_count") as bigint) from 
dependencies, sequences;
+       -- the number of dependencies and sequences shouldn't increase
+drop table "depend_count";
diff --git 
a/sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.stable.err
 
b/sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.stable.err
--- 
a/sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.stable.err
+++ 
b/sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.stable.err
@@ -5,10 +5,6 @@ stderr of test 'drop-table-with-auto_inc
 # 12:21:18 >  "mclient" "-lsql" "-ftest" "-tnone" "-Eutf-8" "-i" "-e" 
"--host=/var/tmp/mtest-868236" "--port=30843"
 # 12:21:18 >  
 
-MAPI  = (monetdb) /var/tmp/mtest-868236/.s.monetdb.30843
-QUERY = drop schema s1;
-
-CODE  = 2BM37
 
 # 12:21:18 >  
 # 12:21:18 >  "Done."
diff --git 
a/sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.stable.out
 
b/sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.stable.out
--- 
a/sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.stable.out
+++ 
b/sql/test/BugTracker-2020/Tests/drop-table-with-auto_increment.Bug-7030.stable.out
@@ -5,10 +5,20 @@ stdout of test 'drop-table-with-auto_inc
 # 12:21:18 >  "mclient" "-lsql" "-ftest" "-tnone" "-Eutf-8" "-i" "-e" 
"--host=/var/tmp/mtest-868236" "--port=30843"
 # 12:21:18 >  
 
+#create local temp table "depend_count" ("a" bigint) on commit preserve rows;
+#insert into "depend_count" values ((select count(*) from dependencies, 
sequences));
+[ 1    ]
 #create schema s1;
 #create table s1.t (i int not null auto_increment);
 #drop table s1.t;
 #drop schema s1;
+#select cast(count(*) - (select "a" from "depend_count") as bigint) from 
dependencies, sequences;
+% .%3 # table_name
+% %3 # name
+% bigint # type
+% 1 # length
+[ 0    ]
+#drop table "depend_count";
 
 # 12:21:18 >  
 # 12:21:18 >  "Done."
diff --git 
a/sql/test/BugTracker-2020/Tests/revokeRoleUserLoggedIN.Bug-7026.SQL.py 
b/sql/test/BugTracker-2020/Tests/revokeRoleUserLoggedIN.Bug-7026.SQL.py
--- a/sql/test/BugTracker-2020/Tests/revokeRoleUserLoggedIN.Bug-7026.SQL.py
+++ b/sql/test/BugTracker-2020/Tests/revokeRoleUserLoggedIN.Bug-7026.SQL.py
@@ -63,3 +63,8 @@ run(c2, 'DELETE FROM test WHERE d = 42;'
 query(c2, 'SELECT * FROM test;')
 query(c2, 'SET role role1; -- verifies role1 is gone')
 
+c2.close()
+run(c1, 'DROP USER bruce;')
+run(c1, 'DROP ROLE role1;')
+run(c1, 'DROP SCHEMA s1 CASCADE;')
+c1.close()
diff --git 
a/sql/test/BugTracker-2020/Tests/revokeRoleUserLoggedIN.Bug-7026.stable.out 
b/sql/test/BugTracker-2020/Tests/revokeRoleUserLoggedIN.Bug-7026.stable.out
--- a/sql/test/BugTracker-2020/Tests/revokeRoleUserLoggedIN.Bug-7026.stable.out
+++ b/sql/test/BugTracker-2020/Tests/revokeRoleUserLoggedIN.Bug-7026.stable.out
@@ -40,6 +40,12 @@ SELECT * FROM test;
 SET role role1; -- verifies role1 is gone
 ! 42000!Role (role1) missing
 
+DROP USER bruce;
+# OK
+DROP ROLE role1;
+# OK
+DROP SCHEMA s1 CASCADE;
+# OK
 
 # 14:34:37 >  
 # 14:34:37 >  "Done."
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to