MonetDB: ordered-set-aggregates - Merge with default branch.

2024-12-05 Thread Sjoerd Mullender via checkin-list
Changeset: 0738c5593359 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/0738c5593359
Modified Files:
monetdb5/modules/atoms/str.c
Branch: ordered-set-aggregates
Log Message:

Merge with default branch.


diffs (252 lines):

diff --git a/monetdb5/mal/mal_listing.c b/monetdb5/mal/mal_listing.c
--- a/monetdb5/mal/mal_listing.c
+++ b/monetdb5/mal/mal_listing.c
@@ -61,33 +61,28 @@ copystring(char **dstp, const char *src,
return *src == 0;
 }
 
-static str
-renderTerm(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int idx, int flg)
+static void
+renderTerm(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int idx, int flg, char 
*buf, size_t max_len)
 {
-   char *buf = 0;
+   char *bufend = buf;
int nameused = 0;
-   size_t max_len = 256;
ValRecord *val = 0;
char *cv = 0;
str tpe;
int showtype = 0, closequote = 0;
int varid = getArg(p, idx);
 
-   buf = GDKzalloc(max_len);
-   if (buf == NULL) {
-   addMalException(mb, "renderTerm: Failed to allocate");
-   return NULL;
-   }
// show the name when required or is used
if ((flg & LIST_MAL_NAME) && !isVarConstant(mb, varid)
&& !isVarTypedef(mb, varid)) {
-   getVarNameIntoBuffer(mb, varid, buf);
+   (void) getVarNameIntoBuffer(mb, varid, bufend);
+   bufend += strlen(bufend);
nameused = 1;
}
// show the value when required or being a constant
if (((flg & LIST_MAL_VALUE) && stk != 0) || isVarConstant(mb, varid)) {
if (nameused)
-   strcat(buf, "=");
+   bufend = stpcpy(bufend, "=");
// locate value record
if (isVarConstant(mb, varid)) {
val = &getVarConstant(mb, varid);
@@ -96,14 +91,11 @@ renderTerm(MalBlkPtr mb, MalStkPtr stk, 
} else if (stk) {
val = &stk->stk[varid];
}
-   if ((cv = VALformat(val)) == NULL) {
-   addMalException(mb, "renderTerm: Failed to allocate");
-   GDKfree(buf);
-   return NULL;
-   }
-   if (!val->bat && strcmp(cv, "nil") == 0) {
-   strcat(buf, cv);
-   GDKfree(cv);
+   cv = VALformat(val);
+   if (cv == NULL) {
+   bufend = stpcpy(bufend, "");
+   } else if (!val->bat && strcmp(cv, "nil") == 0) {
+   bufend = stpcpy(bufend, cv);
showtype = showtype ||
(getBatType(getVarType(mb, varid)) >= TYPE_date
 && getBatType(getVarType(mb, varid)) != 
TYPE_str) ||
@@ -114,18 +106,22 @@ renderTerm(MalBlkPtr mb, MalStkPtr stk, 
&& getBatType(getVarType(mb, varid)) >= 
TYPE_date
&& getBatType(getVarType(mb, varid)) != 
TYPE_str) {
closequote = 1;
-   strcat(buf, "\"");
+   bufend = stpcpy(bufend, "\"");
}
size_t cv_len = strlen(cv);
if (cv_len > 100) {
-   strcpy_len(buf, cv, 101); /* 1 for null 
termination */
-   strconcat_len(buf + 100, max_len - 100, "\" 
. ", NULL);
+   cv_len = 100;
+   if (cv_len > (size_t) ((buf + max_len) - 
bufend))
+   cv_len = (buf + max_len) - bufend - 1;
+   strcpy_len(bufend, cv, cv_len + 1); /* 1 for 
null termination */
+   bufend += cv_len;
+   cv_len = strconcat_len(bufend, (buf + max_len) 
- bufend, "\" . ", NULL);
+   bufend += cv_len;
} else {
-   strcat(buf, cv);
+   bufend = stpcpy(bufend, cv);
}
-   GDKfree(cv);
if (closequote) {
-   strcat(buf, "\"");
+   bufend = stpcpy(bufend, "\"");
}
showtype = showtype || closequote > TYPE_str ||
((isVarTypedef(mb, varid) ||
@@ -136,21 +132,21 @@ renderTerm(MalBlkPtr mb, MalStkPtr stk, 
&& stk->stk[varid].val.bval) {
BAT *d = BBPquickdesc(stk->stk[varid].val.bval);
if (d)
-   snprintf(buf, max_len - strlen(buf), 
"[" BUNFMT "]", BATcount(d));
+   bufend += snprintf(bufend, (buf

MonetDB: default - Cleanup: reinstate variable names in trace/ex...

2024-12-05 Thread Sjoerd Mullender via checkin-list
Changeset: 6eed500ca722 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/6eed500ca722
Modified Files:
monetdb5/mal/mal_listing.c
Branch: default
Log Message:

Cleanup: reinstate variable names in trace/explain, avoid some mallocs.


diffs (252 lines):

diff --git a/monetdb5/mal/mal_listing.c b/monetdb5/mal/mal_listing.c
--- a/monetdb5/mal/mal_listing.c
+++ b/monetdb5/mal/mal_listing.c
@@ -61,33 +61,28 @@ copystring(char **dstp, const char *src,
return *src == 0;
 }
 
-static str
-renderTerm(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int idx, int flg)
+static void
+renderTerm(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int idx, int flg, char 
*buf, size_t max_len)
 {
-   char *buf = 0;
+   char *bufend = buf;
int nameused = 0;
-   size_t max_len = 256;
ValRecord *val = 0;
char *cv = 0;
str tpe;
int showtype = 0, closequote = 0;
int varid = getArg(p, idx);
 
-   buf = GDKzalloc(max_len);
-   if (buf == NULL) {
-   addMalException(mb, "renderTerm: Failed to allocate");
-   return NULL;
-   }
// show the name when required or is used
if ((flg & LIST_MAL_NAME) && !isVarConstant(mb, varid)
&& !isVarTypedef(mb, varid)) {
-   getVarNameIntoBuffer(mb, varid, buf);
+   (void) getVarNameIntoBuffer(mb, varid, bufend);
+   bufend += strlen(bufend);
nameused = 1;
}
// show the value when required or being a constant
if (((flg & LIST_MAL_VALUE) && stk != 0) || isVarConstant(mb, varid)) {
if (nameused)
-   strcat(buf, "=");
+   bufend = stpcpy(bufend, "=");
// locate value record
if (isVarConstant(mb, varid)) {
val = &getVarConstant(mb, varid);
@@ -96,14 +91,11 @@ renderTerm(MalBlkPtr mb, MalStkPtr stk, 
} else if (stk) {
val = &stk->stk[varid];
}
-   if ((cv = VALformat(val)) == NULL) {
-   addMalException(mb, "renderTerm: Failed to allocate");
-   GDKfree(buf);
-   return NULL;
-   }
-   if (!val->bat && strcmp(cv, "nil") == 0) {
-   strcat(buf, cv);
-   GDKfree(cv);
+   cv = VALformat(val);
+   if (cv == NULL) {
+   bufend = stpcpy(bufend, "");
+   } else if (!val->bat && strcmp(cv, "nil") == 0) {
+   bufend = stpcpy(bufend, cv);
showtype = showtype ||
(getBatType(getVarType(mb, varid)) >= TYPE_date
 && getBatType(getVarType(mb, varid)) != 
TYPE_str) ||
@@ -114,18 +106,22 @@ renderTerm(MalBlkPtr mb, MalStkPtr stk, 
&& getBatType(getVarType(mb, varid)) >= 
TYPE_date
&& getBatType(getVarType(mb, varid)) != 
TYPE_str) {
closequote = 1;
-   strcat(buf, "\"");
+   bufend = stpcpy(bufend, "\"");
}
size_t cv_len = strlen(cv);
if (cv_len > 100) {
-   strcpy_len(buf, cv, 101); /* 1 for null 
termination */
-   strconcat_len(buf + 100, max_len - 100, "\" 
. ", NULL);
+   cv_len = 100;
+   if (cv_len > (size_t) ((buf + max_len) - 
bufend))
+   cv_len = (buf + max_len) - bufend - 1;
+   strcpy_len(bufend, cv, cv_len + 1); /* 1 for 
null termination */
+   bufend += cv_len;
+   cv_len = strconcat_len(bufend, (buf + max_len) 
- bufend, "\" . ", NULL);
+   bufend += cv_len;
} else {
-   strcat(buf, cv);
+   bufend = stpcpy(bufend, cv);
}
-   GDKfree(cv);
if (closequote) {
-   strcat(buf, "\"");
+   bufend = stpcpy(bufend, "\"");
}
showtype = showtype || closequote > TYPE_str ||
((isVarTypedef(mb, varid) ||
@@ -136,21 +132,21 @@ renderTerm(MalBlkPtr mb, MalStkPtr stk, 
&& stk->stk[varid].val.bval) {
BAT *d = BBPquickdesc(stk->stk[varid].val.bval);
if (d)
-   snprintf(buf, max_len - strlen(buf), 
"[" BUNFMT "]", BATcount(d));
+   buf

MonetDB: Aug2024 - Add sanity checks on null pointers to prevent...

2024-12-05 Thread Martin van Dinther via checkin-list
Changeset: af4d5a3f8add for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/af4d5a3f8add
Modified Files:
sql/backends/monet5/vaults/csv/csv.c
Branch: Aug2024
Log Message:

Add sanity checks on null pointers to prevent segmentation faults.
See also #7604
Note that we now get 'Column value missing' errors, so issue 7604 is not yet 
completely resolved (IMHO).


diffs (112 lines):

diff --git a/sql/backends/monet5/vaults/csv/csv.c 
b/sql/backends/monet5/vaults/csv/csv.c
--- a/sql/backends/monet5/vaults/csv/csv.c
+++ b/sql/backends/monet5/vaults/csv/csv.c
@@ -37,15 +37,17 @@ csv_open_file(char* filename)
 static const char *
 next_delim(const char *s, const char *e, char delim, char quote)
 {
-   bool inquote = false;
-   for(;  s < e; s++) {
-   if (*s == quote)
-   inquote = !inquote;
-   else if (!inquote && *s == delim)
+   if (s && e) {
+   bool inquote = false;
+   for(;  s < e; s++) {
+   if (*s == quote)
+   inquote = !inquote;
+   else if (!inquote && *s == delim)
+   return s;
+   }
+   if (s <= e)
return s;
}
-   if (s <= e)
-   return s;
return NULL;
 }
 
@@ -242,6 +244,7 @@ detect_time(const char *s, const char *e
 static bool
 detect_date(const char *s, const char *e)
 {
+   /* TODO detect negative years */
if ((e-s) != 10)
return false;
/* -MM-DD */
@@ -256,6 +259,7 @@ detect_date(const char *s, const char *e
 static bool
 detect_timestamp(const char *s, const char *e)
 {
+   /* TODO detect negative years */
if ((e-s) != 16)
return false;
/* DATE TIME */
@@ -276,24 +280,26 @@ detect_types_row(const char *s, const ch
int scale = 0;
 
types[i].type = CSV_STRING;
-   if (n) {
+   types[i].scale = 0;
+   if (n && s) {
if (detect_null(s,n))
types[i].type = CSV_NULL;
else if (detect_bool(s,n))
types[i].type = CSV_BOOLEAN;
else if (detect_bigint(s, n))
types[i].type = CSV_BIGINT;
-   else if (detect_decimal(s, n, &scale))
+   else if (detect_decimal(s, n, &scale)) {
types[i].type = CSV_DECIMAL;
+   types[i].scale = scale;
+   }
else if (detect_time(s, n))
types[i].type = CSV_TIME;
else if (detect_date(s, n))
types[i].type = CSV_DATE;
else if (detect_timestamp(s, n))
types[i].type = CSV_TIMESTAMP;
-   types[i].scale = scale;
+   s = n+1;
}
-   s = n+1;
}
return types;
 }
@@ -310,7 +316,7 @@ detect_types(const char *buf, char delim
 
if (!e)
break;
-   csv_type *ntypes = detect_types_row( cur, e, delim, quote, 
nr_fields);
+   csv_type *ntypes = detect_types_row(cur, e, delim, quote, 
nr_fields);
if (!ntypes)
return NULL;
cur = e+1;
@@ -397,9 +403,7 @@ static str
 csv_relation(mvc *sql, sql_subfunc *f, char *filename, list *res_exps, char 
*tname)
 {
stream *file = csv_open_file(filename);
-   char buf[8196+1];
-
-   if(file == NULL)
+   if (file == NULL)
return RUNTIME_FILE_NOT_FOUND;
 
/*
@@ -407,6 +411,7 @@ csv_relation(mvc *sql, sql_subfunc *f, c
 * detect types
 * detect header
 */
+   char buf[8196+1];
ssize_t l = mnstr_read(file, buf, 1, 8196);
mnstr_close(file);
mnstr_destroy(file);
@@ -424,7 +429,7 @@ csv_relation(mvc *sql, sql_subfunc *f, c
 
f->tname = tname;
 
-   const char *p = buf, *ep = strchr(p, '\n');;
+   const char *p = buf, *ep = strchr(p, '\n');
list *typelist = sa_list(sql->sa);
list *nameslist = sa_list(sql->sa);
for(int col = 0; col < nr_fields; col++) {
___
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org


MonetDB: Aug2024 - Add test for issue #7604

2024-12-05 Thread Martin van Dinther via checkin-list
Changeset: a5109d2964c5 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/a5109d2964c5
Added Files:
sql/test/file_loader/Tests/cars_empty_line.csv
sql/test/file_loader/Tests/cars_missing_separators.csv
Modified Files:
sql/test/file_loader/Tests/file_loader_field_separator.test.in
Branch: Aug2024
Log Message:

Add test for issue #7604
Extend file_loader() tests with csv data files with fewer field separators or 
empty lines.


diffs (82 lines):

diff --git a/sql/test/file_loader/Tests/cars_empty_line.csv 
b/sql/test/file_loader/Tests/cars_empty_line.csv
new file mode 100644
--- /dev/null
+++ b/sql/test/file_loader/Tests/cars_empty_line.csv
@@ -0,0 +1,6 @@
+2000,"Ford","Focus",1994
+2001,"Honda",,
+
+2004,"Tesla","S3XY",2019
+2014,"Lightyear","0",2022
+
diff --git a/sql/test/file_loader/Tests/cars_missing_separators.csv 
b/sql/test/file_loader/Tests/cars_missing_separators.csv
new file mode 100644
--- /dev/null
+++ b/sql/test/file_loader/Tests/cars_missing_separators.csv
@@ -0,0 +1,5 @@
+2000,"Ford","Focus",1994
+2001,"Honda",,
+2004,"Tesla","S3XY",2019
+2014,"Lightyear","0",2022
+2020,"Volvo"
diff --git a/sql/test/file_loader/Tests/file_loader_field_separator.test.in 
b/sql/test/file_loader/Tests/file_loader_field_separator.test.in
--- a/sql/test/file_loader/Tests/file_loader_field_separator.test.in
+++ b/sql/test/file_loader/Tests/file_loader_field_separator.test.in
@@ -132,3 +132,57 @@ Lightyear
 0
 2022
 
+# tests to load incomplete cars (4 columns, 5 rows) data files with missing 
field separators or empty lines
+
+query ITTI nosort
+select * from file_loader(r'$TSTSRCDIR/cars_missing_separators.csv') as 
cars(id, brand, model, "year")
+
+2000
+Ford
+Focus
+1994
+2001
+Honda
+NULL
+NULL
+2004
+Tesla
+S3XY
+2019
+2014
+Lightyear
+0
+2022
+2020
+Volvo
+NULL
+NULL
+
+query ITTI nosort
+select * from file_loader(r'$TSTSRCDIR/cars_empty_line.csv') as cars(id, 
brand, model, "year")
+
+2000
+Ford
+Focus
+1994
+2001
+Honda
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+2004
+Tesla
+S3XY
+2019
+2014
+Lightyear
+0
+2022
+NULL
+NULL
+NULL
+NULL
+
___
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org


MonetDB: default - merge with Aug2024

2024-12-05 Thread Martin van Dinther via checkin-list
Changeset: 145361d0ad77 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/145361d0ad77
Branch: default
Log Message:

merge with Aug2024


diffs (194 lines):

diff --git a/sql/backends/monet5/vaults/csv/csv.c 
b/sql/backends/monet5/vaults/csv/csv.c
--- a/sql/backends/monet5/vaults/csv/csv.c
+++ b/sql/backends/monet5/vaults/csv/csv.c
@@ -37,15 +37,17 @@ csv_open_file(char* filename)
 static const char *
 next_delim(const char *s, const char *e, char delim, char quote)
 {
-   bool inquote = false;
-   for(;  s < e; s++) {
-   if (*s == quote)
-   inquote = !inquote;
-   else if (!inquote && *s == delim)
+   if (s && e) {
+   bool inquote = false;
+   for(;  s < e; s++) {
+   if (*s == quote)
+   inquote = !inquote;
+   else if (!inquote && *s == delim)
+   return s;
+   }
+   if (s <= e)
return s;
}
-   if (s <= e)
-   return s;
return NULL;
 }
 
@@ -242,6 +244,7 @@ detect_time(const char *s, const char *e
 static bool
 detect_date(const char *s, const char *e)
 {
+   /* TODO detect negative years */
if ((e-s) != 10)
return false;
/* -MM-DD */
@@ -256,6 +259,7 @@ detect_date(const char *s, const char *e
 static bool
 detect_timestamp(const char *s, const char *e)
 {
+   /* TODO detect negative years */
if ((e-s) != 16)
return false;
/* DATE TIME */
@@ -276,24 +280,26 @@ detect_types_row(const char *s, const ch
int scale = 0;
 
types[i].type = CSV_STRING;
-   if (n) {
+   types[i].scale = 0;
+   if (n && s) {
if (detect_null(s,n))
types[i].type = CSV_NULL;
else if (detect_bool(s,n))
types[i].type = CSV_BOOLEAN;
else if (detect_bigint(s, n))
types[i].type = CSV_BIGINT;
-   else if (detect_decimal(s, n, &scale))
+   else if (detect_decimal(s, n, &scale)) {
types[i].type = CSV_DECIMAL;
+   types[i].scale = scale;
+   }
else if (detect_time(s, n))
types[i].type = CSV_TIME;
else if (detect_date(s, n))
types[i].type = CSV_DATE;
else if (detect_timestamp(s, n))
types[i].type = CSV_TIMESTAMP;
-   types[i].scale = scale;
+   s = n+1;
}
-   s = n+1;
}
return types;
 }
@@ -310,7 +316,7 @@ detect_types(const char *buf, char delim
 
if (!e)
break;
-   csv_type *ntypes = detect_types_row( cur, e, delim, quote, 
nr_fields);
+   csv_type *ntypes = detect_types_row(cur, e, delim, quote, 
nr_fields);
if (!ntypes)
return NULL;
cur = e+1;
@@ -397,9 +403,7 @@ static str
 csv_relation(mvc *sql, sql_subfunc *f, char *filename, list *res_exps, char 
*tname)
 {
stream *file = csv_open_file(filename);
-   char buf[8196+1];
-
-   if(file == NULL)
+   if (file == NULL)
return RUNTIME_FILE_NOT_FOUND;
 
/*
@@ -407,6 +411,7 @@ csv_relation(mvc *sql, sql_subfunc *f, c
 * detect types
 * detect header
 */
+   char buf[8196+1];
ssize_t l = mnstr_read(file, buf, 1, 8196);
mnstr_close(file);
mnstr_destroy(file);
@@ -424,7 +429,7 @@ csv_relation(mvc *sql, sql_subfunc *f, c
 
f->tname = tname;
 
-   const char *p = buf, *ep = strchr(p, '\n');;
+   const char *p = buf, *ep = strchr(p, '\n');
list *typelist = sa_list(sql->sa);
list *nameslist = sa_list(sql->sa);
for(int col = 0; col < nr_fields; col++) {
diff --git a/sql/test/file_loader/Tests/cars_empty_line.csv 
b/sql/test/file_loader/Tests/cars_empty_line.csv
new file mode 100644
--- /dev/null
+++ b/sql/test/file_loader/Tests/cars_empty_line.csv
@@ -0,0 +1,6 @@
+2000,"Ford","Focus",1994
+2001,"Honda",,
+
+2004,"Tesla","S3XY",2019
+2014,"Lightyear","0",2022
+
diff --git a/sql/test/file_loader/Tests/cars_missing_separators.csv 
b/sql/test/file_loader/Tests/cars_missing_separators.csv
new file mode 100644
--- /dev/null
+++ b/sql/test/file_loader/Tests/cars_missing_separators.csv
@@ -0,0 +1,5 @@
+2000,"Ford","Focus",1994
+2001,"Honda",,
+2004,"Tesla","S3XY",2019
+2014,"Lightyear","0",2022
+2020,"Volvo"
diff --git a/sql/test/file_loader/Tests/file_loader_field_separator.test.in 
b/sql/test/file_loader/Tests/file_loader_fie

MonetDB: odbc_loader - merge with default

2024-12-05 Thread Martin van Dinther via checkin-list
Changeset: 28f30a355975 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/28f30a355975
Branch: odbc_loader
Log Message:

merge with default


diffs (194 lines):

diff --git a/sql/backends/monet5/vaults/csv/csv.c 
b/sql/backends/monet5/vaults/csv/csv.c
--- a/sql/backends/monet5/vaults/csv/csv.c
+++ b/sql/backends/monet5/vaults/csv/csv.c
@@ -37,15 +37,17 @@ csv_open_file(char* filename)
 static const char *
 next_delim(const char *s, const char *e, char delim, char quote)
 {
-   bool inquote = false;
-   for(;  s < e; s++) {
-   if (*s == quote)
-   inquote = !inquote;
-   else if (!inquote && *s == delim)
+   if (s && e) {
+   bool inquote = false;
+   for(;  s < e; s++) {
+   if (*s == quote)
+   inquote = !inquote;
+   else if (!inquote && *s == delim)
+   return s;
+   }
+   if (s <= e)
return s;
}
-   if (s <= e)
-   return s;
return NULL;
 }
 
@@ -242,6 +244,7 @@ detect_time(const char *s, const char *e
 static bool
 detect_date(const char *s, const char *e)
 {
+   /* TODO detect negative years */
if ((e-s) != 10)
return false;
/* -MM-DD */
@@ -256,6 +259,7 @@ detect_date(const char *s, const char *e
 static bool
 detect_timestamp(const char *s, const char *e)
 {
+   /* TODO detect negative years */
if ((e-s) != 16)
return false;
/* DATE TIME */
@@ -276,24 +280,26 @@ detect_types_row(const char *s, const ch
int scale = 0;
 
types[i].type = CSV_STRING;
-   if (n) {
+   types[i].scale = 0;
+   if (n && s) {
if (detect_null(s,n))
types[i].type = CSV_NULL;
else if (detect_bool(s,n))
types[i].type = CSV_BOOLEAN;
else if (detect_bigint(s, n))
types[i].type = CSV_BIGINT;
-   else if (detect_decimal(s, n, &scale))
+   else if (detect_decimal(s, n, &scale)) {
types[i].type = CSV_DECIMAL;
+   types[i].scale = scale;
+   }
else if (detect_time(s, n))
types[i].type = CSV_TIME;
else if (detect_date(s, n))
types[i].type = CSV_DATE;
else if (detect_timestamp(s, n))
types[i].type = CSV_TIMESTAMP;
-   types[i].scale = scale;
+   s = n+1;
}
-   s = n+1;
}
return types;
 }
@@ -310,7 +316,7 @@ detect_types(const char *buf, char delim
 
if (!e)
break;
-   csv_type *ntypes = detect_types_row( cur, e, delim, quote, 
nr_fields);
+   csv_type *ntypes = detect_types_row(cur, e, delim, quote, 
nr_fields);
if (!ntypes)
return NULL;
cur = e+1;
@@ -397,9 +403,7 @@ static str
 csv_relation(mvc *sql, sql_subfunc *f, char *filename, list *res_exps, char 
*tname)
 {
stream *file = csv_open_file(filename);
-   char buf[8196+1];
-
-   if(file == NULL)
+   if (file == NULL)
return RUNTIME_FILE_NOT_FOUND;
 
/*
@@ -407,6 +411,7 @@ csv_relation(mvc *sql, sql_subfunc *f, c
 * detect types
 * detect header
 */
+   char buf[8196+1];
ssize_t l = mnstr_read(file, buf, 1, 8196);
mnstr_close(file);
mnstr_destroy(file);
@@ -424,7 +429,7 @@ csv_relation(mvc *sql, sql_subfunc *f, c
 
f->tname = tname;
 
-   const char *p = buf, *ep = strchr(p, '\n');;
+   const char *p = buf, *ep = strchr(p, '\n');
list *typelist = sa_list(sql->sa);
list *nameslist = sa_list(sql->sa);
for(int col = 0; col < nr_fields; col++) {
diff --git a/sql/test/file_loader/Tests/cars_empty_line.csv 
b/sql/test/file_loader/Tests/cars_empty_line.csv
new file mode 100644
--- /dev/null
+++ b/sql/test/file_loader/Tests/cars_empty_line.csv
@@ -0,0 +1,6 @@
+2000,"Ford","Focus",1994
+2001,"Honda",,
+
+2004,"Tesla","S3XY",2019
+2014,"Lightyear","0",2022
+
diff --git a/sql/test/file_loader/Tests/cars_missing_separators.csv 
b/sql/test/file_loader/Tests/cars_missing_separators.csv
new file mode 100644
--- /dev/null
+++ b/sql/test/file_loader/Tests/cars_missing_separators.csv
@@ -0,0 +1,5 @@
+2000,"Ford","Focus",1994
+2001,"Honda",,
+2004,"Tesla","S3XY",2019
+2014,"Lightyear","0",2022
+2020,"Volvo"
diff --git a/sql/test/file_loader/Tests/file_loader_field_separator.test.in 
b/sql/test/file_loader/Tests/file_loader

MonetDB: odbc_loader - merge with default

2024-12-05 Thread Martin van Dinther via checkin-list
Changeset: b686c8de5479 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/b686c8de5479
Modified Files:
clients/Tests/exports.stable.out
sql/common/sql_types.c
sql/server/sql_parser.y
Branch: odbc_loader
Log Message:

merge with default


diffs (truncated from 28452 to 300 lines):

diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -56,3 +56,4 @@ MacOSX/usr
 
 # Don't keep the result of the documentation compilation
 documentation/build
+.cache/clangd
diff --git a/clients/Tests/MAL-signatures-hge.test 
b/clients/Tests/MAL-signatures-hge.test
--- a/clients/Tests/MAL-signatures-hge.test
+++ b/clients/Tests/MAL-signatures-hge.test
@@ -3444,6 +3444,11 @@ command algebra.groupby(X_0:bat[:oid], X
 ALGgroupby;
 Produces a new BAT with groups identified by the head column. The result 
contains tail times the head value, ie the tail contains the result group sizes.
 algebra
+groupedfirstn
+pattern algebra.groupedfirstn(X_0:lng, X_1:bat[:oid], X_2:bat[:oid], 
X_3:any...):bat[:oid]
+ALGgroupedfirstn;
+Grouped firstn
+algebra
 intersect
 command algebra.intersect(X_0:bat[:any_1], X_1:bat[:any_1], X_2:bat[:oid], 
X_3:bat[:oid], X_4:bit, X_5:bit, X_6:lng):bat[:oid]
 ALGintersect;
@@ -30528,91 +30533,6 @@ eval
 pattern batcapi.eval(X_0:ptr, X_1:bit, X_2:str, X_3:any...):any...
 CUDFevalStd;
 Execute a simple CUDF script value
-batcolor
-blue
-command batcolor.blue(X_0:bat[:color]):bat[:int]
-CLRbatBlue;
-Extracts blue component from a color atom
-batcolor
-cb
-command batcolor.cb(X_0:bat[:color]):bat[:int]
-CLRbatCb;
-Extracts Cb(blue color) component from a color atom
-batcolor
-color
-command batcolor.color(X_0:bat[:str]):bat[:color]
-CLRbatColor;
-Converts string to color
-batcolor
-cr
-command batcolor.cr(X_0:bat[:color]):bat[:int]
-CLRbatCr;
-Extracts Cr(red color) component from a color atom
-batcolor
-green
-command batcolor.green(X_0:bat[:color]):bat[:int]
-CLRbatGreen;
-Extracts green component from a color atom
-batcolor
-hsv
-command batcolor.hsv(X_0:bat[:flt], X_1:bat[:flt], X_2:bat[:flt]):bat[:color]
-CLRbatHsv;
-Converts an HSV triplets to a color atom
-batcolor
-hue
-command batcolor.hue(X_0:bat[:color]):bat[:flt]
-CLRbatHue;
-Extracts hue component from a color atom
-batcolor
-hue
-command batcolor.hue(X_0:bat[:color]):bat[:int]
-CLRbatHueInt;
-Extracts hue component from a color atom
-batcolor
-luminance
-command batcolor.luminance(X_0:bat[:color]):bat[:int]
-CLRbatLuminance;
-Extracts Y(luminance) component from a color atom
-batcolor
-red
-command batcolor.red(X_0:bat[:color]):bat[:int]
-CLRbatRed;
-Extracts red component from a color atom
-batcolor
-rgb
-command batcolor.rgb(X_0:bat[:int], X_1:bat[:int], X_2:bat[:int]):bat[:color]
-CLRbatRgb;
-Converts an RGB triplets to a color atom
-batcolor
-saturation
-command batcolor.saturation(X_0:bat[:color]):bat[:flt]
-CLRbatSaturation;
-Extracts saturation component from a color atom
-batcolor
-saturation
-command batcolor.saturation(X_0:bat[:color]):bat[:int]
-CLRbatSaturationInt;
-Extracts saturation component from a color atom
-batcolor
-str
-command batcolor.str(X_0:bat[:color]):bat[:str]
-CLRbatStr;
-Identity mapping for string bats
-batcolor
-value
-command batcolor.value(X_0:bat[:color]):bat[:flt]
-CLRbatValue;
-Extracts value component from a color atom
-batcolor
-value
-command batcolor.value(X_0:bat[:color]):bat[:int]
-CLRbatValueInt;
-Extracts value component from a color atom
-batcolor
-ycc
-command batcolor.ycc(X_0:bat[:flt], X_1:bat[:flt], X_2:bat[:flt]):bat[:color]
-CLRbatycc;
-Converts an YCC triplets to a color atom
 batgeom
 AsEWKT
 command batgeom.AsEWKT(X_0:bat[:wkb]):bat[:str]
@@ -32300,22 +32220,22 @@ MTIMEstr_to_date_bulk;
 (empty)
 batmtime
 str_to_date
-pattern batmtime.str_to_date(X_0:str, X_1:bat[:str], X_2:bat[:oid], 
X_3:lng):bat[:date]
-MTIMEstr_to_date_bulk_p1;
-(empty)
-batmtime
-str_to_date
 pattern batmtime.str_to_date(X_0:str, X_1:bat[:str], X_2:lng):bat[:date]
 MTIMEstr_to_date_bulk_p1;
 (empty)
 batmtime
 str_to_date
-pattern batmtime.str_to_date(X_0:bat[:str], X_1:str, X_2:bat[:oid], 
X_3:lng):bat[:date]
+pattern batmtime.str_to_date(X_0:str, X_1:bat[:str], X_2:lng, 
X_3:bat[:oid]):bat[:date]
+MTIMEstr_to_date_bulk_p1;
+(empty)
+batmtime
+str_to_date
+pattern batmtime.str_to_date(X_0:bat[:str], X_1:str, X_2:lng):bat[:date]
 MTIMEstr_to_date_bulk_p2;
 (empty)
 batmtime
 str_to_date
-pattern batmtime.str_to_date(X_0:bat[:str], X_1:str, X_2:lng):bat[:date]
+pattern batmtime.str_to_date(X_0:bat[:str], X_1:str, X_2:lng, 
X_3:bat[:oid]):bat[:date]
 MTIMEstr_to_date_bulk_p2;
 (empty)
 batmtime
@@ -32330,22 +32250,22 @@ MTIMEstr_to_time_bulk;
 (empty)
 batmtime
 str_to_time
-pattern batmtime.str_to_time(X_0:str, X_1:bat[:str], X_2:bat[:oid], 
X_3:lng):bat[:daytime]
-MTIMEstr_to_time_bulk_p1;
-(empty)
-batmtime
-str_to_time
 pattern batmtime.str_to_time(X_0:str, X_1:bat[:str], X_2:lng):bat[:daytime]
 MTIMEstr_to_time_bulk_p1;
 (empty)
 batmtime
 str_to_time
-pattern batmtime.str_to_

MonetDB: odbc_loader - Approve

2024-12-05 Thread Martin van Dinther via checkin-list
Changeset: f9b48326a9f9 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/f9b48326a9f9
Modified Files:
clients/Tests/exports.stable.out
Branch: odbc_loader
Log Message:

Approve


diffs (14 lines):

diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -1637,8 +1637,8 @@ str mvc_rollback(mvc *c, int chain, cons
 str number2name(str s, int len, int i);
 bool option_disable_fork;
 sql_part *partition_find_part(sql_trans *tr, sql_table *pt, sql_part *pp);
-int pl_register(char *name, pl_add_types_fptr add_types, pl_load_fptr pl_load);
-void pl_unregister(char *name);
+int pl_register(const char *name, pl_add_types_fptr add_types, pl_load_fptr 
pl_load);
+void pl_unregister(const char *name);
 void qc_delete(qc *cache, cq *q);
 cq *qc_find(qc *cache, int id);
 cq *qc_insert(qc *cache, allocator *sa, sql_rel *r, symbol *s, list *params, 
mapi_query_t type, char *codedstr, int no_mitosis);
___
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org


MonetDB: odbc_loader - Improve the error messages on validating ...

2024-12-05 Thread Martin van Dinther via checkin-list
Changeset: 8bf8eb732114 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/8bf8eb732114
Modified Files:
sql/server/rel_select.c
Branch: odbc_loader
Log Message:

Improve the error messages on validating the scheme of the uri.


diffs (49 lines):

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
@@ -673,25 +673,31 @@ proto_loader_add_table_column_types(mvc 
if (strcmp(uristr, "") == 0)
return "URI missing";
 
-   char *proto = uristr, *ep = strchr(uristr, ':');
-
+   char *proto = uristr;
+   char *ep = strchr(uristr, ':');
if (ep) {
*ep = 0;
proto = mkLower(sa_strdup(sql->sa, proto));
-   }
+   } else
+   return "Missing ':' separator to determine the URI scheme";
+
if (!proto)
-   return "URI protocol missing";
-
+   return "URI scheme missing";
+
+   // check uri scheme on supported protocols (e.g. must be: 'file' or 
'odbc' or 'monetdb')
proto_loader_t *pl = pl_find(proto);
if (!pl)
-   return sa_message(sql->ta, "URI extension '%s' missing", 
proto?proto:"");
+   return sa_message(sql->ta, "URI protocol '%s' not supported", 
proto?proto:"");
+
str err = pl->add_types(sql, f, uristr, res_exps, tname);
if (err)
return err;
+
sql_subtype *st = sql_bind_localtype("str");
sql_exp *proto_exp = exp_atom(sql->sa, atom_string(sql->sa, st, proto));
if (!proto_exp)
return MAL_MALLOC_FAIL;
+
append(exps, proto_exp);
return NULL;
 }
@@ -704,6 +710,7 @@ rel_proto_loader(mvc *sql, list *exps, l
 
if ((f = bind_func_(sql, NULL, "proto_loader", tl, F_UNION, true, 
&found, false))) {
list *nexps = exps;
+   // TODO: test uri scheme on supported protocols (e.g. must be: 
'file' or 'odbc' or 'monetdb')
if (list_empty(tl) || f->func->vararg || (nexps = 
check_arguments_and_find_largest_any_type(sql, NULL, exps, f, 1, false))) {
list *res_exps = sa_list(sql->sa);
if (list_length(exps) == 1 && f && f->func->varres && 
strlen(f->func->mod) == 0 && strlen(f->func->imp) == 0) {
___
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org


MonetDB: recursive_cte - handle some recursive ctes with correla...

2024-12-05 Thread Niels Nes via checkin-list
Changeset: 6fce72691f82 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/6fce72691f82
Modified Files:
sql/server/rel_optimize_proj.c
sql/server/rel_select.c
sql/server/rel_unnest.c
sql/test/cte/Tests/All
sql/test/cte/Tests/recursive_cte_correlated_subquery.test
sql/test/cte/Tests/test_correlated_recursive_cte.test
Branch: recursive_cte
Log Message:

handle some recursive ctes with correlation


diffs (truncated from 578 to 300 lines):

diff --git a/sql/server/rel_optimize_proj.c b/sql/server/rel_optimize_proj.c
--- a/sql/server/rel_optimize_proj.c
+++ b/sql/server/rel_optimize_proj.c
@@ -1752,6 +1752,9 @@ rel_push_aggr_down_n_arry(visitor *v, sq
list *rgbe = NULL, *gbe = NULL, *exps = NULL;
node *n, *m;
 
+   if (is_recursive(u))
+   return rel;
+
// TODO why?
if (u->op == op_project && !need_distinct(u))
u = u->l;
@@ -1910,7 +1913,7 @@ rel_push_aggr_down(visitor *v, sql_rel *
if (!u || !(is_union(u->op) || is_munion(u->op)) || 
need_distinct(u) || is_single(u) || !u->exps || rel_is_ref(u))
return rel;
 
-   if (is_munion(u->op) && !is_recursive(u))
+   if (is_munion(u->op))
return rel_push_aggr_down_n_arry(v, rel);
 
ul = u->l;
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
@@ -259,6 +259,45 @@ rel_subquery_optname(sql_query *query, s
return rel_table_optname(sql, sq, sn->name, refs);
 }
 
+static void
+rel_rename(mvc *sql, sql_rel *nrel, char *rname, sql_rel *brel)
+{
+   assert(is_project(nrel->op));
+   if (brel) {
+   if (is_project(nrel->op) && nrel->exps) {
+   for (node *ne = nrel->exps->h, *be = brel->exps->h; ne 
&& be; ne = ne->next, be = be->next) {
+   sql_exp *e = ne->data;
+   sql_exp *b = be->data;
+   char *name = NULL;
+
+   if (!is_intern(e)) {
+   if (!exp_name(e))
+   name = make_label(sql->sa, 
++sql->label);
+   noninternexp_setname(sql, e, rname, 
name);
+   set_basecol(e);
+   e->alias.label = b->alias.label;
+   }
+   }
+   }
+   list_hash_clear(nrel->exps);
+   } else if (is_project(nrel->op) && nrel->exps) {
+   node *ne = nrel->exps->h;
+
+   for (; ne; ne = ne->next) {
+   sql_exp *e = ne->data;
+   char *name = NULL;
+
+   if (!is_intern(e)) {
+   if (!exp_name(e))
+   name = make_label(sql->sa, 
++sql->label);
+   noninternexp_setname(sql, e, rname, name);
+   set_basecol(e);
+   }
+   }
+   list_hash_clear(nrel->exps);
+   }
+}
+
 sql_rel *
 rel_with_query(sql_query *query, symbol *q )
 {
@@ -275,7 +314,7 @@ rel_with_query(sql_query *query, symbol 
symbol *sym = d->data.sym;
dnode *dn = sym->data.lval->h->next;
char *rname = qname_schema_object(dn->data.lval);
-   sql_rel *nrel;
+   sql_rel *nrel, *base_rel = NULL;
symbol *recursive_part = NULL;
sql_rel_view *recursive_union = NULL;
int recursive_distinct = 0;
@@ -307,7 +346,8 @@ rel_with_query(sql_query *query, symbol 
return sql_error(sql, 02, SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
}
if (recursive && recursive_part) {
-   sql_rel *base_rel = nrel;
+   base_rel = nrel;
+   rel_rename(sql, base_rel, rname, base_rel);
dn->next->next->data.sym = recursive_part;
set_processed(nrel);
nrel = rel_semantic(query, sym);
@@ -352,23 +392,7 @@ rel_with_query(sql_query *query, symbol 
return NULL;
}
}
-   assert(is_project(nrel->op));
-   if (is_project(nrel->op) && nrel->exps) {
-   node *ne = nrel->exps->h;
-
-   for (; ne; ne = ne->next) {
-   sql_exp *e = ne->data;
-   char *name = NULL;
-
-   if (!is_intern(e)) {
-   if (!exp_name(e))
-   name = make_label(sql->sa, 
++sql->label);
-

monetdb-java: default - Remove information on JDBC COMPLIANCE. I...

2024-12-05 Thread Martin van Dinther via checkin-list
Changeset: 1295183c400c for monetdb-java
URL: https://dev.monetdb.org/hg/monetdb-java/rev/1295183c400c
Modified Files:
release.md
Branch: default
Log Message:

Remove information on JDBC COMPLIANCE. It has been added to the web page for 
JDBC driver.


diffs (156 lines):

diff --git a/release.md b/release.md
--- a/release.md
+++ b/release.md
@@ -89,152 +89,6 @@ The old driver class (nl.cwi.monetdb.jdb
 since 12 Nov 2020 and has been removed in release 3.4 
(monetdb-jdbc-3.4.jre8.jar).
 
 
-JDBC COMPLIANCE

-
-The MonetDB JDBC driver is a type 4 driver (100% pure Java) and
-complies to the JDBC 4.2 definition, see
- http://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/index.html
-and
- https://en.wikipedia.org/wiki/Java_Database_Connectivity
-
-Within the current implementation not all functionalities of the JDBC
-interface are available.  It is believed however, that this
-implementation is rich enough to be suitable for a majority of
-application settings.
-
-Below a list of (un)supported features can be found.
-Please read this list if you intend to use this JDBC driver.
-
-If you feel some features are missing or have encountered an issue/bug,
-please let us know at our bugtracker:
-  https://github.com/MonetDB/monetdb-java/issues
-
-Currently implemented JDBC 4.2 interfaces include:
-  * java.sql.Driver
-The following method is NOT useable/supported:
-- getParentLogger
-
-  * java.sql.Connection
-The following features/methods are NOT useable/supported:
-- createArrayOf, createNClob, createStruct, createSQLXML
-- prepareStatement with array of column indices or column names
-- setHoldability (close/hold cursors over commit is not configurable)
-
-NOTE: be sure to check for warnings after setting concurrencies or
-  isolation levels; MonetDB currently does not support anything
-  else but "fully serializable" transactions.
-
-  * java.sql.DatabaseMetaData
-NOTE: the column SPECIFIC_NAME as returned by getProcedures,
-getProcedureColumns, getFunctions and getFunctionColumns contains
-the internal id of the procedure or function. Use it for overloaded
-procedure and function names to match the proper columns info as
-returned by getProcedureColumns or getFunctionColumns to a specifc
-procedure or function name as returned by getProcedures or getFunctions.
-For example, getProcedures(null, "sys", "analyze") will return 4 rows
-as there exists 4 overloaded system procedures called analyze, with
-different (from 0 to 3) parameters. When calling
-getProcedureColumns(null, "sys", "analyze", "%") you will get all the
-6 (0+1+2+3) parameters of the 4 system procedures combined. So you will
-need to use the value of column SPECIFIC_NAME to properly match the right
-parameters to a specific procedure.
-
-  * java.sql.Statement
-The following methods/options are NOT useable/supported:
-- cancel (query execution cannot be terminated, once started)
-   see also: https://github.com/MonetDB/monetdb-java/issues/7
-   or https://github.com/MonetDB/MonetDB/issues/6222
-- execute with column indices or names
-- executeUpdate with column indices or names
-- setMaxFieldSize
-- setCursorName
-The following methods will add an SQLWarning:
-- setEscapeProcessing(true)  for Sep2022 (11.45) and older servers
-- setEscapeProcessing(false) for Jun2023 (11.47) and newer servers
-
-  * java.sql.PreparedStatement
-The following methods are NOT useable/supported:
-- setArray
-- setAsciiStream
-- setBinaryStream
-- setBlob
-- setNClob
-- setRef
-- setRowId
-- setSQLXML
-- setUnicodeStream (note: this method is Deprecated)
-
-  * java.sql.ParameterMetaData
-
-  * java.sql.CallableStatement
-The following methods are NOT useable/supported:
-- all getXyz(parameterIndex/parameterName, ...) methods because
-  output parameters in stored procedures are not supported by MonetDB
-- all registerOutParameter(parameterIndex/parameterName, int sqlType, ...) 
methods
-  because output parameters in stored procedures are not supported by 
MonetDB
-- wasNull() method because output parameters in stored procedures are
-  not supported by MonetDB
-- setArray
-- setAsciiStream
-- setBinaryStream
-- setBlob
-- setNClob
-- setRef
-- setRowId
-- setSQLXML
-- setUnicodeStream (note: this method is Deprecated)
-
-  * java.sql.ResultSet
-The following methods are NOT useable/supported:
-- getArray
-- getAsciiStream, getUnicodeStream
-- getNClob
-- getRef, getRowId, getSQLXML
-- moveToCurrentRow, moveToInsertRow,
-- All methods related to updateable result sets such as:
-  updateArray ... updateTimestamp, cancelRowUpdates,
-  deleteRow, insertRow, refreshRow
-
-  * java.sql.ResultSetMetaData
-
-  * java.sql.SavePoint
-
-  * java.sql.Wrapper
-
-  * java.sql.