Changeset: 1f6077dfb61f for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1f6077dfb61f
Modified Files:
        monetdb5/modules/mal/tablet.c
        sql/backends/monet5/sql_result.c
        sql/test/copy/Tests/int_parse.stable.err
        sql/test/copy/Tests/int_parse.stable.out
        sql/test/copy/Tests/int_parse_best.stable.out
        sql/test/copy/Tests/null_as_string_errors.sql
        sql/test/copy/Tests/null_as_string_errors.stable.err
        sql/test/copy/Tests/null_as_string_errors.stable.out
Branch: resultset
Log Message:

Better handle NULL strings
The old code mixed the MonetDB 'nil' value with the SQL NULL
Also embedded user defined null strings were not kept as is.


diffs (truncated from 342 to 300 lines):

diff --git a/monetdb5/modules/mal/tablet.c b/monetdb5/modules/mal/tablet.c
--- a/monetdb5/modules/mal/tablet.c
+++ b/monetdb5/modules/mal/tablet.c
@@ -900,7 +900,12 @@ SQLload_parse_line(READERtask *task, int
                                        error++;
                                        goto errors1;
                                } else *line++ = 0;
-                       }
+                       } else
+                       /* check for user defined NULL string */
+                       if( fmt->nullstr && task->fields[i][idx]  && 
strncasecmp(task->fields[i][idx], fmt->nullstr, fmt->null_length + 1) == 0) {
+                               task->fields[i][idx] = 0;
+                               line +=fmt->null_length +1;
+                       } 
 
                        /* eat away the column separator */
                        for (; *line; line++)
@@ -927,10 +932,6 @@ SQLload_parse_line(READERtask *task, int
                                i--;
                        }
                  endoffieldcheck:;
-                       /* check for user defined NULL string */
-                       if( fmt->nullstr && task->fields[i][idx]  && 
strncasecmp(task->fields[i][idx], fmt->nullstr, fmt->null_length + 1) == 0) {
-                               task->fields[i][idx] = 0;
-                       }
                }
 #ifdef _DEBUG_TABLET_
                if(error)
@@ -943,9 +944,9 @@ SQLload_parse_line(READERtask *task, int
        for (i = 0; i < as->nr_attrs; i++) {
                task->fields[i][idx] = line;
 #ifdef _DEBUG_TABLET_
-       MT_lock_set(&errorlock, "insert_val");
-       mnstr_printf(GDKout,"before #2 %s\n",line);
-       //MT_lock_unset(&errorlock, "insert_val");
+               MT_lock_set(&errorlock, "insert_val");
+               mnstr_printf(GDKout,"before #2 %s\n",line);
+               //MT_lock_unset(&errorlock, "insert_val");
 #endif
                /* eat away the column separator */
                for (; *line; line++)
@@ -958,9 +959,9 @@ SQLload_parse_line(READERtask *task, int
                                goto endoffield2;
                        }
 #ifdef _DEBUG_TABLET_
-       //MT_lock_set(&errorlock, "insert_val");
-       mnstr_printf(GDKout,"#after #23 %s\n",line);
-       MT_lock_unset(&errorlock, "insert_val");
+               //MT_lock_set(&errorlock, "insert_val");
+               mnstr_printf(GDKout,"#after #23 %s\n",line);
+               MT_lock_unset(&errorlock, "insert_val");
 #endif
                /* not enough fields */
                if (i < as->nr_attrs - 1) {
diff --git a/sql/backends/monet5/sql_result.c b/sql/backends/monet5/sql_result.c
--- a/sql/backends/monet5/sql_result.c
+++ b/sql/backends/monet5/sql_result.c
@@ -564,8 +564,6 @@ static void *
        int len;
        const char *e; 
 
-       if( strcmp(s,"nil")== 0)
-               return NULL;
        if (type == TYPE_str) {
                sql_column *col = (sql_column *) c->extra;
                int len;
@@ -586,8 +584,7 @@ static void *
                        }
                        c->data = p;
                }
-
-               if (s == e) {
+               if (s == e || *s == 0) {
                        len = -1;
                        *(char *) c->data = 0;
                } else if ((len = (int) GDKstrFromStr(c->data, (unsigned char 
*) s, (ssize_t) (e - s))) < 0) {
@@ -603,6 +600,9 @@ static void *
                }
                return c->data;
        }
+       // All other values are not allowed to the MonetDB nil value
+       if( strcmp(s,"nil")== 0)
+               return NULL;
 
        len = (*BATatoms[type].atomFromStr) (s, &c->len, (ptr) &c->data);
        if (len < 0)
diff --git a/sql/test/copy/Tests/int_parse.stable.err 
b/sql/test/copy/Tests/int_parse.stable.err
--- a/sql/test/copy/Tests/int_parse.stable.err
+++ b/sql/test/copy/Tests/int_parse.stable.err
@@ -30,20 +30,24 @@ stderr of test 'int_parse` in directory 
 # 11:23:33 >  "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" 
"--host=/var/tmp/mtest-4649" "--port=31080"
 # 11:23:33 >  
 
-MAPI  = (monetdb) /var/tmp/mtest-7656/.s.monetdb.37934
+MAPI  = (monetdb) /var/tmp/mtest-18609/.s.monetdb.32538
+QUERY = copy 1 records into t_int from stdin USING DELIMITERS ',','\n','\"' 
NULL AS '';
+        ""
+ERROR = !Failed to import table line 1 field 1 'int' expected in ''
+MAPI  = (monetdb) /var/tmp/mtest-18609/.s.monetdb.32538
 QUERY = copy 3 records into t_int from stdin USING DELIMITERS ',','\n','\"' 
NULL AS '';
         0
         5.1
         9
 ERROR = !Failed to import table line 2 field 1 'int' expected in '5.1'
-MAPI  = (monetdb) /var/tmp/mtest-7656/.s.monetdb.37934
+MAPI  = (monetdb) /var/tmp/mtest-18609/.s.monetdb.32538
 QUERY = copy 5 records into t_int from stdin delimiters ',','\n' NULL as '';
         1
         nil
         
         null
         abc
-ERROR = !Failed to import table line 4 field 1 'int' expected in 'null'
+ERROR = !Failed to import table line 2 field 1 'int' expected in 'nil'
 
 # 11:23:33 >  
 # 11:23:33 >  "Done."
diff --git a/sql/test/copy/Tests/int_parse.stable.out 
b/sql/test/copy/Tests/int_parse.stable.out
--- a/sql/test/copy/Tests/int_parse.stable.out
+++ b/sql/test/copy/Tests/int_parse.stable.out
@@ -24,14 +24,14 @@ Ready.
 # 13:54:35 >  mclient -lsql -umonetdb -Pmonetdb --host=eir --port=34075 
 # 13:54:35 >  
 
-[ 1    ]
+#create table t_int(i int);
+#select * from t_int;
 % sys.t_int # table_name
 % i # name
 % int # type
 % 1 # length
-[ NULL ]
 #delete from t_int;
-[ 1    ]
+[ 0    ]
 #copy 2 records into t_int from stdin USING DELIMITERS ',','\n','\"' NULL AS 
'';
 #3.00
 #-4.0000
diff --git a/sql/test/copy/Tests/int_parse_best.stable.out 
b/sql/test/copy/Tests/int_parse_best.stable.out
--- a/sql/test/copy/Tests/int_parse_best.stable.out
+++ b/sql/test/copy/Tests/int_parse_best.stable.out
@@ -62,15 +62,20 @@ Ready.
 #create table t_int(i int);
 #copy 1 records into t_int from stdin USING DELIMITERS ',','\n','\"' NULL AS 
'' best effort;
 #""
-[ 1    ]
+[ 0    ]
 #select * from t_int;
 % sys.t_int # table_name
 % i # name
 % int # type
 % 1 # length
-[ NULL ]
+#select * from sys.rejects;
+% .rejects,    .rejects,       .rejects,       .rejects # table_name
+% rowid,       fldid,  message,        input # name
+% bigint,      int,    clob,   clob # type
+% 1,   1,      14,     1 # length
+[ 1,   1,      "'int' expected",       "\n"    ]
 #delete from t_int;
-[ 1    ]
+[ 0    ]
 #copy 2 records into t_int from stdin USING DELIMITERS ',','\n','\"' NULL AS 
'' best effort;
 #3.00
 #-4.0000
@@ -115,7 +120,7 @@ Ready.
 #
 #null
 #abc
-[ 3    ]
+[ 2    ]
 #select * from t_int;
 % sys.t_int # table_name
 % i # name
@@ -123,16 +128,16 @@ Ready.
 % 1 # length
 [ 1 ]
 [ NULL ]
-[ NULL ]
 #select * from sys.rejects;
 % .rejects,    .rejects,       .rejects,       .rejects # table_name
 % rowid,       fldid,  message,        input # name
 % bigint,      int,    clob,   clob # type
 % 1,   1,      14,     5 # length
+[ 2,   1,      "'int' expected",       "nil\n" ]
 [ 4,   1,      "'int' expected",       "null\n"        ]
 [ 5,   1,      "'int' expected",       "abc\n" ]
 #delete from t_int;
-[ 3    ]
+[ 2    ]
 #drop table t_int;
 
 # 20:58:16 >  
diff --git a/sql/test/copy/Tests/null_as_string_errors.sql 
b/sql/test/copy/Tests/null_as_string_errors.sql
--- a/sql/test/copy/Tests/null_as_string_errors.sql
+++ b/sql/test/copy/Tests/null_as_string_errors.sql
@@ -6,13 +6,22 @@ create table null_as_string (i int, s st
 copy 1 records into null_as_string from stdin delimiters ',','\n' NULL as '';
 NULL,NULL,NULL
 
+select * from sys.rejects;
+call sys.clearrejects();
+
 copy 1 records into null_as_string from stdin delimiters ',','\n' NULL as '';
 NULL,zero,0
 
+select * from sys.rejects;
+call sys.clearrejects();
+
 -- shouldn't fail because NULL as string is just fine
 copy 1 records into null_as_string from stdin delimiters ',','\n' NULL as '';
 1,NULL,1
 
+select * from sys.rejects;
+call sys.clearrejects();
+
 copy 1 records into null_as_string from stdin delimiters ',','\n' NULL as '';
 2,two,NULL
 
diff --git a/sql/test/copy/Tests/null_as_string_errors.stable.err 
b/sql/test/copy/Tests/null_as_string_errors.stable.err
--- a/sql/test/copy/Tests/null_as_string_errors.stable.err
+++ b/sql/test/copy/Tests/null_as_string_errors.stable.err
@@ -80,30 +80,18 @@ stderr of test 'null_as_string_errors` i
 # 21:02:57 >  mclient -lsql -umonetdb -Pmonetdb --host=alf --port=38808 
 # 21:02:57 >  
 
-MAPI  = (monetdb) /var/tmp/mtest-7656/.s.monetdb.37934
+MAPI  = (monetdb) /var/tmp/mtest-21189/.s.monetdb.32700
 QUERY = copy 1 records into null_as_string from stdin delimiters ',','\n' NULL 
as '';
         NULL,NULL,NULL
 ERROR = !Failed to import table line 1 field 1 'int' expected in 'NULL'
-MAPI  = (monetdb) /var/tmp/mtest-7656/.s.monetdb.37934
+MAPI  = (monetdb) /var/tmp/mtest-21189/.s.monetdb.32700
 QUERY = copy 1 records into null_as_string from stdin delimiters ',','\n' NULL 
as '';
         NULL,zero,0
 ERROR = !Failed to import table line 1 field 1 'int' expected in 'NULL'
-MAPI  = (monetdb) /var/tmp/mtest-7656/.s.monetdb.37934
+MAPI  = (monetdb) /var/tmp/mtest-21189/.s.monetdb.32700
 QUERY = copy 1 records into null_as_string from stdin delimiters ',','\n' NULL 
as '';
         2,two,NULL
 ERROR = !Failed to import table line 1 field 3 'decimal(5,2)' expected in 
'NULL'
-MAPI  = (monetdb) /var/tmp/mtest-7656/.s.monetdb.37934
-QUERY = copy 1 records into null_as_string from stdin delimiters ',','\n';
-        ,,
-ERROR = !Failed to import table line 1 field 1 'int' expected in ''
-MAPI  = (monetdb) /var/tmp/mtest-7656/.s.monetdb.37934
-QUERY = copy 1 records into null_as_string from stdin delimiters ',','\n';
-        ,zero,0
-ERROR = !Failed to import table line 1 field 1 'int' expected in ''
-MAPI  = (monetdb) /var/tmp/mtest-7656/.s.monetdb.37934
-QUERY = copy 1 records into null_as_string from stdin delimiters ',','\n';
-        2,two,
-ERROR = !Failed to import table line 1 field 3 'decimal(5,2)' expected in ''
 
 # 08:37:31 >  
 # 08:37:31 >  "Done."
diff --git a/sql/test/copy/Tests/null_as_string_errors.stable.out 
b/sql/test/copy/Tests/null_as_string_errors.stable.out
--- a/sql/test/copy/Tests/null_as_string_errors.stable.out
+++ b/sql/test/copy/Tests/null_as_string_errors.stable.out
@@ -29,9 +29,27 @@ Ready.
 # 08:37:31 >  
 
 #create table null_as_string (i int, s string, d decimal(5,2));
+#select * from sys.rejects;
+% .rejects,    .rejects,       .rejects,       .rejects # table_name
+% rowid,       fldid,  message,        input # name
+% bigint,      int,    clob,   clob # type
+% 1,   1,      23,     15 # length
+[ 1,   1,      "'int' expected",       "NULL,NULL,NULL\n"      ]
+[ 1,   3,      "'decimal(5,2)' expected",      "NULL,NULL,NULL\n"      ]
+#select * from sys.rejects;
+% .rejects,    .rejects,       .rejects,       .rejects # table_name
+% rowid,       fldid,  message,        input # name
+% bigint,      int,    clob,   clob # type
+% 1,   1,      14,     12 # length
+[ 1,   1,      "'int' expected",       "NULL,zero,0\n" ]
 #copy 1 records into null_as_string from stdin delimiters ',','\n' NULL as '';
 #1,NULL,1
 [ 1    ]
+#select * from sys.rejects;
+% .rejects,    .rejects,       .rejects,       .rejects # table_name
+% rowid,       fldid,  message,        input # name
+% bigint,      int,    clob,   clob # type
+% 1,   1,      0,      0 # length
 #select * from null_as_string;
 % sys.null_as_string,  sys.null_as_string,     sys.null_as_string # table_name
 % i,   s,      d # name
@@ -44,18 +62,20 @@ Ready.
 % .rejects,    .rejects,       .rejects,       .rejects # table_name
 % rowid,       fldid,  message,        input # name
 % bigint,      int,    clob,   clob # type
-% 1,   1,      23,     15 # length
-[ 1,   1,      "'int' expected",       "NULL,NULL,NULL\n"      ]
-[ 1,   3,      "'decimal(5,2)' expected",      "NULL,NULL,NULL\n"      ]
-[ 1,   1,      "'int' expected",       "NULL,zero,0\n" ]
+% 1,   1,      23,     11 # length
 [ 1,   3,      "'decimal(5,2)' expected",      "2,two,NULL\n"  ]
+#copy 1 records into null_as_string from stdin delimiters ',','\n' best effort;
+#,,
+[ 0    ]
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to