changeset 86129:1395d225bbe3 sql_profiler

Merge with default.
author Lucas Pereira <lucas.pereira@monetdbsolutions.com>
date Wed, 20 Jul 2022 14:54:32 +0100
parents ede15a1afca4 (current diff) 197e45e5fa02 (diff)
children 1b8c0e0b3295
files monetdb5/mal/mal_client.c sql/storage/store.c
diffstat 32 files changed, 481 insertions(+), 449 deletions(-) [+]
line wrap: on
line diff
--- a/clients/Tests/MAL-signatures-hge.test
+++ b/clients/Tests/MAL-signatures-hge.test
@@ -30533,16 +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
-batcapi
-eval_aggr
-pattern batcapi.eval_aggr(X_0:ptr, X_1:bit, X_2:str, X_3:any...):any... 
-CUDFevalAggr;
-grouped aggregates through CUDF
-batcapi
-subeval_aggr
-pattern batcapi.subeval_aggr(X_0:ptr, X_1:bit, X_2:str, X_3:any...):any... 
-CUDFevalAggr;
-grouped aggregates through CUDF
 batcolor
 blue
 command batcolor.blue(X_0:bat[:color]):bat[:int] 
--- a/clients/Tests/MAL-signatures.test
+++ b/clients/Tests/MAL-signatures.test
@@ -21728,16 +21728,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
-batcapi
-eval_aggr
-pattern batcapi.eval_aggr(X_0:ptr, X_1:bit, X_2:str, X_3:any...):any... 
-CUDFevalAggr;
-grouped aggregates through CUDF
-batcapi
-subeval_aggr
-pattern batcapi.subeval_aggr(X_0:ptr, X_1:bit, X_2:str, X_3:any...):any... 
-CUDFevalAggr;
-grouped aggregates through CUDF
 batcolor
 blue
 command batcolor.blue(X_0:bat[:color]):bat[:int] 
--- a/clients/odbc/ChangeLog
+++ b/clients/odbc/ChangeLog
@@ -1,6 +1,13 @@
 # ChangeLog file for odbc
 # This file is updated with Maddlog
 
+* Thu Jul 14 2022 Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
+- Removed the possibility to retrieve or set the CURRENT_CATALOG
+  via SQLGetConnectAttr(hdbc, SQL_ATTR_CURRENT_CATALOG, ...) and
+  SQLSetConnectAttr(hdbc, SQL_ATTR_CURRENT_CATALOG, ...) as MonetDB does
+  not support CATALOG objects (no SQL support for: CREATE CATALOG abc
+  or SET CATALOG abc) and therefore there is no CURRENT_CATALOG.
+
 * Thu Jun 23 2022 Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
 - Corrected ODBC functions SQLTablePrivileges() and SQLColumnPrivileges()
   for local temporary tables located in schema tmp. They did not return
--- a/clients/odbc/driver/SQLGetConnectAttr.c
+++ b/clients/odbc/driver/SQLGetConnectAttr.c
@@ -84,9 +84,16 @@ MNDBGetConnectAttr(ODBCDbc *dbc,
 		break;
 	case SQL_ATTR_CURRENT_CATALOG:		/* SQLCHAR* */
 		/* SQL_CURRENT_QUALIFIER */
-		copyString(dbc->dbname, strlen(dbc->dbname), ValuePtr,
-			   BufferLength, StringLengthPtr, SQLINTEGER,
-			   addDbcError, dbc, return SQL_ERROR);
+		/* MonetDB does NOT support SQL catalog concept, return empty string */
+		if (BufferLength <= 0) {
+			/* Invalid string or buffer length */
+			addDbcError(dbc, "HY090", NULL, 0);
+			return SQL_ERROR;
+		}
+		strcpy_len((char *) ValuePtr, "", BufferLength);
+		if (StringLengthPtr) {
+			*(StringLengthPtr) = (SQLINTEGER) 0;
+		}
 		break;
 	case SQL_ATTR_TXN_ISOLATION:		/* SQLUINTEGER */
 		/* SQL_TXN_ISOLATION */
--- a/clients/odbc/driver/SQLGetTypeInfo.c
+++ b/clients/odbc/driver/SQLGetTypeInfo.c
@@ -1033,7 +1033,7 @@ MNDBGetTypeInfo(ODBCStmt *stmt,
 {
 	const struct types *t;
 	int i;
-	char query[4096];
+	char query[4352];
 
 	switch (DataType) {
 	case SQL_ALL_TYPES:
@@ -1220,29 +1220,30 @@ MNDBGetTypeInfo(ODBCStmt *stmt,
 		}
 	}
 	i += snprintf(query+ i, sizeof(query) - i, ") as monetdb_types "
-		      "(type_name"
-		      ",data_type"
-		      ",column_size"
-		      ",literal_prefix"
-		      ",literal_suffix"
-		      ",create_params"
-		      ",nullable"
-		      ",case_sensitive"
-		      ",searchable"
-		      ",unsigned_attribute"
-		      ",fixed_prec_scale"
-		      ",auto_unique_value"
-		      ",local_type_name"
-		      ",minimum_scale"
-		      ",maximum_scale"
-		      ",sql_data_type"
-		      ",sql_datetime_sub"
-		      ",num_prec_radix"
-		      ",interval_precision)");
+		      "(\"TYPE_NAME\""
+		      ",\"DATA_TYPE\""
+		      ",\"COLUMN_SIZE\""
+		      ",\"LITERAL_PREFIX\""
+		      ",\"LITERAL_SUFFIX\""
+		      ",\"CREATE_PARAMS\""
+		      ",\"NULLABLE\""
+		      ",\"CASE_SENSITIVE\""
+		      ",\"SEARCHABLE\""
+		      ",\"UNSIGNED_ATTRIBUTE\""
+		      ",\"FIXED_PREC_SCALE\""
+		      ",\"AUTO_UNIQUE_VALUE\""
+		      ",\"LOCAL_TYPE_NAME\""
+		      ",\"MINIMUM_SCALE\""
+		      ",\"MAXIMUM_SCALE\""
+		      ",\"SQL_DATA_TYPE\""
+		      ",\"SQL_DATETIME_SUB\""
+		      ",\"NUM_PREC_RADIX\""
+		      ",\"INTERVAL_PRECISION\")");
 	assert(i < (int) sizeof(query));
 
-	return MNDBExecDirect(stmt, (SQLCHAR *) query,
-			      (SQLINTEGER) i);
+	/* debug: fprintf(stdout, "SQLGetTypeInfo query (pos: %d, len: %zu):\n%s\n\n", i, strlen(query), query); */
+
+	return MNDBExecDirect(stmt, (SQLCHAR *) query, (SQLINTEGER) i);
 }
 
 #ifdef ODBCDEBUG
--- a/clients/odbc/driver/SQLSetConnectAttr.c
+++ b/clients/odbc/driver/SQLSetConnectAttr.c
@@ -58,22 +58,9 @@ MNDBSetConnectAttr(ODBCDbc *dbc,
 		}
 		return SQL_SUCCESS;
 	case SQL_ATTR_CURRENT_CATALOG:		/* SQLCHAR* */
-		fixODBCstring(ValuePtr, StringLength, SQLINTEGER,
-			      addDbcError, dbc, return SQL_ERROR);
-		if (dbc->Connected) {
-			/* Driver does not support this functions */
-			addDbcError(dbc, "IM001", NULL, 0);
-			return SQL_ERROR;
-		}
-		if (dbc->dbname)
-			free(dbc->dbname);
-		dbc->dbname = dupODBCstring(ValuePtr, StringLength);
-		if (dbc->dbname == NULL) {
-			/* Memory allocation error */
-			addDbcError(dbc, "HY001", NULL, 0);
-			return SQL_ERROR;
-		}
-		break;
+		/* Driver does not support this function */
+		addDbcError(dbc, "IM001", NULL, 0);
+		return SQL_ERROR;
 	case SQL_ATTR_CONNECTION_TIMEOUT:	/* SQLUINTEGER */
 		dbc->sql_attr_connection_timeout = (SQLUINTEGER) (uintptr_t) ValuePtr;
 		if (dbc->mid)
--- a/clients/odbc/tests/ODBCmetadata.c
+++ b/clients/odbc/tests/ODBCmetadata.c
@@ -18,6 +18,7 @@
  * SQLColumnPrivileges()
  * SQLProcedures()
  * SQLProcedureColumns()
+ * SQLGetTypeInfo()
  */
 
 #ifdef _MSC_VER
@@ -30,10 +31,14 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <inttypes.h>
+#define ODBCVER 0x0352		/* Important: this must be defined before include of sql.h and sqlext.h */
 #include <sql.h>
 #include <sqlext.h>
 #include <string.h>
 
+#define SQL_HUGEINT	0x4000	/* as defined in ODBCGlobal.h */
+
 static void
 prerr(SQLSMALLINT tpe, SQLHANDLE hnd, const char *func, const char *pref)
 {
@@ -89,6 +94,53 @@ check(SQLRETURN ret, SQLSMALLINT tpe, SQ
 	}
 }
 
+static char *
+nameofSQLtype(SQLSMALLINT dataType)
+{
+	/* https://docs.microsoft.com/en-us/sql/odbc/reference/appendixes/sql-data-types */
+	switch (dataType) {
+	case SQL_CHAR:		return "CHAR";
+	case SQL_VARCHAR:	return "VARCHAR";
+	case SQL_LONGVARCHAR:	return "LONG VARCHAR";
+	case SQL_WCHAR:		return "WCHAR";
+	case SQL_WVARCHAR:	return "WVARCHAR";
+	case SQL_WLONGVARCHAR:	return "WLONGVARCHAR";
+	case SQL_DECIMAL:	return "DECIMAL";
+	case SQL_NUMERIC:	return "NUMERIC";
+	case SQL_SMALLINT:	return "SMALLINT";
+	case SQL_INTEGER:	return "INTEGER";
+	case SQL_REAL:		return "REAL";
+	case SQL_FLOAT:		return "FLOAT";
+	case SQL_DOUBLE:	return "DOUBLE";
+	case SQL_BIT:   	return "BOOLEAN";	/* MonetDB boolean type is mapped to SQL_BIT in ODBC (see msql_types[] in SQLExecute.c) */
+	case SQL_TINYINT:	return "TINYINT";
+	case SQL_BIGINT:	return "BIGINT";
+	case SQL_BINARY:	return "BINARY";
+	case SQL_VARBINARY:	return "VARBINARY";
+	case SQL_LONGVARBINARY:	return "LONG VARBINARY";
+	case SQL_DATETIME:	return "DATETIME";
+	case SQL_TYPE_DATE:	return "DATE";
+	case SQL_TYPE_TIME:	return "TIME";
+	case SQL_TYPE_TIMESTAMP:	return "TIMESTAMP";
+	case SQL_INTERVAL_MONTH:	return "INTERVAL MONTH";
+	case SQL_INTERVAL_YEAR: 	return "INTERVAL YEAR";
+	case SQL_INTERVAL_YEAR_TO_MONTH: return "INTERVAL YEAR TO MONTH";
+	case SQL_INTERVAL_DAY:		return "INTERVAL DAY";
+	case SQL_INTERVAL_HOUR:		return "INTERVAL HOUR";
+	case SQL_INTERVAL_MINUTE:	return "INTERVAL MINUTE";
+	case SQL_INTERVAL_SECOND:	return "INTERVAL SECOND";
+	case SQL_INTERVAL_DAY_TO_HOUR:	return "INTERVAL DAY TO HOUR";
+	case SQL_INTERVAL_DAY_TO_MINUTE:	return "INTERVAL DAY TO MINUTE";
+	case SQL_INTERVAL_DAY_TO_SECOND:	return "INTERVAL DAY TO SECOND";
+	case SQL_INTERVAL_HOUR_TO_MINUTE:	return "INTERVAL HOUR TO MINUTE";
+	case SQL_INTERVAL_HOUR_TO_SECOND:	return "INTERVAL HOUR TO SECOND";
+	case SQL_INTERVAL_MINUTE_TO_SECOND:	return "INTERVAL MINUTE TO SECOND";
+	case SQL_GUID:		return "GUID";
+	case SQL_HUGEINT:	return "HUGEINT";	/* 0x4000 (defined in ODBCGlobal.h) */
+	default:		return "Undefined";
+	}
+}
+
 static void
 compareResult(SQLHANDLE stmt, SQLRETURN retcode, const char * functionname, const char * expected)
 {
@@ -102,6 +154,9 @@ compareResult(SQLHANDLE stmt, SQLRETURN 
 	SQLUSMALLINT col;
 	SQLLEN indicator;
 	char buf[2048];
+	SQLSMALLINT dataType = 0;
+	SQLULEN columnSize = 0;
+	SQLSMALLINT decimalDigits = 0;
 	int replaceId = 0;	/* used to replace system id values in column SPECIFIC_NAME of getProcedures and getProcedureColumns */
 
 	if (outp == NULL) {
@@ -119,17 +174,49 @@ compareResult(SQLHANDLE stmt, SQLRETURN 
 	/* How many rows are there */
 	ret = SQLRowCount(stmt, &rows);
 	check(ret, SQL_HANDLE_STMT, stmt, "SQLRowCount()");
-	pos += snprintf(outp + pos, outp_len - pos, "Resultset with %ld rows\n", rows);
+	pos += snprintf(outp + pos, outp_len - pos, "Resultset with %"PRId64" rows\n", (int64_t) rows);
 
 	/* get Result Column Names and print them */
 	for (col = 1; col <= columns; col++) {
 		ret = SQLDescribeCol(stmt, col, (SQLCHAR *) buf, sizeof(buf),
 			NULL, NULL, NULL, NULL, NULL);
-		check(ret, SQL_HANDLE_STMT, stmt, "SQLDescribeCol()");
+		check(ret, SQL_HANDLE_STMT, stmt, "SQLDescribeCol(colName)");
 		pos += snprintf(outp + pos, outp_len - pos,
 				(col > 1) ? "\t%s" : "%s", buf);
 	}
 	pos += snprintf(outp + pos, outp_len - pos, "\n");
+	/* get Result Column Data Types and print them */
+	for (col = 1; col <= columns; col++) {
+		ret = SQLDescribeCol(stmt, col, (SQLCHAR *) buf, sizeof(buf),
+			NULL, &dataType, &columnSize, &decimalDigits, NULL);
+		check(ret, SQL_HANDLE_STMT, stmt, "SQLDescribeCol(colType)");
+		pos += snprintf(outp + pos, outp_len - pos,
+				(col > 1) ? "\t%s" : "%s", nameofSQLtype(dataType));
+		switch (dataType) {
+		case SQL_CHAR:
+		case SQL_VARCHAR:
+		case SQL_LONGVARCHAR:
+		case SQL_WCHAR:
+		case SQL_WVARCHAR:
+		case SQL_WLONGVARCHAR:
+		case SQL_DECIMAL:
+		case SQL_NUMERIC:
+		case SQL_BINARY:
+		case SQL_VARBINARY:
+		case SQL_LONGVARBINARY:
+			if (columnSize != 0) {
+				if (decimalDigits != 0) {
+					pos += snprintf(outp + pos, outp_len - pos,
+						"(%d,%d)", (int) columnSize, (int) decimalDigits);
+				} else {
+					pos += snprintf(outp + pos, outp_len - pos,
+						"(%d)", (int) columnSize);
+				}
+			}
+			break;
+		}
+	}
+	pos += snprintf(outp + pos, outp_len - pos, "\n");
 
 	/* detect if special handling of data of column SPECIFIC_NAME returned by SQLProcedures and SQLProcedureColumns
 	   is needed as it contains system generated id values which can differ per version and platform */
@@ -287,6 +374,7 @@ main(int argc, char **argv)
 		"Resultset with 5 columns\n"
 		"Resultset with 1 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	TABLE_TYPE	REMARKS\n"
+		"WVARCHAR(2048)	WVARCHAR(1)	WVARCHAR(1)	WVARCHAR(1)	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	NULL	NULL	NULL	NULL\n");
 
 	// All schemas query
@@ -297,6 +385,7 @@ main(int argc, char **argv)
 		"Resultset with 5 columns\n"
 		"Resultset with 8 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	TABLE_TYPE	REMARKS\n"
+		"WVARCHAR(1)	WVARCHAR(1024)	WVARCHAR(1)	WVARCHAR(1)	WVARCHAR(1)\n"
 		"NULL	json	NULL	NULL	NULL\n"
 		"NULL	logging	NULL	NULL	NULL\n"
 		"NULL	odbctst	NULL	NULL	NULL\n"
@@ -314,6 +403,7 @@ main(int argc, char **argv)
 		"Resultset with 5 columns\n"
 		"Resultset with 10 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	TABLE_TYPE	REMARKS\n"
+		"WVARCHAR(1)	WVARCHAR(1)	WVARCHAR(1)	WVARCHAR(25)	WVARCHAR(1)\n"
 		"NULL	NULL	NULL	GLOBAL TEMPORARY TABLE	NULL\n"
 		"NULL	NULL	NULL	LOCAL TEMPORARY TABLE	NULL\n"
 		"NULL	NULL	NULL	MERGE TABLE	NULL\n"
@@ -333,6 +423,7 @@ main(int argc, char **argv)
 		"Resultset with 5 columns\n"
 		"Resultset with 7 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	TABLE_TYPE	REMARKS\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(25)	WVARCHAR(65000)\n"
 		"mTests_sql_odbc_tests	odbctst	CUSTOMERS	TABLE	NULL\n"
 		"mTests_sql_odbc_tests	odbctst	LINES	TABLE	NULL\n"
 		"mTests_sql_odbc_tests	odbctst	ORDERS	TABLE	NULL\n"
@@ -349,6 +440,7 @@ main(int argc, char **argv)
 		"Resultset with 5 columns\n"
 		"Resultset with 11 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	TABLE_TYPE	REMARKS\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(25)	WVARCHAR(65000)\n"
 		"mTests_sql_odbc_tests	tmp	glbl_nopk_twoucs	GLOBAL TEMPORARY TABLE	NULL\n"
 		"mTests_sql_odbc_tests	tmp	glbl_pk_uc	GLOBAL TEMPORARY TABLE	NULL\n"
 		"mTests_sql_odbc_tests	tmp	tmp_nopk_twoucs	LOCAL TEMPORARY TABLE	NULL\n"
@@ -369,6 +461,7 @@ main(int argc, char **argv)
 		"Resultset with 18 columns\n"
 		"Resultset with 7 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	NUM_PREC_RADIX	NULLABLE	REMARKS	COLUMN_DEF	SQL_DATA_TYPE	SQL_DATETIME_SUB	CHAR_OCTET_LENGTH	ORDINAL_POSITION	IS_NULLABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WCHAR(25)	INTEGER	BIGINT	BIGINT	SMALLINT	SMALLINT	WVARCHAR(65000)	WVARCHAR(2048)	SMALLINT	SMALLINT	BIGINT	INTEGER	WVARCHAR(3)\n"
 		"mTests_sql_odbc_tests	odbctst	nopk_twoucs	id2	4	INTEGER	32	11	0	2	0	NULL	NULL	4	NULL	NULL	1	NO\n"
 		"mTests_sql_odbc_tests	odbctst	nopk_twoucs	name2	-9	VARCHAR	99	198	NULL	NULL	1	NULL	NULL	-9	NULL	198	2	YES\n"
 		"mTests_sql_odbc_tests	odbctst	pk2c	pkc1	4	INTEGER	32	11	0	2	0	NULL	NULL	4	NULL	NULL	1	NO\n"
@@ -385,6 +478,7 @@ main(int argc, char **argv)
 		"Resultset with 18 columns\n"
 		"Resultset with 8 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	NUM_PREC_RADIX	NULLABLE	REMARKS	COLUMN_DEF	SQL_DATA_TYPE	SQL_DATETIME_SUB	CHAR_OCTET_LENGTH	ORDINAL_POSITION	IS_NULLABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WCHAR(25)	INTEGER	BIGINT	BIGINT	SMALLINT	SMALLINT	WVARCHAR(65000)	WVARCHAR(2048)	SMALLINT	SMALLINT	BIGINT	INTEGER	WVARCHAR(3)\n"
 		"mTests_sql_odbc_tests	tmp	glbl_nopk_twoucs	id2	4	INTEGER	32	11	0	2	0	NULL	NULL	4	NULL	NULL	1	NO\n"
 		"mTests_sql_odbc_tests	tmp	glbl_nopk_twoucs	name2	-9	VARCHAR	99	198	NULL	NULL	1	NULL	NULL	-9	NULL	198	2	YES\n"
 		"mTests_sql_odbc_tests	tmp	glbl_pk_uc	id1	4	INTEGER	32	11	0	2	0	NULL	NULL	4	NULL	NULL	1	NO\n"
@@ -402,6 +496,7 @@ main(int argc, char **argv)
 		"Resultset with 18 columns\n"
 		"Resultset with 4 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	NUM_PREC_RADIX	NULLABLE	REMARKS	COLUMN_DEF	SQL_DATA_TYPE	SQL_DATETIME_SUB	CHAR_OCTET_LENGTH	ORDINAL_POSITION	IS_NULLABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WCHAR(25)	INTEGER	BIGINT	BIGINT	SMALLINT	SMALLINT	WVARCHAR(65000)	WVARCHAR(2048)	SMALLINT	SMALLINT	BIGINT	INTEGER	WVARCHAR(3)\n"
 		"mTests_sql_odbc_tests	tmp	glbl_nopk_twoucs	name2	-9	VARCHAR	99	198	NULL	NULL	1	NULL	NULL	-9	NULL	198	2	YES\n"
 		"mTests_sql_odbc_tests	tmp	glbl_pk_uc	name1	-9	VARCHAR	99	198	NULL	NULL	1	NULL	NULL	-9	NULL	198	2	YES\n"
 		"mTests_sql_odbc_tests	tmp	tmp_nopk_twoucs	name2	-9	VARCHAR	99	198	NULL	NULL	1	NULL	NULL	-9	NULL	198	2	YES\n"
@@ -414,6 +509,7 @@ main(int argc, char **argv)
 		"Resultset with 6 columns\n"
 		"Resultset with 1 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	KEY_SEQ	PK_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1024)\n"
 		"mTests_sql_odbc_tests	sys	table_types	table_type_id	1	table_types_table_type_id_pkey\n");
 
 	ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
@@ -423,6 +519,7 @@ main(int argc, char **argv)
 		"Resultset with 8 columns\n"
 		"Resultset with 1 rows\n"
 		"SCOPE	COLUMN_NAME	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	PSEUDO_COLUMN\n"
+		"SMALLINT	WVARCHAR(1024)	SMALLINT	WCHAR(25)	INTEGER	BIGINT	BIGINT	SMALLINT\n"
 		"1	table_type_id	5	SMALLINT	16	6	0	1\n");
 
 	ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
@@ -432,6 +529,7 @@ main(int argc, char **argv)
 		"Resultset with 13 columns\n"
 		"Resultset with 2 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	NON_UNIQUE	INDEX_QUALIFIER	INDEX_NAME	TYPE	ORDINAL_POSITION	COLUMN_NAME	ASC_OR_DESC	CARDINALITY	PAGES	FILTER_CONDITION\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1)	WVARCHAR(1024)	SMALLINT	SMALLINT	WVARCHAR(1024)	WCHAR(1)	INTEGER	INTEGER	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	sys	table_types	0	NULL	table_types_table_type_id_pkey	2	1	table_type_id	NULL	10	NULL	NULL\n"
 		"mTests_sql_odbc_tests	sys	table_types	0	NULL	table_types_table_type_name_unique	2	1	table_type_name	NULL	10	NULL	NULL\n");
 
@@ -442,6 +540,7 @@ main(int argc, char **argv)
 		"Resultset with 13 columns\n"
 		"Resultset with 2 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	NON_UNIQUE	INDEX_QUALIFIER	INDEX_NAME	TYPE	ORDINAL_POSITION	COLUMN_NAME	ASC_OR_DESC	CARDINALITY	PAGES	FILTER_CONDITION\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1)	WVARCHAR(1024)	SMALLINT	SMALLINT	WVARCHAR(1024)	WCHAR(1)	INTEGER	INTEGER	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	sys	table_types	0	NULL	table_types_table_type_id_pkey	2	1	table_type_id	NULL	10	NULL	NULL\n"
 		"mTests_sql_odbc_tests	sys	table_types	0	NULL	table_types_table_type_name_unique	2	1	table_type_name	NULL	10	NULL	NULL\n");
 
@@ -450,7 +549,8 @@ main(int argc, char **argv)
 	compareResult(stmt, ret, "SQLTablePrivileges (sys, table_types)",
 		"Resultset with 7 columns\n"
 		"Resultset with 0 rows\n"
-		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n");
+		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n");
 
 	ret = SQLColumnPrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
 			(SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"table_types", SQL_NTS,
@@ -458,7 +558,8 @@ main(int argc, char **argv)
 	compareResult(stmt, ret, "SQLColumnPrivileges (sys, table_types, %)",
 		"Resultset with 8 columns\n"
 		"Resultset with 0 rows\n"
-		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n");
+		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n");
 
 	// odbctst.pk_uc
 	ret = SQLPrimaryKeys(stmt, (SQLCHAR*)"", SQL_NTS,
@@ -467,6 +568,7 @@ main(int argc, char **argv)
 		"Resultset with 6 columns\n"
 		"Resultset with 1 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	KEY_SEQ	PK_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1024)\n"
 		"mTests_sql_odbc_tests	odbctst	pk_uc	id1	1	pk_uc_id1_pkey\n");
 
 	ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
@@ -476,6 +578,7 @@ main(int argc, char **argv)
 		"Resultset with 8 columns\n"
 		"Resultset with 1 rows\n"
 		"SCOPE	COLUMN_NAME	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	PSEUDO_COLUMN\n"
+		"SMALLINT	WVARCHAR(1024)	SMALLINT	WCHAR(25)	INTEGER	BIGINT	BIGINT	SMALLINT\n"
 		"1	id1	4	INTEGER	32	11	0	1\n");
 
 	ret = SQLSpecialColumns(stmt, SQL_ROWVER, (SQLCHAR*)"", SQL_NTS,
@@ -484,7 +587,8 @@ main(int argc, char **argv)
 	compareResult(stmt, ret, "SQLSpecialColumns (odbctst, pk_uc, SQL_ROWVER)",
 		"Resultset with 8 columns\n"
 		"Resultset with 0 rows\n"
-		"SCOPE	COLUMN_NAME	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	PSEUDO_COLUMN\n");
+		"SCOPE	COLUMN_NAME	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	PSEUDO_COLUMN\n"
+		"SMALLINT	WVARCHAR(1)	SMALLINT	WVARCHAR(4)	INTEGER	INTEGER	SMALLINT	SMALLINT\n");
 
 	ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
 			(SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk_uc", SQL_NTS,
@@ -493,6 +597,7 @@ main(int argc, char **argv)
 		"Resultset with 13 columns\n"
 		"Resultset with 2 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	NON_UNIQUE	INDEX_QUALIFIER	INDEX_NAME	TYPE	ORDINAL_POSITION	COLUMN_NAME	ASC_OR_DESC	CARDINALITY	PAGES	FILTER_CONDITION\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1)	WVARCHAR(1024)	SMALLINT	SMALLINT	WVARCHAR(1024)	WCHAR(1)	INTEGER	INTEGER	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	odbctst	pk_uc	0	NULL	pk_uc_id1_pkey	2	1	id1	NULL	0	NULL	NULL\n"
 		"mTests_sql_odbc_tests	odbctst	pk_uc	0	NULL	pk_uc_name1_unique	2	1	name1	NULL	0	NULL	NULL\n");
 
@@ -503,6 +608,7 @@ main(int argc, char **argv)
 		"Resultset with 13 columns\n"
 		"Resultset with 4 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	NON_UNIQUE	INDEX_QUALIFIER	INDEX_NAME	TYPE	ORDINAL_POSITION	COLUMN_NAME	ASC_OR_DESC	CARDINALITY	PAGES	FILTER_CONDITION\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1)	WVARCHAR(1024)	SMALLINT	SMALLINT	WVARCHAR(1024)	WCHAR(1)	INTEGER	INTEGER	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	odbctst	pk_uc	0	NULL	pk_uc_id1_pkey	2	1	id1	NULL	0	NULL	NULL\n"
 		"mTests_sql_odbc_tests	odbctst	pk_uc	0	NULL	pk_uc_name1_unique	2	1	name1	NULL	0	NULL	NULL\n"
 		"mTests_sql_odbc_tests	odbctst	pk_uc	1	NULL	pk_uc_i	2	1	id1	NULL	NULL	NULL	NULL\n"
@@ -514,6 +620,7 @@ main(int argc, char **argv)
 		"Resultset with 7 columns\n"
 		"Resultset with 4 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n"
 		"mTests_sql_odbc_tests	odbctst	pk_uc	_SYSTEM	monetdb	DELETE	NO\n"
 		"mTests_sql_odbc_tests	odbctst	pk_uc	_SYSTEM	monetdb	INSERT	NO\n"
 		"mTests_sql_odbc_tests	odbctst	pk_uc	monetdb	PUBLIC	SELECT	NO\n"
@@ -525,7 +632,8 @@ main(int argc, char **argv)
 	compareResult(stmt, ret, "SQLColumnPrivileges (odbctst, pk_uc, %1)",
 		"Resultset with 8 columns\n"
 		"Resultset with 0 rows\n"
-		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n");
+		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n");
 
 	// tmp.tmp_pk_uc
 	ret = SQLPrimaryKeys(stmt, (SQLCHAR*)"", SQL_NTS,
@@ -534,6 +642,7 @@ main(int argc, char **argv)
 		"Resultset with 6 columns\n"
 		"Resultset with 1 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	KEY_SEQ	PK_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1024)\n"
 		"mTests_sql_odbc_tests	tmp	tmp_pk_uc	id1	1	tmp_pk_uc_id1_pkey\n");
 
 	ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
@@ -543,6 +652,7 @@ main(int argc, char **argv)
 		"Resultset with 8 columns\n"
 		"Resultset with 1 rows\n"
 		"SCOPE	COLUMN_NAME	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	PSEUDO_COLUMN\n"
+		"SMALLINT	WVARCHAR(1024)	SMALLINT	WCHAR(25)	INTEGER	BIGINT	BIGINT	SMALLINT\n"
 		"1	id1	4	INTEGER	32	11	0	1\n");
 
 	ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
@@ -552,6 +662,7 @@ main(int argc, char **argv)
 		"Resultset with 13 columns\n"
 		"Resultset with 2 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	NON_UNIQUE	INDEX_QUALIFIER	INDEX_NAME	TYPE	ORDINAL_POSITION	COLUMN_NAME	ASC_OR_DESC	CARDINALITY	PAGES	FILTER_CONDITION\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1)	WVARCHAR(1024)	SMALLINT	SMALLINT	WVARCHAR(1024)	WCHAR(1)	INTEGER	INTEGER	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	tmp	tmp_pk_uc	0	NULL	tmp_pk_uc_id1_pkey	2	1	id1	NULL	NULL	NULL	NULL\n"
 		"mTests_sql_odbc_tests	tmp	tmp_pk_uc	0	NULL	tmp_pk_uc_name1_unique	2	1	name1	NULL	NULL	NULL	NULL\n");
 
@@ -562,6 +673,7 @@ main(int argc, char **argv)
 		"Resultset with 13 columns\n"
 		"Resultset with 4 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	NON_UNIQUE	INDEX_QUALIFIER	INDEX_NAME	TYPE	ORDINAL_POSITION	COLUMN_NAME	ASC_OR_DESC	CARDINALITY	PAGES	FILTER_CONDITION\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1)	WVARCHAR(1024)	SMALLINT	SMALLINT	WVARCHAR(1024)	WCHAR(1)	INTEGER	INTEGER	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	tmp	tmp_pk_uc	0	NULL	tmp_pk_uc_id1_pkey	2	1	id1	NULL	NULL	NULL	NULL\n"
 		"mTests_sql_odbc_tests	tmp	tmp_pk_uc	0	NULL	tmp_pk_uc_name1_unique	2	1	name1	NULL	NULL	NULL	NULL\n"
 		"mTests_sql_odbc_tests	tmp	tmp_pk_uc	1	NULL	tmp_pk_uc_i	2	1	id1	NULL	NULL	NULL	NULL\n"
@@ -573,6 +685,7 @@ main(int argc, char **argv)
 		"Resultset with 7 columns\n"
 		"Resultset with 2 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n"
 		"mTests_sql_odbc_tests	tmp	tmp_pk_uc	_SYSTEM	monetdb	DELETE	NO\n"
 		"mTests_sql_odbc_tests	tmp	tmp_pk_uc	_SYSTEM	monetdb	INSERT	NO\n");
 
@@ -583,6 +696,7 @@ main(int argc, char **argv)
 		"Resultset with 8 columns\n"
 		"Resultset with 3 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n"
 		"mTests_sql_odbc_tests	tmp	tmp_pk_uc	id1	_SYSTEM	monetdb	SELECT	NO\n"
 		"mTests_sql_odbc_tests	tmp	tmp_pk_uc	name1	_SYSTEM	monetdb	SELECT	NO\n"
 		"mTests_sql_odbc_tests	tmp	tmp_pk_uc	name1	_SYSTEM	monetdb	UPDATE	NO\n");
@@ -594,6 +708,7 @@ main(int argc, char **argv)
 		"Resultset with 6 columns\n"
 		"Resultset with 1 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	KEY_SEQ	PK_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1024)\n"
 		"mTests_sql_odbc_tests	tmp	glbl_pk_uc	id1	1	glbl_pk_uc_id1_pkey\n");
 
 	ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
@@ -603,6 +718,7 @@ main(int argc, char **argv)
 		"Resultset with 8 columns\n"
 		"Resultset with 1 rows\n"
 		"SCOPE	COLUMN_NAME	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	PSEUDO_COLUMN\n"
+		"SMALLINT	WVARCHAR(1024)	SMALLINT	WCHAR(25)	INTEGER	BIGINT	BIGINT	SMALLINT\n"
 		"1	id1	4	INTEGER	32	11	0	1\n");
 
 	ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
@@ -612,6 +728,7 @@ main(int argc, char **argv)
 		"Resultset with 13 columns\n"
 		"Resultset with 2 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	NON_UNIQUE	INDEX_QUALIFIER	INDEX_NAME	TYPE	ORDINAL_POSITION	COLUMN_NAME	ASC_OR_DESC	CARDINALITY	PAGES	FILTER_CONDITION\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1)	WVARCHAR(1024)	SMALLINT	SMALLINT	WVARCHAR(1024)	WCHAR(1)	INTEGER	INTEGER	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	tmp	glbl_pk_uc	0	NULL	glbl_pk_uc_id1_pkey	2	1	id1	NULL	0	NULL	NULL\n"
 		"mTests_sql_odbc_tests	tmp	glbl_pk_uc	0	NULL	glbl_pk_uc_name1_unique	2	1	name1	NULL	0	NULL	NULL\n");
 
@@ -622,6 +739,7 @@ main(int argc, char **argv)
 		"Resultset with 13 columns\n"
 		"Resultset with 4 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	NON_UNIQUE	INDEX_QUALIFIER	INDEX_NAME	TYPE	ORDINAL_POSITION	COLUMN_NAME	ASC_OR_DESC	CARDINALITY	PAGES	FILTER_CONDITION\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1)	WVARCHAR(1024)	SMALLINT	SMALLINT	WVARCHAR(1024)	WCHAR(1)	INTEGER	INTEGER	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	tmp	glbl_pk_uc	0	NULL	glbl_pk_uc_id1_pkey	2	1	id1	NULL	0	NULL	NULL\n"
 		"mTests_sql_odbc_tests	tmp	glbl_pk_uc	0	NULL	glbl_pk_uc_name1_unique	2	1	name1	NULL	0	NULL	NULL\n"
 		"mTests_sql_odbc_tests	tmp	glbl_pk_uc	1	NULL	glbl_pk_uc_i	2	1	id1	NULL	NULL	NULL	NULL\n"
@@ -633,6 +751,7 @@ main(int argc, char **argv)
 		"Resultset with 7 columns\n"
 		"Resultset with 2 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n"
 		"mTests_sql_odbc_tests	tmp	glbl_pk_uc	_SYSTEM	monetdb	DELETE	NO\n"
 		"mTests_sql_odbc_tests	tmp	glbl_pk_uc	_SYSTEM	monetdb	INSERT	NO\n");
 
@@ -643,6 +762,7 @@ main(int argc, char **argv)
 		"Resultset with 8 columns\n"
 		"Resultset with 3 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n"
 		"mTests_sql_odbc_tests	tmp	glbl_pk_uc	id1	_SYSTEM	monetdb	SELECT	NO\n"
 		"mTests_sql_odbc_tests	tmp	glbl_pk_uc	name1	_SYSTEM	monetdb	SELECT	NO\n"
 		"mTests_sql_odbc_tests	tmp	glbl_pk_uc	name1	_SYSTEM	monetdb	UPDATE	NO\n");
@@ -653,7 +773,8 @@ main(int argc, char **argv)
 	compareResult(stmt, ret, "SQLPrimaryKeys (odbctst, nopk_twoucs)",
 		"Resultset with 6 columns\n"
 		"Resultset with 0 rows\n"
-		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	KEY_SEQ	PK_NAME\n");
+		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	KEY_SEQ	PK_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1024)\n");
 
 	ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
 			(SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"nopk_twoucs", SQL_NTS,
@@ -662,6 +783,7 @@ main(int argc, char **argv)
 		"Resultset with 8 columns\n"
 		"Resultset with 1 rows\n"
 		"SCOPE	COLUMN_NAME	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	PSEUDO_COLUMN\n"
+		"SMALLINT	WVARCHAR(1024)	SMALLINT	WCHAR(25)	INTEGER	BIGINT	BIGINT	SMALLINT\n"
 		"1	id2	4	INTEGER	32	11	0	1\n");
 
 	ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
@@ -671,6 +793,7 @@ main(int argc, char **argv)
 		"Resultset with 13 columns\n"
 		"Resultset with 2 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	NON_UNIQUE	INDEX_QUALIFIER	INDEX_NAME	TYPE	ORDINAL_POSITION	COLUMN_NAME	ASC_OR_DESC	CARDINALITY	PAGES	FILTER_CONDITION\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1)	WVARCHAR(1024)	SMALLINT	SMALLINT	WVARCHAR(1024)	WCHAR(1)	INTEGER	INTEGER	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	odbctst	nopk_twoucs	0	NULL	nopk_twoucs_id2_unique	2	1	id2	NULL	0	NULL	NULL\n"
 		"mTests_sql_odbc_tests	odbctst	nopk_twoucs	0	NULL	nopk_twoucs_name2_unique	2	1	name2	NULL	0	NULL	NULL\n");
 
@@ -681,6 +804,7 @@ main(int argc, char **argv)
 		"Resultset with 13 columns\n"
 		"Resultset with 4 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	NON_UNIQUE	INDEX_QUALIFIER	INDEX_NAME	TYPE	ORDINAL_POSITION	COLUMN_NAME	ASC_OR_DESC	CARDINALITY	PAGES	FILTER_CONDITION\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1)	WVARCHAR(1024)	SMALLINT	SMALLINT	WVARCHAR(1024)	WCHAR(1)	INTEGER	INTEGER	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	odbctst	nopk_twoucs	0	NULL	nopk_twoucs_id2_unique	2	1	id2	NULL	0	NULL	NULL\n"
 		"mTests_sql_odbc_tests	odbctst	nopk_twoucs	0	NULL	nopk_twoucs_name2_unique	2	1	name2	NULL	0	NULL	NULL\n"
 		"mTests_sql_odbc_tests	odbctst	nopk_twoucs	1	NULL	nopk_twoucs_i	2	1	id2	NULL	NULL	NULL	NULL\n"
@@ -691,7 +815,8 @@ main(int argc, char **argv)
 	compareResult(stmt, ret, "SQLTablePrivileges (odbctst, nopk_twoucs)",
 		"Resultset with 7 columns\n"
 		"Resultset with 0 rows\n"
-		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n");
+		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n");
 
 	ret = SQLColumnPrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
 			(SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"nopk_twoucs", SQL_NTS,
@@ -700,6 +825,7 @@ main(int argc, char **argv)
 		"Resultset with 8 columns\n"
 		"Resultset with 3 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n"
 		"mTests_sql_odbc_tests	odbctst	nopk_twoucs	id2	_SYSTEM	monetdb	SELECT	NO\n"
 		"mTests_sql_odbc_tests	odbctst	nopk_twoucs	name2	_SYSTEM	monetdb	SELECT	NO\n"
 		"mTests_sql_odbc_tests	odbctst	nopk_twoucs	name2	_SYSTEM	monetdb	UPDATE	NO\n");
@@ -710,7 +836,8 @@ main(int argc, char **argv)
 	compareResult(stmt, ret, "SQLPrimaryKeys (tmp, tmp_nopk_twoucs)",
 		"Resultset with 6 columns\n"
 		"Resultset with 0 rows\n"
-		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	KEY_SEQ	PK_NAME\n");
+		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	KEY_SEQ	PK_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1024)\n");
 
 	ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
 			(SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"tmp_nopk_twoucs", SQL_NTS,
@@ -719,6 +846,7 @@ main(int argc, char **argv)
 		"Resultset with 8 columns\n"
 		"Resultset with 1 rows\n"
 		"SCOPE	COLUMN_NAME	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	PSEUDO_COLUMN\n"
+		"SMALLINT	WVARCHAR(1024)	SMALLINT	WCHAR(25)	INTEGER	BIGINT	BIGINT	SMALLINT\n"
 		"1	id2	4	INTEGER	32	11	0	1\n");
 
 	ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
@@ -728,6 +856,7 @@ main(int argc, char **argv)
 		"Resultset with 13 columns\n"
 		"Resultset with 2 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	NON_UNIQUE	INDEX_QUALIFIER	INDEX_NAME	TYPE	ORDINAL_POSITION	COLUMN_NAME	ASC_OR_DESC	CARDINALITY	PAGES	FILTER_CONDITION\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1)	WVARCHAR(1024)	SMALLINT	SMALLINT	WVARCHAR(1024)	WCHAR(1)	INTEGER	INTEGER	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	tmp	tmp_nopk_twoucs	0	NULL	tmp_nopk_twoucs_id2_unique	2	1	id2	NULL	NULL	NULL	NULL\n"
 		"mTests_sql_odbc_tests	tmp	tmp_nopk_twoucs	0	NULL	tmp_nopk_twoucs_name2_unique	2	1	name2	NULL	NULL	NULL	NULL\n");
 
@@ -738,6 +867,7 @@ main(int argc, char **argv)
 		"Resultset with 13 columns\n"
 		"Resultset with 4 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	NON_UNIQUE	INDEX_QUALIFIER	INDEX_NAME	TYPE	ORDINAL_POSITION	COLUMN_NAME	ASC_OR_DESC	CARDINALITY	PAGES	FILTER_CONDITION\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1)	WVARCHAR(1024)	SMALLINT	SMALLINT	WVARCHAR(1024)	WCHAR(1)	INTEGER	INTEGER	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	tmp	tmp_nopk_twoucs	0	NULL	tmp_nopk_twoucs_id2_unique	2	1	id2	NULL	NULL	NULL	NULL\n"
 		"mTests_sql_odbc_tests	tmp	tmp_nopk_twoucs	0	NULL	tmp_nopk_twoucs_name2_unique	2	1	name2	NULL	NULL	NULL	NULL\n"
 		"mTests_sql_odbc_tests	tmp	tmp_nopk_twoucs	1	NULL	tmp_nopk_twoucs_i	2	1	id2	NULL	NULL	NULL	NULL\n"
@@ -749,6 +879,7 @@ main(int argc, char **argv)
 		"Resultset with 7 columns\n"
 		"Resultset with 2 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n"
 		"mTests_sql_odbc_tests	tmp	tmp_nopk_twoucs	_SYSTEM	monetdb	DELETE	NO\n"
 		"mTests_sql_odbc_tests	tmp	tmp_nopk_twoucs	_SYSTEM	monetdb	INSERT	NO\n");
 
@@ -759,6 +890,7 @@ main(int argc, char **argv)
 		"Resultset with 8 columns\n"
 		"Resultset with 3 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n"
 		"mTests_sql_odbc_tests	tmp	tmp_nopk_twoucs	id2	_SYSTEM	monetdb	SELECT	NO\n"
 		"mTests_sql_odbc_tests	tmp	tmp_nopk_twoucs	name2	_SYSTEM	monetdb	SELECT	NO\n"
 		"mTests_sql_odbc_tests	tmp	tmp_nopk_twoucs	name2	_SYSTEM	monetdb	UPDATE	NO\n");
@@ -769,7 +901,8 @@ main(int argc, char **argv)
 	compareResult(stmt, ret, "SQLPrimaryKeys (tmp, glbl_nopk_twoucs)",
 		"Resultset with 6 columns\n"
 		"Resultset with 0 rows\n"
-		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	KEY_SEQ	PK_NAME\n");
+		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	KEY_SEQ	PK_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1024)\n");
 
 	ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
 			(SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"glbl_nopk_twoucs", SQL_NTS,
@@ -778,6 +911,7 @@ main(int argc, char **argv)
 		"Resultset with 8 columns\n"
 		"Resultset with 1 rows\n"
 		"SCOPE	COLUMN_NAME	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	PSEUDO_COLUMN\n"
+		"SMALLINT	WVARCHAR(1024)	SMALLINT	WCHAR(25)	INTEGER	BIGINT	BIGINT	SMALLINT\n"
 		"1	id2	4	INTEGER	32	11	0	1\n");
 
 	ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
@@ -787,6 +921,7 @@ main(int argc, char **argv)
 		"Resultset with 13 columns\n"
 		"Resultset with 2 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	NON_UNIQUE	INDEX_QUALIFIER	INDEX_NAME	TYPE	ORDINAL_POSITION	COLUMN_NAME	ASC_OR_DESC	CARDINALITY	PAGES	FILTER_CONDITION\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1)	WVARCHAR(1024)	SMALLINT	SMALLINT	WVARCHAR(1024)	WCHAR(1)	INTEGER	INTEGER	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	tmp	glbl_nopk_twoucs	0	NULL	glbl_nopk_twoucs_id2_unique	2	1	id2	NULL	0	NULL	NULL\n"
 		"mTests_sql_odbc_tests	tmp	glbl_nopk_twoucs	0	NULL	glbl_nopk_twoucs_name2_unique	2	1	name2	NULL	0	NULL	NULL\n");
 
@@ -797,6 +932,7 @@ main(int argc, char **argv)
 		"Resultset with 13 columns\n"
 		"Resultset with 4 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	NON_UNIQUE	INDEX_QUALIFIER	INDEX_NAME	TYPE	ORDINAL_POSITION	COLUMN_NAME	ASC_OR_DESC	CARDINALITY	PAGES	FILTER_CONDITION\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1)	WVARCHAR(1024)	SMALLINT	SMALLINT	WVARCHAR(1024)	WCHAR(1)	INTEGER	INTEGER	WVARCHAR(1)\n"
 		"mTests_sql_odbc_tests	tmp	glbl_nopk_twoucs	0	NULL	glbl_nopk_twoucs_id2_unique	2	1	id2	NULL	0	NULL	NULL\n"
 		"mTests_sql_odbc_tests	tmp	glbl_nopk_twoucs	0	NULL	glbl_nopk_twoucs_name2_unique	2	1	name2	NULL	0	NULL	NULL\n"
 		"mTests_sql_odbc_tests	tmp	glbl_nopk_twoucs	1	NULL	glbl_nopk_twoucs_i	2	1	id2	NULL	NULL	NULL	NULL\n"
@@ -808,6 +944,7 @@ main(int argc, char **argv)
 		"Resultset with 7 columns\n"
 		"Resultset with 2 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n"
 		"mTests_sql_odbc_tests	tmp	glbl_nopk_twoucs	_SYSTEM	monetdb	DELETE	NO\n"
 		"mTests_sql_odbc_tests	tmp	glbl_nopk_twoucs	_SYSTEM	monetdb	INSERT	NO\n");
 
@@ -818,6 +955,7 @@ main(int argc, char **argv)
 		"Resultset with 8 columns\n"
 		"Resultset with 3 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n"
 		"mTests_sql_odbc_tests	tmp	glbl_nopk_twoucs	id2	_SYSTEM	monetdb	SELECT	NO\n"
 		"mTests_sql_odbc_tests	tmp	glbl_nopk_twoucs	name2	_SYSTEM	monetdb	SELECT	NO\n"
 		"mTests_sql_odbc_tests	tmp	glbl_nopk_twoucs	name2	_SYSTEM	monetdb	UPDATE	NO\n");
@@ -829,6 +967,7 @@ main(int argc, char **argv)
 		"Resultset with 6 columns\n"
 		"Resultset with 1 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	KEY_SEQ	PK_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1024)\n"
 		"mTests_sql_odbc_tests	odbctst	ORDERS	ORDERID	1	ORDERS_ORDERID_pkey\n");
 
 	ret = SQLForeignKeys(stmt, NULL, 0, NULL, 0, (SQLCHAR*)"ORDERS", SQL_NTS, NULL, 0, NULL, 0, NULL, 0);
@@ -836,6 +975,7 @@ main(int argc, char **argv)
 		"Resultset with 14 columns\n"
 		"Resultset with 1 rows\n"
 		"PKTABLE_CAT	PKTABLE_SCHEM	PKTABLE_NAME	PKCOLUMN_NAME	FKTABLE_CAT	FKTABLE_SCHEM	FKTABLE_NAME	FKCOLUMN_NAME	KEY_SEQ	UPDATE_RULE	DELETE_RULE	FK_NAME	PK_NAME	DEFERRABILITY\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	SMALLINT	SMALLINT	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT\n"
 		"mTests_sql_odbc_tests	odbctst	ORDERS	ORDERID	mTests_sql_odbc_tests	odbctst	LINES	ORDERID	1	1	1	LINES_ORDERID_fkey	ORDERS_ORDERID_pkey	7\n");
 
 	ret = SQLForeignKeys(stmt, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, (SQLCHAR*)"ORDERS", SQL_NTS);
@@ -843,6 +983,7 @@ main(int argc, char **argv)
 		"Resultset with 14 columns\n"
 		"Resultset with 1 rows\n"
 		"PKTABLE_CAT	PKTABLE_SCHEM	PKTABLE_NAME	PKCOLUMN_NAME	FKTABLE_CAT	FKTABLE_SCHEM	FKTABLE_NAME	FKCOLUMN_NAME	KEY_SEQ	UPDATE_RULE	DELETE_RULE	FK_NAME	PK_NAME	DEFERRABILITY\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	SMALLINT	SMALLINT	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT\n"
 		"mTests_sql_odbc_tests	odbctst	CUSTOMERS	CUSTID	mTests_sql_odbc_tests	odbctst	ORDERS	CUSTID	1	1	1	ORDERS_CUSTID_fkey	CUSTOMERS_CUSTID_pkey	7\n");
 
 	/* odbctst.pk2c and odbctst.fk2c (tests multi-column pks and multiple multi-column fks from one table */
@@ -851,6 +992,7 @@ main(int argc, char **argv)
 		"Resultset with 6 columns\n"
 		"Resultset with 2 rows\n"
 		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	KEY_SEQ	PK_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	WVARCHAR(1024)\n"
 		"mTests_sql_odbc_tests	odbctst	pk2c	pkc2	1	pk2c_pkc2_pkc1_pkey\n"
 		"mTests_sql_odbc_tests	odbctst	pk2c	pkc1	2	pk2c_pkc2_pkc1_pkey\n");
 
@@ -862,6 +1004,7 @@ main(int argc, char **argv)
 		"Resultset with 14 columns\n"
 		"Resultset with 4 rows\n"
 		"PKTABLE_CAT	PKTABLE_SCHEM	PKTABLE_NAME	PKCOLUMN_NAME	FKTABLE_CAT	FKTABLE_SCHEM	FKTABLE_NAME	FKCOLUMN_NAME	KEY_SEQ	UPDATE_RULE	DELETE_RULE	FK_NAME	PK_NAME	DEFERRABILITY\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	SMALLINT	SMALLINT	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT\n"
 		"mTests_sql_odbc_tests	odbctst	pk2c	pkc2	mTests_sql_odbc_tests	odbctst	fk2c	fkc2	1	0	1	fk2c_fkc2_fkc1_fkey	pk2c_pkc2_pkc1_pkey	7\n"
 		"mTests_sql_odbc_tests	odbctst	pk2c	pkc1	mTests_sql_odbc_tests	odbctst	fk2c	fkc1	2	0	1	fk2c_fkc2_fkc1_fkey	pk2c_pkc2_pkc1_pkey	7\n"
 		"mTests_sql_odbc_tests	odbctst	pk2c	pkc2	mTests_sql_odbc_tests	odbctst	fk2c	fkc2	1	2	3	fk2c_fkc2_fkc3_fkey	pk2c_pkc2_pkc1_pkey	7\n"
@@ -875,6 +1018,7 @@ main(int argc, char **argv)
 		"Resultset with 14 columns\n"
 		"Resultset with 4 rows\n"
 		"PKTABLE_CAT	PKTABLE_SCHEM	PKTABLE_NAME	PKCOLUMN_NAME	FKTABLE_CAT	FKTABLE_SCHEM	FKTABLE_NAME	FKCOLUMN_NAME	KEY_SEQ	UPDATE_RULE	DELETE_RULE	FK_NAME	PK_NAME	DEFERRABILITY\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	SMALLINT	SMALLINT	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT\n"
 		"mTests_sql_odbc_tests	odbctst	pk2c	pkc2	mTests_sql_odbc_tests	odbctst	fk2c	fkc2	1	0	1	fk2c_fkc2_fkc1_fkey	pk2c_pkc2_pkc1_pkey	7\n"
 		"mTests_sql_odbc_tests	odbctst	pk2c	pkc1	mTests_sql_odbc_tests	odbctst	fk2c	fkc1	2	0	1	fk2c_fkc2_fkc1_fkey	pk2c_pkc2_pkc1_pkey	7\n"
 		"mTests_sql_odbc_tests	odbctst	pk2c	pkc2	mTests_sql_odbc_tests	odbctst	fk2c	fkc2	1	2	3	fk2c_fkc2_fkc3_fkey	pk2c_pkc2_pkc1_pkey	7\n"
@@ -888,6 +1032,7 @@ main(int argc, char **argv)
 		"Resultset with 14 columns\n"
 		"Resultset with 4 rows\n"
 		"PKTABLE_CAT	PKTABLE_SCHEM	PKTABLE_NAME	PKCOLUMN_NAME	FKTABLE_CAT	FKTABLE_SCHEM	FKTABLE_NAME	FKCOLUMN_NAME	KEY_SEQ	UPDATE_RULE	DELETE_RULE	FK_NAME	PK_NAME	DEFERRABILITY\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT	SMALLINT	SMALLINT	WVARCHAR(1024)	WVARCHAR(1024)	SMALLINT\n"
 		"mTests_sql_odbc_tests	odbctst	pk2c	pkc2	mTests_sql_odbc_tests	odbctst	fk2c	fkc2	1	0	1	fk2c_fkc2_fkc1_fkey	pk2c_pkc2_pkc1_pkey	7\n"
 		"mTests_sql_odbc_tests	odbctst	pk2c	pkc1	mTests_sql_odbc_tests	odbctst	fk2c	fkc1	2	0	1	fk2c_fkc2_fkc1_fkey	pk2c_pkc2_pkc1_pkey	7\n"
 		"mTests_sql_odbc_tests	odbctst	pk2c	pkc2	mTests_sql_odbc_tests	odbctst	fk2c	fkc2	1	2	3	fk2c_fkc2_fkc3_fkey	pk2c_pkc2_pkc1_pkey	7\n"
@@ -898,7 +1043,8 @@ main(int argc, char **argv)
 	compareResult(stmt, ret, "SQLTablePrivileges (odbctst, pk_2c)",
 		"Resultset with 7 columns\n"
 		"Resultset with 0 rows\n"
-		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n");
+		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n");
 
 	ret = SQLColumnPrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
 			(SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk_2c", SQL_NTS,
@@ -906,7 +1052,8 @@ main(int argc, char **argv)
 	compareResult(stmt, ret, "SQLColumnPrivileges (odbctst, pk_2c, %)",
 		"Resultset with 8 columns\n"
 		"Resultset with 0 rows\n"
-		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n");
+		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	GRANTOR	GRANTEE	PRIVILEGE	IS_GRANTABLE\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(1024)	WCHAR(1024)	WCHAR(1024)	WVARCHAR(40)	WCHAR(3)\n");
 
 
 	// test procedure sys.analyze(). There are 4 overloaded variants of this procedure in MonetDB with 0, 1, 2 or 3 input parameters.
@@ -916,6 +1063,7 @@ main(int argc, char **argv)
 		"Resultset with 9 columns\n"
 		"Resultset with 4 rows\n"
 		"PROCEDURE_CAT	PROCEDURE_SCHEM	PROCEDURE_NAME	NUM_INPUT_PARAMS	NUM_OUTPUT_PARAMS	NUM_RESULT_SETS	REMARKS	PROCEDURE_TYPE	SPECIFIC_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(256)	TINYINT	TINYINT	TINYINT	WVARCHAR(65000)	SMALLINT	WVARCHAR(10)\n"
 		"mTests_sql_odbc_tests	sys	analyze	0	0	0	NULL	1	replacedId\n"
 		"mTests_sql_odbc_tests	sys	analyze	0	0	0	NULL	1	replacedId\n"
 		"mTests_sql_odbc_tests	sys	analyze	0	0	0	NULL	1	replacedId\n"
@@ -928,6 +1076,7 @@ main(int argc, char **argv)
 		"Resultset with 20 columns\n"
 		"Resultset with 6 rows\n"
 		"PROCEDURE_CAT	PROCEDURE_SCHEM	PROCEDURE_NAME	COLUMN_NAME	COLUMN_TYPE	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	NUM_PREC_RADIX	NULLABLE	REMARKS	COLUMN_DEF	SQL_DATA_TYPE	SQL_DATETIME_SUB	CHAR_OCTET_LENGTH	ORDINAL_POSITION	IS_NULLABLE	SPECIFIC_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(256)	WVARCHAR(256)	TINYINT	SMALLINT	WCHAR(25)	INTEGER	BIGINT	BIGINT	SMALLINT	SMALLINT	WVARCHAR(65000)	WVARCHAR(1)	SMALLINT	SMALLINT	BIGINT	BIGINT	WCHAR	WVARCHAR(10)\n"
 		"mTests_sql_odbc_tests	sys	analyze	sname	1	-9	VARCHAR	1024	2048	NULL	NULL	2	NULL	NULL	-9	NULL	2048	1		replacedId\n"
 		"mTests_sql_odbc_tests	sys	analyze	sname	1	-9	VARCHAR	1024	2048	NULL	NULL	2	NULL	NULL	-9	NULL	2048	1		replacedId\n"
 		"mTests_sql_odbc_tests	sys	analyze	tname	1	-9	VARCHAR	1024	2048	NULL	NULL	2	NULL	NULL	-9	NULL	2048	2		replacedId\n"
@@ -942,6 +1091,7 @@ main(int argc, char **argv)
 		"Resultset with 9 columns\n"
 		"Resultset with 2 rows\n"
 		"PROCEDURE_CAT	PROCEDURE_SCHEM	PROCEDURE_NAME	NUM_INPUT_PARAMS	NUM_OUTPUT_PARAMS	NUM_RESULT_SETS	REMARKS	PROCEDURE_TYPE	SPECIFIC_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(256)	TINYINT	TINYINT	TINYINT	WVARCHAR(65000)	SMALLINT	WVARCHAR(10)\n"
 		"mTests_sql_odbc_tests	sys	sin	0	0	0	NULL	2	replacedId\n"
 		"mTests_sql_odbc_tests	sys	sin	0	0	0	NULL	2	replacedId\n");
 
@@ -952,6 +1102,7 @@ main(int argc, char **argv)
 		"Resultset with 20 columns\n"
 		"Resultset with 4 rows\n"
 		"PROCEDURE_CAT	PROCEDURE_SCHEM	PROCEDURE_NAME	COLUMN_NAME	COLUMN_TYPE	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	NUM_PREC_RADIX	NULLABLE	REMARKS	COLUMN_DEF	SQL_DATA_TYPE	SQL_DATETIME_SUB	CHAR_OCTET_LENGTH	ORDINAL_POSITION	IS_NULLABLE	SPECIFIC_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(256)	WVARCHAR(256)	TINYINT	SMALLINT	WCHAR(25)	INTEGER	BIGINT	BIGINT	SMALLINT	SMALLINT	WVARCHAR(65000)	WVARCHAR(1)	SMALLINT	SMALLINT	BIGINT	BIGINT	WCHAR	WVARCHAR(10)\n"
 		"mTests_sql_odbc_tests	sys	sin	arg_1	1	7	REAL	24	14	7	2	2	NULL	NULL	7	NULL	NULL	1		replacedId\n"
 		"mTests_sql_odbc_tests	sys	sin	res_0	5	7	REAL	24	14	7	2	2	NULL	NULL	7	NULL	NULL	0		replacedId\n"
 		"mTests_sql_odbc_tests	sys	sin	arg_1	1	8	DOUBLE	53	24	15	2	2	NULL	NULL	8	NULL	NULL	1		replacedId\n"
@@ -964,6 +1115,7 @@ main(int argc, char **argv)
 		"Resultset with 9 columns\n"
 		"Resultset with 1 rows\n"
 		"PROCEDURE_CAT	PROCEDURE_SCHEM	PROCEDURE_NAME	NUM_INPUT_PARAMS	NUM_OUTPUT_PARAMS	NUM_RESULT_SETS	REMARKS	PROCEDURE_TYPE	SPECIFIC_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(256)	TINYINT	TINYINT	TINYINT	WVARCHAR(65000)	SMALLINT	WVARCHAR(10)\n"
 		"mTests_sql_odbc_tests	sys	env	0	0	0	NULL	2	replacedId\n");
 
 	ret = SQLProcedureColumns(stmt, (SQLCHAR*)"", SQL_NTS,
@@ -973,6 +1125,7 @@ main(int argc, char **argv)
 		"Resultset with 20 columns\n"
 		"Resultset with 2 rows\n"
 		"PROCEDURE_CAT	PROCEDURE_SCHEM	PROCEDURE_NAME	COLUMN_NAME	COLUMN_TYPE	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	NUM_PREC_RADIX	NULLABLE	REMARKS	COLUMN_DEF	SQL_DATA_TYPE	SQL_DATETIME_SUB	CHAR_OCTET_LENGTH	ORDINAL_POSITION	IS_NULLABLE	SPECIFIC_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(256)	WVARCHAR(256)	TINYINT	SMALLINT	WCHAR(25)	INTEGER	BIGINT	BIGINT	SMALLINT	SMALLINT	WVARCHAR(65000)	WVARCHAR(1)	SMALLINT	SMALLINT	BIGINT	BIGINT	WCHAR	WVARCHAR(10)\n"
 		"mTests_sql_odbc_tests	sys	env	name	3	-9	VARCHAR	1024	2048	NULL	NULL	2	NULL	NULL	-9	NULL	2048	1		replacedId\n"
 		"mTests_sql_odbc_tests	sys	env	value	3	-9	VARCHAR	2048	4096	NULL	NULL	2	NULL	NULL	-9	NULL	4096	2		replacedId\n");
 
@@ -983,6 +1136,7 @@ main(int argc, char **argv)
 		"Resultset with 9 columns\n"
 		"Resultset with 4 rows\n"
 		"PROCEDURE_CAT	PROCEDURE_SCHEM	PROCEDURE_NAME	NUM_INPUT_PARAMS	NUM_OUTPUT_PARAMS	NUM_RESULT_SETS	REMARKS	PROCEDURE_TYPE	SPECIFIC_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(256)	TINYINT	TINYINT	TINYINT	WVARCHAR(65000)	SMALLINT	WVARCHAR(10)\n"
 		"mTests_sql_odbc_tests	sys	statistics	0	0	0	NULL	2	replacedId\n"
 		"mTests_sql_odbc_tests	sys	statistics	0	0	0	NULL	2	replacedId\n"
 		"mTests_sql_odbc_tests	sys	statistics	0	0	0	NULL	2	replacedId\n"
@@ -995,6 +1149,7 @@ main(int argc, char **argv)
 		"Resultset with 20 columns\n"
 		"Resultset with 58 rows\n"
 		"PROCEDURE_CAT	PROCEDURE_SCHEM	PROCEDURE_NAME	COLUMN_NAME	COLUMN_TYPE	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	NUM_PREC_RADIX	NULLABLE	REMARKS	COLUMN_DEF	SQL_DATA_TYPE	SQL_DATETIME_SUB	CHAR_OCTET_LENGTH	ORDINAL_POSITION	IS_NULLABLE	SPECIFIC_NAME\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(256)	WVARCHAR(256)	TINYINT	SMALLINT	WCHAR(25)	INTEGER	BIGINT	BIGINT	SMALLINT	SMALLINT	WVARCHAR(65000)	WVARCHAR(1)	SMALLINT	SMALLINT	BIGINT	BIGINT	WCHAR	WVARCHAR(10)\n"
 		// 0 input argument and 13 result columns of sys.statistics()
 		"mTests_sql_odbc_tests	sys	statistics	column_id	3	4	INTEGER	32	11	0	2	2	NULL	NULL	4	NULL	NULL	1		replacedId\n"
 		"mTests_sql_odbc_tests	sys	statistics	schema	3	-9	VARCHAR	1024	2048	NULL	NULL	2	NULL	NULL	-9	NULL	2048	2		replacedId\n"
@@ -1061,6 +1216,119 @@ main(int argc, char **argv)
 		"mTests_sql_odbc_tests	sys	statistics	sorted	3	-7	BOOLEAN	1	1	NULL	NULL	2	NULL	NULL	-7	NULL	NULL	12		replacedId\n"
 		"mTests_sql_odbc_tests	sys	statistics	revsorted	3	-7	BOOLEAN	1	1	NULL	NULL	2	NULL	NULL	-7	NULL	NULL	13		replacedId\n");
 
+	ret = SQLGetTypeInfo(stmt, SQL_ALL_TYPES);
+	compareResult(stmt, ret, "SQLGetTypeInfo(stmt, SQL_ALL_TYPES)",
+		"Resultset with 19 columns\n"
+		"Resultset with 44 rows\n"
+		"TYPE_NAME	DATA_TYPE	COLUMN_SIZE	LITERAL_PREFIX	LITERAL_SUFFIX	CREATE_PARAMS	NULLABLE	CASE_SENSITIVE	SEARCHABLE	UNSIGNED_ATTRIBUTE	FIXED_PREC_SCALE	AUTO_UNIQUE_VALUE	LOCAL_TYPE_NAME	MINIMUM_SCALE	MAXIMUM_SCALE	SQL_DATA_TYPE	SQL_DATETIME_SUB	NUM_PREC_RADIX	INTERVAL_PRECISION\n"
+		"WCHAR(128)	SMALLINT	INTEGER	WCHAR(11)	WCHAR(1)	WCHAR(15)	SMALLINT	SMALLINT	SMALLINT	SMALLINT	SMALLINT	SMALLINT	WCHAR(16)	SMALLINT	SMALLINT	SMALLINT	SMALLINT	INTEGER	SMALLINT\n"
+		"uuid	-11	36	uuid '	'	NULL	1	0	2	-1	0	-1	uuid	-1	-1	-11	-1	-1	-1\n"
+		"character large object	-10	1000000	'	'	NULL	1	1	3	-1	0	0	NULL	-1	-1	-10	-1	-1	-1\n"
+		"json	-10	1000000	json '	'	NULL	1	1	3	-1	0	0	json	-1	-1	-10	-1	-1	-1\n"
+		"url	-10	1000000	url '	'	NULL	1	1	3	-1	0	0	url	-1	-1	-10	-1	-1	-1\n"
+		"varchar	-9	1000000	'	'	length	1	1	3	-1	0	-1	NULL	-1	-1	-9	-1	-1	-1\n"
+		"character	-8	1000000	'	'	length	1	1	3	-1	0	0	NULL	-1	-1	-8	-1	-1	-1\n"
+		"char	-8	1000000	'	'	length	1	1	3	-1	0	0	NULL	-1	-1	-8	-1	-1	-1\n"
+		"boolean	-7	1	NULL	NULL	NULL	1	0	2	1	1	0	boolean	-1	-1	-7	-1	-1	-1\n"
+		"tinyint	-6	3	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	-6	-1	10	-1\n"
+		"bigint	-5	19	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	-5	-1	10	-1\n"
+		"bigserial	-5	19	NULL	NULL	NULL	0	0	2	0	0	1	bigserial	0	0	-5	-1	10	-1\n"
+		"binary large object	-4	1000000	x'	'	NULL	1	1	3	-1	0	0	NULL	-1	-1	-4	-1	-1	-1\n"
+		"binary large object	-3	1000000	x'	'	length	1	1	3	-1	0	0	blob(max_length)	-1	-1	-3	-1	-1	-1\n"
+		"character large object	-1	1000000	'	'	NULL	1	1	3	-1	0	0	NULL	-1	-1	-1	-1	-1	-1\n"
+		"char	1	1000000	'	'	length	1	1	3	-1	0	0	NULL	-1	-1	1	-1	-1	-1\n"
+		"numeric	2	19	NULL	NULL	precision,scale	1	0	2	0	0	0	NULL	0	18	2	-1	10	-1\n"
+		"decimal	3	19	NULL	NULL	precision,scale	1	0	2	0	0	0	NULL	0	18	3	-1	10	-1\n"
+		"integer	4	10	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	4	-1	10	-1\n"
+		"int	4	10	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	4	-1	10	-1\n"
+		"mediumint	4	10	NULL	NULL	NULL	1	0	2	0	0	0	int	0	0	4	-1	10	-1\n"
+		"serial	4	10	NULL	NULL	NULL	0	0	2	0	0	1	serial	0	0	4	-1	10	-1\n"
+		"smallint	5	5	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	5	-1	10	-1\n"
+		"float	6	53	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	6	-1	2	-1\n"
+		"real	7	24	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	7	-1	2	-1\n"
+		"double	8	53	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	8	-1	2	-1\n"
+		"varchar	12	1000000	'	'	length	1	1	3	-1	0	-1	NULL	-1	-1	12	-1	-1	-1\n"
+		"date	91	10	date '	'	NULL	1	0	2	-1	0	-1	NULL	-1	-1	9	1	-1	-1\n"
+		"time	92	8	time '	'	NULL	1	0	2	-1	0	-1	NULL	0	0	9	2	-1	-1\n"
+		"time(precision)	92	15	time '	'	precision	1	0	2	-1	0	-1	NULL	0	6	9	2	-1	-1\n"
+		"timestamp	93	19	timestamp '	'	NULL	1	0	2	-1	0	-1	NULL	0	0	9	3	-1	-1\n"
+		"timestamp(precision)	93	26	timestamp '	'	precision	1	0	2	-1	0	-1	NULL	0	6	9	3	-1	-1\n"
+		"interval year	101	9	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	1	-1	9\n"
+		"interval month	102	10	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	2	-1	10\n"
+		"interval day	103	5	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	3	-1	5\n"
+		"interval hour	104	6	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	4	-1	6\n"
+		"interval minute	105	8	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	5	-1	8\n"
+		"interval second	106	10	'	'	precision	1	0	2	-1	0	-1	NULL	0	0	10	6	-1	10\n"
+		"interval year to month	107	12	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	7	-1	9\n"
+		"interval day to hour	108	8	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	8	-1	5\n"
+		"interval day to minute	109	11	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	9	-1	5\n"
+		"interval day to second	110	14	'	'	precision	1	0	2	-1	0	-1	NULL	0	0	10	10	-1	5\n"
+		"interval hour to minute	111	9	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	11	-1	6\n"
+		"interval hour to second	112	12	'	'	precision	1	0	2	-1	0	-1	NULL	0	0	10	12	-1	6\n"
+		"interval minute to second	113	13	'	'	precision	1	0	2	-1	0	-1	NULL	0	0	10	13	-1	10\n");
+
+	/* MonetDB specific type "hugeint" is currently not returned by SQLGetTypeInfo(SQL_ALL_TYPES). However it can be queried when requested explicitly. Test it. */
+	ret = SQLGetTypeInfo(stmt, SQL_HUGEINT);
+	compareResult(stmt, ret, "SQLGetTypeInfo(stmt, SQL_HUGEINT)",
+		"Resultset with 19 columns\n"
+		"Resultset with 1 rows\n"
+		"TYPE_NAME	DATA_TYPE	COLUMN_SIZE	LITERAL_PREFIX	LITERAL_SUFFIX	CREATE_PARAMS	NULLABLE	CASE_SENSITIVE	SEARCHABLE	UNSIGNED_ATTRIBUTE	FIXED_PREC_SCALE	AUTO_UNIQUE_VALUE	LOCAL_TYPE_NAME	MINIMUM_SCALE	MAXIMUM_SCALE	SQL_DATA_TYPE	SQL_DATETIME_SUB	NUM_PREC_RADIX	INTERVAL_PRECISION\n"
+		"WVARCHAR(128)	SMALLINT	INTEGER	WVARCHAR(128)	WVARCHAR(128)	WVARCHAR(128)	SMALLINT	SMALLINT	SMALLINT	SMALLINT	SMALLINT	SMALLINT	WVARCHAR(128)	SMALLINT	SMALLINT	SMALLINT	SMALLINT	INTEGER	SMALLINT\n"
+		"hugeint	16384	38	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	16384	-1	10	-1\n");
+
+	/* strangely when we repeat SQLGetTypeInfo(stmt, SQL_ALL_TYPES) now after calling SQLGetTypeInfo(stmt, SQL_HUGEINT), it suddenly does include hugeint in the result! */
+	ret = SQLGetTypeInfo(stmt, SQL_ALL_TYPES);
+	compareResult(stmt, ret, "SQLGetTypeInfo(stmt, SQL_ALL_TYPES)",
+		"Resultset with 19 columns\n"
+		"Resultset with 45 rows\n"
+		"TYPE_NAME	DATA_TYPE	COLUMN_SIZE	LITERAL_PREFIX	LITERAL_SUFFIX	CREATE_PARAMS	NULLABLE	CASE_SENSITIVE	SEARCHABLE	UNSIGNED_ATTRIBUTE	FIXED_PREC_SCALE	AUTO_UNIQUE_VALUE	LOCAL_TYPE_NAME	MINIMUM_SCALE	MAXIMUM_SCALE	SQL_DATA_TYPE	SQL_DATETIME_SUB	NUM_PREC_RADIX	INTERVAL_PRECISION\n"
+		"WCHAR(128)	SMALLINT	INTEGER	WCHAR(11)	WCHAR(1)	WCHAR(15)	SMALLINT	SMALLINT	SMALLINT	SMALLINT	SMALLINT	SMALLINT	WCHAR(16)	SMALLINT	SMALLINT	SMALLINT	SMALLINT	INTEGER	SMALLINT\n"
+		"uuid	-11	36	uuid '	'	NULL	1	0	2	-1	0	-1	uuid	-1	-1	-11	-1	-1	-1\n"
+		"character large object	-10	1000000	'	'	NULL	1	1	3	-1	0	0	NULL	-1	-1	-10	-1	-1	-1\n"
+		"json	-10	1000000	json '	'	NULL	1	1	3	-1	0	0	json	-1	-1	-10	-1	-1	-1\n"
+		"url	-10	1000000	url '	'	NULL	1	1	3	-1	0	0	url	-1	-1	-10	-1	-1	-1\n"
+		"varchar	-9	1000000	'	'	length	1	1	3	-1	0	-1	NULL	-1	-1	-9	-1	-1	-1\n"
+		"character	-8	1000000	'	'	length	1	1	3	-1	0	0	NULL	-1	-1	-8	-1	-1	-1\n"
+		"char	-8	1000000	'	'	length	1	1	3	-1	0	0	NULL	-1	-1	-8	-1	-1	-1\n"
+		"boolean	-7	1	NULL	NULL	NULL	1	0	2	1	1	0	boolean	-1	-1	-7	-1	-1	-1\n"
+		"tinyint	-6	3	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	-6	-1	10	-1\n"
+		"bigint	-5	19	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	-5	-1	10	-1\n"
+		"bigserial	-5	19	NULL	NULL	NULL	0	0	2	0	0	1	bigserial	0	0	-5	-1	10	-1\n"
+		"binary large object	-4	1000000	x'	'	NULL	1	1	3	-1	0	0	NULL	-1	-1	-4	-1	-1	-1\n"
+		"binary large object	-3	1000000	x'	'	length	1	1	3	-1	0	0	blob(max_length)	-1	-1	-3	-1	-1	-1\n"
+		"character large object	-1	1000000	'	'	NULL	1	1	3	-1	0	0	NULL	-1	-1	-1	-1	-1	-1\n"
+		"char	1	1000000	'	'	length	1	1	3	-1	0	0	NULL	-1	-1	1	-1	-1	-1\n"
+		"numeric	2	19	NULL	NULL	precision,scale	1	0	2	0	0	0	NULL	0	18	2	-1	10	-1\n"
+		"decimal	3	19	NULL	NULL	precision,scale	1	0	2	0	0	0	NULL	0	18	3	-1	10	-1\n"
+		"integer	4	10	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	4	-1	10	-1\n"
+		"int	4	10	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	4	-1	10	-1\n"
+		"mediumint	4	10	NULL	NULL	NULL	1	0	2	0	0	0	int	0	0	4	-1	10	-1\n"
+		"serial	4	10	NULL	NULL	NULL	0	0	2	0	0	1	serial	0	0	4	-1	10	-1\n"
+		"smallint	5	5	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	5	-1	10	-1\n"
+		"float	6	53	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	6	-1	2	-1\n"
+		"real	7	24	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	7	-1	2	-1\n"
+		"double	8	53	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	8	-1	2	-1\n"
+		"varchar	12	1000000	'	'	length	1	1	3	-1	0	-1	NULL	-1	-1	12	-1	-1	-1\n"
+		"date	91	10	date '	'	NULL	1	0	2	-1	0	-1	NULL	-1	-1	9	1	-1	-1\n"
+		"time	92	8	time '	'	NULL	1	0	2	-1	0	-1	NULL	0	0	9	2	-1	-1\n"
+		"time(precision)	92	15	time '	'	precision	1	0	2	-1	0	-1	NULL	0	6	9	2	-1	-1\n"
+		"timestamp	93	19	timestamp '	'	NULL	1	0	2	-1	0	-1	NULL	0	0	9	3	-1	-1\n"
+		"timestamp(precision)	93	26	timestamp '	'	precision	1	0	2	-1	0	-1	NULL	0	6	9	3	-1	-1\n"
+		"interval year	101	9	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	1	-1	9\n"
+		"interval month	102	10	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	2	-1	10\n"
+		"interval day	103	5	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	3	-1	5\n"
+		"interval hour	104	6	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	4	-1	6\n"
+		"interval minute	105	8	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	5	-1	8\n"
+		"interval second	106	10	'	'	precision	1	0	2	-1	0	-1	NULL	0	0	10	6	-1	10\n"
+		"interval year to month	107	12	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	7	-1	9\n"
+		"interval day to hour	108	8	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	8	-1	5\n"
+		"interval day to minute	109	11	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	9	-1	5\n"
+		"interval day to second	110	14	'	'	precision	1	0	2	-1	0	-1	NULL	0	0	10	10	-1	5\n"
+		"interval hour to minute	111	9	'	'	NULL	1	0	2	-1	0	-1	NULL	0	0	10	11	-1	6\n"
+		"interval hour to second	112	12	'	'	precision	1	0	2	-1	0	-1	NULL	0	0	10	12	-1	6\n"
+		"interval minute to second	113	13	'	'	precision	1	0	2	-1	0	-1	NULL	0	0	10	13	-1	10\n"
+		"hugeint	16384	38	NULL	NULL	NULL	1	0	2	0	0	0	NULL	0	0	16384	-1	10	-1\n");
+
 
 	// cleanup
 	ret = SQLExecDirect(stmt, (SQLCHAR *)
@@ -1095,7 +1363,8 @@ main(int argc, char **argv)
 	compareResult(stmt, ret, "SQLTables (odbctst, %, NULL)",
 		"Resultset with 5 columns\n"
 		"Resultset with 0 rows\n"
-		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	TABLE_TYPE	REMARKS\n");
+		"TABLE_CAT	TABLE_SCHEM	TABLE_NAME	TABLE_TYPE	REMARKS\n"
+		"WCHAR(21)	WVARCHAR(1024)	WVARCHAR(1024)	WVARCHAR(25)	WVARCHAR(65000)\n");
 
 	ret = SQLExecDirect(stmt, (SQLCHAR *)
 		"SET SCHEMA sys;\n"
--- a/cmake/monetdb-toolchain.cmake
+++ b/cmake/monetdb-toolchain.cmake
@@ -66,6 +66,8 @@ function(monetdb_default_compiler_option
       add_option_if_available("-Wmissing-declarations")
       add_option_if_available("-Wmissing-format-attribute")
       add_option_if_available("-Wmissing-prototypes")
+      # need this for gcc 4.8.5 on CentOS 7:
+      add_option_if_available("-Wno-missing-braces")
       # need this for clang 9.1.0 on Darwin:
       add_option_if_available("-Wno-missing-field-initializers")
       add_option_if_available("-Wold-style-definition")
--- a/gdk/ChangeLog
+++ b/gdk/ChangeLog
@@ -1,6 +1,9 @@
 # ChangeLog file for GDK
 # This file is updated with Maddlog
 
+* Wed Jul 13 2022 Sjoerd Mullender <sjoerd@acm.org>
+- Implemented BC/AD (and BCE/CE) suffixes when parsing dates.
+
 * Thu Jun  2 2022 Panagiotis Koutsourakis <kutsurak@monetdbsolutions.com>
 - The interface for using strimps has not changed (create an imprint index
   on a column of a read only table), but now construction happens at the
--- a/gdk/gdk_align.c
+++ b/gdk/gdk_align.c
@@ -147,6 +147,7 @@ VIEWcreate(oid seq, BAT *b)
 		}
 		if (bn->tvheap) {
 			BBPunshare(bn->tvheap->parentid);
+			BBPunfix(bn->tvheap->parentid);
 			HEAPdecref(bn->tvheap, false);
 		}
 		HEAPdecref(bn->theap, false);
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -85,8 +85,10 @@ insert_string_bat(BAT *b, BATiter *ni, s
 		/* we can share the vheaps, so we then only need to
 		 * append the offsets */
 		MT_lock_set(&b->theaplock);
-		if (b->tvheap->parentid != b->batCacheid)
+		if (b->tvheap->parentid != b->batCacheid) {
 			BBPunshare(b->tvheap->parentid);
+			BBPunfix(b->tvheap->parentid);
+		}
 		HEAPdecref(b->tvheap, b->tvheap->parentid == b->batCacheid);
 		HEAPincref(ni->vh);
 		b->tvheap = ni->vh;
@@ -144,6 +146,7 @@ insert_string_bat(BAT *b, BATiter *ni, s
 				}
 				memcpy(b->tvheap->base + toff, ni->vh->base, ni->vhfree);
 				b->tvheap->free = toff + ni->vhfree;
+				b->tvheap->dirty = true;
 				MT_lock_unset(&b->theaplock);
 			}
 		}
@@ -350,8 +353,10 @@ append_varsized_bat(BAT *b, BATiter *ni,
 		 * is read-only, we replace b's vheap with a reference
 		 * to n's */
 		MT_lock_set(&b->theaplock);
-		if (b->tvheap->parentid != b->batCacheid)
+		if (b->tvheap->parentid != b->batCacheid) {
 			BBPunshare(b->tvheap->parentid);
+			BBPunfix(b->tvheap->parentid);
+		}
 		BBPshare(ni->vh->parentid);
 		HEAPdecref(b->tvheap, true);
 		HEAPincref(ni->vh);
@@ -406,13 +411,15 @@ append_varsized_bat(BAT *b, BATiter *ni,
 			GDKfree(h);
 			return GDK_FAIL;
 		}
-		BBPunshare(b->tvheap->parentid);
+		bat parid = b->tvheap->parentid;
+		BBPunshare(parid);
 		ATOMIC_INIT(&h->refs, 1);
 		MT_lock_set(&b->theaplock);
 		Heap *oh = b->tvheap;
 		b->tvheap = h;
 		MT_lock_unset(&b->theaplock);
 		HEAPdecref(oh, false);
+		BBPunfix(parid);
 	}
 	if (BATcount(b) == 0 && BATatoms[b->ttype].atomFix == NULL &&
 	    ci->tpe == cand_dense && ci->ncand == ni->count) {
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -429,6 +429,8 @@ vheapinit(BAT *b, const char *buf, unsig
 		TRC_CRITICAL(GDK, "invalid format for BBP.dir on line %d", lineno);
 		return -1;
 	}
+	if (b->batCount == 0)
+		free = 0;
 	if (b->ttype >= 0 &&
 	    ATOMstorage(b->ttype) == TYPE_str &&
 	    free < GDK_STRHASHTABLE * sizeof(stridx_t) + BATTINY * GDK_VARALIGN)
@@ -1933,7 +1935,7 @@ vheap_entry(FILE *fp, BATiter *bi, BUN s
 	(void) size;
 	if (bi->vh == NULL)
 		return 0;
-	return fprintf(fp, " %zu", bi->vhfree);
+	return fprintf(fp, " %zu", size == 0 ? 0 : bi->vhfree);
 }
 
 static gdk_return
@@ -3445,17 +3447,8 @@ BBPprepare(bool subcommit)
 {
 	bool start_subcommit;
 	int set = 1 + subcommit;
-	str bakdirpath, subdirpath;
 	gdk_return ret = GDK_SUCCEED;
 
-	bakdirpath = GDKfilepath(0, NULL, BAKDIR, NULL);
-	subdirpath = GDKfilepath(0, NULL, SUBDIR, NULL);
-	if (bakdirpath == NULL || subdirpath == NULL) {
-		GDKfree(bakdirpath);
-		GDKfree(subdirpath);
-		return GDK_FAIL;
-	}
-
 	start_subcommit = (subcommit && backup_subdir == 0);
 	if (start_subcommit) {
 		/* starting a subcommit. Make sure SUBDIR and DELDIR
@@ -3465,36 +3458,47 @@ BBPprepare(bool subcommit)
 	if (backup_files == 0) {
 		backup_dir = 0;
 		ret = BBPrecover(0);
-		if (ret == GDK_SUCCEED) {
-			if (MT_mkdir(bakdirpath) < 0 && errno != EEXIST) {
-				GDKsyserror("cannot create directory %s\n", bakdirpath);
-				ret = GDK_FAIL;
-			}
-			/* if BAKDIR already exists, don't signal error */
-			TRC_DEBUG(IO_, "mkdir %s = %d\n", bakdirpath, (int) ret);
+		if (ret != GDK_SUCCEED)
+			return ret;
+		str bakdirpath = GDKfilepath(0, NULL, BAKDIR, NULL);
+		if (bakdirpath == NULL) {
+			return GDK_FAIL;
+		}
+
+		if (MT_mkdir(bakdirpath) < 0 && errno != EEXIST) {
+			GDKsyserror("cannot create directory %s\n", bakdirpath);
+			GDKfree(bakdirpath);
+			return GDK_FAIL;
 		}
+		/* if BAKDIR already exists, don't signal error */
+		TRC_DEBUG(IO_, "mkdir %s = %d\n", bakdirpath, (int) ret);
+		GDKfree(bakdirpath);
 	}
-	if (ret == GDK_SUCCEED && start_subcommit) {
+	if (start_subcommit) {
 		/* make a new SUBDIR (subdir of BAKDIR) */
+		str subdirpath = GDKfilepath(0, NULL, SUBDIR, NULL);
+		if (subdirpath == NULL) {
+			return GDK_FAIL;
+		}
+
 		if (MT_mkdir(subdirpath) < 0) {
 			GDKsyserror("cannot create directory %s\n", subdirpath);
-			ret = GDK_FAIL;
+			GDKfree(subdirpath);
+			return GDK_FAIL;
 		}
 		TRC_DEBUG(IO_, "mkdir %s = %d\n", subdirpath, (int) ret);
+		GDKfree(subdirpath);
 	}
-	if (ret == GDK_SUCCEED && backup_dir != set) {
+	if (backup_dir != set) {
 		/* a valid backup dir *must* at least contain BBP.dir */
-		if ((ret = GDKmove(0, backup_dir ? BAKDIR : BATDIR, "BBP", "dir", subcommit ? SUBDIR : BAKDIR, "BBP", "dir", true)) == GDK_SUCCEED) {
-			backup_dir = set;
-		}
+		if ((ret = GDKmove(0, backup_dir ? BAKDIR : BATDIR, "BBP", "dir", subcommit ? SUBDIR : BAKDIR, "BBP", "dir", true)) != GDK_SUCCEED)
+			return ret;
+		backup_dir = set;
 	}
 	/* increase counters */
-	if (ret == GDK_SUCCEED) {
-		backup_subdir += subcommit;
-		backup_files++;
-	}
-	GDKfree(bakdirpath);
-	GDKfree(subdirpath);
+	backup_subdir += subcommit;
+	backup_files++;
+
 	return ret;
 }
 
@@ -3942,7 +3946,11 @@ BBPsync(int cnt, bat *restrict subcommit
 					break;
 				}
 				bi = bat_iterator(BBP_desc(i));
-				if (b) {
+				assert(sizes == NULL || size <= bi.count);
+				assert(sizes == NULL || bi.width == 0 || (bi.type == TYPE_msk ? ((size + 31) / 32) * 4 : size << bi.shift) <= bi.hfree);
+				if (size > bi.count) /* includes sizes==NULL */
+					size = bi.count;
+				if (b && size != 0) {
 					/* wait for BBPSAVING so that we
 					 * can set it, wait for
 					 * BBPUNLOADING before
@@ -3959,10 +3967,6 @@ BBPsync(int cnt, bat *restrict subcommit
 					BBP_status_on(i, BBPSAVING);
 					if (lock)
 						MT_lock_unset(&GDKswapLock(i));
-					assert(sizes == NULL || size <= bi.count);
-					assert(sizes == NULL || bi.width == 0 || (bi.type == TYPE_msk ? ((size + 31) / 32) * 4 : size << bi.shift) <= bi.hfree);
-					if (size > bi.count)
-						size = bi.count;
 					MT_rwlock_rdlock(&b->thashlock);
 					ret = BATsave_locked(b, &bi, size);
 					MT_rwlock_rdunlock(&b->thashlock);
@@ -4396,7 +4400,8 @@ BBPdiskscan(const char *parent, size_t b
 				delete = true;
 			} else if (strncmp(p + 1, "tail", 4) == 0) {
 				BAT *b = getdesc(bid);
-				delete = (b == NULL || !b->ttype || !b->batCopiedtodisk);
+				delete = (b == NULL || !b->ttype || !b->batCopiedtodisk || b->batCount == 0);
+				assert(b->batCount > 0 || b->theap->free == 0);
 				if (!delete) {
 					if (b->ttype == TYPE_str) {
 						switch (b->twidth) {
@@ -4421,7 +4426,7 @@ BBPdiskscan(const char *parent, size_t b
 				}
 			} else if (strncmp(p + 1, "theap", 5) == 0) {
 				BAT *b = getdesc(bid);
-				delete = (b == NULL || !b->tvheap || !b->batCopiedtodisk);
+				delete = (b == NULL || !b->tvheap || !b->batCopiedtodisk || b->tvheap->free == 0);
 			} else if (strncmp(p + 1, "thashl", 6) == 0 ||
 				   strncmp(p + 1, "thashb", 6) == 0) {
 #ifdef PERSISTENTHASH
--- a/gdk/gdk_hash.c
+++ b/gdk/gdk_hash.c
@@ -974,6 +974,8 @@ BAThash_impl(BAT *restrict b, struct can
 
   bailout:
 	bat_iterator_end(&bi);
+	HEAPfree(&h->heaplink, true);
+	HEAPfree(&h->heapbckt, true);
 	GDKfree(h);
 	return NULL;
 }
--- a/gdk/gdk_logger.c
+++ b/gdk/gdk_logger.c
@@ -284,7 +284,7 @@ log_write_id(logger *lg, int id)
 	return GDK_FAIL;
 }
 
-static int
+static log_return
 log_read_id(logger *lg, log_id *id)
 {
 	assert(!lg->inmemory);
@@ -2255,7 +2255,7 @@ log_next_logfile(logger *lg, ulng ts)
 {
 	if (!lg->pending || !lg->pending->next)
 		return 0;
-	if (lg->pending->last_ts < ts)
+	if (lg->pending->last_ts <= ts)
 		return lg->pending->id;
 	return 0;
 }
@@ -2373,6 +2373,8 @@ log_flush(logger *lg, ulng ts)
 lng
 log_changes(logger *lg)
 {
+	if (LOG_DISABLED(lg))
+		return 0;
 	MT_lock_set(&lg->rotation_lock);
 	lng changes = lg->id - lg->saved_id - 1;
 	MT_lock_unset(&lg->rotation_lock);
--- a/gdk/gdk_logger_old.c
+++ b/gdk/gdk_logger_old.c
@@ -384,7 +384,7 @@ log_read_seq(old_logger *lg, logformat *
 	return LOG_OK;
 }
 
-static int
+static log_return
 log_read_id(old_logger *lg, char *tpe, oid *id)
 {
 	lng lid;
--- a/gdk/gdk_storage.c
+++ b/gdk/gdk_storage.c
@@ -800,7 +800,9 @@ BATload_intern(bat bid, bool lock)
 	/* LOAD bun heap */
 	if (b->ttype != TYPE_void) {
 		b->theap->storage = b->theap->newstorage = STORE_INVALID;
-		if (HEAPload(b->theap, b->theap->filename, NULL, b->batRestricted == BAT_READ) != GDK_SUCCEED) {
+		if ((b->batCount == 0 ?
+		     HEAPalloc(b->theap, b->batCapacity, b->twidth, ATOMsize(b->ttype)) :
+		     HEAPload(b->theap, b->theap->filename, NULL, b->batRestricted == BAT_READ)) != GDK_SUCCEED) {
 			HEAPfree(b->theap, false);
 			return NULL;
 		}
@@ -817,7 +819,9 @@ BATload_intern(bat bid, bool lock)
 	/* LOAD tail heap */
 	if (ATOMvarsized(b->ttype)) {
 		b->tvheap->storage = b->tvheap->newstorage = STORE_INVALID;
-		if (HEAPload(b->tvheap, nme, "theap", b->batRestricted == BAT_READ) != GDK_SUCCEED) {
+		if ((b->tvheap->free == 0 ?
+		     ATOMheap(b->ttype, b->tvheap, b->batCapacity) :
+		     HEAPload(b->tvheap, nme, "theap", b->batRestricted == BAT_READ)) != GDK_SUCCEED) {
 			HEAPfree(b->theap, false);
 			HEAPfree(b->tvheap, false);
 			return NULL;
--- a/gdk/gdk_time.c
+++ b/gdk/gdk_time.c
@@ -550,12 +550,12 @@ parse_date(const char *buf, date *d, boo
 	if (external && strncmp(buf, "nil", 3) == 0)
 		return 3;
 	if ((yearneg = (buf[0] == '-')))
-		buf++;
-	if (!yearneg && !GDKisdigit(buf[0])) {
+		pos++;
+	if (!yearneg && !GDKisdigit(buf[pos])) {
 		yearlast = true;
 		sep = ' ';
 	} else {
-		for (pos = 0; GDKisdigit(buf[pos]); pos++) {
+		for (; GDKisdigit(buf[pos]); pos++) {
 			year = (buf[pos] - '0') + year * 10;
 			if (year > YEAR_MAX)
 				break;
@@ -610,13 +610,35 @@ parse_date(const char *buf, date *d, boo
 				break;
 		}
 	}
+	if (!yearneg && buf[pos] == ' ') {
+		ssize_t opos = pos;
+		while (buf[++pos] == ' ')
+			;
+		if (strncasecmp(buf + pos, "BCE", 3) == 0) {
+			/* Before Common Era */
+			yearneg = true;
+			pos += 3;
+		} else if (strncasecmp(buf + pos, "BC", 2) == 0) {
+			/* Before Christ */
+			yearneg = true;
+			pos += 2;
+		} else if (strncasecmp(buf + pos, "CE", 2) == 0) {
+			/* Common Era */
+			pos += 2;
+		} else if (strncasecmp(buf + pos, "AD", 2) == 0) {
+			/* Anno Domino */
+			pos += 2;
+		} else {
+			pos = opos;
+		}
+	}
 	/* handle semantic error here */
 	*d = date_create(yearneg ? -year : year, month, day);
 	if (is_date_nil(*d)) {
 		GDKerror("Semantic error in date.\n");
 		return -1;
 	}
-	return pos + yearneg;
+	return pos;
 }
 
 ssize_t
--- a/monetdb5/mal/mal.c
+++ b/monetdb5/mal/mal.c
@@ -64,6 +64,8 @@ initialize_tl_client_key(void)
 Client
 getClientContext(void)
 {
+	if (initialize_tl_client_key())
+		return NULL;
 	return (Client) pthread_getspecific(tl_client_key);
 }
 
@@ -103,6 +105,8 @@ initialize_tl_client_key(void)
 Client
 getClientContext(void)
 {
+	if (initialize_tl_client_key())
+		return NULL;
 	return (Client) TlsGetValue(tl_client_key);
 }
 
--- a/sql/storage/objectset.c
+++ b/sql/storage/objectset.c
@@ -766,6 +766,7 @@ os_add_name_based(objectset *os, struct 
 		objectversion *co = name_based_node->ov;
 		objectversion *oo = get_valid_object_name(tr, co);
 		if (co != oo) { /* conflict ? */
+			TRC_WARNING(SQL_STORE, "%s" "if (co != oo) { /* conflict ? */", __func__);
 			return -3;
 		}
 
@@ -780,6 +781,7 @@ os_add_name_based(objectset *os, struct 
 			*/
 			ATOMIC_BASE_TYPE expected_deleted = deleted;
 			if (!ATOMIC_CAS(&oo->state, &expected_deleted, block_destruction)) {
+				TRC_WARNING(SQL_STORE, "%s: " "if (!ATOMIC_CAS(&oo->state, &expected_deleted, block_destruction)) { /*conflict with cleaner or write-write conflict*/ ", __func__);
 				return -3; /*conflict with cleaner or write-write conflict*/
 			}
 		}
@@ -816,6 +818,7 @@ os_add_id_based(objectset *os, struct sq
 		objectversion *co = id_based_node->ov;
 		objectversion *oo = get_valid_object_id(tr, co);
 		if (co != oo) { /* conflict ? */
+			TRC_WARNING(SQL_STORE, "%s" "if (co != oo) { /* conflict ? */", __func__);
 			return -3;
 		}
 
@@ -830,6 +833,7 @@ os_add_id_based(objectset *os, struct sq
 			*/
 			ATOMIC_BASE_TYPE expected_deleted = deleted;
 			if (!ATOMIC_CAS(&oo->state, &expected_deleted, block_destruction)) {
+				TRC_WARNING(SQL_STORE, "%s" "if (!ATOMIC_CAS(&oo->state, &expected_deleted, block_destruction)) { /*conflict with cleaner or write-write conflict*/", __func__);
 				return -3; /*conflict with cleaner or write-write conflict*/
 			}
 		}
@@ -870,6 +874,7 @@ os_add_(objectset *os, struct sql_trans 
 		if (os->destroy)
 			os->destroy(os->store, ov->b);
 		_DELETE(ov);
+		TRC_WARNING(SQL_STORE, "%s" "if (!os->concurrent && os_has_changes(os, tr)) { /* for object sets without concurrent support, conflict if concurrent changes are there */", __func__);
 		return -3; /* conflict */
 	}
 
@@ -912,6 +917,7 @@ os_del_name_based(objectset *os, struct 
 		objectversion *oo = get_valid_object_name(tr, co);
 		ov->name_based_head = oo->name_based_head;
 		if (co != oo) { /* conflict ? */
+			TRC_WARNING(SQL_STORE, "%s: " "if (co != oo) { /* conflict ? */", __func__);
 			return -3;
 		}
 		ov->name_based_older = oo;
@@ -943,6 +949,7 @@ os_del_id_based(objectset *os, struct sq
 		objectversion *oo = get_valid_object_id(tr, co);
 		ov->id_based_head = oo->id_based_head;
 		if (co != oo) { /* conflict ? */
+			TRC_WARNING(SQL_STORE, "%s" "if (co != oo) { /* conflict ? */", __func__);
 			return -3;
 		}
 		ov->id_based_older = oo;
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -2101,6 +2101,7 @@ store_init(int debug, store_type store_t
 	for(int i = 0; i<NR_COLUMN_LOCKS; i++)
 		MT_lock_init(&store->column_locks[i], "sqlstore_column");
 
+	MT_lock_set(&store->flush);
 	MT_lock_set(&store->lock);
 
 	store->generic_event_wrapper = event_wrapper;
@@ -2209,7 +2210,7 @@ store_apply_deltas(sqlstore *store)
 	store_lock(store);
 	ulng oldest = store_oldest_pending(store);
 	store_unlock(store);
-	TRC_DEBUG(SQL_STORE, "Store aplly deltas (" ULLFMT ")\n", oldest-1);
+	TRC_DEBUG(SQL_STORE, "Store apply deltas (" ULLFMT ")\n", oldest-1);
 	if (oldest)
 	    res = store->logger_api.flush(store, oldest-1);
 	return res;
@@ -2300,7 +2301,7 @@ store_manager(sqlstore *store)
 	MT_lock_set(&store->flush);
 
 	for (;;) {
-		int res;
+		int res = LOG_OK;
 
 		if (ATOMIC_GET(&store->nr_active) == 0 &&
 			(store->debug&128 || ATOMIC_GET(&store->lastactive) + IDLE_TIME * 1000000 < (ATOMIC_BASE_TYPE) GDKusec())) {
@@ -5826,6 +5827,12 @@ int
 sql_trans_drop_table(sql_trans *tr, sql_schema *s, const char *name, int drop_action)
 {
 	sql_table *t = find_sql_table(tr, s, name), *gt = NULL;
+
+	if (!t) {
+		TRC_ERROR(SQL_STORE, "sql_trans_drop_table: Table %s.%s does not exist\n", s->base.name, name);
+		return -1;
+	}
+
 	if (t && isTempTable(t)) {
 		gt = find_sql_table_id(tr, s, t->base.id);
 		if (gt)
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2018/Tests/truncate_geom_tables.Bug-6543.reqtests
@@ -0,0 +1,1 @@
+truncate_add_user
--- a/sql/test/BugTracker-2019/Tests/remote-table-non-existent-column.Bug-6750.py
+++ b/sql/test/BugTracker-2019/Tests/remote-table-non-existent-column.Bug-6750.py
@@ -5,7 +5,6 @@ try:
 except ImportError:
     import process
 
-
 with tempfile.TemporaryDirectory() as farm_dir:
     os.makedirs(os.path.join(farm_dir, 'node1'))
     with process.server(mapiport='0', dbname='node1', dbfarm=os.path.join(farm_dir, 'node1'), stdin=process.PIPE, stdout=process.PIPE, stderr=process.PIPE) as prc1:
--- a/sql/test/dict/Tests/dict03.py
+++ b/sql/test/dict/Tests/dict03.py
@@ -9,7 +9,7 @@ from MonetDBtesting.sqltest import SQLTe
 with tempfile.TemporaryDirectory() as farm_dir:
     os.mkdir(os.path.join(farm_dir, 'db1'))
 
-    with process.server(mapiport='0', dbname='db1', dbfarm=os.path.join(farm_dir, 'db1'), stdin = process.PIPE, stdout = process.PIPE, stderr = process.PIPE) as s:
+    with process.server(mapiport='0', dbname='db1', dbfarm=os.path.join(farm_dir, 'db1'), stdin=process.PIPE, stdout=process.PIPE, stderr=process.PIPE) as s:
         with SQLTestCase() as mdb:
             mdb.connect(database='db1', port=s.dbport, username="monetdb", password="monetdb")
             mdb.execute("""
@@ -33,14 +33,14 @@ with tempfile.TemporaryDirectory() as fa
             mdb.execute("SELECT c0 FROM t2;").assertSucceeded().assertDataResultMatch([(-1981639662,),])
         s.communicate()
 
-    with process.server(mapiport='0', dbname='db1', dbfarm=os.path.join(farm_dir, 'db1'), stdin = process.PIPE, stdout = process.PIPE, stderr = process.PIPE) as s:
+    with process.server(mapiport='0', dbname='db1', dbfarm=os.path.join(farm_dir, 'db1'), stdin=process.PIPE, stdout=process.PIPE, stderr=process.PIPE) as s:
         with SQLTestCase() as mdb:
             mdb.connect(database='db1', port=s.dbport, username="monetdb", password="monetdb")
             mdb.execute("SELECT c0 FROM t1 ORDER BY c0;").assertSucceeded().assertDataResultMatch([('',),('3be汉字0',),('aa8877',)])
             mdb.execute("SELECT c0 FROM t2;").assertSucceeded().assertDataResultMatch([(-1981639662,),])
         s.communicate()
 
-    with process.server(mapiport='0', dbname='db1', dbfarm=os.path.join(farm_dir, 'db1'), stdin = process.PIPE, stdout = process.PIPE, stderr = process.PIPE) as s:
+    with process.server(mapiport='0', dbname='db1', dbfarm=os.path.join(farm_dir, 'db1'), stdin=process.PIPE, stdout=process.PIPE, stderr=process.PIPE) as s:
         with SQLTestCase() as mdb:
             mdb.connect(database='db1', port=s.dbport, username="monetdb", password="monetdb")
             mdb.execute("SELECT c0 FROM t1 ORDER BY c0;").assertSucceeded().assertDataResultMatch([('',),('3be汉字0',),('aa8877',)])
--- a/sql/test/pg_regress/Tests/date.test
+++ b/sql/test/pg_regress/Tests/date.test
@@ -1253,8 +1253,10 @@ SELECT date '1/18/1999'
 statement error
 SELECT date '18/1/1999'
 
-statement error
+query T rowsort
 SELECT date '01/02/03'
+----
+0001-02-03
 
 statement error
 SELECT date '19990108'
@@ -1271,160 +1273,10 @@ SELECT date 'J2451187'
 statement error
 SELECT date 'January 8, 99 BC'
 
-statement error
+query T rowsort
 SELECT date '99-Jan-08'
-
-query T rowsort
-SELECT date '1999-Jan-08'
-----
-1999-01-08
-
-statement error
-SELECT date '08-Jan-99'
-
-statement error
-SELECT date '08-Jan-1999'
-
-statement error
-SELECT date 'Jan-08-99'
-
-statement error
-SELECT date 'Jan-08-1999'
-
-statement error
-SELECT date '99-08-Jan'
-
-statement error
-SELECT date '1999-08-Jan'
-
-statement error
-SELECT date '99 Jan 08'
-
-query T rowsort
-SELECT date '1999 Jan 08'
-----
-1999-01-08
-
-statement error
-SELECT date '08 Jan 99'
-
-statement error
-SELECT date '08 Jan 1999'
-
-statement error
-SELECT date 'Jan 08 99'
-
-query T rowsort
-SELECT date 'Jan 08 1999'
-----
-1999-01-08
-
-statement error
-SELECT date '99 08 Jan'
-
-statement error
-SELECT date '1999 08 Jan'
-
-statement error
-SELECT date '99-01-08'
-
-query T rowsort
-SELECT date '1999-01-08'
 ----
-1999-01-08
-
-statement error
-SELECT date '08-01-99'
-
-statement error
-SELECT date '08-01-1999'
-
-statement error
-SELECT date '01-08-99'
-
-statement error
-SELECT date '01-08-1999'
-
-statement error
-SELECT date '99-08-01'
-
-query T rowsort
-SELECT date '1999-08-01'
-----
-1999-08-01
-
-statement error
-SELECT date '99 01 08'
-
-query T rowsort
-SELECT date '1999 01 08'
-----
-1999-01-08
-
-statement error
-SELECT date '08 01 99'
-
-statement error
-SELECT date '08 01 1999'
-
-statement error
-SELECT date '01 08 99'
-
-statement error
-SELECT date '01 08 1999'
-
-statement error
-SELECT date '99 08 01'
-
-query T rowsort
-SELECT date '1999 08 01'
-----
-1999-08-01
-
-query T rowsort
-SELECT date 'January 8, 1999'
-----
-1999-01-08
-
-query T rowsort
-SELECT date '1999-01-08'
-----
-1999-01-08
-
-query T rowsort
-SELECT date '1999-01-18'
-----
-1999-01-18
-
-statement error
-SELECT date '1/8/1999'
-
-statement error
-SELECT date '1/18/1999'
-
-statement error
-SELECT date '18/1/1999'
-
-statement error
-SELECT date '01/02/03'
-
-statement error
-SELECT date '19990108'
-
-statement error
-SELECT date '990108'
-
-statement error
-SELECT date '1999.008'
-
-statement error
-SELECT date 'J2451187'
-
-statement error
-SELECT date 'January 8, 99 BC'
-
-statement error
-SELECT date '99-Jan-08'
+0099-01-08
 
 query T rowsort
 SELECT date '1999-Jan-08'
@@ -1449,8 +1301,10 @@ SELECT date '99-08-Jan'
 statement error
 SELECT date '1999-08-Jan'
 
-statement error
+query T rowsort
 SELECT date '99 Jan 08'
+----
+0099-01-08
 
 query T rowsort
 SELECT date '1999 Jan 08'
@@ -1463,8 +1317,10 @@ SELECT date '08 Jan 99'
 statement error
 SELECT date '08 Jan 1999'
 
-statement error
+query T rowsort
 SELECT date 'Jan 08 99'
+----
+0099-01-08
 
 query T rowsort
 SELECT date 'Jan 08 1999'
@@ -1477,8 +1333,10 @@ SELECT date '99 08 Jan'
 statement error
 SELECT date '1999 08 Jan'
 
-statement error
+query T rowsort
 SELECT date '99-01-08'
+----
+0099-01-08
 
 query T rowsort
 SELECT date '1999-01-08'
@@ -1497,16 +1355,20 @@ SELECT date '01-08-99'
 statement error
 SELECT date '01-08-1999'
 
-statement error
+query T rowsort
 SELECT date '99-08-01'
+----
+0099-08-01
 
 query T rowsort
 SELECT date '1999-08-01'
 ----
 1999-08-01
 
-statement error
+query T rowsort
 SELECT date '99 01 08'
+----
+0099-01-08
 
 query T rowsort
 SELECT date '1999 01 08'
@@ -1525,160 +1387,10 @@ SELECT date '01 08 99'
 statement error
 SELECT date '01 08 1999'
 
-statement error
+query T rowsort
 SELECT date '99 08 01'
-
-query T rowsort
-SELECT date '1999 08 01'
-----
-1999-08-01
-
-query T rowsort
-SELECT date 'January 8, 1999'
-----
-1999-01-08
-
-query T rowsort
-SELECT date '1999-01-08'
-----
-1999-01-08
-
-query T rowsort
-SELECT date '1999-01-18'
-----
-1999-01-18
-
-statement error
-SELECT date '1/8/1999'
-
-statement error
-SELECT date '1/18/1999'
-
-statement error
-SELECT date '18/1/1999'
-
-statement error
-SELECT date '01/02/03'
-
-statement error
-SELECT date '19990108'
-
-statement error
-SELECT date '990108'
-
-statement error
-SELECT date '1999.008'
-
-statement error
-SELECT date 'J2451187'
-
-statement error
-SELECT date 'January 8, 99 BC'
-
-statement error
-SELECT date '99-Jan-08'
-
-query T rowsort
-SELECT date '1999-Jan-08'
 ----
-1999-01-08
-
-statement error
-SELECT date '08-Jan-99'
-
-statement error
-SELECT date '08-Jan-1999'
-
-statement error
-SELECT date 'Jan-08-99'
-
-statement error
-SELECT date 'Jan-08-1999'
-
-statement error
-SELECT date '99-08-Jan'
-
-statement error
-SELECT date '1999-08-Jan'
-
-statement error
-SELECT date '99 Jan 08'
-
-query T rowsort
-SELECT date '1999 Jan 08'
-----
-1999-01-08
-
-statement error
-SELECT date '08 Jan 99'
-
-statement error
-SELECT date '08 Jan 1999'
-
-statement error
-SELECT date 'Jan 08 99'
-
-query T rowsort
-SELECT date 'Jan 08 1999'
-----
-1999-01-08
-
-statement error
-SELECT date '99 08 Jan'
-
-statement error
-SELECT date '1999 08 Jan'
-
-statement error
-SELECT date '99-01-08'
-
-query T rowsort
-SELECT date '1999-01-08'
-----
-1999-01-08
-
-statement error
-SELECT date '08-01-99'
-
-statement error
-SELECT date '08-01-1999'
-
-statement error
-SELECT date '01-08-99'
-
-statement error
-SELECT date '01-08-1999'
-
-statement error
-SELECT date '99-08-01'
-
-query T rowsort
-SELECT date '1999-08-01'
-----
-1999-08-01
-
-statement error
-SELECT date '99 01 08'
-
-query T rowsort
-SELECT date '1999 01 08'
-----
-1999-01-08
-
-statement error
-SELECT date '08 01 99'
-
-statement error
-SELECT date '08 01 1999'
-
-statement error
-SELECT date '01 08 99'
-
-statement error
-SELECT date '01 08 1999'
-
-statement error
-SELECT date '99 08 01'
+0099-08-01
 
 query T rowsort
 SELECT date '1999 08 01'
@@ -1729,17 +1441,17 @@ SELECT sql_add(current_date, 24*60*60.0)
 query I rowsort
 SELECT EXTRACT(CENTURY FROM DATE '0101-12-31 BC')
 ----
-2
+-2
 
 query I rowsort
 SELECT EXTRACT(CENTURY FROM DATE '0100-12-31 BC')
 ----
-1
+-1
 
 query I rowsort
 SELECT EXTRACT(CENTURY FROM DATE '0001-12-31 BC')
 ----
-1
+-1
 
 query I rowsort
 SELECT EXTRACT(CENTURY FROM DATE '0001-01-01')
@@ -1823,12 +1535,12 @@ 0
 query I rowsort
 SELECT EXTRACT(DECADE FROM DATE '0011-01-01 BC')
 ----
-1
+-1
 
 query I rowsort
 SELECT EXTRACT(DECADE FROM DATE '0012-12-31 BC')
 ----
-1
+-1
 
 statement error
 SELECT EXTRACT(CENTURY FROM NOW())>=21 AS True
--- a/sql/test/wlcr/Tests/wlr01.py
+++ b/sql/test/wlcr/Tests/wlr01.py
@@ -17,7 +17,7 @@ dbnameclone = tstdb + 'clone'
 
 with process.server(dbname=dbnameclone, mapiport='0', stdin=process.PIPE, stdout=process.PIPE, stderr=process.PIPE) as slave, \
         SQLTestCase() as tc:
-    tc.connect(database=dbnameclone, port=tc.dbport)
+    tc.connect(database=dbnameclone, port=slave.dbport)
     tc.execute("select 'hello';")\
             .assertSucceeded()\
             .assertRowCount(1)
--- a/sql/test/wlcr/Tests/wlr20.py
+++ b/sql/test/wlcr/Tests/wlr20.py
@@ -18,7 +18,7 @@ dbnameclone = tstdb + 'clone'
 
 with process.server(dbname=dbnameclone, mapiport='0', stdin=process.PIPE, stdout=process.PIPE, stderr=process.PIPE) as slave, \
         SQLTestCase() as tc:
-    tc.connect(database=dbnameclone, port=tc.dbport)
+    tc.connect(database=dbnameclone, port=slave.dbport)
     tc.execute("call wlr.master('%s');" % dbname).assertSucceeded()
     tc.execute("call wlr.replicate(3);").assertSucceeded()
     tc.execute("select * from tmp;")\
--- a/sql/test/wlcr/Tests/wlr30.py
+++ b/sql/test/wlcr/Tests/wlr30.py
@@ -17,7 +17,7 @@ dbnameclone = tstdb + 'clone'
 
 with process.server(dbname=dbnameclone, mapiport='0', stdin=process.PIPE, stdout=process.PIPE, stderr=process.PIPE) as slave, \
         SQLTestCase() as tc:
-    tc.connect(database=dbnameclone, port=tc.dbport)
+    tc.connect(database=dbnameclone, port=slave.dbport)
     tc.execute("select * from tmp;")\
             .assertSucceeded()\
             .assertDataResultMatch([(1, 'hello'), (2, 'world'), (3, 'blah'), (4, 'bloh'), (5, 'red'), (6, 'fox')])
--- a/sql/test/wlcr/Tests/wlr35.py
+++ b/sql/test/wlcr/Tests/wlr35.py
@@ -17,7 +17,7 @@ dbnameclone = tstdb + 'clone'
 
 with process.server(dbname=dbnameclone, mapiport='0', stdin=process.PIPE, stdout=process.PIPE, stderr=process.PIPE) as slave, \
         SQLTestCase() as tc:
-    tc.connect(database=dbnameclone, port=tc.dbport)
+    tc.connect(database=dbnameclone, port=slave.dbport)
     tc.execute("call wlr.replicate(9);").assertSucceeded()
     tc.execute("select * from tmp;")\
             .assertSucceeded()\
--- a/sql/test/wlcr/Tests/wlr40.py
+++ b/sql/test/wlcr/Tests/wlr40.py
@@ -17,7 +17,7 @@ dbnameclone = tstdb + 'clone'
 
 with process.server(dbname=dbnameclone, mapiport='0', stdin=process.PIPE, stdout=process.PIPE, stderr=process.PIPE) as slave, \
         SQLTestCase() as tc:
-    tc.connect(database=dbnameclone, port=tc.dbport)
+    tc.connect(database=dbnameclone, port=slave.dbport)
     tc.execute("call wlr.master('%s');" % dbname).assertSucceeded()
     tc.execute("call wlr.replicate(9);").assertSucceeded()
     tc.execute("select * from tmp;")\
--- a/sql/test/wlcr/Tests/wlr50.py
+++ b/sql/test/wlcr/Tests/wlr50.py
@@ -17,7 +17,7 @@ dbnameclone = tstdb + 'clone'
 
 with process.server(dbname=dbnameclone, mapiport='0', stdin=process.PIPE, stdout=process.PIPE, stderr=process.PIPE) as slave, \
         SQLTestCase() as tc:
-    tc.connect(database=dbnameclone, port=tc.dbport)
+    tc.connect(database=dbnameclone, port=slave.dbport)
     tc.execute("call wlr.master('%s');" % dbname).assertSucceeded()
     tc.execute("call wlr.replicate();").assertSucceeded()
     tc.execute("select * from tmp;")\
--- a/testing/Mtest.py.in
+++ b/testing/Mtest.py.in
@@ -3495,6 +3495,7 @@ def main(argv) :
             mserver5_opts.extend(['--set', a])
             if a == 'sql_debug=128':
                 CONDITIONALS['NOWAL'] = True
+                os.environ['NOWAL'] = 'True'
     if opts.loadmodule:
         for a in opts.loadmodule:
             mserver5_opts.extend(['--loadmodule', a])
--- a/testing/process.py
+++ b/testing/process.py
@@ -370,6 +370,8 @@ class server(Popen):
             cmd = ['mserver5',
                    '--set', ipv6 and 'mapi_listenaddr=all' or 'mapi_listenaddr=0.0.0.0',
                    '--set', 'gdk_nr_threads=1']
+        if os.getenv('NOWAL'):
+            cmd.extend(['--set', 'sql_debug=128'])
         if verbose:
             sys.stdout.write('Default server: ' + ' '.join(cmd +  args) + '\n')
         if notrace and '--trace' in cmd: