Changeset: d47fadbc0f0c for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d47fadbc0f0c Added Files: sql/test/BugTracker-2016/Tests/null_in_null.Bug-3900.sql sql/test/BugTracker-2016/Tests/null_in_null.Bug-3900.stable.err sql/test/BugTracker-2016/Tests/null_in_null.Bug-3900.stable.out sql/test/BugTracker-2016/Tests/rank_rewrite.Bug-3890.sql sql/test/BugTracker-2016/Tests/rank_rewrite.Bug-3890.stable.err sql/test/BugTracker-2016/Tests/rank_rewrite.Bug-3890.stable.out Modified Files: gdk/gdk_posix.c monetdb5/modules/kernel/algebra.c monetdb5/modules/mal/batExtensions.c monetdb5/modules/mal/tablet.c sql/common/sql_types.h sql/server/rel_exp.c sql/server/rel_optimizer.c sql/server/rel_select.c sql/server/rel_updates.c sql/test/BugTracker-2010/Tests/incomplete-utf8-sequence.Bug-2575.stable.err sql/test/BugTracker-2016/Tests/All Branch: default Log Message:
Merge with Jul2015 branch, not propagating changeset 98cdca21a670. diffs (truncated from 595 to 300 lines): diff --git a/gdk/gdk_posix.c b/gdk/gdk_posix.c --- a/gdk/gdk_posix.c +++ b/gdk/gdk_posix.c @@ -400,7 +400,11 @@ MT_mremap(const char *path, int mode, vo PTRFMTCAST ((char *) old_address + *new_size), old_size - *new_size); fprintf(stderr, "= %s:%d: MT_mremap(%s,"PTRFMT","SZFMT","SZFMT"): munmap() failed\n", __FILE__, __LINE__, path?path:"NULL", PTRFMTCAST old_address, old_size, *new_size); - return NULL; + /* even though the system call failed, we + * don't need to propagate the error up: the + * address should still work in the same way + * as it did before */ + return old_address; } if (path && truncate(path, *new_size) < 0) fprintf(stderr, "#MT_mremap(%s): truncate failed\n", path); 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 @@ -142,7 +142,7 @@ ALGminany(ptr result, const bat *bid) "atom '%s' cannot be ordered linearly", ATOMname(b->ttype)); } else { - if (ATOMvarsized(b->ttype)) { + if (ATOMextern(b->ttype)) { * (ptr *) result = p = BATmin(b, NULL); } else { p = BATmin(b, result); @@ -170,7 +170,7 @@ ALGmaxany(ptr result, const bat *bid) "atom '%s' cannot be ordered linearly", ATOMname(b->ttype)); } else { - if (ATOMvarsized(b->ttype)) { + if (ATOMextern(b->ttype)) { * (ptr *) result = p = BATmax(b, NULL); } else { p = BATmax(b, result); diff --git a/monetdb5/modules/mal/batExtensions.c b/monetdb5/modules/mal/batExtensions.c --- a/monetdb5/modules/mal/batExtensions.c +++ b/monetdb5/modules/mal/batExtensions.c @@ -183,13 +183,9 @@ CMDBATsingle(Client cntxt, MalBlkPtr mb, if( b == 0) throw(MAL,"bat.single","Could not create it"); BATseqbase(b, 0); - if (b->ttype >= TYPE_str && ATOMstorage(b->ttype) >= TYPE_str) { - if (u == 0 || *(str*)u == 0) - u = (ptr) str_nil; - else - u = (ptr) *(str *)u; - } - BUNappend(b,u, FALSE); + if (ATOMextern(b->ttype)) + u = (ptr) *(str *)u; + BUNappend(b, u, FALSE); BBPincref(*ret = b->batCacheid, TRUE); return MAL_SUCCEED; } 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 @@ -862,7 +862,7 @@ SQLload_error(READERtask *task, lng idx, if (i < attrs - 1) s = mycpstr(s, task->csep); } - strcat(line, task->rsep); + strcpy(s, task->rsep); return line; } @@ -871,6 +871,10 @@ SQLload_error(READERtask *task, lng idx, * the null-replacement string then we grab the underlying nil. * If the string starts with the quote identified from SQL, we locate the tail * and interpret the body. + * + * If inserting fails, we return -1; if the value cannot be parsed, we + * return -1 if besteffort is not set, otherwise we return 0, but in + * either case an entry is added to the error table. */ static inline int SQLinsert_val(READERtask *task, int col, int idx) @@ -889,26 +893,39 @@ SQLinsert_val(READERtask *task, int col, } else adt = fmt->frstr(fmt, fmt->adt, s); + /* col is zero-based, but for error messages it needs to be + * one-based, and from here on, we only use col anymore to produce + * error messages */ + col++; + if (adt == NULL) { lng row = task->cnt + idx + 1; - snprintf(buf, BUFSIZ, "'%s' expected", fmt->type); + snprintf(buf, sizeof(buf), "'%s' expected", fmt->type); err = SQLload_error(task, idx, task->as->nr_attrs); if (task->rowerror) { + size_t slen = mystrlen(s); + char *scpy = GDKmalloc(slen + 1); + if (scpy) + mycpstr(scpy, s); MT_lock_set(&errorlock); - col++; - BUNappend(task->cntxt->error_row, &row, FALSE); - BUNappend(task->cntxt->error_fld, &col, FALSE); - BUNappend(task->cntxt->error_msg, buf, FALSE); - BUNappend(task->cntxt->error_input, err, FALSE); - snprintf(buf, BUFSIZ, "line " LLFMT " field %d '%s' expected in '%s'", row, col, fmt->type, s); - buf[BUFSIZ-1]=0; + snprintf(buf, sizeof(buf), "line " LLFMT " field %d '%s' expected in '%s'", row, col, fmt->type, scpy ? scpy : buf); + GDKfree(scpy); + buf[sizeof(buf)-1]=0; if (task->as->error == NULL && (task->as->error = GDKstrdup(buf)) == NULL) task->as->error = M5OutOfMemory; task->rowerror[idx]++; task->errorcnt++; + if (BUNappend(task->cntxt->error_row, &row, FALSE) != GDK_SUCCEED || + BUNappend(task->cntxt->error_fld, &col, FALSE) != GDK_SUCCEED || + BUNappend(task->cntxt->error_msg, buf, FALSE) != GDK_SUCCEED || + BUNappend(task->cntxt->error_input, err, FALSE) != GDK_SUCCEED) { + GDKfree(err); + task->besteffort = 0; /* no longer best effort */ + return -1; + } MT_lock_unset(&errorlock); } - ret = -1 * (task->besteffort == 0); + ret = -!task->besteffort; /* yep, two unary operators ;-) */ GDKfree(err); /* replace it with a nil */ adt = fmt->nildata; @@ -926,10 +943,11 @@ SQLinsert_val(READERtask *task, int col, err = SQLload_error(task, idx,task->as->nr_attrs); BUNappend(task->cntxt->error_input, err, FALSE); GDKfree(err); - task->rowerror[row - 1]++; + task->rowerror[idx]++; task->errorcnt++; MT_lock_unset(&errorlock); } + task->besteffort = 0; /* no longer best effort */ return -1; } @@ -951,9 +969,8 @@ SQLworker_column(READERtask *task, int c MT_lock_unset(&mal_copyLock); for (i = 0; i < task->top[task->cur]; i++) { - if (!fmt[col].skip && SQLinsert_val(task, col, i) < 0){ - if(task->besteffort == 0) - return -1; + if (!fmt[col].skip && SQLinsert_val(task, col, i) < 0) { + return -1; } } @@ -1135,7 +1152,7 @@ SQLworker(void *arg) if (SQLload_parse_line(task, j) < 0) { task->errorcnt++; // early break unless best effort - if(task->besteffort == 0) + if (!task->besteffort) break; } } @@ -1146,7 +1163,8 @@ SQLworker(void *arg) for (i = 0; i < task->as->nr_attrs; i++) if (task->cols[i]) { t0 = GDKusec(); - SQLworker_column(task, task->cols[i] - 1); + if (SQLworker_column(task, task->cols[i] - 1) < 0) + break; t0 = GDKusec() - t0; task->time[i] += t0; task->wtime += t0; @@ -1612,7 +1630,7 @@ SQLload_file(Client cntxt, Tablet *as, b mnstr_printf(GDKout, "#Prepare copy work for %d threads col '%s' rec '%s' quot '%c'\n", threads, csep, rsep, quote); #endif - memset((char *) ptask, 0, MAXWORKERS * sizeof(READERtask)); + memset(ptask, 0, sizeof(ptask)); if (task == 0) { //SQLload file error @@ -1808,9 +1826,15 @@ SQLload_file(Client cntxt, Tablet *as, b tio = t1 - tio; /* await completion of the BAT updates */ - if (res == 0 && task->top[task->cur]) - for (j = 0; j < threads; j++) + if (res == 0 && task->top[task->cur]) { + for (j = 0; j < threads; j++) { MT_sema_down(&ptask[j].reply); + if (ptask[j].errorcnt > 0 && !ptask[j].besteffort) { + res = -1; + best = 0; + } + } + } /* trim the BATs discarding error tuples */ #define trimerrors(TYPE) \ @@ -1882,6 +1906,11 @@ SQLload_file(Client cntxt, Tablet *as, b task->errorcnt = 0; } + if (res < 0) { + /* producer should stop */ + task->maxrow = cnt; + task->state = ENDOFCOPY; + } MT_sema_up(&task->producer); } #ifdef _DEBUG_TABLET_ @@ -1915,10 +1944,12 @@ SQLload_file(Client cntxt, Tablet *as, b mnstr_printf(GDKout, "#Activate sync on disk \n"); #endif // activate the workers to sync the BATs to disk - for (j = 0; j < threads; j++) { - // stage three, update the BATs - ptask[j].state = SYNCBAT; - MT_sema_up(&ptask[j].sema); + if (res == 0) { + for (j = 0; j < threads; j++) { + // stage three, update the BATs + ptask[j].state = SYNCBAT; + MT_sema_up(&ptask[j].sema); + } } if (!task->ateof || cnt < task->maxrow) { @@ -1928,9 +1959,11 @@ SQLload_file(Client cntxt, Tablet *as, b MT_sema_up(&task->producer); } MT_join_thread(task->tid); - // await completion of the BAT syncs - for (j = 0; j < threads; j++) - MT_sema_down(&ptask[j].reply); + if (res == 0) { + // await completion of the BAT syncs + for (j = 0; j < threads; j++) + MT_sema_down(&ptask[j].reply); + } #ifdef _DEBUG_TABLET_ mnstr_printf(GDKout, "#Activate endofcopy\n"); diff --git a/sql/common/sql_types.h b/sql/common/sql_types.h --- a/sql/common/sql_types.h +++ b/sql/common/sql_types.h @@ -18,6 +18,7 @@ #define EC_MAX 17 #define EC_ANY 0 +#define IS_ANY(e) (e==EC_ANY) #define EC_TABLE 1 #define EC_BIT 2 #define EC_CHAR 3 diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c --- a/sql/server/rel_select.c +++ b/sql/server/rel_select.c @@ -765,14 +765,17 @@ table_ref(mvc *sql, sql_rel *rel, symbol (void)rel; if (tableref->token == SQL_NAME) { + dlist *name = tableref->data.lval->h->data.lval; sql_rel *temp_table = NULL; - char *sname = qname_schema(tableref->data.lval->h->data.lval); + char *sname = qname_schema(name); sql_schema *s = NULL; - tname = qname_table(tableref->data.lval->h->data.lval); + tname = qname_table(name); + + if (dlist_length(name) > 2) + return sql_error(sql, 02, "3F000!SELECT: only a schema and table name expected"); if (sname && !(s=mvc_bind_schema(sql,sname))) return sql_error(sql, 02, "3F000!SELECT: no such schema '%s'", sname); - /* TODO: search path */ if (!t && !sname) { t = stack_find_table(sql, tname); if (!t && sql->use_views) @@ -1790,7 +1793,12 @@ rel_logical_value_exp(mvc *sql, sql_rel sql_rel *z = NULL, *rl; r = rel_value_exp(sql, &z, sval, f, ek); - if (!r || !(r=rel_check_type(sql, st, r, type_equal))) { + if (l && IS_ANY(st->type->eclass)){ + l = rel_check_type(sql, exp_subtype(r), l, type_equal); + if (l) + st = exp_subtype(l); + } + if (!l || !r || !(r=rel_check_type(sql, st, r, type_equal))) { rel_destroy(right); return NULL; } @@ -2749,7 +2757,35 @@ rel_binop_(mvc *sql, sql_exp *l, sql_exp r = exp_aggr1(sql->sa, r, zero_or_one, 0, 0, CARD_ATOM, 0); } - return exp_binop(sql->sa, l, r, f); + /* bind types of l and r */ + t1 = exp_subtype(l); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list