Changeset: 841ab61d0703 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=841ab61d0703
Added Files:
sql/test/copy/Tests/incorrect_columns.sql
sql/test/copy/Tests/incorrect_columns.stable.err
sql/test/copy/Tests/incorrect_columns.stable.out
Modified Files:
clients/odbc/driver/SQLDriverConnect.c
gdk/gdk_logger.c
monetdb5/modules/kernel/algebra.c
monetdb5/modules/mal/tablet.c
sql/test/copy/Tests/All
sql/test/copy/Tests/key_copy.sql
sql/test/copy/Tests/key_copy.stable.err
Branch: default
Log Message:
merged with jul2015
diffs (truncated from 462 to 300 lines):
diff --git a/clients/odbc/driver/SQLDriverConnect.c
b/clients/odbc/driver/SQLDriverConnect.c
--- a/clients/odbc/driver/SQLDriverConnect.c
+++ b/clients/odbc/driver/SQLDriverConnect.c
@@ -217,16 +217,17 @@ ODBCConnectionString(SQLRETURN rc,
/* calculate how much space was needed */
if (StringLength2Ptr)
- *StringLength2Ptr = (int) (strlen(dsn ? dsn : "DEFAULT") + 5 +
- (uid ? strlen(uid) + 5 : 0) +
- (pwd ? strlen(pwd) + 5 : 0) +
- (host ? strlen(host) + 6 : 0) +
- (port ? port + 6 : 0) +
- (database ? strlen(database) + 10 :
0)
+ *StringLength2Ptr = (SQLSMALLINT)
+ (strlen(dsn ? dsn : "DEFAULT") + 5 +
+ (uid ? strlen(uid) + 5 : 0) +
+ (pwd ? strlen(pwd) + 5 : 0) +
+ (host ? strlen(host) + 6 : 0) +
+ (port ? port + 6 : 0) +
+ (database ? strlen(database) + 10 : 0)
#ifdef ODBCDEBUG
- + (ODBCdebug && getenv("ODBCDEBUG")
== NULL ? strlen(ODBCdebug) + 9 : 0)
+ + (ODBCdebug && getenv("ODBCDEBUG") == NULL ?
strlen(ODBCdebug) + 9 : 0)
#endif
- );
+ );
#ifdef ODBCDEBUG
ODBCLOG("ConnectionString: \"%.*s\" %d\n", buf ? buflen : 6, buf ?
(char *) buf : "(null)", buflen);
diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c
--- a/gdk/gdk_logger.c
+++ b/gdk/gdk_logger.c
@@ -1643,6 +1643,9 @@ logger_load(int debug, const char* fn, c
if (BBPrename(lg->dsnapshots->batCacheid, bak) < 0)
logger_fatal("Logger_new: BBPrename to %s
failed", bak, 0, 0);
logger_add_bat(lg, lg->dsnapshots, "dsnapshots");
+
+ if (bm_subcommit(lg->catalog_bid, lg->catalog_nme,
lg->catalog_bid, lg->catalog_nme, lg->dcatalog, NULL, lg->debug) != GDK_SUCCEED)
+ logger_fatal("Logger_new: commit failed", 0, 0,
0);
}
}
lg->freed = logbat_new(TYPE_int, 1, TRANSIENT);
diff --git a/monetdb5/modules/kernel/algebra.c
b/monetdb5/modules/kernel/algebra.c
--- a/monetdb5/modules/kernel/algebra.c
+++ b/monetdb5/modules/kernel/algebra.c
@@ -108,6 +108,8 @@ CMDgen_group(BAT **result, BAT *gids, BA
r -> hdense = TRUE;
r -> hsorted = TRUE;
r -> hrevsorted = FALSE;
+ r -> tkey = FALSE;
+ r -> tdense = FALSE;
r -> tsorted = BATtordered(gids);
r -> trevsorted = BATtrevordered(gids);
r -> T ->nonil = gids->T->nonil;
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
@@ -838,14 +838,14 @@ mycpstr(char *t, const char *s)
}
static str
-SQLload_error(READERtask *task, lng idx)
+SQLload_error(READERtask *task, lng idx, BUN attrs)
{
str line;
char *s;
size_t sz = 0;
- unsigned int i;
+ BUN i;
- for (i = 0; i < task->as->nr_attrs; i++) {
+ for (i = 0; i < attrs; i++) {
if (task->fields[i][idx])
sz += mystrlen(task->fields[i][idx]);
sz += task->seplen;
@@ -856,10 +856,10 @@ SQLload_error(READERtask *task, lng idx)
tablet_error(task, idx, int_nil, "SQLload malloc error",
"SQLload_error");
return 0;
}
- for (i = 0; i < task->as->nr_attrs; i++) {
+ for (i = 0; i < attrs; i++) {
if (task->fields[i][idx])
s = mycpstr(s, task->fields[i][idx]);
- if (i < task->as->nr_attrs - 1)
+ if (i < attrs - 1)
s = mycpstr(s, task->csep);
}
strcat(line, task->rsep);
@@ -893,7 +893,7 @@ SQLinsert_val(READERtask *task, int col,
if (adt == NULL) {
lng row = task->cnt + idx + 1;
snprintf(buf, BUFSIZ, "'%s' expected", fmt->type);
- err = SQLload_error(task, idx);
+ err = SQLload_error(task, idx, task->as->nr_attrs);
if (task->rowerror) {
MT_lock_set(&errorlock, "insert_val");
col++;
@@ -925,7 +925,7 @@ SQLinsert_val(READERtask *task, int col,
BUNappend(task->cntxt->error_row, &row, FALSE);
BUNappend(task->cntxt->error_fld, &col, FALSE);
BUNappend(task->cntxt->error_msg, "insert failed", FALSE);
- err = SQLload_error(task, idx);
+ err = SQLload_error(task, idx,task->as->nr_attrs);
BUNappend(task->cntxt->error_input, err, FALSE);
GDKfree(err);
task->rowerror[row - 1]++;
@@ -953,8 +953,10 @@ SQLworker_column(READERtask *task, int c
MT_lock_unset(&mal_copyLock, "tablet insert value");
for (i = 0; i < task->top[task->cur]; i++) {
- if (!fmt[col].skip && SQLinsert_val(task, col, i) < 0)
- return -1;
+ if (!fmt[col].skip && SQLinsert_val(task, col, i) < 0){
+ if(task->besteffort == 0)
+ return -1;
+ }
}
return 0;
@@ -984,10 +986,11 @@ SQLload_parse_line(READERtask *task, int
//mnstr_printf(GDKout, "#SQL break line id %d state %d\n%s", task->id,
idx, line);
#endif
assert(idx < task->top[task->cur]);
+ assert(line);
errmsg[0] = 0;
if (task->quote || task->seplen != 1) {
- for (i = 0; i < as->nr_attrs; i++) {
+ for (i = 0; *line && i < as->nr_attrs; i++) {
task->fields[i][idx] = line;
/* recognize fields starting with a quote, keep them */
if (*line == task->quote) {
@@ -1000,7 +1003,7 @@ SQLload_parse_line(READERtask *task, int
mnstr_printf(GDKout, "after #1 %s\n", s);
#endif
if (!line) {
- errline = SQLload_error(task,
task->top[task->cur]);
+ errline = SQLload_error(task, idx, i+1);
snprintf(errmsg, BUFSIZ, "Quote (%c)
missing", task->quote);
tablet_error(task, idx, (int) i,
errmsg, errline);
GDKfree(errline);
@@ -1023,8 +1026,8 @@ SQLload_parse_line(READERtask *task, int
/* not enough fields */
if (i < as->nr_attrs - 1) {
- errline = SQLload_error(task,
task->top[task->cur]);
- snprintf(errmsg, BUFSIZ, "Separator missing
'%s' ", fmt->sep);
+ errline = SQLload_error(task, idx, i+1);
+ snprintf(errmsg, BUFSIZ, "Column value "BUNFMT"
missing ", i+1);
tablet_error(task, idx, (int) i, errmsg,
errline);
GDKfree(errline);
error++;
@@ -1033,18 +1036,14 @@ SQLload_parse_line(READERtask *task, int
for (; i < as->nr_attrs; i++)
task->fields[i][idx] = NULL;
i--;
- }
+ }
endoffieldcheck:
;
/* check for user defined NULL string */
if (!fmt->skip && 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)
- mnstr_printf(GDKout, "#line break failed %d:%s\n", idx,
line);
-#endif
- return error ? -1 : 0;
+ goto endofline;
}
assert(!task->quote);
assert(task->seplen == 1);
@@ -1068,8 +1067,8 @@ SQLload_parse_line(READERtask *task, int
#endif
/* not enough fields */
if (i < as->nr_attrs - 1) {
- errline = SQLload_error(task, task->top[task->cur]);
- snprintf(errmsg, BUFSIZ, "Separator missing '%s' ",
fmt->sep);
+ errline = SQLload_error(task, idx,i+1);
+ snprintf(errmsg, BUFSIZ, "Column value "BUNFMT"
missing",i+1);
tablet_error(task, idx, (int) i, errmsg, errline);
GDKfree(errline);
error++;
@@ -1085,6 +1084,15 @@ SQLload_parse_line(READERtask *task, int
task->fields[i][idx] = 0;
}
}
+endofline:
+ /* check for too many values as well*/
+ if (*line && i == as->nr_attrs) {
+ errline = SQLload_error(task, idx, task->as->nr_attrs);
+ snprintf(errmsg, BUFSIZ, "Leftover data '%s'",line);
+ tablet_error(task, idx, (int) i, errmsg, errline);
+ GDKfree(errline);
+ error++;
+ }
#ifdef _DEBUG_TABLET_
if (error)
mnstr_printf(GDKout, "#line break failed %d:%s\n", idx, line);
@@ -1125,8 +1133,10 @@ SQLworker(void *arg)
for (j = piece * task->id; j < task->top[task->cur] &&
j < piece * (task->id +1); j++)
if (task->lines[task->cur][j]) {
if (SQLload_parse_line(task, j) < 0) {
- task->error++;
- break;
+ task->errorcnt++;
+ // early break unless best
effort
+ if(task->besteffort == 0)
+ break;
}
}
task->wtime = GDKusec() - t0;
@@ -1550,7 +1560,7 @@ SQLproducer(void *p)
BUN
SQLload_file(Client cntxt, Tablet *as, bstream *b, stream *out, char *csep,
char *rsep, char quote, lng skip, lng maxrow, int best)
{
- BUN cnt = 0, cntstart = 0;
+ BUN cnt = 0, cntstart = 0, leftover = 0;
int res = 0; /* < 0: error, > 0: success, == 0: continue
processing */
int j;
BUN i, attr;
@@ -1794,7 +1804,7 @@ SQLload_file(Client cntxt, Tablet *as, b
#define trimerrors(TYPE)
\
do {
\
TYPE *src, *dst;
\
- BUN leftover= BATcount(task->as->format[attr].c);
\
+ leftover= BATcount(task->as->format[attr].c);
\
limit = leftover - cntstart;
\
dst =src= (TYPE *)
BUNtloc(task->as->format[attr].ci,cntstart); \
for(j = 0; j < (int) limit; j++, src++){
\
@@ -1813,8 +1823,14 @@ SQLload_file(Client cntxt, Tablet *as, b
#endif
if (best && BATcount(as->format[0].c)) {
BUN limit;
+ int width;
+
for (attr = 0; attr < as->nr_attrs; attr++) {
- switch (ATOMsize(as->format[attr].c->ttype)) {
+ if( as->format[attr].c->ttype == TYPE_str)
+ width = as->format[attr].c->T->width;
+ else
+ width =
ATOMsize(as->format[attr].c->ttype);
+ switch (width){
case 1:
trimerrors(unsigned char);
break;
diff --git a/sql/test/copy/Tests/All b/sql/test/copy/Tests/All
--- a/sql/test/copy/Tests/All
+++ b/sql/test/copy/Tests/All
@@ -11,3 +11,4 @@ overflow_error
format_date
key_copy
nonutf8
+incorrect_columns
diff --git a/sql/test/copy/Tests/incorrect_columns.sql
b/sql/test/copy/Tests/incorrect_columns.sql
new file mode 100644
--- /dev/null
+++ b/sql/test/copy/Tests/incorrect_columns.sql
@@ -0,0 +1,17 @@
+-- test the situation where the number of column values are incorrect
+create table t_columns(i int, t string);
+
+copy 7 records into t_columns from stdin delimiters ',','\n' best effort;
+1,hello
+2
+no tag
+3,too much,xyz
+4,world
+5,wereld
+6,maan
+
+select * from t_columns;
+
+select * from sys.rejects();
+
+drop table t_columns;
diff --git a/sql/test/copy/Tests/incorrect_columns.stable.err
b/sql/test/copy/Tests/incorrect_columns.stable.err
new file mode 100644
--- /dev/null
+++ b/sql/test/copy/Tests/incorrect_columns.stable.err
@@ -0,0 +1,37 @@
+stderr of test 'incorrect_columns` in directory 'sql/test/copy` itself:
+
+
+# 08:11:47 >
+# 08:11:47 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set"
"mapi_open=true" "--set" "mapi_port=37579" "--set"
"mapi_usock=/var/tmp/mtest-26664/.s.monetdb.37579" "--set" "monet_prompt="
"--forcemito" "--set" "mal_listing=2"
"--dbpath=/export/scratch1/mk/Jul2015//Linux/var/MonetDB/mTests_sql_test_copy"
"--set" "mal_listing=0" "--set" "embedded_r=yes"
+# 08:11:47 >
+
+# builtin opt gdk_dbpath =
/export/scratch1/mk/Jul2015//Linux/var/monetdb5/dbfarm/demo
+# builtin opt gdk_debug = 0
+# builtin opt gdk_vmtrim = no
+# builtin opt monet_prompt = >
+# builtin opt monet_daemon = no
+# builtin opt mapi_port = 50000
+# builtin opt mapi_open = false
+# builtin opt mapi_autosense = false
+# builtin opt sql_optimizer = default_pipe
+# builtin opt sql_debug = 0
+# cmdline opt gdk_nr_threads = 0
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list