Changeset: ad1e7f4cf5d6 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ad1e7f4cf5d6 Added Files: sql/test/BugTracker-2020/Tests/global_table_propagation.Bug-6846.py sql/test/BugTracker-2020/Tests/global_table_propagation.Bug-6846.stable.err sql/test/BugTracker-2020/Tests/global_table_propagation.Bug-6846.stable.out Modified Files: clients/Tests/All clients/Tests/MAL-signatures.stable.out clients/Tests/MAL-signatures.stable.out.int128 clients/Tests/SingleServer clients/mapiclient/mclient.1 gdk/gdk_bat.c gdk/gdk_tracer.c monetdb5/mal/mal.c monetdb5/mal/mal_parser.c monetdb5/modules/mal/tablet.c monetdb5/optimizer/opt_pushselect.c monetdb5/tools/Tests/mserver5--help.stable.err monetdb5/tools/Tests/mserver5--help.stable.err.Windows sql/ChangeLog.Jun2020 sql/backends/monet5/sql.c sql/backends/monet5/sql_cat.c sql/backends/monet5/sql_result.c sql/server/rel_schema.c sql/server/sql_mvc.c sql/server/sql_partition.c sql/storage/bat/bat_storage.c sql/storage/sql_storage.h sql/storage/store.c sql/test/BugTracker-2018/Tests/nested-merge-tables.Bug-6585.stable.err sql/test/BugTracker-2019/Tests/grant-select-column.Bug-6765.py sql/test/BugTracker-2019/Tests/grant-select-column.Bug-6765.stable.err sql/test/BugTracker-2019/Tests/grant-select-column.Bug-6765.stable.out sql/test/BugTracker-2019/Tests/python-loader-string.Bug-6759.py sql/test/BugTracker-2019/Tests/python-loader-string.Bug-6759.stable.err sql/test/BugTracker-2019/Tests/python-loader-string.Bug-6759.stable.out sql/test/BugTracker-2020/Tests/All sql/test/BugTracker-2020/Tests/alter-table-add-column.Bug-6816.py sql/test/BugTracker-2020/Tests/alter-table-add-column.Bug-6816.stable.err sql/test/BugTracker-2020/Tests/alter-table-add-column.Bug-6816.stable.out sql/test/BugTracker-2020/Tests/functions-not-persist.Bug-6819.SQL.py sql/test/BugTracker-2020/Tests/functions-not-persist.Bug-6819.stable.err sql/test/BugTracker-2020/Tests/functions-not-persist.Bug-6819.stable.out sql/test/merge-partitions/Tests/mergepart05.stable.err sql/test/merge-partitions/Tests/mergepart07.stable.err sql/test/mergetables/Tests/mergedropcrash.stable.err sql/test/pg_regress/Tests/alter_table.stable.err sql/test/pg_regress/Tests/drop.stable.err tools/merovingian/client/monetdb.1 tools/merovingian/daemon/monetdbd.1.in tools/mserver/mserver5.1.in tools/mserver/mserver5.c Branch: scoping Log Message:
Merged with default diffs (truncated from 2176 to 300 lines): diff --git a/clients/Tests/All b/clients/Tests/All --- a/clients/Tests/All +++ b/clients/Tests/All @@ -1,4 +1,4 @@ exports -HAVE_FITS&HAVE_GEOM&HAVE_LIBR&HAVE_LIDAR&HAVE_NETCDF&HAVE_SHP?MAL-signatures +HAVE_FITS&HAVE_GEOM&HAVE_LIBR&HAVE_LIBPY3&HAVE_LIDAR&HAVE_NETCDF&HAVE_SHP&NOT_WIN32?MAL-signatures MERCURIAL?malcheck mclient-uri diff --git a/clients/Tests/MAL-signatures.stable.out b/clients/Tests/MAL-signatures.stable.out --- a/clients/Tests/MAL-signatures.stable.out +++ b/clients/Tests/MAL-signatures.stable.out @@ -64,7 +64,7 @@ stdout of test 'MAL-signatures` in direc % .%1, .%1, .%1, .%1, .%1 # table_name % module, function, signature, address, comment # name % clob, clob, clob, clob, clob # type -% 10, 28, 364, 38, 874 # length +% 12, 28, 364, 38, 874 # length [ "aggr", "allnotequal", "command aggr.allnotequal(l:bat[:any_1], r:bat[:any_1]):bit ", "SQLallnotequal;", "if all values in r are not equal to l return true, else if r has nil nil else false" ] [ "aggr", "anyequal", "pattern aggr.anyequal(l:any_1, r:any_1):bit ", "CMDvarEQ;", "" ] [ "aggr", "anyequal", "command aggr.anyequal(l:bat[:any_1], r:bat[:any_1]):bit ", "SQLanyequal;", "if any value in r is equal to l return true, else if r has nil nil else false" ] @@ -11242,6 +11242,14 @@ stdout of test 'MAL-signatures` in direc [ "batmtime", "year", "command batmtime.year(d:bat[:date]):bat[:int] ", "MTIMEdate_extract_year_bulk;", "" ] [ "batpcre", "replace", "command batpcre.replace(orig:bat[:str], pat:str, repl:str, flag:str):bat[:str] ", "PCREreplace_bat_wrap;", "" ] [ "batpcre", "replace_first", "command batpcre.replace_first(orig:bat[:str], pat:str, repl:str, flag:str):bat[:str] ", "PCREreplacefirst_bat_wrap;", "" ] +[ "batpyapi3", "eval", "unsafe pattern batpyapi3.eval(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalStd;", "Execute a simple Python script value" ] +[ "batpyapi3", "eval_aggr", "unsafe pattern batpyapi3.eval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggr;", "grouped aggregates through Python" ] +[ "batpyapi3", "eval_loader", "unsafe pattern batpyapi3.eval_loader(fptr:ptr, expr:str):any... ", "PYAPI3PyAPIevalLoader;", "loader functions through Python" ] +[ "batpyapi3", "eval_loader", "unsafe pattern batpyapi3.eval_loader(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalLoader;", "loader functions through Python" ] +[ "batpyapi3", "subeval_aggr", "unsafe pattern batpyapi3.subeval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggr;", "grouped aggregates through Python" ] +[ "batpyapi3map", "eval", "pattern batpyapi3map.eval(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalStdMap;", "Execute a simple Python script value" ] +[ "batpyapi3map", "eval_aggr", "pattern batpyapi3map.eval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggrMap;", "grouped aggregates through Python" ] +[ "batpyapi3map", "subeval_aggr", "pattern batpyapi3map.subeval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggrMap;", "grouped aggregates through Python" ] [ "batrapi", "eval", "pattern batrapi.eval(fptr:ptr, expr:str, arg:any...):any... ", "RAPIevalStd;", "Execute a simple R script value" ] [ "batrapi", "eval_aggr", "pattern batrapi.eval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "RAPIevalAggr;", "grouped aggregates through R" ] [ "batrapi", "subeval_aggr", "pattern batrapi.subeval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "RAPIevalAggr;", "grouped aggregates through R" ] @@ -13949,6 +13957,17 @@ stdout of test 'MAL-signatures` in direc [ "profiler", "starttrace", "pattern profiler.starttrace():void ", "CMDstartTrace;", "Start collecting trace information" ] [ "profiler", "stop", "pattern profiler.stop():void ", "CMDstopProfiler;", "Stop offline performance profiling" ] [ "profiler", "stoptrace", "pattern profiler.stoptrace():void ", "CMDstopTrace;", "Stop collecting trace information" ] +[ "pyapi3", "eval", "unsafe pattern pyapi3.eval(fptr:ptr, expr:str):any ", "PYAPI3PyAPIevalStd;", "Execute a simple Python script returning a single value" ] +[ "pyapi3", "eval", "unsafe pattern pyapi3.eval(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalStd;", "Execute a simple Python script value" ] +[ "pyapi3", "eval_aggr", "unsafe pattern pyapi3.eval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggr;", "grouped aggregates through Python" ] +[ "pyapi3", "eval_loader", "unsafe pattern pyapi3.eval_loader(fptr:ptr, expr:str):any... ", "PYAPI3PyAPIevalLoader;", "loader functions through Python" ] +[ "pyapi3", "eval_loader", "unsafe pattern pyapi3.eval_loader(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalLoader;", "loader functions through Python" ] +[ "pyapi3", "prelude", "command pyapi3.prelude():void ", "PYAPI3PyAPIprelude;", "" ] +[ "pyapi3", "subeval_aggr", "unsafe pattern pyapi3.subeval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggr;", "grouped aggregates through Python" ] +[ "pyapi3map", "eval", "pattern pyapi3map.eval(fptr:ptr, expr:str):any ", "PYAPI3PyAPIevalStdMap;", "Execute a simple Python script returning a single value" ] +[ "pyapi3map", "eval", "pattern pyapi3map.eval(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalStdMap;", "Execute a simple Python script value" ] +[ "pyapi3map", "eval_aggr", "pattern pyapi3map.eval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggrMap;", "grouped aggregates through Python" ] +[ "pyapi3map", "subeval_aggr", "pattern pyapi3map.subeval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggrMap;", "grouped aggregates through Python" ] [ "querylog", "append", "pattern querylog.append(q:str, pipe:str, usr:str, tick:timestamp):void ", "QLOGappend;", "Add a new query call to the query log" ] [ "querylog", "call", "pattern querylog.call(tick1:timestamp, tick2:timestamp, arg:str, tuples:lng, xtime:lng, rtime:lng, cpu:int, iowait:int):void ", "QLOGcall;", "Add a new query call to the query log" ] [ "querylog", "context", "command querylog.context(release:str, version:str, revision:str, uri:str):void ", "QLOGcontextNaive;", "Noop operation, just marking the query" ] diff --git a/clients/Tests/MAL-signatures.stable.out.int128 b/clients/Tests/MAL-signatures.stable.out.int128 --- a/clients/Tests/MAL-signatures.stable.out.int128 +++ b/clients/Tests/MAL-signatures.stable.out.int128 @@ -68,7 +68,7 @@ stdout of test 'MAL-signatures` in direc % .%1, .%1, .%1, .%1, .%1 # table_name % module, function, signature, address, comment # name % clob, clob, clob, clob, clob # type -% 10, 28, 364, 38, 874 # length +% 12, 28, 364, 38, 874 # length [ "aggr", "allnotequal", "command aggr.allnotequal(l:bat[:any_1], r:bat[:any_1]):bit ", "SQLallnotequal;", "if all values in r are not equal to l return true, else if r has nil nil else false" ] [ "aggr", "anyequal", "pattern aggr.anyequal(l:any_1, r:any_1):bit ", "CMDvarEQ;", "" ] [ "aggr", "anyequal", "command aggr.anyequal(l:bat[:any_1], r:bat[:any_1]):bit ", "SQLanyequal;", "if any value in r is equal to l return true, else if r has nil nil else false" ] @@ -15997,6 +15997,14 @@ stdout of test 'MAL-signatures` in direc [ "batmtime", "year", "command batmtime.year(d:bat[:date]):bat[:int] ", "MTIMEdate_extract_year_bulk;", "" ] [ "batpcre", "replace", "command batpcre.replace(orig:bat[:str], pat:str, repl:str, flag:str):bat[:str] ", "PCREreplace_bat_wrap;", "" ] [ "batpcre", "replace_first", "command batpcre.replace_first(orig:bat[:str], pat:str, repl:str, flag:str):bat[:str] ", "PCREreplacefirst_bat_wrap;", "" ] +[ "batpyapi3", "eval", "unsafe pattern batpyapi3.eval(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalStd;", "Execute a simple Python script value" ] +[ "batpyapi3", "eval_aggr", "unsafe pattern batpyapi3.eval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggr;", "grouped aggregates through Python" ] +[ "batpyapi3", "eval_loader", "unsafe pattern batpyapi3.eval_loader(fptr:ptr, expr:str):any... ", "PYAPI3PyAPIevalLoader;", "loader functions through Python" ] +[ "batpyapi3", "eval_loader", "unsafe pattern batpyapi3.eval_loader(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalLoader;", "loader functions through Python" ] +[ "batpyapi3", "subeval_aggr", "unsafe pattern batpyapi3.subeval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggr;", "grouped aggregates through Python" ] +[ "batpyapi3map", "eval", "pattern batpyapi3map.eval(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalStdMap;", "Execute a simple Python script value" ] +[ "batpyapi3map", "eval_aggr", "pattern batpyapi3map.eval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggrMap;", "grouped aggregates through Python" ] +[ "batpyapi3map", "subeval_aggr", "pattern batpyapi3map.subeval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggrMap;", "grouped aggregates through Python" ] [ "batrapi", "eval", "pattern batrapi.eval(fptr:ptr, expr:str, arg:any...):any... ", "RAPIevalStd;", "Execute a simple R script value" ] [ "batrapi", "eval_aggr", "pattern batrapi.eval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "RAPIevalAggr;", "grouped aggregates through R" ] [ "batrapi", "subeval_aggr", "pattern batrapi.subeval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "RAPIevalAggr;", "grouped aggregates through R" ] @@ -19401,6 +19409,17 @@ stdout of test 'MAL-signatures` in direc [ "profiler", "starttrace", "pattern profiler.starttrace():void ", "CMDstartTrace;", "Start collecting trace information" ] [ "profiler", "stop", "pattern profiler.stop():void ", "CMDstopProfiler;", "Stop offline performance profiling" ] [ "profiler", "stoptrace", "pattern profiler.stoptrace():void ", "CMDstopTrace;", "Stop collecting trace information" ] +[ "pyapi3", "eval", "unsafe pattern pyapi3.eval(fptr:ptr, expr:str):any ", "PYAPI3PyAPIevalStd;", "Execute a simple Python script returning a single value" ] +[ "pyapi3", "eval", "unsafe pattern pyapi3.eval(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalStd;", "Execute a simple Python script value" ] +[ "pyapi3", "eval_aggr", "unsafe pattern pyapi3.eval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggr;", "grouped aggregates through Python" ] +[ "pyapi3", "eval_loader", "unsafe pattern pyapi3.eval_loader(fptr:ptr, expr:str):any... ", "PYAPI3PyAPIevalLoader;", "loader functions through Python" ] +[ "pyapi3", "eval_loader", "unsafe pattern pyapi3.eval_loader(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalLoader;", "loader functions through Python" ] +[ "pyapi3", "prelude", "command pyapi3.prelude():void ", "PYAPI3PyAPIprelude;", "" ] +[ "pyapi3", "subeval_aggr", "unsafe pattern pyapi3.subeval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggr;", "grouped aggregates through Python" ] +[ "pyapi3map", "eval", "pattern pyapi3map.eval(fptr:ptr, expr:str):any ", "PYAPI3PyAPIevalStdMap;", "Execute a simple Python script returning a single value" ] +[ "pyapi3map", "eval", "pattern pyapi3map.eval(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalStdMap;", "Execute a simple Python script value" ] +[ "pyapi3map", "eval_aggr", "pattern pyapi3map.eval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggrMap;", "grouped aggregates through Python" ] +[ "pyapi3map", "subeval_aggr", "pattern pyapi3map.subeval_aggr(fptr:ptr, expr:str, arg:any...):any... ", "PYAPI3PyAPIevalAggrMap;", "grouped aggregates through Python" ] [ "querylog", "append", "pattern querylog.append(q:str, pipe:str, usr:str, tick:timestamp):void ", "QLOGappend;", "Add a new query call to the query log" ] [ "querylog", "call", "pattern querylog.call(tick1:timestamp, tick2:timestamp, arg:str, tuples:lng, xtime:lng, rtime:lng, cpu:int, iowait:int):void ", "QLOGcall;", "Add a new query call to the query log" ] [ "querylog", "context", "command querylog.context(release:str, version:str, revision:str, uri:str):void ", "QLOGcontextNaive;", "Noop operation, just marking the query" ] diff --git a/clients/Tests/SingleServer b/clients/Tests/SingleServer --- a/clients/Tests/SingleServer +++ b/clients/Tests/SingleServer @@ -1,2 +1,3 @@ ---set embedded_py=2 +--set embedded_py=3 --set embedded_r=true +--set embedded_c=true diff --git a/clients/mapiclient/mclient.1 b/clients/mapiclient/mclient.1 --- a/clients/mapiclient/mclient.1 +++ b/clients/mapiclient/mclient.1 @@ -169,8 +169,12 @@ All timings are reported on stderr. .br \fBNote\fP that the client-measured wall-clock time is reported per query \fBonly\fP when options \fB\-\-interactive\fP or \fB\-\-echo\fP are used, -because only then does mclient send individual lines (statements) of the SQL -script to the server. Otherwise, when mclient sends the SQL script in +because only then does +.I mclient +send individual lines (statements) of the SQL +script to the server. Otherwise, when +.I mclient +sends the SQL script in large(r) batch(es), only the total wall-clock time per batch is measured and reported. The server-measured detailed performance timings are always measured and reported per query. @@ -454,7 +458,9 @@ is the name of the database. mclient \-d $db \-s \(dqCOPY INTO $table FROM '$file' USING DELIMITERS ',',E'\e\en','\e\(dq'\(dq .PP Efficiently import data from a CSV file into a table when the file is -to be read by mclient (e.g. the server has no access to the file). +to be read by +.I mclient +(e.g. the server has no access to the file). .I $file is the (absolute or relative) path name of the file, .I $table diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c --- a/gdk/gdk_bat.c +++ b/gdk/gdk_bat.c @@ -2363,13 +2363,16 @@ BATassertProps(BAT *b) BUN mask; if ((hs = GDKzalloc(sizeof(Hash))) == NULL) { - TRC_ERROR(BAT_, "Cannot allocate hash table\n"); + TRC_WARNING(BAT_, "Cannot allocate hash table\n"); goto abort_check; } if (snprintf(hs->heaplink.filename, sizeof(hs->heaplink.filename), "%s.thshprpl%x", nme, (unsigned) THRgettid()) >= (int) sizeof(hs->heaplink.filename) || snprintf(hs->heapbckt.filename, sizeof(hs->heapbckt.filename), "%s.thshprpb%x", nme, (unsigned) THRgettid()) >= (int) sizeof(hs->heapbckt.filename)) { + /* cannot happen, see comment in gdk.h + * about sizes near definition of + * BBPINIT */ GDKfree(hs); - TRC_ERROR(BAT_, "Heap filename is too large\n"); + TRC_CRITICAL(BAT_, "Heap filename is too large\n"); goto abort_check; } if (ATOMsize(b->ttype) == 1) @@ -2385,7 +2388,7 @@ BATassertProps(BAT *b) HASHnew(hs, b->ttype, BUNlast(b), mask, BUN_NONE, false) != GDK_SUCCEED) { GDKfree(hs); - TRC_ERROR(BAT_, "Cannot allocate hash table\n"); + TRC_WARNING(BAT_, "Cannot allocate hash table\n"); goto abort_check; } BATloop(b, p, q) { diff --git a/gdk/gdk_tracer.c b/gdk/gdk_tracer.c --- a/gdk/gdk_tracer.c +++ b/gdk/gdk_tracer.c @@ -104,14 +104,24 @@ static gdk_return const char *trace_path; trace_path = GDKgetenv("gdk_dbtrace"); - if (trace_path == NULL) + if (trace_path == NULL) { trace_path = GDKgetenv("gdk_dbpath"); - if (trace_path == NULL) { - active_tracer = stderr; - return GDK_SUCCEED; + if (trace_path == NULL) { + active_tracer = stderr; + return GDK_SUCCEED; + } + if (strconcat_len(file_name, sizeof(file_name), + trace_path, DIR_SEP_STR, FILE_NAME, NULL) + >= sizeof(file_name)) { + goto too_long; + } + } else { + if (strcpy_len(file_name, trace_path, sizeof(file_name)) + >= sizeof(file_name)) { + goto too_long; + } } - snprintf(file_name, sizeof(file_name), "%s%c%s", trace_path, DIR_SEP, FILE_NAME); active_tracer = fopen(file_name, "a"); if (active_tracer == NULL) { @@ -122,6 +132,12 @@ static gdk_return } return GDK_SUCCEED; + + too_long: + GDK_TRACER_EXCEPTION("path name for dbtrace file too long"); + file_name[0] = 0; /* uninitialize */ + active_tracer = stderr; + return GDK_FAIL; } diff --git a/monetdb5/mal/mal.c b/monetdb5/mal/mal.c --- a/monetdb5/mal/mal.c +++ b/monetdb5/mal/mal.c @@ -70,7 +70,7 @@ int mal_init(void){ #ifndef NDEBUG mdbExit(); #endif - TRC_ERROR(MAL_SERVER, "%s\n", err); + TRC_CRITICAL(MAL_SERVER, "%s\n", err); freeException(err); return -1; } diff --git a/monetdb5/mal/mal_parser.c b/monetdb5/mal/mal_parser.c --- a/monetdb5/mal/mal_parser.c +++ b/monetdb5/mal/mal_parser.c @@ -1051,12 +1051,12 @@ parseInclude(Client cntxt) s = loadLibrary(modnme, FALSE); if (s) { parseError(cntxt, s); - GDKfree(s); + freeException(s); return 0; } if ((s = malInclude(cntxt, modnme, 0))) { parseError(cntxt, s); - GDKfree(s); + freeException(s); return 0; } return 0; 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 @@ -1304,80 +1304,71 @@ SQLproducer(void *p) goto reportlackofinput; } for (e = s; *e && e < end && cnt < task->maxrow;) { - /* tokenize the record completely the format of the input - * should comply to the following grammar rule [ - * [[quote][[esc]char]*[quote]csep]*rsep]* where quote is - * a single user defined character within the quoted - * fields a character may be escaped with a backslash The - * user should supply the correct number of fields. - * In the first phase we simply break the lines at the - * record boundary. */ + /* tokenize the record completely + * + * The format of the input should comply to the following + * grammar rule [ [[quote][[esc]char]*[quote]csep]*rsep]* + * where quote is a single user-defined character. + * Within the quoted fields a character may be escaped + * with a backslash. The correct number of fields should + * be supplied. In the first phase we simply break the + * lines at the record boundary. */ int nutf = 0; int m = 0; bool bs = false; char q = 0; size_t i = 0; while (*e) { - /* check for correctly encoded UTF-8 */ - if (nutf > 0) { - if ((*e & 0xC0) != 0x80) - goto badutf8; - if (m != 0 && (*e & m) == 0) - goto badutf8; - m = 0; - nutf--; - } else if ((*e & 0xE0) == 0xC0) { - nutf = 1; - if ((e[0] & 0x1E) == 0) + if (task->skip > 0) { + /* no interpretation of data we're skipping, just + * look for newline */ + if (*e == '\n') + break; + } else { + /* check for correctly encoded UTF-8 */ + if (nutf > 0) { + if ((*e & 0xC0) != 0x80) + goto badutf8; + if (m != 0 && (*e & m) == 0) + goto badutf8; + m = 0; + nutf--; + } else if ((*e & 0xE0) == 0xC0) { + nutf = 1; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list