LCOV - code coverage report
Current view: top level - clients/odbc/tests - ODBCmetadata.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 324 414 78.3 %
Date: 2025-03-26 20:06:40 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024, 2025 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : /*
      14             :  * MonetDB program to test ODBC metadata/catalog functions (all return a result-set):
      15             :  * SQLTables()
      16             :  * SQLColumns()
      17             :  * SQLSpecialColumns()
      18             :  * SQLPrimaryKeys()
      19             :  * SQLForeignKeys()
      20             :  * SQLStatistics()
      21             :  * SQLTablePrivileges()
      22             :  * SQLColumnPrivileges()
      23             :  * SQLProcedures()
      24             :  * SQLProcedureColumns()
      25             :  * SQLGetTypeInfo()
      26             :  */
      27             : 
      28             : #ifdef _MSC_VER
      29             : /* Visual Studio 8 has deprecated lots of stuff: suppress warnings */
      30             : #ifndef _CRT_SECURE_NO_DEPRECATE
      31             : #define _CRT_SECURE_NO_DEPRECATE 1
      32             : #endif
      33             : #include <WTypes.h>
      34             : #endif
      35             : #include <stdio.h>
      36             : #include <stdlib.h>
      37             : #include <stdint.h>
      38             : #include <inttypes.h>
      39             : 
      40             : /**** Define the ODBC Version our ODBC driver complies with ****/
      41             : #define ODBCVER 0x0352          /* Important: this must be defined before include of sql.h and sqlext.h */
      42             : #include <sql.h>
      43             : #include <sqlext.h>
      44             : #include <string.h>
      45             : 
      46             : #define SQL_HUGEINT     0x4000  /* as defined in ODBCGlobal.h */
      47             : 
      48             : static void
      49           0 : prerr(SQLSMALLINT tpe, SQLHANDLE hnd, const char *func, const char *pref)
      50             : {
      51           0 :         SQLCHAR state[6];
      52           0 :         SQLINTEGER errnr;
      53           0 :         SQLCHAR msg[256];
      54           0 :         SQLSMALLINT msglen;
      55           0 :         SQLRETURN ret;
      56             : 
      57           0 :         ret = SQLGetDiagRec(tpe, hnd, 1, state, &errnr, msg, sizeof(msg), &msglen);
      58           0 :         switch (ret) {
      59           0 :         case SQL_SUCCESS_WITH_INFO:
      60           0 :                 if (msglen >= (signed int) sizeof(msg))
      61           0 :                         fprintf(stderr, "(message truncated)\n");
      62             :                 /* fall through */
      63             :         case SQL_SUCCESS:
      64           0 :                 fprintf(stderr, "%s: %s: SQLstate %s, Errnr %d, Message %s\n", func, pref, (char*)state, (int)errnr, (char*)msg);
      65           0 :                 break;
      66           0 :         case SQL_INVALID_HANDLE:
      67           0 :                 fprintf(stderr, "%s: %s, invalid handle passed to error function\n", func, pref);
      68           0 :                 break;
      69           0 :         case SQL_ERROR:
      70           0 :                 fprintf(stderr, "%s: %s, unexpected error from SQLGetDiagRec\n", func, pref);
      71           0 :                 break;
      72             :         case SQL_NO_DATA:
      73             :                 break;
      74           0 :         default:
      75           0 :                 fprintf(stderr, "%s: %s, weird return value from SQLGetDiagRec\n", func, pref);
      76           0 :                 break;
      77             :         }
      78           0 : }
      79             : 
      80             : static void
      81        7407 : check(SQLRETURN ret, SQLSMALLINT tpe, SQLHANDLE hnd, const char *func)
      82             : {
      83        7407 :         switch (ret) {
      84             :         case SQL_SUCCESS:
      85             :                 break;
      86           0 :         case SQL_SUCCESS_WITH_INFO:
      87           0 :                 prerr(tpe, hnd, func, "Info");
      88           0 :                 break;
      89           0 :         case SQL_ERROR:
      90           0 :                 prerr(tpe, hnd, func, "Error");
      91           0 :                 break;
      92             :         case SQL_NO_DATA:
      93             :                 break;
      94           0 :         case SQL_INVALID_HANDLE:
      95           0 :                 fprintf(stderr, "%s: Error: invalid handle\n", func);
      96           0 :                 break;
      97           0 :         default:
      98           0 :                 fprintf(stderr, "%s: Unexpected return value\n", func);
      99           0 :                 break;
     100             :         }
     101        7407 : }
     102             : 
     103             : static char *
     104         790 : nameofSQLtype(SQLSMALLINT dataType)
     105             : {
     106             :         /* https://docs.microsoft.com/en-us/sql/odbc/reference/appendixes/sql-data-types */
     107         790 :         switch (dataType) {
     108             :         case SQL_CHAR:          return "CHAR";
     109           0 :         case SQL_VARCHAR:       return "VARCHAR";
     110           0 :         case SQL_LONGVARCHAR:   return "LONG VARCHAR";
     111          14 :         case SQL_WCHAR:         return "WCHAR";
     112         475 :         case SQL_WVARCHAR:      return "WVARCHAR";
     113           1 :         case SQL_WLONGVARCHAR:  return "WLONGVARCHAR";
     114           2 :         case SQL_DECIMAL:       return "DECIMAL";
     115           0 :         case SQL_NUMERIC:       return "NUMERIC";
     116         197 :         case SQL_SMALLINT:      return "SMALLINT";
     117          88 :         case SQL_INTEGER:       return "INTEGER";
     118           0 :         case SQL_REAL:          return "REAL";
     119           0 :         case SQL_FLOAT:         return "FLOAT";
     120           0 :         case SQL_DOUBLE:        return "DOUBLE";
     121           0 :         case SQL_BIT:           return "BOOLEAN";     /* MonetDB boolean type is mapped to SQL_BIT in ODBC (see msql_types[] in SQLExecute.c) */
     122          12 :         case SQL_TINYINT:       return "TINYINT";
     123           1 :         case SQL_BIGINT:        return "BIGINT";
     124           0 :         case SQL_BINARY:        return "BINARY";
     125           0 :         case SQL_VARBINARY:     return "VARBINARY";
     126           0 :         case SQL_LONGVARBINARY: return "LONG VARBINARY";
     127           0 :         case SQL_DATETIME:      return "DATETIME";
     128           0 :         case SQL_TYPE_DATE:     return "DATE";
     129           0 :         case SQL_TYPE_TIME:     return "TIME";
     130           0 :         case SQL_TYPE_TIMESTAMP:        return "TIMESTAMP";
     131           0 :         case SQL_INTERVAL_MONTH:        return "INTERVAL MONTH";
     132           0 :         case SQL_INTERVAL_YEAR:         return "INTERVAL YEAR";
     133           0 :         case SQL_INTERVAL_YEAR_TO_MONTH: return "INTERVAL YEAR TO MONTH";
     134           0 :         case SQL_INTERVAL_DAY:          return "INTERVAL DAY";
     135           0 :         case SQL_INTERVAL_HOUR:         return "INTERVAL HOUR";
     136           0 :         case SQL_INTERVAL_MINUTE:       return "INTERVAL MINUTE";
     137           0 :         case SQL_INTERVAL_SECOND:       return "INTERVAL SECOND";
     138           0 :         case SQL_INTERVAL_DAY_TO_HOUR:  return "INTERVAL DAY TO HOUR";
     139           0 :         case SQL_INTERVAL_DAY_TO_MINUTE:        return "INTERVAL DAY TO MINUTE";
     140           0 :         case SQL_INTERVAL_DAY_TO_SECOND:        return "INTERVAL DAY TO SECOND";
     141           0 :         case SQL_INTERVAL_HOUR_TO_MINUTE:       return "INTERVAL HOUR TO MINUTE";
     142           0 :         case SQL_INTERVAL_HOUR_TO_SECOND:       return "INTERVAL HOUR TO SECOND";
     143           0 :         case SQL_INTERVAL_MINUTE_TO_SECOND:     return "INTERVAL MINUTE TO SECOND";
     144           0 :         case SQL_GUID:          return "GUID";
     145           0 :         case SQL_HUGEINT:       return "HUGEINT";     /* 0x4000 (defined in ODBCGlobal.h) */
     146           0 :         default:                return "Undefined";
     147             :         }
     148             : }
     149             : 
     150             : static void
     151          82 : compareResultOptClose(SQLHANDLE stmt, SQLRETURN retcode, const char * functionname, const char * expected, int closeCursor)
     152             : {
     153          82 :         SQLRETURN ret;
     154          82 :         SQLSMALLINT columns;    /* Number of columns in result-set */
     155          82 :         SQLLEN rows;            /* Number of rows in result-set */
     156          82 :         size_t expct_len = strlen(expected);
     157          82 :         size_t outp_len = expct_len + 10000;
     158          82 :         char * outp = NULL;
     159          82 :         size_t pos = 0;
     160          82 :         SQLUSMALLINT col;
     161          82 :         SQLLEN indicator;
     162          82 :         char buf[2048];
     163          82 :         SQLSMALLINT dataType = 0;
     164          82 :         SQLULEN columnSize = 0;
     165          82 :         SQLSMALLINT decimalDigits = 0;
     166          82 :         int replaceId = 0;      /* used to replace system id values in column SPECIFIC_NAME of getProcedures and getProcedureColumns */
     167          82 :         int replaceTraceData = 0; /* used to replace second result set data of a TRACE query */
     168             : 
     169          82 :         check(retcode, SQL_HANDLE_STMT, stmt, functionname);
     170          82 :         if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
     171           0 :                 fprintf(stderr, "Invalid retcode (%d). Skipping compareResult(%s)\n", retcode, functionname);
     172           0 :                 return;
     173             :         }
     174             : 
     175          82 :         outp = malloc(outp_len);
     176          82 :         if (outp == NULL) {
     177           0 :                 fprintf(stderr, "Failed to allocate %zu memory!\n", outp_len);
     178           0 :                 return;
     179             :         }
     180             : 
     181             :         /* How many columns are there */
     182          82 :         ret = SQLNumResultCols(stmt, &columns);
     183          82 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLNumResultCols()");
     184          82 :         pos += snprintf(outp + pos, outp_len - pos, "Resultset with %d columns\n", columns);
     185             : 
     186             :         /* How many rows are there */
     187          82 :         ret = SQLRowCount(stmt, &rows);
     188          82 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLRowCount()");
     189          82 :         pos += snprintf(outp + pos, outp_len - pos, "Resultset with %"PRId64" rows\n", (int64_t) rows);
     190             : 
     191             :         /* detect if special handling of data returned by second TRACE resultset is needed */
     192          82 :         if (columns == 2 && (strncmp("TRACE(2) ", functionname, 9) == 0)) {
     193          82 :                 replaceTraceData = 1;
     194             :         }
     195             : 
     196             :         /* get Result Column Names and print them */
     197         872 :         for (col = 1; col <= columns; col++) {
     198         790 :                 ret = SQLDescribeCol(stmt, col, (SQLCHAR *) buf, sizeof(buf),
     199             :                         NULL, NULL, NULL, NULL, NULL);
     200         790 :                 check(ret, SQL_HANDLE_STMT, stmt, "SQLDescribeCol(colName)");
     201         872 :                 pos += snprintf(outp + pos, outp_len - pos,
     202             :                                 (col > 1) ? "\t%s" : "%s", buf);
     203             :         }
     204          82 :         pos += snprintf(outp + pos, outp_len - pos, "\n");
     205             :         /* get Result Column Data Types and print them */
     206         872 :         for (col = 1; col <= columns; col++) {
     207         790 :                 ret = SQLDescribeCol(stmt, col, (SQLCHAR *) buf, sizeof(buf),
     208             :                         NULL, &dataType, &columnSize, &decimalDigits, NULL);
     209         790 :                 check(ret, SQL_HANDLE_STMT, stmt, "SQLDescribeCol(colType)");
     210         790 :                 pos += snprintf(outp + pos, outp_len - pos,
     211             :                                 (col > 1) ? "\t%s" : "%s", nameofSQLtype(dataType));
     212         790 :                 switch (dataType) {
     213         492 :                 case SQL_CHAR:
     214             :                 case SQL_VARCHAR:
     215             :                 case SQL_LONGVARCHAR:
     216             :                 case SQL_WCHAR:
     217             :                 case SQL_WVARCHAR:
     218             :                 case SQL_WLONGVARCHAR:
     219             :                 case SQL_DECIMAL:
     220             :                 case SQL_NUMERIC:
     221             :                 case SQL_BINARY:
     222             :                 case SQL_VARBINARY:
     223             :                 case SQL_LONGVARBINARY:
     224         492 :                         if (columnSize != 0 && replaceTraceData == 0) {
     225         487 :                                 if (decimalDigits != 0) {
     226           2 :                                         pos += snprintf(outp + pos, outp_len - pos,
     227             :                                                 "(%d,%d)", (int) columnSize, (int) decimalDigits);
     228             :                                 } else {
     229         485 :                                         pos += snprintf(outp + pos, outp_len - pos,
     230             :                                                 "(%d)", (int) columnSize);
     231             :                                 }
     232             :                         }
     233             :                         break;
     234             :                 }
     235             :         }
     236          82 :         pos += snprintf(outp + pos, outp_len - pos, "\n");
     237             : 
     238             :         /* detect if special handling of data of column SPECIFIC_NAME returned by SQLProcedures and SQLProcedureColumns
     239             :            is needed as it contains system generated id values which can differ per version and platform */
     240          82 :         if (columns == 9 || columns == 20) {
     241             :                 /* this result could be from SQLProcedures or SQLProcedureColumns */
     242           8 :                 if ((strncmp("SQLProcedures", functionname, 13) == 0)
     243           4 :                  || (strncmp("SQLProcedureColumns", functionname, 19) == 0)) {
     244           8 :                         if (strncmp("SPECIFIC_NAME", buf, 13) == 0)
     245          82 :                                 replaceId = 1;
     246             :                 }
     247             :         }
     248             : 
     249             :         /* Loop through the rows in the result-set */
     250          82 :         ret = SQLFetch(stmt);
     251          82 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLFetch(1)");
     252         491 :         while (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
     253             :                 /* Loop through the columns */
     254        5396 :                 for (col = 1; col <= columns; col++) {
     255             :                         /* Retrieve column data as a string */
     256        4987 :                         ret = SQLGetData(stmt, col, SQL_C_CHAR, buf, sizeof(buf), &indicator);
     257        4987 :                         check(ret, SQL_HANDLE_STMT, stmt, "SQLGetData()");
     258        4987 :                         if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
     259             :                                 /* some rows of EXPLAIN output (which has only 1 result column) must be suppressed to get stable output */
     260        4987 :                                 if (columns == 1 &&
     261          49 :                                     (strncmp(buf, "# ", 2) == 0 ||
     262          18 :                                      strncmp(buf, "barrier X_", 10) == 0 ||
     263          17 :                                      strncmp(buf, "exit X_", 7) == 0) ) {
     264          33 :                                         continue;
     265             :                                 }
     266             : 
     267        4954 :                                 if (replaceTraceData == 1) {
     268          24 :                                         pos += snprintf(outp + pos, outp_len - pos,
     269             :                                                 (col == 1) ? "4" : "\tvariable output");
     270          24 :                                         continue;
     271             :                                 }
     272             : 
     273             :                                 /* Check if we need to replace the system id values to get stable output */
     274        4930 :                                 if (replaceId == 0 ||
     275        1499 :                                    (replaceId == 1 && col < columns)) {
     276        4849 :                                         pos += snprintf(outp + pos, outp_len - pos,
     277             :                                                 (col > 1) ? "\t%s" : "%s",
     278             :                                                 /* Handle null columns */
     279        9698 :                                                 (indicator == SQL_NULL_DATA) ? "NULL" : buf);
     280             :                                 } else {
     281          81 :                                         pos += snprintf(outp + pos, outp_len - pos, "\treplacedId");
     282             :                                 }
     283             :                         }
     284             :                 }
     285         409 :                 pos += snprintf(outp + pos, outp_len - pos, "\n");
     286         409 :                 ret = SQLFetch(stmt);
     287         409 :                 check(ret, SQL_HANDLE_STMT, stmt, "SQLFetch(n)");
     288             :         }
     289             : 
     290          82 :         if (strcmp(expected, outp) != 0) {
     291           0 :                 size_t len_expected = strlen(expected);
     292           0 :                 size_t len_outp = strlen(outp);
     293           0 :                 int c = 0;
     294           0 :                 int line = 1;
     295           0 :                 int pos = 1;
     296             : 
     297           0 :                 fprintf(stderr, "Testing %s\nExpected (strlen=%zu):\n%s\nGotten (strlen=%zu):\n%s\n",
     298             :                         functionname, len_expected, expected, len_outp, outp);
     299             : 
     300             :                 /* scan string to find location (line and position in line) of first character difference */
     301           0 :                 while (expected[c] != '\0' && outp[c] != '\0' && expected[c] == outp[c]) {
     302           0 :                         if (expected[c] == '\n') {
     303           0 :                                 line++;
     304           0 :                                 pos = 0;
     305             :                         }
     306           0 :                         c++;
     307           0 :                         pos++;
     308             :                 }
     309           0 :                 fprintf(stderr, "First difference found at line %d, position %d, data: %-20s\n\n",
     310             :                         line, pos, (expected[c] != '\0' ? &expected[c] : &outp[c]) );
     311             :         }
     312             : 
     313             :         /* cleanup */
     314          82 :         free(outp);
     315             : 
     316          82 :         if (closeCursor == 1) {
     317          81 :                 ret = SQLCloseCursor(stmt);
     318          81 :                 check(ret, SQL_HANDLE_STMT, stmt, "SQLCloseCursor");
     319             :         }
     320             : }
     321             : 
     322             : #define compareResultNoClose(stmt, retcode, functionname, expected)  compareResultOptClose(stmt, retcode, functionname, expected, 0)
     323             : #define compareResult(stmt, retcode, functionname, expected)         compareResultOptClose(stmt, retcode, functionname, expected, 1)
     324             : 
     325             : /*
     326             :  * Utility function to query the gdk_nr_threads value from the server.
     327             :  * The output of some queries (EXPLAIN, TRACE) differ when the server
     328             :  * is started with 1 thread, as is done in our testweb.
     329             :  */
     330             : static int
     331           1 : getNrOfServerThreads(SQLHANDLE dbc)
     332             : {
     333           1 :         SQLRETURN ret;
     334           1 :         SQLHANDLE stmt;
     335           1 :         SQLLEN indicator;
     336           1 :         int threads = 0;
     337             : 
     338           1 :         ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
     339           1 :         check(ret, SQL_HANDLE_DBC, dbc, "SQLAllocHandle (STMT)");
     340             : 
     341           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *)
     342             :                 "SELECT cast(value as int) as val from sys.env() where name = 'gdk_nr_threads';"
     343             :                 , SQL_NTS);
     344           1 :         check(ret, SQL_HANDLE_STMT, stmt, "select gdk_nr_threads");
     345             : 
     346           1 :         ret = SQLFetch(stmt);
     347           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLFetch(gdk_nr_threads)");
     348           1 :         if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
     349           1 :                 ret = SQLGetData(stmt, 1, SQL_C_LONG, &threads, sizeof(threads), &indicator);
     350           1 :                 check(ret, SQL_HANDLE_STMT, stmt, "SQLGetData(gdk_nr_threads)");
     351             :         }
     352           1 :         ret = SQLCloseCursor(stmt);
     353           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLCloseCursor");
     354             : 
     355             :         /* fprintf(stderr, "getNrOfServerThreads: %d\n", threads); */
     356           1 :         return threads;
     357             : }
     358             : 
     359             : int
     360           1 : main(int argc, char **argv)
     361             : {
     362           1 :         SQLRETURN ret;
     363           1 :         SQLHANDLE env;
     364           1 :         SQLHANDLE dbc;
     365           1 :         SQLHANDLE stmt;
     366           1 :         char *dsn = "MonetDB";
     367           1 :         char *user = "monetdb";
     368           1 :         char *pass = "monetdb";
     369           1 :         int nrServerThreads = 0;
     370             : 
     371           1 :         if (argc > 1)
     372           1 :                 dsn = argv[1];
     373           1 :         if (argc > 2)
     374           0 :                 user = argv[2];
     375           0 :         if (argc > 3)
     376           0 :                 pass = argv[3];
     377           1 :         if (argc > 4 || *dsn == '-') {
     378           0 :                 fprintf(stderr, "Wrong arguments. Usage: %s [datasource [user [password]]]\n", argv[0]);
     379           0 :                 exit(1);
     380             :         }
     381             : 
     382           1 :         ret = SQLAllocHandle(SQL_HANDLE_ENV, NULL, &env);
     383           1 :         if (ret != SQL_SUCCESS) {
     384           0 :                 fprintf(stderr, "Cannot allocate ODBC environment handle!\n");
     385           0 :                 exit(1);
     386             :         }
     387             : 
     388           1 :         ret = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (uintptr_t) SQL_OV_ODBC3, 0);
     389           1 :         check(ret, SQL_HANDLE_ENV, env, "SQLSetEnvAttr (SQL_ATTR_ODBC_VERSION ODBC3)");
     390             : 
     391           1 :         ret = SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
     392           1 :         check(ret, SQL_HANDLE_ENV, env, "SQLAllocHandle (DBC)");
     393             : 
     394           1 :         ret = SQLConnect(dbc, (SQLCHAR *) dsn, SQL_NTS, (SQLCHAR *) user, SQL_NTS, (SQLCHAR *) pass, SQL_NTS);
     395           1 :         check(ret, SQL_HANDLE_DBC, dbc, "SQLConnect");
     396             : 
     397           1 :         ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
     398           1 :         check(ret, SQL_HANDLE_DBC, dbc, "SQLAllocHandle (STMT)");
     399             : 
     400           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *)
     401             :                 "CREATE SCHEMA odbctst;\n"
     402             :                 "SET SCHEMA odbctst;\n"
     403             :                 , SQL_NTS);
     404           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLExecDirect (create and set schema script)");
     405             : 
     406             :         // create tables to populate catalog. Used for testing SQLTables(),
     407             :         // SQLColumns(), SQLSpecialColumns(), SQLPrimaryKeys() and SQLForeignKeys()
     408           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *)
     409             :                 "CREATE TABLE odbctst.pk_uc (id1 INT NOT NULL PRIMARY KEY, name1 VARCHAR(99) UNIQUE);\n"
     410             :                 "CREATE LOCAL TEMP TABLE tmp.tmp_pk_uc (id1 INT NOT NULL PRIMARY KEY, name1 VARCHAR(99) UNIQUE);\n"
     411             :                 "CREATE GLOBAL TEMP TABLE tmp.glbl_pk_uc (id1 INT NOT NULL PRIMARY KEY, name1 VARCHAR(99) UNIQUE);\n"
     412             :                 "CREATE TABLE odbctst.nopk_twoucs (id2 INT NOT NULL UNIQUE, name2 VARCHAR(99) UNIQUE);\n"
     413             :                 "CREATE LOCAL TEMP TABLE tmp.tmp_nopk_twoucs (id2 INT NOT NULL UNIQUE, name2 VARCHAR(99) UNIQUE);\n"
     414             :                 "CREATE GLOBAL TEMP TABLE tmp.glbl_nopk_twoucs (id2 INT NOT NULL UNIQUE, name2 VARCHAR(99) UNIQUE);\n"
     415             :                 /* next 3 tables copied from example in https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlforeignkeys-function?view=sql-server-ver15 */
     416             :                 "CREATE TABLE \"CUSTOMERS\" (\"CUSTID\" INT PRIMARY KEY, \"NAME\" VARCHAR(60) NOT NULL, \"ADDRESS\" VARCHAR(90), \"PHONE\" VARCHAR(20));\n"
     417             :                 "CREATE TABLE \"ORDERS\" (\"ORDERID\" INT PRIMARY KEY, \"CUSTID\" INT NOT NULL REFERENCES \"CUSTOMERS\" (\"CUSTID\"), \"OPENDATE\" DATE NOT NULL, \"SALESPERSON\" VARCHAR(60), \"STATUS\" VARCHAR(10) NOT NULL);\n"
     418             :                 "CREATE TABLE \"LINES\" (\"ORDERID\" INT NOT NULL REFERENCES \"ORDERS\" (\"ORDERID\"), \"LINES\" INT, PRIMARY KEY (\"ORDERID\", \"LINES\"), \"PARTID\" INT NOT NULL, \"QUANTITY\" DECIMAL(9,3) NOT NULL);\n"
     419             :                 /* also test situation where one table has multiple fks to the same multi column pk */
     420             :                 "CREATE TABLE odbctst.pk2c (pkc1 INT, pkc2 VARCHAR(99), name1 VARCHAR(99) UNIQUE, PRIMARY KEY (pkc2, pkc1));\n"
     421             :                 "CREATE TABLE odbctst.fk2c (fkc1 INT NOT NULL PRIMARY KEY, fkc2 VARCHAR(99), fkc3 INT"
     422             :                 ", FOREIGN KEY (fkc2, fkc1) REFERENCES odbctst.pk2c (pkc2, pkc1) ON UPDATE CASCADE ON DELETE RESTRICT"
     423             :                 ", FOREIGN KEY (fkc2, fkc3) REFERENCES odbctst.pk2c (pkc2, pkc1) ON UPDATE SET NULL ON DELETE NO ACTION);\n"
     424             :                 , SQL_NTS);
     425           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLExecDirect (create tables script)");
     426             : 
     427             :         // create indexes to populate catalog. Used for testing SQLStatistics()
     428           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *)
     429             :                 "CREATE INDEX pk_uc_i ON odbctst.pk_uc (id1, name1);\n"
     430             :                 "CREATE INDEX tmp_pk_uc_i ON tmp.tmp_pk_uc (id1, name1);\n"
     431             :                 "CREATE INDEX glbl_pk_uc_i ON tmp.glbl_pk_uc (id1, name1);\n"
     432             :                 "CREATE INDEX nopk_twoucs_i ON odbctst.nopk_twoucs (id2, name2);\n"
     433             :                 "CREATE INDEX tmp_nopk_twoucs_i ON tmp.tmp_nopk_twoucs (id2, name2);\n"
     434             :                 "CREATE INDEX glbl_nopk_twoucs_i ON tmp.glbl_nopk_twoucs (id2, name2);\n"
     435             :                 , SQL_NTS);
     436           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLExecDirect (create indices script)");
     437             : 
     438             :         // grant privileges to populate catalog. Used for testing SQLTablePrivileges() and SQLColumnPrivileges()
     439           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *)
     440             :                 "GRANT SELECT ON TABLE odbctst.pk_uc TO PUBLIC;\n"
     441             :                 "GRANT INSERT, UPDATE, DELETE ON TABLE odbctst.pk_uc TO monetdb;\n"
     442             :                 "GRANT SELECT (id2, name2), UPDATE (name2) ON TABLE odbctst.nopk_twoucs TO monetdb;\n"
     443             :                 "GRANT INSERT, DELETE ON TABLE tmp.tmp_pk_uc TO monetdb;\n"
     444             :                 "GRANT SELECT (id1, name1), UPDATE (name1) ON TABLE tmp.tmp_pk_uc TO monetdb;\n"
     445             :                 "GRANT INSERT, DELETE ON TABLE tmp.glbl_pk_uc TO monetdb;\n"
     446             :                 "GRANT SELECT (id1, name1), UPDATE (name1) ON TABLE tmp.glbl_pk_uc TO monetdb;\n"
     447             :                 "GRANT INSERT, DELETE ON TABLE tmp.tmp_nopk_twoucs TO monetdb;\n"
     448             :                 "GRANT SELECT (id2, name2), UPDATE (name2) ON TABLE tmp.tmp_nopk_twoucs TO monetdb;\n"
     449             :                 "GRANT DELETE, INSERT ON TABLE tmp.glbl_nopk_twoucs TO monetdb;\n"
     450             :                 "GRANT SELECT (id2, name2), UPDATE (name2) ON TABLE tmp.glbl_nopk_twoucs TO monetdb;\n"
     451             :                 , SQL_NTS);
     452           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLExecDirect (add privileges script)");
     453             : 
     454             :         // TODO add user procedures / functions to test SQLProcedures() and SQLProcedureColumns() more
     455             : 
     456             :         // set COMMENT ON schema, tables, columns, indexes, procedures and functions to fetch (and test) data in the REMARKS result column
     457           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *)
     458             :                 "COMMENT ON SCHEMA odbctst IS 'odbctst schema comment';\n"
     459             :                 "COMMENT ON TABLE odbctst.pk_uc IS 'odbctst.pk_uc table comment';\n"
     460             :                 "COMMENT ON TABLE odbctst.nopk_twoucs IS 'odbctst.nopk_twoucs table comment';\n"
     461             :                 "COMMENT ON COLUMN odbctst.nopk_twoucs.id2 IS 'odbctst.nopk_twoucs.id2 column comment';\n"
     462             :                 "COMMENT ON COLUMN odbctst.nopk_twoucs.name2 IS 'odbctst.nopk_twoucs.name2 column comment';\n"
     463             :                 "COMMENT ON INDEX odbctst.pk_uc_i IS 'odbctst.pk_uc_i index comment';\n"
     464             :                 "COMMENT ON INDEX odbctst.nopk_twoucs_i IS 'odbctst.nopk_twoucs_i index comment';\n"
     465             :                 "COMMENT ON PROCEDURE sys.analyze() IS 'sys.analyze() procedure comment';\n"
     466             :                 "COMMENT ON FUNCTION sys.sin(double) IS 'sys.sin(double) function comment';\n"
     467             :                 "COMMENT ON FUNCTION sys.env() IS 'sys.env() function comment';\n"
     468             :                 "COMMENT ON FUNCTION sys.statistics() IS 'sys.statistics() function comment';\n"
     469             :                 , SQL_NTS);
     470           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLExecDirect (add comments script)");
     471             : 
     472             : /* run actual metadata query tests */
     473             :         // All catalogs query. MonetDB should return no rows. Catalog qualifier not supported.
     474           1 :         ret = SQLTables(stmt, (SQLCHAR*)SQL_ALL_CATALOGS, SQL_NTS,
     475             :                         (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS,
     476             :                         (SQLCHAR*)"", SQL_NTS);
     477           1 :         compareResult(stmt, ret, "SQLTables (SQL_ALL_CATALOGS)",
     478             :                 "Resultset with 5 columns\n"
     479             :                 "Resultset with 0 rows\n"
     480             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      TABLE_TYPE      REMARKS\n"
     481             :                 "WVARCHAR(1)       WVARCHAR(1)     WVARCHAR(1)     WVARCHAR(1)     WVARCHAR(1)\n");
     482             : 
     483             :         // All schemas query. All columns except the TABLE_SCHEM column should contain NULLs.
     484           1 :         ret = SQLTables(stmt, (SQLCHAR*)"", SQL_NTS,
     485             :                         (SQLCHAR*)SQL_ALL_SCHEMAS, SQL_NTS,
     486             :                         (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS);
     487           1 :         compareResult(stmt, ret, "SQLTables (SQL_ALL_SCHEMAS)",
     488             :                 "Resultset with 5 columns\n"
     489             :                 "Resultset with 7 rows\n"
     490             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      TABLE_TYPE      REMARKS\n"
     491             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1)     WVARCHAR(1)     WVARCHAR(1)\n"
     492             :                 "NULL      information_schema      NULL    NULL    NULL\n"
     493             :                 "NULL      json    NULL    NULL    NULL\n"
     494             :                 "NULL      logging NULL    NULL    NULL\n"
     495             :                 "NULL      odbctst NULL    NULL    NULL\n"
     496             :                 "NULL      profiler        NULL    NULL    NULL\n"
     497             :                 "NULL      sys     NULL    NULL    NULL\n"
     498             :                 "NULL      tmp     NULL    NULL    NULL\n");
     499             : 
     500             :         // All table types query. All columns except the TABLE_TYPE column should contain NULLs.
     501           1 :         ret = SQLTables(stmt, (SQLCHAR*)"", SQL_NTS,
     502             :                         (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS,
     503             :                         (SQLCHAR*)SQL_ALL_TABLE_TYPES, SQL_NTS);
     504           1 :         compareResult(stmt, ret, "SQLTables (SQL_ALL_TABLE_TYPES)",
     505             :                 "Resultset with 5 columns\n"
     506             :                 "Resultset with 10 rows\n"
     507             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      TABLE_TYPE      REMARKS\n"
     508             :                 "WVARCHAR(1)       WVARCHAR(1)     WVARCHAR(1)     WVARCHAR(25)    WVARCHAR(1)\n"
     509             :                 "NULL      NULL    NULL    GLOBAL TEMPORARY TABLE  NULL\n"
     510             :                 "NULL      NULL    NULL    LOCAL TEMPORARY TABLE   NULL\n"
     511             :                 "NULL      NULL    NULL    MERGE TABLE     NULL\n"
     512             :                 "NULL      NULL    NULL    REMOTE TABLE    NULL\n"
     513             :                 "NULL      NULL    NULL    REPLICA TABLE   NULL\n"
     514             :                 "NULL      NULL    NULL    SYSTEM TABLE    NULL\n"
     515             :                 "NULL      NULL    NULL    SYSTEM VIEW     NULL\n"
     516             :                 "NULL      NULL    NULL    TABLE   NULL\n"
     517             :                 "NULL      NULL    NULL    UNLOGGED TABLE  NULL\n"
     518             :                 "NULL      NULL    NULL    VIEW    NULL\n");
     519             : 
     520             :         // All tables in schema odbctst
     521           1 :         ret = SQLTables(stmt, (SQLCHAR*)"", SQL_NTS,
     522             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"%", SQL_NTS,
     523             :                         (SQLCHAR*)"TABLE,VIEW,SYSTEM TABLE,GLOBAL TEMPORARY TABLE,LOCAL TEMPORARY TABLE,ALIAS,SYNONYM", SQL_NTS);
     524           1 :         compareResult(stmt, ret, "SQLTables (odbctst, %)",
     525             :                 "Resultset with 5 columns\n"
     526             :                 "Resultset with 7 rows\n"
     527             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      TABLE_TYPE      REMARKS\n"
     528             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(25)    WVARCHAR(65000)\n"
     529             :                 "NULL      odbctst CUSTOMERS       TABLE   NULL\n"
     530             :                 "NULL      odbctst LINES   TABLE   NULL\n"
     531             :                 "NULL      odbctst ORDERS  TABLE   NULL\n"
     532             :                 "NULL      odbctst fk2c    TABLE   NULL\n"
     533             :                 "NULL      odbctst nopk_twoucs     TABLE   odbctst.nopk_twoucs table comment\n"
     534             :                 "NULL      odbctst pk2c    TABLE   NULL\n"
     535             :                 "NULL      odbctst pk_uc   TABLE   odbctst.pk_uc table comment\n");
     536             : 
     537           1 :         ret = SQLTables(stmt, (SQLCHAR*)"", SQL_NTS,
     538             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"%", SQL_NTS,
     539             :                         (SQLCHAR*)"BASE TABLE,GLOBAL TEMPORARY,LOCAL TEMPORARY", SQL_NTS);
     540           1 :         compareResult(stmt, ret, "SQLTables (odbctst, %)",
     541             :                 "Resultset with 5 columns\n"
     542             :                 "Resultset with 7 rows\n"
     543             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      TABLE_TYPE      REMARKS\n"
     544             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(25)    WVARCHAR(65000)\n"
     545             :                 "NULL      odbctst CUSTOMERS       TABLE   NULL\n"
     546             :                 "NULL      odbctst LINES   TABLE   NULL\n"
     547             :                 "NULL      odbctst ORDERS  TABLE   NULL\n"
     548             :                 "NULL      odbctst fk2c    TABLE   NULL\n"
     549             :                 "NULL      odbctst nopk_twoucs     TABLE   odbctst.nopk_twoucs table comment\n"
     550             :                 "NULL      odbctst pk2c    TABLE   NULL\n"
     551             :                 "NULL      odbctst pk_uc   TABLE   odbctst.pk_uc table comment\n");
     552             : 
     553             :         // All user tables in schema tmp
     554           1 :         ret = SQLTables(stmt, (SQLCHAR*)"", SQL_NTS,
     555             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"%", SQL_NTS,
     556             :                         (SQLCHAR*)"'BASE TABLE','GLOBAL TEMPORARY','LOCAL TEMPORARY'", SQL_NTS);
     557           1 :         compareResult(stmt, ret, "SQLTables (tmp, %)",
     558             :                 "Resultset with 5 columns\n"
     559             :                 "Resultset with 4 rows\n"
     560             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      TABLE_TYPE      REMARKS\n"
     561             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(25)    WVARCHAR(65000)\n"
     562             :                 "NULL      tmp     glbl_nopk_twoucs        GLOBAL TEMPORARY TABLE  NULL\n"
     563             :                 "NULL      tmp     glbl_pk_uc      GLOBAL TEMPORARY TABLE  NULL\n"
     564             :                 "NULL      tmp     tmp_nopk_twoucs LOCAL TEMPORARY TABLE   NULL\n"
     565             :                 "NULL      tmp     tmp_pk_uc       LOCAL TEMPORARY TABLE   NULL\n");
     566             : 
     567             :         // All user tables and views in schema odbctst
     568           1 :         ret = SQLTables(stmt, (SQLCHAR*)"", SQL_NTS,
     569             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"%", SQL_NTS,
     570             :                         (SQLCHAR*)"'TABLE' , 'VIEW'", SQL_NTS);       // using quotes around the type names
     571           1 :         compareResult(stmt, ret, "SQLTables (odbctst, %, 'TABLE' , 'VIEW')",
     572             :                 "Resultset with 5 columns\n"
     573             :                 "Resultset with 7 rows\n"
     574             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      TABLE_TYPE      REMARKS\n"
     575             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(25)    WVARCHAR(65000)\n"
     576             :                 "NULL      odbctst CUSTOMERS       TABLE   NULL\n"
     577             :                 "NULL      odbctst LINES   TABLE   NULL\n"
     578             :                 "NULL      odbctst ORDERS  TABLE   NULL\n"
     579             :                 "NULL      odbctst fk2c    TABLE   NULL\n"
     580             :                 "NULL      odbctst nopk_twoucs     TABLE   odbctst.nopk_twoucs table comment\n"
     581             :                 "NULL      odbctst pk2c    TABLE   NULL\n"
     582             :                 "NULL      odbctst pk_uc   TABLE   odbctst.pk_uc table comment\n");
     583             : 
     584             :         // All user tables and views in all schemas
     585           1 :         ret = SQLTables(stmt, (SQLCHAR*)"", SQL_NTS,
     586             :                         (SQLCHAR*)"%", SQL_NTS, (SQLCHAR*)"%", SQL_NTS,
     587             :                         (SQLCHAR*)"TABLE, VIEW, GLOBAL TEMPORARY TABLE, LOCAL TEMPORARY TABLE", SQL_NTS);
     588           1 :         compareResult(stmt, ret, "SQLTables (%, %, TABLE, VIEW, GLOBAL TEMPORARY TABLE, LOCAL TEMPORARY TABLE)",
     589             :                 "Resultset with 5 columns\n"
     590             :                 "Resultset with 11 rows\n"
     591             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      TABLE_TYPE      REMARKS\n"
     592             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(25)    WVARCHAR(65000)\n"
     593             :                 "NULL      tmp     glbl_nopk_twoucs        GLOBAL TEMPORARY TABLE  NULL\n"
     594             :                 "NULL      tmp     glbl_pk_uc      GLOBAL TEMPORARY TABLE  NULL\n"
     595             :                 "NULL      tmp     tmp_nopk_twoucs LOCAL TEMPORARY TABLE   NULL\n"
     596             :                 "NULL      tmp     tmp_pk_uc       LOCAL TEMPORARY TABLE   NULL\n"
     597             :                 "NULL      odbctst CUSTOMERS       TABLE   NULL\n"
     598             :                 "NULL      odbctst LINES   TABLE   NULL\n"
     599             :                 "NULL      odbctst ORDERS  TABLE   NULL\n"
     600             :                 "NULL      odbctst fk2c    TABLE   NULL\n"
     601             :                 "NULL      odbctst nopk_twoucs     TABLE   odbctst.nopk_twoucs table comment\n"
     602             :                 "NULL      odbctst pk2c    TABLE   NULL\n"
     603             :                 "NULL      odbctst pk_uc   TABLE   odbctst.pk_uc table comment\n");
     604             : 
     605             :         // All columns of odbctst tables containing 'pk' in their name
     606           1 :         ret = SQLColumns(stmt, (SQLCHAR*)"", SQL_NTS,
     607             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"%pk%", SQL_NTS,
     608             :                         (SQLCHAR*)"%", SQL_NTS);
     609           1 :         compareResult(stmt, ret, "SQLColumns (odbctst, %pk%, %)",
     610             :                 "Resultset with 18 columns\n"
     611             :                 "Resultset with 7 rows\n"
     612             :                 "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"
     613             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT        SMALLINT        WVARCHAR(65000) WVARCHAR(2048)  SMALLINT        SMALLINT        INTEGER INTEGER WVARCHAR(3)\n"
     614             :                 "NULL      odbctst nopk_twoucs     id2     4       INTEGER 31      11      0       2       0       odbctst.nopk_twoucs.id2 column comment  NULL    4       NULL    NULL    1       NO\n"
     615             :                 "NULL      odbctst nopk_twoucs     name2   -9      VARCHAR 99      198     NULL    NULL    1       odbctst.nopk_twoucs.name2 column comment        NULL    -9      NULL    396     2       YES\n"
     616             :                 "NULL      odbctst pk2c    pkc1    4       INTEGER 31      11      0       2       0       NULL    NULL    4       NULL    NULL    1       NO\n"
     617             :                 "NULL      odbctst pk2c    pkc2    -9      VARCHAR 99      198     NULL    NULL    0       NULL    NULL    -9      NULL    396     2       NO\n"
     618             :                 "NULL      odbctst pk2c    name1   -9      VARCHAR 99      198     NULL    NULL    1       NULL    NULL    -9      NULL    396     3       YES\n"
     619             :                 "NULL      odbctst pk_uc   id1     4       INTEGER 31      11      0       2       0       NULL    NULL    4       NULL    NULL    1       NO\n"
     620             :                 "NULL      odbctst pk_uc   name1   -9      VARCHAR 99      198     NULL    NULL    1       NULL    NULL    -9      NULL    396     2       YES\n");
     621             : 
     622             :         // All columns of all tmp tables containing 'pk' in their name
     623           1 :         ret = SQLColumns(stmt, (SQLCHAR*)"", SQL_NTS,
     624             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"%pk%", SQL_NTS,
     625             :                         (SQLCHAR*)"%%", SQL_NTS);
     626           1 :         compareResult(stmt, ret, "SQLColumns (tmp, %pk%, %%)",
     627             :                 "Resultset with 18 columns\n"
     628             :                 "Resultset with 8 rows\n"
     629             :                 "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"
     630             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT        SMALLINT        WVARCHAR(65000) WVARCHAR(2048)  SMALLINT        SMALLINT        INTEGER INTEGER WVARCHAR(3)\n"
     631             :                 "NULL      tmp     glbl_nopk_twoucs        id2     4       INTEGER 31      11      0       2       0       NULL    NULL    4       NULL    NULL    1       NO\n"
     632             :                 "NULL      tmp     glbl_nopk_twoucs        name2   -9      VARCHAR 99      198     NULL    NULL    1       NULL    NULL    -9      NULL    396     2       YES\n"
     633             :                 "NULL      tmp     glbl_pk_uc      id1     4       INTEGER 31      11      0       2       0       NULL    NULL    4       NULL    NULL    1       NO\n"
     634             :                 "NULL      tmp     glbl_pk_uc      name1   -9      VARCHAR 99      198     NULL    NULL    1       NULL    NULL    -9      NULL    396     2       YES\n"
     635             :                 "NULL      tmp     tmp_nopk_twoucs id2     4       INTEGER 31      11      0       2       0       NULL    NULL    4       NULL    NULL    1       NO\n"
     636             :                 "NULL      tmp     tmp_nopk_twoucs name2   -9      VARCHAR 99      198     NULL    NULL    1       NULL    NULL    -9      NULL    396     2       YES\n"
     637             :                 "NULL      tmp     tmp_pk_uc       id1     4       INTEGER 31      11      0       2       0       NULL    NULL    4       NULL    NULL    1       NO\n"
     638             :                 "NULL      tmp     tmp_pk_uc       name1   -9      VARCHAR 99      198     NULL    NULL    1       NULL    NULL    -9      NULL    396     2       YES\n");
     639             : 
     640             :         // All columns of all tmp tables containing 'pk' in their name and the column matching name_ pattern
     641           1 :         ret = SQLColumns(stmt, (SQLCHAR*)"", SQL_NTS,
     642             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"%pk%", SQL_NTS,
     643             :                         (SQLCHAR*)"name_", SQL_NTS);
     644           1 :         compareResult(stmt, ret, "SQLColumns (tmp, %pk%, name_)",
     645             :                 "Resultset with 18 columns\n"
     646             :                 "Resultset with 4 rows\n"
     647             :                 "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"
     648             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT        SMALLINT        WVARCHAR(65000) WVARCHAR(2048)  SMALLINT        SMALLINT        INTEGER INTEGER WVARCHAR(3)\n"
     649             :                 "NULL      tmp     glbl_nopk_twoucs        name2   -9      VARCHAR 99      198     NULL    NULL    1       NULL    NULL    -9      NULL    396     2       YES\n"
     650             :                 "NULL      tmp     glbl_pk_uc      name1   -9      VARCHAR 99      198     NULL    NULL    1       NULL    NULL    -9      NULL    396     2       YES\n"
     651             :                 "NULL      tmp     tmp_nopk_twoucs name2   -9      VARCHAR 99      198     NULL    NULL    1       NULL    NULL    -9      NULL    396     2       YES\n"
     652             :                 "NULL      tmp     tmp_pk_uc       name1   -9      VARCHAR 99      198     NULL    NULL    1       NULL    NULL    -9      NULL    396     2       YES\n");
     653             : 
     654           1 :         ret = SQLSpecialColumns(stmt, SQL_ROWVER, (SQLCHAR*)NULL, 0,
     655             :                         (SQLCHAR*)"%", SQL_NTS, (SQLCHAR*)"%", SQL_NTS,
     656             :                         SQL_SCOPE_SESSION, SQL_NO_NULLS);
     657           1 :         compareResult(stmt, ret, "SQLSpecialColumns (%, %, SQL_ROWVER)",
     658             :                 "Resultset with 8 columns\n"
     659             :                 "Resultset with 0 rows\n"
     660             :                 "SCOPE     COLUMN_NAME     DATA_TYPE       TYPE_NAME       COLUMN_SIZE     BUFFER_LENGTH   DECIMAL_DIGITS  PSEUDO_COLUMN\n"
     661             :                 "SMALLINT  WVARCHAR(1)     SMALLINT        WVARCHAR(4)     INTEGER INTEGER SMALLINT        SMALLINT\n");
     662             : 
     663             :         // sys.table_types
     664           1 :         ret = SQLPrimaryKeys(stmt, (SQLCHAR*)"", SQL_NTS,
     665             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"table_types", SQL_NTS);
     666           1 :         compareResult(stmt, ret, "SQLPrimaryKeys (sys, table_types)",
     667             :                 "Resultset with 6 columns\n"
     668             :                 "Resultset with 1 rows\n"
     669             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     KEY_SEQ PK_NAME\n"
     670             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1024)\n"
     671             :                 "NULL      sys     table_types     table_type_id   1       table_types_table_type_id_pkey\n");
     672             : 
     673           1 :         ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
     674             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"table_types", SQL_NTS,
     675             :                         SQL_SCOPE_SESSION, SQL_NO_NULLS);
     676           1 :         compareResult(stmt, ret, "SQLSpecialColumns (sys, table_types)",
     677             :                 "Resultset with 8 columns\n"
     678             :                 "Resultset with 1 rows\n"
     679             :                 "SCOPE     COLUMN_NAME     DATA_TYPE       TYPE_NAME       COLUMN_SIZE     BUFFER_LENGTH   DECIMAL_DIGITS  PSEUDO_COLUMN\n"
     680             :                 "SMALLINT  WVARCHAR(1024)  SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT\n"
     681             :                 "1 table_type_id   5       SMALLINT        15      6       0       1\n");
     682             : 
     683           1 :         ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
     684             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"table_types", SQL_NTS,
     685             :                         SQL_INDEX_UNIQUE, SQL_ENSURE);
     686           1 :         compareResult(stmt, ret, "SQLStatistics (sys, table_types, SQL_INDEX_UNIQUE, SQL_ENSURE)",
     687             :                 "Resultset with 13 columns\n"
     688             :                 "Resultset with 2 rows\n"
     689             :                 "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"
     690             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1)     WVARCHAR(1024)  SMALLINT        SMALLINT        WVARCHAR(1024)  WCHAR(1)        INTEGER INTEGER WVARCHAR(1)\n"
     691             :                 "NULL      sys     table_types     0       NULL    table_types_table_type_id_pkey  2       1       table_type_id   NULL    10      NULL    NULL\n"
     692             :                 "NULL      sys     table_types     0       NULL    table_types_table_type_name_unique      2       1       table_type_name NULL    10      NULL    NULL\n");
     693             : 
     694           1 :         ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
     695             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"table_types", SQL_NTS,
     696             :                         SQL_INDEX_ALL, SQL_QUICK);
     697           1 :         compareResult(stmt, ret, "SQLStatistics (sys, table_types, SQL_INDEX_ALL, SQL_QUICK)",
     698             :                 "Resultset with 13 columns\n"
     699             :                 "Resultset with 2 rows\n"
     700             :                 "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"
     701             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1)     WVARCHAR(1024)  SMALLINT        SMALLINT        WVARCHAR(1024)  WCHAR(1)        INTEGER INTEGER WVARCHAR(1)\n"
     702             :                 "NULL      sys     table_types     0       NULL    table_types_table_type_id_pkey  2       1       table_type_id   NULL    10      NULL    NULL\n"
     703             :                 "NULL      sys     table_types     0       NULL    table_types_table_type_name_unique      2       1       table_type_name NULL    10      NULL    NULL\n");
     704             : 
     705           1 :         ret = SQLTablePrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
     706             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"table_types", SQL_NTS);
     707           1 :         compareResult(stmt, ret, "SQLTablePrivileges (sys, table_types)",
     708             :                 "Resultset with 7 columns\n"
     709             :                 "Resultset with 0 rows\n"
     710             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
     711             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n");
     712             : 
     713           1 :         ret = SQLColumnPrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
     714             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"table_types", SQL_NTS,
     715             :                         (SQLCHAR*)"%", SQL_NTS);
     716           1 :         compareResult(stmt, ret, "SQLColumnPrivileges (sys, table_types, %)",
     717             :                 "Resultset with 8 columns\n"
     718             :                 "Resultset with 0 rows\n"
     719             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
     720             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n");
     721             : 
     722             :         // odbctst.pk_uc
     723           1 :         ret = SQLPrimaryKeys(stmt, (SQLCHAR*)"", SQL_NTS,
     724             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk_uc", SQL_NTS);
     725           1 :         compareResult(stmt, ret, "SQLPrimaryKeys (odbctst, pk_uc)",
     726             :                 "Resultset with 6 columns\n"
     727             :                 "Resultset with 1 rows\n"
     728             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     KEY_SEQ PK_NAME\n"
     729             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1024)\n"
     730             :                 "NULL      odbctst pk_uc   id1     1       pk_uc_id1_pkey\n");
     731             : 
     732           1 :         ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
     733             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk_uc", SQL_NTS,
     734             :                         SQL_SCOPE_SESSION, SQL_NO_NULLS);
     735           1 :         compareResult(stmt, ret, "SQLSpecialColumns (odbctst, pk_uc, SQL_BEST_ROWID)",
     736             :                 "Resultset with 8 columns\n"
     737             :                 "Resultset with 1 rows\n"
     738             :                 "SCOPE     COLUMN_NAME     DATA_TYPE       TYPE_NAME       COLUMN_SIZE     BUFFER_LENGTH   DECIMAL_DIGITS  PSEUDO_COLUMN\n"
     739             :                 "SMALLINT  WVARCHAR(1024)  SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT\n"
     740             :                 "1 id1     4       INTEGER 31      11      0       1\n");
     741             : 
     742           1 :         ret = SQLSpecialColumns(stmt, SQL_ROWVER, (SQLCHAR*)"", SQL_NTS,
     743             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk_uc", SQL_NTS,
     744             :                         SQL_SCOPE_SESSION, SQL_NO_NULLS);
     745           1 :         compareResult(stmt, ret, "SQLSpecialColumns (odbctst, pk_uc, SQL_ROWVER)",
     746             :                 "Resultset with 8 columns\n"
     747             :                 "Resultset with 0 rows\n"
     748             :                 "SCOPE     COLUMN_NAME     DATA_TYPE       TYPE_NAME       COLUMN_SIZE     BUFFER_LENGTH   DECIMAL_DIGITS  PSEUDO_COLUMN\n"
     749             :                 "SMALLINT  WVARCHAR(1)     SMALLINT        WVARCHAR(4)     INTEGER INTEGER SMALLINT        SMALLINT\n");
     750             : 
     751           1 :         ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
     752             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk_uc", SQL_NTS,
     753             :                         SQL_INDEX_UNIQUE, SQL_ENSURE);
     754           1 :         compareResult(stmt, ret, "SQLStatistics (odbctst, pk_uc, SQL_INDEX_UNIQUE, SQL_ENSURE)",
     755             :                 "Resultset with 13 columns\n"
     756             :                 "Resultset with 2 rows\n"
     757             :                 "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"
     758             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1)     WVARCHAR(1024)  SMALLINT        SMALLINT        WVARCHAR(1024)  WCHAR(1)        INTEGER INTEGER WVARCHAR(1)\n"
     759             :                 "NULL      odbctst pk_uc   0       NULL    pk_uc_id1_pkey  2       1       id1     NULL    0       NULL    NULL\n"
     760             :                 "NULL      odbctst pk_uc   0       NULL    pk_uc_name1_unique      2       1       name1   NULL    0       NULL    NULL\n");
     761             : 
     762           1 :         ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
     763             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk_uc", SQL_NTS,
     764             :                         SQL_INDEX_ALL, SQL_QUICK);
     765           1 :         compareResult(stmt, ret, "SQLStatistics (odbctst, pk_uc, SQL_INDEX_ALL, SQL_QUICK)",
     766             :                 "Resultset with 13 columns\n"
     767             :                 "Resultset with 4 rows\n"
     768             :                 "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"
     769             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1)     WVARCHAR(1024)  SMALLINT        SMALLINT        WVARCHAR(1024)  WCHAR(1)        INTEGER INTEGER WVARCHAR(1)\n"
     770             :                 "NULL      odbctst pk_uc   0       NULL    pk_uc_id1_pkey  2       1       id1     NULL    0       NULL    NULL\n"
     771             :                 "NULL      odbctst pk_uc   0       NULL    pk_uc_name1_unique      2       1       name1   NULL    0       NULL    NULL\n"
     772             :                 "NULL      odbctst pk_uc   1       NULL    pk_uc_i 2       1       id1     NULL    NULL    NULL    NULL\n"
     773             :                 "NULL      odbctst pk_uc   1       NULL    pk_uc_i 2       2       name1   NULL    NULL    NULL    NULL\n");
     774             : 
     775           1 :         ret = SQLTablePrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
     776             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk_uc", SQL_NTS);
     777           1 :         compareResult(stmt, ret, "SQLTablePrivileges (odbctst, pk_uc)",
     778             :                 "Resultset with 7 columns\n"
     779             :                 "Resultset with 4 rows\n"
     780             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
     781             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n"
     782             :                 "NULL      odbctst pk_uc   _SYSTEM monetdb DELETE  NO\n"
     783             :                 "NULL      odbctst pk_uc   _SYSTEM monetdb INSERT  NO\n"
     784             :                 "NULL      odbctst pk_uc   monetdb PUBLIC  SELECT  NO\n"
     785             :                 "NULL      odbctst pk_uc   _SYSTEM monetdb UPDATE  NO\n");
     786             : 
     787           1 :         ret = SQLColumnPrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
     788             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk_uc", SQL_NTS,
     789             :                         (SQLCHAR*)"%1", SQL_NTS);
     790           1 :         compareResult(stmt, ret, "SQLColumnPrivileges (odbctst, pk_uc, %1)",
     791             :                 "Resultset with 8 columns\n"
     792             :                 "Resultset with 0 rows\n"
     793             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
     794             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n");
     795             : 
     796             :         // tmp.tmp_pk_uc
     797           1 :         ret = SQLPrimaryKeys(stmt, (SQLCHAR*)"", SQL_NTS,
     798             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"tmp_pk_uc", SQL_NTS);
     799           1 :         compareResult(stmt, ret, "SQLPrimaryKeys (tmp, tmp_pk_uc)",
     800             :                 "Resultset with 6 columns\n"
     801             :                 "Resultset with 1 rows\n"
     802             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     KEY_SEQ PK_NAME\n"
     803             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1024)\n"
     804             :                 "NULL      tmp     tmp_pk_uc       id1     1       tmp_pk_uc_id1_pkey\n");
     805             : 
     806           1 :         ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
     807             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"tmp_pk_uc", SQL_NTS,
     808             :                         SQL_SCOPE_SESSION, SQL_NO_NULLS);
     809           1 :         compareResult(stmt, ret, "SQLSpecialColumns (tmp, tmp_pk_uc)",
     810             :                 "Resultset with 8 columns\n"
     811             :                 "Resultset with 1 rows\n"
     812             :                 "SCOPE     COLUMN_NAME     DATA_TYPE       TYPE_NAME       COLUMN_SIZE     BUFFER_LENGTH   DECIMAL_DIGITS  PSEUDO_COLUMN\n"
     813             :                 "SMALLINT  WVARCHAR(1024)  SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT\n"
     814             :                 "1 id1     4       INTEGER 31      11      0       1\n");
     815             : 
     816           1 :         ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
     817             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"tmp_pk_uc", SQL_NTS,
     818             :                         SQL_INDEX_UNIQUE, SQL_ENSURE);
     819           1 :         compareResult(stmt, ret, "SQLStatistics (tmp, tmp_pk_uc, SQL_INDEX_UNIQUE, SQL_ENSURE)",
     820             :                 "Resultset with 13 columns\n"
     821             :                 "Resultset with 2 rows\n"
     822             :                 "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"
     823             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1)     WVARCHAR(1024)  SMALLINT        SMALLINT        WVARCHAR(1024)  WCHAR(1)        INTEGER INTEGER WVARCHAR(1)\n"
     824             :                 "NULL      tmp     tmp_pk_uc       0       NULL    tmp_pk_uc_id1_pkey      2       1       id1     NULL    NULL    NULL    NULL\n"
     825             :                 "NULL      tmp     tmp_pk_uc       0       NULL    tmp_pk_uc_name1_unique  2       1       name1   NULL    NULL    NULL    NULL\n");
     826             : 
     827           1 :         ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
     828             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"tmp_pk_uc", SQL_NTS,
     829             :                         SQL_INDEX_ALL, SQL_QUICK);
     830           1 :         compareResult(stmt, ret, "SQLStatistics (tmp, tmp_pk_uc, SQL_INDEX_ALL, SQL_QUICK)",
     831             :                 "Resultset with 13 columns\n"
     832             :                 "Resultset with 4 rows\n"
     833             :                 "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"
     834             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1)     WVARCHAR(1024)  SMALLINT        SMALLINT        WVARCHAR(1024)  WCHAR(1)        INTEGER INTEGER WVARCHAR(1)\n"
     835             :                 "NULL      tmp     tmp_pk_uc       0       NULL    tmp_pk_uc_id1_pkey      2       1       id1     NULL    NULL    NULL    NULL\n"
     836             :                 "NULL      tmp     tmp_pk_uc       0       NULL    tmp_pk_uc_name1_unique  2       1       name1   NULL    NULL    NULL    NULL\n"
     837             :                 "NULL      tmp     tmp_pk_uc       1       NULL    tmp_pk_uc_i     2       1       id1     NULL    NULL    NULL    NULL\n"
     838             :                 "NULL      tmp     tmp_pk_uc       1       NULL    tmp_pk_uc_i     2       2       name1   NULL    NULL    NULL    NULL\n");
     839             : 
     840           1 :         ret = SQLTablePrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
     841             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"tmp_pk_uc", SQL_NTS);
     842           1 :         compareResult(stmt, ret, "SQLTablePrivileges (tmp, tmp_pk_uc)",
     843             :                 "Resultset with 7 columns\n"
     844             :                 "Resultset with 2 rows\n"
     845             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
     846             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n"
     847             :                 "NULL      tmp     tmp_pk_uc       _SYSTEM monetdb DELETE  NO\n"
     848             :                 "NULL      tmp     tmp_pk_uc       _SYSTEM monetdb INSERT  NO\n");
     849             : 
     850           1 :         ret = SQLColumnPrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
     851             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"tmp_pk_uc", SQL_NTS,
     852             :                         (SQLCHAR*)"%1", SQL_NTS);
     853           1 :         compareResult(stmt, ret, "SQLColumnPrivileges (tmp, tmp_pk_uc, %1)",
     854             :                 "Resultset with 8 columns\n"
     855             :                 "Resultset with 3 rows\n"
     856             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
     857             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n"
     858             :                 "NULL      tmp     tmp_pk_uc       id1     _SYSTEM monetdb SELECT  NO\n"
     859             :                 "NULL      tmp     tmp_pk_uc       name1   _SYSTEM monetdb SELECT  NO\n"
     860             :                 "NULL      tmp     tmp_pk_uc       name1   _SYSTEM monetdb UPDATE  NO\n");
     861             : 
     862             :         // tmp.glbl_pk_uc
     863           1 :         ret = SQLPrimaryKeys(stmt, (SQLCHAR*)"", SQL_NTS,
     864             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"glbl_pk_uc", SQL_NTS);
     865           1 :         compareResult(stmt, ret, "SQLPrimaryKeys (tmp, glbl_pk_uc)",
     866             :                 "Resultset with 6 columns\n"
     867             :                 "Resultset with 1 rows\n"
     868             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     KEY_SEQ PK_NAME\n"
     869             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1024)\n"
     870             :                 "NULL      tmp     glbl_pk_uc      id1     1       glbl_pk_uc_id1_pkey\n");
     871             : 
     872           1 :         ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
     873             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"glbl_pk_uc", SQL_NTS,
     874             :                         SQL_SCOPE_SESSION, SQL_NO_NULLS);
     875           1 :         compareResult(stmt, ret, "SQLSpecialColumns (tmp, glbl_pk_uc)",
     876             :                 "Resultset with 8 columns\n"
     877             :                 "Resultset with 1 rows\n"
     878             :                 "SCOPE     COLUMN_NAME     DATA_TYPE       TYPE_NAME       COLUMN_SIZE     BUFFER_LENGTH   DECIMAL_DIGITS  PSEUDO_COLUMN\n"
     879             :                 "SMALLINT  WVARCHAR(1024)  SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT\n"
     880             :                 "1 id1     4       INTEGER 31      11      0       1\n");
     881             : 
     882           1 :         ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
     883             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"glbl_pk_uc", SQL_NTS,
     884             :                         SQL_INDEX_UNIQUE, SQL_ENSURE);
     885           1 :         compareResult(stmt, ret, "SQLStatistics (tmp, glbl_pk_uc, SQL_INDEX_UNIQUE, SQL_ENSURE)",
     886             :                 "Resultset with 13 columns\n"
     887             :                 "Resultset with 2 rows\n"
     888             :                 "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"
     889             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1)     WVARCHAR(1024)  SMALLINT        SMALLINT        WVARCHAR(1024)  WCHAR(1)        INTEGER INTEGER WVARCHAR(1)\n"
     890             :                 "NULL      tmp     glbl_pk_uc      0       NULL    glbl_pk_uc_id1_pkey     2       1       id1     NULL    0       NULL    NULL\n"
     891             :                 "NULL      tmp     glbl_pk_uc      0       NULL    glbl_pk_uc_name1_unique 2       1       name1   NULL    0       NULL    NULL\n");
     892             : 
     893           1 :         ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
     894             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"glbl_pk_uc", SQL_NTS,
     895             :                         SQL_INDEX_ALL, SQL_QUICK);
     896           1 :         compareResult(stmt, ret, "SQLStatistics (tmp, glbl_pk_uc, SQL_INDEX_ALL, SQL_QUICK)",
     897             :                 "Resultset with 13 columns\n"
     898             :                 "Resultset with 4 rows\n"
     899             :                 "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"
     900             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1)     WVARCHAR(1024)  SMALLINT        SMALLINT        WVARCHAR(1024)  WCHAR(1)        INTEGER INTEGER WVARCHAR(1)\n"
     901             :                 "NULL      tmp     glbl_pk_uc      0       NULL    glbl_pk_uc_id1_pkey     2       1       id1     NULL    0       NULL    NULL\n"
     902             :                 "NULL      tmp     glbl_pk_uc      0       NULL    glbl_pk_uc_name1_unique 2       1       name1   NULL    0       NULL    NULL\n"
     903             :                 "NULL      tmp     glbl_pk_uc      1       NULL    glbl_pk_uc_i    2       1       id1     NULL    NULL    NULL    NULL\n"
     904             :                 "NULL      tmp     glbl_pk_uc      1       NULL    glbl_pk_uc_i    2       2       name1   NULL    NULL    NULL    NULL\n");
     905             : 
     906           1 :         ret = SQLTablePrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
     907             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"glbl_pk_uc", SQL_NTS);
     908           1 :         compareResult(stmt, ret, "SQLTablePrivileges (tmp, glbl_pk_uc)",
     909             :                 "Resultset with 7 columns\n"
     910             :                 "Resultset with 2 rows\n"
     911             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
     912             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n"
     913             :                 "NULL      tmp     glbl_pk_uc      _SYSTEM monetdb DELETE  NO\n"
     914             :                 "NULL      tmp     glbl_pk_uc      _SYSTEM monetdb INSERT  NO\n");
     915             : 
     916           1 :         ret = SQLColumnPrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
     917             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"glbl_pk_uc", SQL_NTS,
     918             :                         (SQLCHAR*)"%1", SQL_NTS);
     919           1 :         compareResult(stmt, ret, "SQLColumnPrivileges (tmp, glbl_pk_uc, %1)",
     920             :                 "Resultset with 8 columns\n"
     921             :                 "Resultset with 3 rows\n"
     922             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
     923             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n"
     924             :                 "NULL      tmp     glbl_pk_uc      id1     _SYSTEM monetdb SELECT  NO\n"
     925             :                 "NULL      tmp     glbl_pk_uc      name1   _SYSTEM monetdb SELECT  NO\n"
     926             :                 "NULL      tmp     glbl_pk_uc      name1   _SYSTEM monetdb UPDATE  NO\n");
     927             : 
     928             :         // odbctst.nopk_twoucs
     929           1 :         ret = SQLPrimaryKeys(stmt, (SQLCHAR*)"", SQL_NTS,
     930             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"nopk_twoucs", SQL_NTS);
     931           1 :         compareResult(stmt, ret, "SQLPrimaryKeys (odbctst, nopk_twoucs)",
     932             :                 "Resultset with 6 columns\n"
     933             :                 "Resultset with 0 rows\n"
     934             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     KEY_SEQ PK_NAME\n"
     935             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1024)\n");
     936             : 
     937           1 :         ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
     938             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"nopk_twoucs", SQL_NTS,
     939             :                         SQL_SCOPE_SESSION, SQL_NO_NULLS);
     940           1 :         compareResult(stmt, ret, "SQLSpecialColumns (odbctst, nopk_twoucs)",
     941             :                 "Resultset with 8 columns\n"
     942             :                 "Resultset with 1 rows\n"
     943             :                 "SCOPE     COLUMN_NAME     DATA_TYPE       TYPE_NAME       COLUMN_SIZE     BUFFER_LENGTH   DECIMAL_DIGITS  PSEUDO_COLUMN\n"
     944             :                 "SMALLINT  WVARCHAR(1024)  SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT\n"
     945             :                 "1 id2     4       INTEGER 31      11      0       1\n");
     946             : 
     947           1 :         ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
     948             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"nopk_twoucs", SQL_NTS,
     949             :                         SQL_INDEX_UNIQUE, SQL_ENSURE);
     950           1 :         compareResult(stmt, ret, "SQLStatistics (odbctst, nopk_twoucs, SQL_INDEX_UNIQUE, SQL_ENSURE)",
     951             :                 "Resultset with 13 columns\n"
     952             :                 "Resultset with 2 rows\n"
     953             :                 "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"
     954             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1)     WVARCHAR(1024)  SMALLINT        SMALLINT        WVARCHAR(1024)  WCHAR(1)        INTEGER INTEGER WVARCHAR(1)\n"
     955             :                 "NULL      odbctst nopk_twoucs     0       NULL    nopk_twoucs_id2_unique  2       1       id2     NULL    0       NULL    NULL\n"
     956             :                 "NULL      odbctst nopk_twoucs     0       NULL    nopk_twoucs_name2_unique        2       1       name2   NULL    0       NULL    NULL\n");
     957             : 
     958           1 :         ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
     959             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"nopk_twoucs", SQL_NTS,
     960             :                         SQL_INDEX_ALL, SQL_QUICK);
     961           1 :         compareResult(stmt, ret, "SQLStatistics (odbctst, nopk_twoucs, SQL_INDEX_ALL, SQL_QUICK)",
     962             :                 "Resultset with 13 columns\n"
     963             :                 "Resultset with 4 rows\n"
     964             :                 "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"
     965             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1)     WVARCHAR(1024)  SMALLINT        SMALLINT        WVARCHAR(1024)  WCHAR(1)        INTEGER INTEGER WVARCHAR(1)\n"
     966             :                 "NULL      odbctst nopk_twoucs     0       NULL    nopk_twoucs_id2_unique  2       1       id2     NULL    0       NULL    NULL\n"
     967             :                 "NULL      odbctst nopk_twoucs     0       NULL    nopk_twoucs_name2_unique        2       1       name2   NULL    0       NULL    NULL\n"
     968             :                 "NULL      odbctst nopk_twoucs     1       NULL    nopk_twoucs_i   2       1       id2     NULL    NULL    NULL    NULL\n"
     969             :                 "NULL      odbctst nopk_twoucs     1       NULL    nopk_twoucs_i   2       2       name2   NULL    NULL    NULL    NULL\n");
     970             : 
     971           1 :         ret = SQLTablePrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
     972             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"nopk_twoucs", SQL_NTS);
     973           1 :         compareResult(stmt, ret, "SQLTablePrivileges (odbctst, nopk_twoucs)",
     974             :                 "Resultset with 7 columns\n"
     975             :                 "Resultset with 0 rows\n"
     976             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
     977             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n");
     978             : 
     979           1 :         ret = SQLColumnPrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
     980             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"nopk_twoucs", SQL_NTS,
     981             :                         (SQLCHAR*)"%2", SQL_NTS);
     982           1 :         compareResult(stmt, ret, "SQLColumnPrivileges (odbctst, nopk_twoucs, %2)",
     983             :                 "Resultset with 8 columns\n"
     984             :                 "Resultset with 3 rows\n"
     985             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
     986             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n"
     987             :                 "NULL      odbctst nopk_twoucs     id2     _SYSTEM monetdb SELECT  NO\n"
     988             :                 "NULL      odbctst nopk_twoucs     name2   _SYSTEM monetdb SELECT  NO\n"
     989             :                 "NULL      odbctst nopk_twoucs     name2   _SYSTEM monetdb UPDATE  NO\n");
     990             : 
     991             :         // tmp.tmp_nopk_twoucs
     992           1 :         ret = SQLPrimaryKeys(stmt, (SQLCHAR*)"", SQL_NTS,
     993             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"tmp_nopk_twoucs", SQL_NTS);
     994           1 :         compareResult(stmt, ret, "SQLPrimaryKeys (tmp, tmp_nopk_twoucs)",
     995             :                 "Resultset with 6 columns\n"
     996             :                 "Resultset with 0 rows\n"
     997             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     KEY_SEQ PK_NAME\n"
     998             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1024)\n");
     999             : 
    1000           1 :         ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
    1001             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"tmp_nopk_twoucs", SQL_NTS,
    1002             :                         SQL_SCOPE_SESSION, SQL_NO_NULLS);
    1003           1 :         compareResult(stmt, ret, "SQLSpecialColumns (tmp, tmp_nopk_twoucs)",
    1004             :                 "Resultset with 8 columns\n"
    1005             :                 "Resultset with 1 rows\n"
    1006             :                 "SCOPE     COLUMN_NAME     DATA_TYPE       TYPE_NAME       COLUMN_SIZE     BUFFER_LENGTH   DECIMAL_DIGITS  PSEUDO_COLUMN\n"
    1007             :                 "SMALLINT  WVARCHAR(1024)  SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT\n"
    1008             :                 "1 id2     4       INTEGER 31      11      0       1\n");
    1009             : 
    1010           1 :         ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
    1011             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"tmp_nopk_twoucs", SQL_NTS,
    1012             :                         SQL_INDEX_UNIQUE, SQL_ENSURE);
    1013           1 :         compareResult(stmt, ret, "SQLStatistics (tmp, tmp_nopk_twoucs, SQL_INDEX_UNIQUE, SQL_ENSURE)",
    1014             :                 "Resultset with 13 columns\n"
    1015             :                 "Resultset with 2 rows\n"
    1016             :                 "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"
    1017             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1)     WVARCHAR(1024)  SMALLINT        SMALLINT        WVARCHAR(1024)  WCHAR(1)        INTEGER INTEGER WVARCHAR(1)\n"
    1018             :                 "NULL      tmp     tmp_nopk_twoucs 0       NULL    tmp_nopk_twoucs_id2_unique      2       1       id2     NULL    NULL    NULL    NULL\n"
    1019             :                 "NULL      tmp     tmp_nopk_twoucs 0       NULL    tmp_nopk_twoucs_name2_unique    2       1       name2   NULL    NULL    NULL    NULL\n");
    1020             : 
    1021           1 :         ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
    1022             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"tmp_nopk_twoucs", SQL_NTS,
    1023             :                         SQL_INDEX_ALL, SQL_QUICK);
    1024           1 :         compareResult(stmt, ret, "SQLStatistics (tmp, tmp_nopk_twoucs, SQL_INDEX_ALL, SQL_QUICK)",
    1025             :                 "Resultset with 13 columns\n"
    1026             :                 "Resultset with 4 rows\n"
    1027             :                 "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"
    1028             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1)     WVARCHAR(1024)  SMALLINT        SMALLINT        WVARCHAR(1024)  WCHAR(1)        INTEGER INTEGER WVARCHAR(1)\n"
    1029             :                 "NULL      tmp     tmp_nopk_twoucs 0       NULL    tmp_nopk_twoucs_id2_unique      2       1       id2     NULL    NULL    NULL    NULL\n"
    1030             :                 "NULL      tmp     tmp_nopk_twoucs 0       NULL    tmp_nopk_twoucs_name2_unique    2       1       name2   NULL    NULL    NULL    NULL\n"
    1031             :                 "NULL      tmp     tmp_nopk_twoucs 1       NULL    tmp_nopk_twoucs_i       2       1       id2     NULL    NULL    NULL    NULL\n"
    1032             :                 "NULL      tmp     tmp_nopk_twoucs 1       NULL    tmp_nopk_twoucs_i       2       2       name2   NULL    NULL    NULL    NULL\n");
    1033             : 
    1034           1 :         ret = SQLTablePrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
    1035             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"tmp_nopk_twoucs", SQL_NTS);
    1036           1 :         compareResult(stmt, ret, "SQLTablePrivileges (tmp, tmp_nopk_twoucs)",
    1037             :                 "Resultset with 7 columns\n"
    1038             :                 "Resultset with 2 rows\n"
    1039             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
    1040             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n"
    1041             :                 "NULL      tmp     tmp_nopk_twoucs _SYSTEM monetdb DELETE  NO\n"
    1042             :                 "NULL      tmp     tmp_nopk_twoucs _SYSTEM monetdb INSERT  NO\n");
    1043             : 
    1044           1 :         ret = SQLColumnPrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
    1045             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"tmp_nopk_twoucs", SQL_NTS,
    1046             :                         (SQLCHAR*)"%2", SQL_NTS);
    1047           1 :         compareResult(stmt, ret, "SQLColumnPrivileges (tmp, tmp_nopk_twoucs, %2)",
    1048             :                 "Resultset with 8 columns\n"
    1049             :                 "Resultset with 3 rows\n"
    1050             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
    1051             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n"
    1052             :                 "NULL      tmp     tmp_nopk_twoucs id2     _SYSTEM monetdb SELECT  NO\n"
    1053             :                 "NULL      tmp     tmp_nopk_twoucs name2   _SYSTEM monetdb SELECT  NO\n"
    1054             :                 "NULL      tmp     tmp_nopk_twoucs name2   _SYSTEM monetdb UPDATE  NO\n");
    1055             : 
    1056             :         // tmp.glbl_nopk_twoucs
    1057           1 :         ret = SQLPrimaryKeys(stmt, (SQLCHAR*)"", SQL_NTS,
    1058             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"glbl_nopk_twoucs", SQL_NTS);
    1059           1 :         compareResult(stmt, ret, "SQLPrimaryKeys (tmp, glbl_nopk_twoucs)",
    1060             :                 "Resultset with 6 columns\n"
    1061             :                 "Resultset with 0 rows\n"
    1062             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     KEY_SEQ PK_NAME\n"
    1063             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1024)\n");
    1064             : 
    1065           1 :         ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
    1066             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"glbl_nopk_twoucs", SQL_NTS,
    1067             :                         SQL_SCOPE_SESSION, SQL_NO_NULLS);
    1068           1 :         compareResult(stmt, ret, "SQLSpecialColumns (tmp, glbl_nopk_twoucs)",
    1069             :                 "Resultset with 8 columns\n"
    1070             :                 "Resultset with 1 rows\n"
    1071             :                 "SCOPE     COLUMN_NAME     DATA_TYPE       TYPE_NAME       COLUMN_SIZE     BUFFER_LENGTH   DECIMAL_DIGITS  PSEUDO_COLUMN\n"
    1072             :                 "SMALLINT  WVARCHAR(1024)  SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT\n"
    1073             :                 "1 id2     4       INTEGER 31      11      0       1\n");
    1074             : 
    1075           1 :         ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
    1076             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"glbl_nopk_twoucs", SQL_NTS,
    1077             :                         SQL_INDEX_UNIQUE, SQL_ENSURE);
    1078           1 :         compareResult(stmt, ret, "SQLStatistics (tmp, glbl_nopk_twoucs, SQL_INDEX_UNIQUE, SQL_ENSURE)",
    1079             :                 "Resultset with 13 columns\n"
    1080             :                 "Resultset with 2 rows\n"
    1081             :                 "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"
    1082             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1)     WVARCHAR(1024)  SMALLINT        SMALLINT        WVARCHAR(1024)  WCHAR(1)        INTEGER INTEGER WVARCHAR(1)\n"
    1083             :                 "NULL      tmp     glbl_nopk_twoucs        0       NULL    glbl_nopk_twoucs_id2_unique     2       1       id2     NULL    0       NULL    NULL\n"
    1084             :                 "NULL      tmp     glbl_nopk_twoucs        0       NULL    glbl_nopk_twoucs_name2_unique   2       1       name2   NULL    0       NULL    NULL\n");
    1085             : 
    1086           1 :         ret = SQLStatistics(stmt, (SQLCHAR*)"", SQL_NTS,
    1087             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"glbl_nopk_twoucs", SQL_NTS,
    1088             :                         SQL_INDEX_ALL, SQL_QUICK);
    1089           1 :         compareResult(stmt, ret, "SQLStatistics (tmp, glbl_nopk_twoucs, SQL_INDEX_ALL, SQL_QUICK)",
    1090             :                 "Resultset with 13 columns\n"
    1091             :                 "Resultset with 4 rows\n"
    1092             :                 "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"
    1093             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1)     WVARCHAR(1024)  SMALLINT        SMALLINT        WVARCHAR(1024)  WCHAR(1)        INTEGER INTEGER WVARCHAR(1)\n"
    1094             :                 "NULL      tmp     glbl_nopk_twoucs        0       NULL    glbl_nopk_twoucs_id2_unique     2       1       id2     NULL    0       NULL    NULL\n"
    1095             :                 "NULL      tmp     glbl_nopk_twoucs        0       NULL    glbl_nopk_twoucs_name2_unique   2       1       name2   NULL    0       NULL    NULL\n"
    1096             :                 "NULL      tmp     glbl_nopk_twoucs        1       NULL    glbl_nopk_twoucs_i      2       1       id2     NULL    NULL    NULL    NULL\n"
    1097             :                 "NULL      tmp     glbl_nopk_twoucs        1       NULL    glbl_nopk_twoucs_i      2       2       name2   NULL    NULL    NULL    NULL\n");
    1098             : 
    1099           1 :         ret = SQLTablePrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
    1100             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"glbl_nopk_twoucs", SQL_NTS);
    1101           1 :         compareResult(stmt, ret, "SQLTablePrivileges (tmp, glbl_nopk_twoucs)",
    1102             :                 "Resultset with 7 columns\n"
    1103             :                 "Resultset with 2 rows\n"
    1104             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
    1105             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n"
    1106             :                 "NULL      tmp     glbl_nopk_twoucs        _SYSTEM monetdb DELETE  NO\n"
    1107             :                 "NULL      tmp     glbl_nopk_twoucs        _SYSTEM monetdb INSERT  NO\n");
    1108             : 
    1109           1 :         ret = SQLColumnPrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
    1110             :                         (SQLCHAR*)"tmp", SQL_NTS, (SQLCHAR*)"glbl_nopk_twoucs", SQL_NTS,
    1111             :                         (SQLCHAR*)"%2", SQL_NTS);
    1112           1 :         compareResult(stmt, ret, "SQLColumnPrivileges (tmp, glbl_nopk_twoucs, %2)",
    1113             :                 "Resultset with 8 columns\n"
    1114             :                 "Resultset with 3 rows\n"
    1115             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
    1116             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n"
    1117             :                 "NULL      tmp     glbl_nopk_twoucs        id2     _SYSTEM monetdb SELECT  NO\n"
    1118             :                 "NULL      tmp     glbl_nopk_twoucs        name2   _SYSTEM monetdb SELECT  NO\n"
    1119             :                 "NULL      tmp     glbl_nopk_twoucs        name2   _SYSTEM monetdb UPDATE  NO\n");
    1120             : 
    1121             :         // sys.storagemodelinput
    1122           1 :         ret = SQLSpecialColumns(stmt, SQL_BEST_ROWID, (SQLCHAR*)"", SQL_NTS,
    1123             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"storagemodelinput", SQL_NTS,
    1124             :                         SQL_SCOPE_SESSION, SQL_NO_NULLS);
    1125           1 :         compareResult(stmt, ret, "SQLSpecialColumns (sys, storagemodelinput)",
    1126             :                 "Resultset with 8 columns\n"
    1127             :                 "Resultset with 10 rows\n"
    1128             :                 "SCOPE     COLUMN_NAME     DATA_TYPE       TYPE_NAME       COLUMN_SIZE     BUFFER_LENGTH   DECIMAL_DIGITS  PSEUDO_COLUMN\n"
    1129             :                 "SMALLINT  WVARCHAR(1024)  SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT\n"
    1130             :                 "1 schema  -9      VARCHAR 1024    2048    NULL    1\n"
    1131             :                 "1 table   -9      VARCHAR 1024    2048    NULL    1\n"
    1132             :                 "1 column  -9      VARCHAR 1024    2048    NULL    1\n"
    1133             :                 "1 type    -9      VARCHAR 1024    2048    NULL    1\n"
    1134             :                 "1 typewidth       4       INTEGER 31      11      0       1\n"
    1135             :                 "1 count   -5      BIGINT  63      20      0       1\n"
    1136             :                 "1 distinct        -5      BIGINT  63      20      0       1\n"
    1137             :                 "1 atomwidth       4       INTEGER 31      11      0       1\n"
    1138             :                 "1 reference       -7      BOOLEAN 1       1       NULL    1\n"
    1139             :                 "1 isacolumn       -7      BOOLEAN 1       1       NULL    1\n");
    1140             : 
    1141             :         // odbctst.CUSTOMERS, odbctst.ORDERS and odbctst.LINES
    1142             :         /* next tests are copied from code examples on https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlforeignkeys-function?view=sql-server-ver15 */
    1143           1 :         ret = SQLPrimaryKeys(stmt, NULL, 0, NULL, 0, (SQLCHAR*)"ORDERS", SQL_NTS);
    1144           1 :         compareResult(stmt, ret, "SQLPrimaryKeys (NULL, ORDERS)",
    1145             :                 "Resultset with 6 columns\n"
    1146             :                 "Resultset with 1 rows\n"
    1147             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     KEY_SEQ PK_NAME\n"
    1148             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1024)\n"
    1149             :                 "NULL      odbctst ORDERS  ORDERID 1       ORDERS_ORDERID_pkey\n");
    1150             : 
    1151           1 :         ret = SQLForeignKeys(stmt, NULL, 0, NULL, 0, (SQLCHAR*)"ORDERS", SQL_NTS, NULL, 0, NULL, 0, NULL, 0);
    1152           1 :         compareResult(stmt, ret, "SQLForeignKeys (NULL, ORDERS, NULL, NULL)",
    1153             :                 "Resultset with 14 columns\n"
    1154             :                 "Resultset with 1 rows\n"
    1155             :                 "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"
    1156             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1)     WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        SMALLINT        SMALLINT        WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT\n"
    1157             :                 "NULL      odbctst ORDERS  ORDERID NULL    odbctst LINES   ORDERID 1       1       1       LINES_ORDERID_fkey      ORDERS_ORDERID_pkey     7\n");
    1158             : 
    1159           1 :         ret = SQLForeignKeys(stmt, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, (SQLCHAR*)"ORDERS", SQL_NTS);
    1160           1 :         compareResult(stmt, ret, "SQLForeignKeys (NULL, NULL, NULL, ORDERS)",
    1161             :                 "Resultset with 14 columns\n"
    1162             :                 "Resultset with 1 rows\n"
    1163             :                 "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"
    1164             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1)     WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        SMALLINT        SMALLINT        WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT\n"
    1165             :                 "NULL      odbctst CUSTOMERS       CUSTID  NULL    odbctst ORDERS  CUSTID  1       1       1       ORDERS_CUSTID_fkey      CUSTOMERS_CUSTID_pkey   7\n");
    1166             : 
    1167             :         /* odbctst.pk2c and odbctst.fk2c (tests multi-column pks and multiple multi-column fks from one table */
    1168           1 :         ret = SQLPrimaryKeys(stmt, NULL, 0, (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk2c", SQL_NTS);
    1169           1 :         compareResult(stmt, ret, "SQLPrimaryKeys (odbctst, pk2c)",
    1170             :                 "Resultset with 6 columns\n"
    1171             :                 "Resultset with 2 rows\n"
    1172             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     KEY_SEQ PK_NAME\n"
    1173             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        WVARCHAR(1024)\n"
    1174             :                 "NULL      odbctst pk2c    pkc2    1       pk2c_pkc2_pkc1_pkey\n"
    1175             :                 "NULL      odbctst pk2c    pkc1    2       pk2c_pkc2_pkc1_pkey\n");
    1176             : 
    1177           1 :         ret = SQLForeignKeys(stmt, (SQLCHAR*)"", SQL_NTS,
    1178             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk2c", SQL_NTS,
    1179             :                         (SQLCHAR*)"", SQL_NTS,
    1180             :                         (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS);
    1181           1 :         compareResult(stmt, ret, "SQLForeignKeys (odbctst, pk2c, , )",
    1182             :                 "Resultset with 14 columns\n"
    1183             :                 "Resultset with 4 rows\n"
    1184             :                 "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"
    1185             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1)     WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        SMALLINT        SMALLINT        WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT\n"
    1186             :                 "NULL      odbctst pk2c    pkc2    NULL    odbctst fk2c    fkc2    1       0       1       fk2c_fkc2_fkc1_fkey     pk2c_pkc2_pkc1_pkey     7\n"
    1187             :                 "NULL      odbctst pk2c    pkc1    NULL    odbctst fk2c    fkc1    2       0       1       fk2c_fkc2_fkc1_fkey     pk2c_pkc2_pkc1_pkey     7\n"
    1188             :                 "NULL      odbctst pk2c    pkc2    NULL    odbctst fk2c    fkc2    1       2       3       fk2c_fkc2_fkc3_fkey     pk2c_pkc2_pkc1_pkey     7\n"
    1189             :                 "NULL      odbctst pk2c    pkc1    NULL    odbctst fk2c    fkc3    2       2       3       fk2c_fkc2_fkc3_fkey     pk2c_pkc2_pkc1_pkey     7\n");
    1190             : 
    1191           1 :         ret = SQLForeignKeys(stmt, (SQLCHAR*)"", SQL_NTS,
    1192             :                         (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS,
    1193             :                         (SQLCHAR*)"", SQL_NTS,
    1194             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"fk2c", SQL_NTS);
    1195           1 :         compareResult(stmt, ret, "SQLForeignKeys (, , odbctst, fk2c)",
    1196             :                 "Resultset with 14 columns\n"
    1197             :                 "Resultset with 4 rows\n"
    1198             :                 "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"
    1199             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1)     WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        SMALLINT        SMALLINT        WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT\n"
    1200             :                 "NULL      odbctst pk2c    pkc2    NULL    odbctst fk2c    fkc2    1       0       1       fk2c_fkc2_fkc1_fkey     pk2c_pkc2_pkc1_pkey     7\n"
    1201             :                 "NULL      odbctst pk2c    pkc1    NULL    odbctst fk2c    fkc1    2       0       1       fk2c_fkc2_fkc1_fkey     pk2c_pkc2_pkc1_pkey     7\n"
    1202             :                 "NULL      odbctst pk2c    pkc2    NULL    odbctst fk2c    fkc2    1       2       3       fk2c_fkc2_fkc3_fkey     pk2c_pkc2_pkc1_pkey     7\n"
    1203             :                 "NULL      odbctst pk2c    pkc1    NULL    odbctst fk2c    fkc3    2       2       3       fk2c_fkc2_fkc3_fkey     pk2c_pkc2_pkc1_pkey     7\n");
    1204             : 
    1205           1 :         ret = SQLForeignKeys(stmt, (SQLCHAR*)"", SQL_NTS,
    1206             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk2c", SQL_NTS,
    1207             :                         (SQLCHAR*)"", SQL_NTS,
    1208             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"fk2c", SQL_NTS);
    1209           1 :         compareResult(stmt, ret, "SQLForeignKeys (odbctst, pk2c, odbctst, fk2c)",
    1210             :                 "Resultset with 14 columns\n"
    1211             :                 "Resultset with 4 rows\n"
    1212             :                 "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"
    1213             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1)     WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT        SMALLINT        SMALLINT        WVARCHAR(1024)  WVARCHAR(1024)  SMALLINT\n"
    1214             :                 "NULL      odbctst pk2c    pkc2    NULL    odbctst fk2c    fkc2    1       0       1       fk2c_fkc2_fkc1_fkey     pk2c_pkc2_pkc1_pkey     7\n"
    1215             :                 "NULL      odbctst pk2c    pkc1    NULL    odbctst fk2c    fkc1    2       0       1       fk2c_fkc2_fkc1_fkey     pk2c_pkc2_pkc1_pkey     7\n"
    1216             :                 "NULL      odbctst pk2c    pkc2    NULL    odbctst fk2c    fkc2    1       2       3       fk2c_fkc2_fkc3_fkey     pk2c_pkc2_pkc1_pkey     7\n"
    1217             :                 "NULL      odbctst pk2c    pkc1    NULL    odbctst fk2c    fkc3    2       2       3       fk2c_fkc2_fkc3_fkey     pk2c_pkc2_pkc1_pkey     7\n");
    1218             : 
    1219           1 :         ret = SQLTablePrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
    1220             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk_2c", SQL_NTS);
    1221           1 :         compareResult(stmt, ret, "SQLTablePrivileges (odbctst, pk_2c)",
    1222             :                 "Resultset with 7 columns\n"
    1223             :                 "Resultset with 0 rows\n"
    1224             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
    1225             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n");
    1226             : 
    1227           1 :         ret = SQLColumnPrivileges(stmt, (SQLCHAR*)"", SQL_NTS,
    1228             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk_2c", SQL_NTS,
    1229             :                         (SQLCHAR*)"%", SQL_NTS);
    1230           1 :         compareResult(stmt, ret, "SQLColumnPrivileges (odbctst, pk_2c, %)",
    1231             :                 "Resultset with 8 columns\n"
    1232             :                 "Resultset with 0 rows\n"
    1233             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      COLUMN_NAME     GRANTOR GRANTEE PRIVILEGE       IS_GRANTABLE\n"
    1234             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(40)    WVARCHAR(3)\n");
    1235             : 
    1236             : 
    1237             :         // test procedure sys.analyze(). There are 4 overloaded variants of this procedure in MonetDB with 0, 1, 2 or 3 input parameters.
    1238           1 :         ret = SQLProcedures(stmt, (SQLCHAR*)"", SQL_NTS,
    1239             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"analyze", SQL_NTS);
    1240           1 :         compareResult(stmt, ret, "SQLProcedures (sys, analyze)",
    1241             :                 "Resultset with 9 columns\n"
    1242             :                 "Resultset with 4 rows\n"
    1243             :                 "PROCEDURE_CAT     PROCEDURE_SCHEM PROCEDURE_NAME  NUM_INPUT_PARAMS        NUM_OUTPUT_PARAMS       NUM_RESULT_SETS REMARKS PROCEDURE_TYPE  SPECIFIC_NAME\n"
    1244             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(256)   TINYINT TINYINT TINYINT WVARCHAR(65000) SMALLINT        WVARCHAR(10)\n"
    1245             :                 "NULL      sys     analyze 0       0       0       sys.analyze() procedure comment 1       replacedId\n"
    1246             :                 "NULL      sys     analyze 0       0       0       NULL    1       replacedId\n"
    1247             :                 "NULL      sys     analyze 0       0       0       NULL    1       replacedId\n"
    1248             :                 "NULL      sys     analyze 0       0       0       NULL    1       replacedId\n");
    1249             : 
    1250           1 :         ret = SQLProcedureColumns(stmt, (SQLCHAR*)"", SQL_NTS,
    1251             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"analyze", SQL_NTS,
    1252             :                         (SQLCHAR*)"%", SQL_NTS);
    1253           1 :         compareResult(stmt, ret, "SQLProcedureColumns (sys, analyze, %)",
    1254             :                 "Resultset with 20 columns\n"
    1255             :                 "Resultset with 6 rows\n"
    1256             :                 "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"
    1257             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(256)   WVARCHAR(256)   SMALLINT        SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT        SMALLINT        WVARCHAR(65000) WVARCHAR(1)     SMALLINT        SMALLINT        INTEGER INTEGER WVARCHAR        WVARCHAR(10)\n"
    1258             :                 "NULL      sys     analyze sname   1       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    1               replacedId\n"
    1259             :                 "NULL      sys     analyze sname   1       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    1               replacedId\n"
    1260             :                 "NULL      sys     analyze tname   1       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    2               replacedId\n"
    1261             :                 "NULL      sys     analyze sname   1       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    1               replacedId\n"
    1262             :                 "NULL      sys     analyze tname   1       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    2               replacedId\n"
    1263             :                 "NULL      sys     analyze cname   1       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    3               replacedId\n");
    1264             : 
    1265             :         // test function sys.sin(). There are 2 overloaded variants of this function in MonetDB: sys.sin(real) and sys.sin(double).
    1266           1 :         ret = SQLProcedures(stmt, (SQLCHAR*)"", SQL_NTS,
    1267             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"sin", SQL_NTS);
    1268           1 :         compareResult(stmt, ret, "SQLProcedures (sys, sin)",
    1269             :                 "Resultset with 9 columns\n"
    1270             :                 "Resultset with 2 rows\n"
    1271             :                 "PROCEDURE_CAT     PROCEDURE_SCHEM PROCEDURE_NAME  NUM_INPUT_PARAMS        NUM_OUTPUT_PARAMS       NUM_RESULT_SETS REMARKS PROCEDURE_TYPE  SPECIFIC_NAME\n"
    1272             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(256)   TINYINT TINYINT TINYINT WVARCHAR(65000) SMALLINT        WVARCHAR(10)\n"
    1273             :                 "NULL      sys     sin     0       0       0       NULL    2       replacedId\n"
    1274             :                 "NULL      sys     sin     0       0       0       sys.sin(double) function comment        2       replacedId\n");
    1275             : 
    1276           1 :         ret = SQLProcedureColumns(stmt, (SQLCHAR*)"", SQL_NTS,
    1277             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"sin", SQL_NTS,
    1278             :                         (SQLCHAR*)"%", SQL_NTS);
    1279           1 :         compareResult(stmt, ret, "SQLProcedureColumns (sys, sin, %)",
    1280             :                 "Resultset with 20 columns\n"
    1281             :                 "Resultset with 4 rows\n"
    1282             :                 "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"
    1283             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(256)   WVARCHAR(256)   SMALLINT        SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT        SMALLINT        WVARCHAR(65000) WVARCHAR(1)     SMALLINT        SMALLINT        INTEGER INTEGER WVARCHAR        WVARCHAR(10)\n"
    1284             :                 "NULL      sys     sin     arg_1   1       7       REAL    24      14      7       2       2       NULL    NULL    7       NULL    NULL    1               replacedId\n"
    1285             :                 "NULL      sys     sin     res_0   5       7       REAL    24      14      7       2       2       NULL    NULL    7       NULL    NULL    0               replacedId\n"
    1286             :                 "NULL      sys     sin     arg_1   1       8       DOUBLE  53      24      15      2       2       NULL    NULL    8       NULL    NULL    1               replacedId\n"
    1287             :                 "NULL      sys     sin     res_0   5       8       DOUBLE  53      24      15      2       2       NULL    NULL    8       NULL    NULL    0               replacedId\n");
    1288             : 
    1289             :         // test table returning function sys.env(). It has no input parameters. Only 2 result columns.
    1290           1 :         ret = SQLProcedures(stmt, (SQLCHAR*)"", SQL_NTS,
    1291             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"env", SQL_NTS);
    1292           1 :         compareResult(stmt, ret, "SQLProcedures (sys, env)",
    1293             :                 "Resultset with 9 columns\n"
    1294             :                 "Resultset with 1 rows\n"
    1295             :                 "PROCEDURE_CAT     PROCEDURE_SCHEM PROCEDURE_NAME  NUM_INPUT_PARAMS        NUM_OUTPUT_PARAMS       NUM_RESULT_SETS REMARKS PROCEDURE_TYPE  SPECIFIC_NAME\n"
    1296             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(256)   TINYINT TINYINT TINYINT WVARCHAR(65000) SMALLINT        WVARCHAR(10)\n"
    1297             :                 "NULL      sys     env     0       0       0       sys.env() function comment      2       replacedId\n");
    1298             : 
    1299           1 :         ret = SQLProcedureColumns(stmt, (SQLCHAR*)"", SQL_NTS,
    1300             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"env", SQL_NTS,
    1301             :                         (SQLCHAR*)"%", SQL_NTS);
    1302           1 :         compareResult(stmt, ret, "SQLProcedureColumns (sys, env, %)",
    1303             :                 "Resultset with 20 columns\n"
    1304             :                 "Resultset with 2 rows\n"
    1305             :                 "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"
    1306             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(256)   WVARCHAR(256)   SMALLINT        SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT        SMALLINT        WVARCHAR(65000) WVARCHAR(1)     SMALLINT        SMALLINT        INTEGER INTEGER WVARCHAR        WVARCHAR(10)\n"
    1307             :                 "NULL      sys     env     name    3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    1               replacedId\n"
    1308             :                 "NULL      sys     env     value   3       -9      VARCHAR 2048    4096    NULL    NULL    2       NULL    NULL    -9      NULL    8192    2               replacedId\n");
    1309             : 
    1310             :         // test table returning function sys.statistics(). 4 overloaded variants with 0, 1, 2 or 3 input parameters. 13 result columns.
    1311           1 :         ret = SQLProcedures(stmt, (SQLCHAR*)"", SQL_NTS,
    1312             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"statistics", SQL_NTS);
    1313           1 :         compareResult(stmt, ret, "SQLProcedures (sys, statistics)",
    1314             :                 "Resultset with 9 columns\n"
    1315             :                 "Resultset with 4 rows\n"
    1316             :                 "PROCEDURE_CAT     PROCEDURE_SCHEM PROCEDURE_NAME  NUM_INPUT_PARAMS        NUM_OUTPUT_PARAMS       NUM_RESULT_SETS REMARKS PROCEDURE_TYPE  SPECIFIC_NAME\n"
    1317             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(256)   TINYINT TINYINT TINYINT WVARCHAR(65000) SMALLINT        WVARCHAR(10)\n"
    1318             :                 "NULL      sys     statistics      0       0       0       sys.statistics() function comment       2       replacedId\n"
    1319             :                 "NULL      sys     statistics      0       0       0       NULL    2       replacedId\n"
    1320             :                 "NULL      sys     statistics      0       0       0       NULL    2       replacedId\n"
    1321             :                 "NULL      sys     statistics      0       0       0       NULL    2       replacedId\n");
    1322             : 
    1323           1 :         ret = SQLProcedureColumns(stmt, (SQLCHAR*)"", SQL_NTS,
    1324             :                         (SQLCHAR*)"sys", SQL_NTS, (SQLCHAR*)"statistics", SQL_NTS,
    1325             :                         (SQLCHAR*)"%", SQL_NTS);
    1326           1 :         compareResult(stmt, ret, "SQLProcedureColumns (sys, statistics, %)",
    1327             :                 "Resultset with 20 columns\n"
    1328             :                 "Resultset with 58 rows\n"
    1329             :                 "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"
    1330             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(256)   WVARCHAR(256)   SMALLINT        SMALLINT        WVARCHAR(25)    INTEGER INTEGER SMALLINT        SMALLINT        SMALLINT        WVARCHAR(65000) WVARCHAR(1)     SMALLINT        SMALLINT        INTEGER INTEGER WVARCHAR        WVARCHAR(10)\n"
    1331             :                 // 0 input argument and 13 result columns of sys.statistics()
    1332             :                 "NULL      sys     statistics      column_id       3       4       INTEGER 31      11      0       2       2       NULL    NULL    4       NULL    NULL    1               replacedId\n"
    1333             :                 "NULL      sys     statistics      schema  3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    2               replacedId\n"
    1334             :                 "NULL      sys     statistics      table   3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    3               replacedId\n"
    1335             :                 "NULL      sys     statistics      column  3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    4               replacedId\n"
    1336             :                 "NULL      sys     statistics      type    3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    5               replacedId\n"
    1337             :                 "NULL      sys     statistics      width   3       4       INTEGER 31      11      0       2       2       NULL    NULL    4       NULL    NULL    6               replacedId\n"
    1338             :                 "NULL      sys     statistics      count   3       -5      BIGINT  63      20      0       2       2       NULL    NULL    -5      NULL    NULL    7               replacedId\n"
    1339             :                 "NULL      sys     statistics      unique  3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    8               replacedId\n"
    1340             :                 "NULL      sys     statistics      nils    3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    9               replacedId\n"
    1341             :                 "NULL      sys     statistics      minval  3       -9      VARCHAR 0       0       NULL    NULL    2       NULL    NULL    -9      NULL    0       10              replacedId\n"
    1342             :                 "NULL      sys     statistics      maxval  3       -9      VARCHAR 0       0       NULL    NULL    2       NULL    NULL    -9      NULL    0       11              replacedId\n"
    1343             :                 "NULL      sys     statistics      sorted  3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    12              replacedId\n"
    1344             :                 "NULL      sys     statistics      revsorted       3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    13              replacedId\n"
    1345             : 
    1346             :                 // 1 input argument and 13 result columns of sys.statistics(sname)
    1347             :                 "NULL      sys     statistics      sname   1       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    1               replacedId\n"
    1348             :                 "NULL      sys     statistics      column_id       3       4       INTEGER 31      11      0       2       2       NULL    NULL    4       NULL    NULL    1               replacedId\n"
    1349             :                 "NULL      sys     statistics      schema  3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    2               replacedId\n"
    1350             :                 "NULL      sys     statistics      table   3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    3               replacedId\n"
    1351             :                 "NULL      sys     statistics      column  3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    4               replacedId\n"
    1352             :                 "NULL      sys     statistics      type    3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    5               replacedId\n"
    1353             :                 "NULL      sys     statistics      width   3       4       INTEGER 31      11      0       2       2       NULL    NULL    4       NULL    NULL    6               replacedId\n"
    1354             :                 "NULL      sys     statistics      count   3       -5      BIGINT  63      20      0       2       2       NULL    NULL    -5      NULL    NULL    7               replacedId\n"
    1355             :                 "NULL      sys     statistics      unique  3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    8               replacedId\n"
    1356             :                 "NULL      sys     statistics      nils    3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    9               replacedId\n"
    1357             :                 "NULL      sys     statistics      minval  3       -9      VARCHAR 0       0       NULL    NULL    2       NULL    NULL    -9      NULL    0       10              replacedId\n"
    1358             :                 "NULL      sys     statistics      maxval  3       -9      VARCHAR 0       0       NULL    NULL    2       NULL    NULL    -9      NULL    0       11              replacedId\n"
    1359             :                 "NULL      sys     statistics      sorted  3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    12              replacedId\n"
    1360             :                 "NULL      sys     statistics      revsorted       3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    13              replacedId\n"
    1361             : 
    1362             :                 // 2 input arguments and 13 result columns of sys.statistics(sname, tname)
    1363             :                 "NULL      sys     statistics      sname   1       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    1               replacedId\n"
    1364             :                 "NULL      sys     statistics      tname   1       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    2               replacedId\n"
    1365             :                 "NULL      sys     statistics      column_id       3       4       INTEGER 31      11      0       2       2       NULL    NULL    4       NULL    NULL    1               replacedId\n"
    1366             :                 "NULL      sys     statistics      schema  3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    2               replacedId\n"
    1367             :                 "NULL      sys     statistics      table   3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    3               replacedId\n"
    1368             :                 "NULL      sys     statistics      column  3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    4               replacedId\n"
    1369             :                 "NULL      sys     statistics      type    3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    5               replacedId\n"
    1370             :                 "NULL      sys     statistics      width   3       4       INTEGER 31      11      0       2       2       NULL    NULL    4       NULL    NULL    6               replacedId\n"
    1371             :                 "NULL      sys     statistics      count   3       -5      BIGINT  63      20      0       2       2       NULL    NULL    -5      NULL    NULL    7               replacedId\n"
    1372             :                 "NULL      sys     statistics      unique  3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    8               replacedId\n"
    1373             :                 "NULL      sys     statistics      nils    3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    9               replacedId\n"
    1374             :                 "NULL      sys     statistics      minval  3       -9      VARCHAR 0       0       NULL    NULL    2       NULL    NULL    -9      NULL    0       10              replacedId\n"
    1375             :                 "NULL      sys     statistics      maxval  3       -9      VARCHAR 0       0       NULL    NULL    2       NULL    NULL    -9      NULL    0       11              replacedId\n"
    1376             :                 "NULL      sys     statistics      sorted  3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    12              replacedId\n"
    1377             :                 "NULL      sys     statistics      revsorted       3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    13              replacedId\n"
    1378             : 
    1379             :                 // 3 input arguments and 13 result columns of sys.statistics(sname, tname, cname)
    1380             :                 "NULL      sys     statistics      sname   1       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    1               replacedId\n"
    1381             :                 "NULL      sys     statistics      tname   1       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    2               replacedId\n"
    1382             :                 "NULL      sys     statistics      cname   1       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    3               replacedId\n"
    1383             :                 "NULL      sys     statistics      column_id       3       4       INTEGER 31      11      0       2       2       NULL    NULL    4       NULL    NULL    1               replacedId\n"
    1384             :                 "NULL      sys     statistics      schema  3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    2               replacedId\n"
    1385             :                 "NULL      sys     statistics      table   3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    3               replacedId\n"
    1386             :                 "NULL      sys     statistics      column  3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    4               replacedId\n"
    1387             :                 "NULL      sys     statistics      type    3       -9      VARCHAR 1024    2048    NULL    NULL    2       NULL    NULL    -9      NULL    4096    5               replacedId\n"
    1388             :                 "NULL      sys     statistics      width   3       4       INTEGER 31      11      0       2       2       NULL    NULL    4       NULL    NULL    6               replacedId\n"
    1389             :                 "NULL      sys     statistics      count   3       -5      BIGINT  63      20      0       2       2       NULL    NULL    -5      NULL    NULL    7               replacedId\n"
    1390             :                 "NULL      sys     statistics      unique  3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    8               replacedId\n"
    1391             :                 "NULL      sys     statistics      nils    3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    9               replacedId\n"
    1392             :                 "NULL      sys     statistics      minval  3       -9      VARCHAR 0       0       NULL    NULL    2       NULL    NULL    -9      NULL    0       10              replacedId\n"
    1393             :                 "NULL      sys     statistics      maxval  3       -9      VARCHAR 0       0       NULL    NULL    2       NULL    NULL    -9      NULL    0       11              replacedId\n"
    1394             :                 "NULL      sys     statistics      sorted  3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    12              replacedId\n"
    1395             :                 "NULL      sys     statistics      revsorted       3       -7      BOOLEAN 1       1       NULL    NULL    2       NULL    NULL    -7      NULL    NULL    13              replacedId\n");
    1396             : 
    1397           1 :         ret = SQLGetTypeInfo(stmt, SQL_ALL_TYPES);
    1398           1 :         compareResult(stmt, ret, "SQLGetTypeInfo(stmt, SQL_ALL_TYPES)",
    1399             :                 "Resultset with 19 columns\n"
    1400             :                 "Resultset with 44 rows\n"
    1401             :                 "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"
    1402             :                 "WVARCHAR(128)     SMALLINT        INTEGER WVARCHAR(11)    WVARCHAR(18)    WVARCHAR(15)    SMALLINT        SMALLINT        SMALLINT        SMALLINT        SMALLINT        SMALLINT        WVARCHAR(16)    SMALLINT        SMALLINT        SMALLINT        SMALLINT        INTEGER SMALLINT\n"
    1403             :                 "uuid      -11     36      uuid '  '       NULL    1       0       2       -1      0       -1      uuid    -1      -1      -11     -1      -1      -1\n"
    1404             :                 "character large object    -10     1000000 '       '       NULL    1       1       3       -1      0       0       NULL    -1      -1      -10     -1      -1      -1\n"
    1405             :                 "json      -10     1000000 json '  '       NULL    1       1       3       -1      0       0       json    -1      -1      -10     -1      -1      -1\n"
    1406             :                 "url       -10     1000000 url '   '       NULL    1       1       3       -1      0       0       url     -1      -1      -10     -1      -1      -1\n"
    1407             :                 "varchar   -9      1000000 '       '       length  1       1       3       -1      0       -1      NULL    -1      -1      -9      -1      -1      -1\n"
    1408             :                 "character -8      1000000 '       '       length  1       1       3       -1      0       0       NULL    -1      -1      -8      -1      -1      -1\n"
    1409             :                 "char      -8      1000000 '       '       length  1       1       3       -1      0       0       NULL    -1      -1      -8      -1      -1      -1\n"
    1410             :                 "boolean   -7      1       NULL    NULL    NULL    1       0       2       1       1       0       boolean -1      -1      -7      -1      -1      -1\n"
    1411             :                 "tinyint   -6      3       NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       -6      -1      10      -1\n"
    1412             :                 "bigint    -5      19      NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       -5      -1      10      -1\n"
    1413             :                 "bigserial -5      19      NULL    NULL    NULL    0       0       2       0       0       1       bigserial       0       0       -5      -1      10      -1\n"
    1414             :                 "binary large object       -4      1000000 x'      '       NULL    1       1       3       -1      0       0       NULL    -1      -1      -4      -1      -1      -1\n"
    1415             :                 "binary large object       -3      1000000 x'      '       length  1       1       3       -1      0       0       blob(max_length)        -1      -1      -3      -1      -1      -1\n"
    1416             :                 "character large object    -1      1000000 '       '       NULL    1       1       3       -1      0       0       NULL    -1      -1      -1      -1      -1      -1\n"
    1417             :                 "char      1       1000000 '       '       length  1       1       3       -1      0       0       NULL    -1      -1      1       -1      -1      -1\n"
    1418             :                 "numeric   2       19      NULL    NULL    precision,scale 1       0       2       0       0       0       NULL    0       18      2       -1      10      -1\n"
    1419             :                 "decimal   3       19      NULL    NULL    precision,scale 1       0       2       0       0       0       NULL    0       18      3       -1      10      -1\n"
    1420             :                 "integer   4       10      NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       4       -1      10      -1\n"
    1421             :                 "int       4       10      NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       4       -1      10      -1\n"
    1422             :                 "mediumint 4       10      NULL    NULL    NULL    1       0       2       0       0       0       int     0       0       4       -1      10      -1\n"
    1423             :                 "serial    4       10      NULL    NULL    NULL    0       0       2       0       0       1       serial  0       0       4       -1      10      -1\n"
    1424             :                 "smallint  5       5       NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       5       -1      10      -1\n"
    1425             :                 "float     6       53      NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       6       -1      2       -1\n"
    1426             :                 "real      7       24      NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       7       -1      2       -1\n"
    1427             :                 "double    8       53      NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       8       -1      2       -1\n"
    1428             :                 "varchar   12      1000000 '       '       length  1       1       3       -1      0       -1      NULL    -1      -1      12      -1      -1      -1\n"
    1429             :                 "date      91      10      date '  '       NULL    1       0       2       -1      0       -1      NULL    -1      -1      9       1       -1      -1\n"
    1430             :                 "time      92      8       time '  '       NULL    1       0       2       -1      0       -1      NULL    0       0       9       2       -1      -1\n"
    1431             :                 "time(precision)   92      15      time '  '       precision       1       0       2       -1      0       -1      NULL    0       6       9       2       -1      -1\n"
    1432             :                 "timestamp 93      19      timestamp '     '       NULL    1       0       2       -1      0       -1      NULL    0       0       9       3       -1      -1\n"
    1433             :                 "timestamp(precision)      93      26      timestamp '     '       precision       1       0       2       -1      0       -1      NULL    0       6       9       3       -1      -1\n"
    1434             :                 "interval year     101     9       interval '      ' year  NULL    1       0       2       -1      0       -1      NULL    0       0       10      1       -1      9\n"
    1435             :                 "interval month    102     10      interval '      ' month NULL    1       0       2       -1      0       -1      NULL    0       0       10      2       -1      10\n"
    1436             :                 "interval day      103     5       interval '      ' day   NULL    1       0       2       -1      0       -1      NULL    0       0       10      3       -1      5\n"
    1437             :                 "interval hour     104     6       interval '      ' hour  NULL    1       0       2       -1      0       -1      NULL    0       0       10      4       -1      6\n"
    1438             :                 "interval minute   105     8       interval '      ' minute        NULL    1       0       2       -1      0       -1      NULL    0       0       10      5       -1      8\n"
    1439             :                 "interval second   106     10      interval '      ' second        scale   1       0       2       -1      0       -1      NULL    0       0       10      6       -1      10\n"
    1440             :                 "interval year to month    107     12      interval '      ' year to month NULL    1       0       2       -1      0       -1      NULL    0       0       10      7       -1      9\n"
    1441             :                 "interval day to hour      108     8       interval '      ' day to hour   NULL    1       0       2       -1      0       -1      NULL    0       0       10      8       -1      5\n"
    1442             :                 "interval day to minute    109     11      interval '      ' day to minute NULL    1       0       2       -1      0       -1      NULL    0       0       10      9       -1      5\n"
    1443             :                 "interval day to second    110     14      interval '      ' day to second scale   1       0       2       -1      0       -1      NULL    0       0       10      10      -1      5\n"
    1444             :                 "interval hour to minute   111     9       interval '      ' hour to minute        NULL    1       0       2       -1      0       -1      NULL    0       0       10      11      -1      6\n"
    1445             :                 "interval hour to second   112     12      interval '      ' hour to second        scale   1       0       2       -1      0       -1      NULL    0       0       10      12      -1      6\n"
    1446             :                 "interval minute to second 113     13      interval '      ' minute to second      scale   1       0       2       -1      0       -1      NULL    0       0       10      13      -1      10\n");
    1447             : 
    1448             :         /* MonetDB specific type "hugeint" is currently not returned by SQLGetTypeInfo(SQL_ALL_TYPES). However it can be queried when requested explicitly. Test it. */
    1449           1 :         ret = SQLGetTypeInfo(stmt, SQL_HUGEINT);
    1450           1 :         compareResult(stmt, ret, "SQLGetTypeInfo(stmt, SQL_HUGEINT)",
    1451             :                 "Resultset with 19 columns\n"
    1452             :                 "Resultset with 1 rows\n"
    1453             :                 "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"
    1454             :                 "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"
    1455             :                 "hugeint   16384   38      NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       16384   -1      10      -1\n");
    1456             : 
    1457             :         /* strangely when we repeat SQLGetTypeInfo(stmt, SQL_ALL_TYPES) now after calling SQLGetTypeInfo(stmt, SQL_HUGEINT), it suddenly does include hugeint in the result! */
    1458           1 :         ret = SQLGetTypeInfo(stmt, SQL_ALL_TYPES);
    1459           1 :         compareResult(stmt, ret, "SQLGetTypeInfo(stmt, SQL_ALL_TYPES)",
    1460             :                 "Resultset with 19 columns\n"
    1461             :                 "Resultset with 45 rows\n"
    1462             :                 "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"
    1463             :                 "WVARCHAR(128)     SMALLINT        INTEGER WVARCHAR(11)    WVARCHAR(18)    WVARCHAR(15)    SMALLINT        SMALLINT        SMALLINT        SMALLINT        SMALLINT        SMALLINT        WVARCHAR(16)    SMALLINT        SMALLINT        SMALLINT        SMALLINT        INTEGER SMALLINT\n"
    1464             :                 "uuid      -11     36      uuid '  '       NULL    1       0       2       -1      0       -1      uuid    -1      -1      -11     -1      -1      -1\n"
    1465             :                 "character large object    -10     1000000 '       '       NULL    1       1       3       -1      0       0       NULL    -1      -1      -10     -1      -1      -1\n"
    1466             :                 "json      -10     1000000 json '  '       NULL    1       1       3       -1      0       0       json    -1      -1      -10     -1      -1      -1\n"
    1467             :                 "url       -10     1000000 url '   '       NULL    1       1       3       -1      0       0       url     -1      -1      -10     -1      -1      -1\n"
    1468             :                 "varchar   -9      1000000 '       '       length  1       1       3       -1      0       -1      NULL    -1      -1      -9      -1      -1      -1\n"
    1469             :                 "character -8      1000000 '       '       length  1       1       3       -1      0       0       NULL    -1      -1      -8      -1      -1      -1\n"
    1470             :                 "char      -8      1000000 '       '       length  1       1       3       -1      0       0       NULL    -1      -1      -8      -1      -1      -1\n"
    1471             :                 "boolean   -7      1       NULL    NULL    NULL    1       0       2       1       1       0       boolean -1      -1      -7      -1      -1      -1\n"
    1472             :                 "tinyint   -6      3       NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       -6      -1      10      -1\n"
    1473             :                 "bigint    -5      19      NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       -5      -1      10      -1\n"
    1474             :                 "bigserial -5      19      NULL    NULL    NULL    0       0       2       0       0       1       bigserial       0       0       -5      -1      10      -1\n"
    1475             :                 "binary large object       -4      1000000 x'      '       NULL    1       1       3       -1      0       0       NULL    -1      -1      -4      -1      -1      -1\n"
    1476             :                 "binary large object       -3      1000000 x'      '       length  1       1       3       -1      0       0       blob(max_length)        -1      -1      -3      -1      -1      -1\n"
    1477             :                 "character large object    -1      1000000 '       '       NULL    1       1       3       -1      0       0       NULL    -1      -1      -1      -1      -1      -1\n"
    1478             :                 "char      1       1000000 '       '       length  1       1       3       -1      0       0       NULL    -1      -1      1       -1      -1      -1\n"
    1479             :                 "numeric   2       19      NULL    NULL    precision,scale 1       0       2       0       0       0       NULL    0       18      2       -1      10      -1\n"
    1480             :                 "decimal   3       19      NULL    NULL    precision,scale 1       0       2       0       0       0       NULL    0       18      3       -1      10      -1\n"
    1481             :                 "integer   4       10      NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       4       -1      10      -1\n"
    1482             :                 "int       4       10      NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       4       -1      10      -1\n"
    1483             :                 "mediumint 4       10      NULL    NULL    NULL    1       0       2       0       0       0       int     0       0       4       -1      10      -1\n"
    1484             :                 "serial    4       10      NULL    NULL    NULL    0       0       2       0       0       1       serial  0       0       4       -1      10      -1\n"
    1485             :                 "smallint  5       5       NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       5       -1      10      -1\n"
    1486             :                 "float     6       53      NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       6       -1      2       -1\n"
    1487             :                 "real      7       24      NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       7       -1      2       -1\n"
    1488             :                 "double    8       53      NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       8       -1      2       -1\n"
    1489             :                 "varchar   12      1000000 '       '       length  1       1       3       -1      0       -1      NULL    -1      -1      12      -1      -1      -1\n"
    1490             :                 "date      91      10      date '  '       NULL    1       0       2       -1      0       -1      NULL    -1      -1      9       1       -1      -1\n"
    1491             :                 "time      92      8       time '  '       NULL    1       0       2       -1      0       -1      NULL    0       0       9       2       -1      -1\n"
    1492             :                 "time(precision)   92      15      time '  '       precision       1       0       2       -1      0       -1      NULL    0       6       9       2       -1      -1\n"
    1493             :                 "timestamp 93      19      timestamp '     '       NULL    1       0       2       -1      0       -1      NULL    0       0       9       3       -1      -1\n"
    1494             :                 "timestamp(precision)      93      26      timestamp '     '       precision       1       0       2       -1      0       -1      NULL    0       6       9       3       -1      -1\n"
    1495             :                 "interval year     101     9       interval '      ' year  NULL    1       0       2       -1      0       -1      NULL    0       0       10      1       -1      9\n"
    1496             :                 "interval month    102     10      interval '      ' month NULL    1       0       2       -1      0       -1      NULL    0       0       10      2       -1      10\n"
    1497             :                 "interval day      103     5       interval '      ' day   NULL    1       0       2       -1      0       -1      NULL    0       0       10      3       -1      5\n"
    1498             :                 "interval hour     104     6       interval '      ' hour  NULL    1       0       2       -1      0       -1      NULL    0       0       10      4       -1      6\n"
    1499             :                 "interval minute   105     8       interval '      ' minute        NULL    1       0       2       -1      0       -1      NULL    0       0       10      5       -1      8\n"
    1500             :                 "interval second   106     10      interval '      ' second        scale   1       0       2       -1      0       -1      NULL    0       0       10      6       -1      10\n"
    1501             :                 "interval year to month    107     12      interval '      ' year to month NULL    1       0       2       -1      0       -1      NULL    0       0       10      7       -1      9\n"
    1502             :                 "interval day to hour      108     8       interval '      ' day to hour   NULL    1       0       2       -1      0       -1      NULL    0       0       10      8       -1      5\n"
    1503             :                 "interval day to minute    109     11      interval '      ' day to minute NULL    1       0       2       -1      0       -1      NULL    0       0       10      9       -1      5\n"
    1504             :                 "interval day to second    110     14      interval '      ' day to second scale   1       0       2       -1      0       -1      NULL    0       0       10      10      -1      5\n"
    1505             :                 "interval hour to minute   111     9       interval '      ' hour to minute        NULL    1       0       2       -1      0       -1      NULL    0       0       10      11      -1      6\n"
    1506             :                 "interval hour to second   112     12      interval '      ' hour to second        scale   1       0       2       -1      0       -1      NULL    0       0       10      12      -1      6\n"
    1507             :                 "interval minute to second 113     13      interval '      ' minute to second      scale   1       0       2       -1      0       -1      NULL    0       0       10      13      -1      10\n"
    1508             :                 "hugeint   16384   38      NULL    NULL    NULL    1       0       2       0       0       0       NULL    0       0       16384   -1      10      -1\n");
    1509             : 
    1510             : 
    1511           1 :         nrServerThreads = getNrOfServerThreads(dbc);
    1512             : 
    1513             :         // test SELECT query
    1514           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *) "SELECT * from odbctst.\"LINES\";", SQL_NTS);
    1515           1 :         compareResult(stmt, ret, "SELECT * from odbctst.\"LINES\"",
    1516             :                 "Resultset with 4 columns\n"
    1517             :                 "Resultset with 0 rows\n"
    1518             :                 "ORDERID   LINES   PARTID  QUANTITY\n"
    1519             :                 "INTEGER   INTEGER INTEGER DECIMAL(9,3)\n");
    1520             : 
    1521             :         // test PLAN SELECT query
    1522           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *) "PLAN SELECT * from odbctst.\"LINES\";", SQL_NTS);
    1523           1 :         compareResult(stmt, ret, "PLAN SELECT * from odbctst.\"LINES\"",
    1524             :                 "Resultset with 1 columns\n"
    1525             :                 "Resultset with 3 rows\n"
    1526             :                 "rel\n"
    1527             :                 "WVARCHAR(176)\n"
    1528             :                 "project (\n"
    1529             :                 "| table(\"odbctst\".\"LINES\") [ \"LINES\".\"ORDERID\" NOT NULL UNIQUE HASHCOL , \"LINES\".\"LINES\" NOT NULL UNIQUE, \"LINES\".\"PARTID\" NOT NULL UNIQUE, \"LINES\".\"QUANTITY\" NOT NULL UNIQUE ]\n"
    1530             :                 ") [ \"LINES\".\"ORDERID\" NOT NULL UNIQUE HASHCOL , \"LINES\".\"LINES\" NOT NULL UNIQUE, \"LINES\".\"PARTID\" NOT NULL UNIQUE, \"LINES\".\"QUANTITY\" NOT NULL UNIQUE ]\n");
    1531             : 
    1532             :         // test EXPLAIN SELECT query
    1533           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *) "EXPLAIN SELECT * from odbctst.\"LINES\";", SQL_NTS);
    1534           1 :         compareResult(stmt, ret, "EXPLAIN SELECT * from odbctst.\"LINES\"",
    1535             :             nrServerThreads > 1 ?
    1536             :                 "Resultset with 1 columns\n"
    1537             :                 "Resultset with 46 rows\n"
    1538             :                 "mal\n"
    1539             :                 "WLONGVARCHAR(174)\n"
    1540             :                 "function user.main():void;\n"
    1541             :                 "    X_1:void := querylog.define(\"explain select * from odbctst.\\\"LINES\\\";\":str, \"default_pipe\":str, 26:int);\n"
    1542             :                 "\n"
    1543             :                 "    X_33:bat[:int] := bat.new(nil:int);\n"
    1544             :                 "    X_34:bat[:int] := bat.new(nil:int);\n"
    1545             :                 "    X_35:bat[:int] := bat.new(nil:int);\n"
    1546             :                 "    X_36:bat[:int] := bat.new(nil:int);\n"
    1547             :                 "    X_38:bat[:str] := bat.pack(\"odbctst.LINES\":str, \"odbctst.LINES\":str, \"odbctst.LINES\":str, \"odbctst.LINES\":str);\n"
    1548             :                 "    X_39:bat[:str] := bat.pack(\"ORDERID\":str, \"LINES\":str, \"PARTID\":str, \"QUANTITY\":str);\n"
    1549             :                 "    X_40:bat[:str] := bat.pack(\"int\":str, \"int\":str, \"int\":str, \"decimal\":str);\n"
    1550             :                 "    X_41:bat[:int] := bat.pack(31:int, 31:int, 31:int, 9:int);\n"
    1551             :                 "    X_42:bat[:int] := bat.pack(0:int, 0:int, 0:int, 3:int);\n"
    1552             :                 "\n"
    1553             :                 "    X_37:int := sql.resultSet(X_38:bat[:str], X_39:bat[:str], X_40:bat[:str], X_41:bat[:int], X_42:bat[:int], X_33:bat[:int], X_34:bat[:int], X_35:bat[:int], X_36:bat[:int]);\n"
    1554             :                 "end user.main;\n"
    1555             :                 "\n\n\n\n\n\n\n\n\n\n"
    1556             :                 "\n\n\n\n\n\n\n\n\n\n"
    1557             :                 "\n\n\n\n\n\n\n\n\n\n"
    1558             :                 "\n"
    1559             :             :
    1560             :                 "Resultset with 1 columns\n"
    1561             :                 "Resultset with 44 rows\n"
    1562             :                 "mal\n"
    1563             :                 "WLONGVARCHAR(174)\n"
    1564             :                 "function user.main():void;\n"
    1565             :                 "    X_1:void := querylog.define(\"explain select * from odbctst.\\\"LINES\\\";\":str, \"default_pipe\":str, 26:int);\n"
    1566             :                 "    X_33:bat[:int] := bat.new(nil:int);\n"
    1567             :                 "    X_34:bat[:int] := bat.new(nil:int);\n"
    1568             :                 "    X_35:bat[:int] := bat.new(nil:int);\n"
    1569             :                 "    X_36:bat[:int] := bat.new(nil:int);\n"
    1570             :                 "    X_38:bat[:str] := bat.pack(\"odbctst.LINES\":str, \"odbctst.LINES\":str, \"odbctst.LINES\":str, \"odbctst.LINES\":str);\n"
    1571             :                 "    X_39:bat[:str] := bat.pack(\"ORDERID\":str, \"LINES\":str, \"PARTID\":str, \"QUANTITY\":str);\n"
    1572             :                 "    X_40:bat[:str] := bat.pack(\"int\":str, \"int\":str, \"int\":str, \"decimal\":str);\n"
    1573             :                 "    X_41:bat[:int] := bat.pack(31:int, 31:int, 31:int, 9:int);\n"
    1574             :                 "    X_42:bat[:int] := bat.pack(0:int, 0:int, 0:int, 3:int);\n"
    1575             :                 "    X_37:int := sql.resultSet(X_38:bat[:str], X_39:bat[:str], X_40:bat[:str], X_41:bat[:int], X_42:bat[:int], X_33:bat[:int], X_34:bat[:int], X_35:bat[:int], X_36:bat[:int]);\n"
    1576             :                 "end user.main;\n"
    1577             :                 "\n\n\n\n\n\n\n\n\n\n"
    1578             :                 "\n\n\n\n\n\n\n\n\n\n"
    1579             :                 "\n\n\n\n\n\n\n\n\n\n"
    1580             :                 "\n");
    1581             : 
    1582             :         // test TRACE SELECT query.
    1583             :         // This will return two resultsets: first with the query results and next with the trace results
    1584             :         // We use (and thus test) SQLMoreResults() to get the next/second result.
    1585           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *) "TRACE SELECT * from odbctst.\"LINES\";", SQL_NTS);
    1586           1 :         compareResultNoClose(stmt, ret, "TRACE(1) SELECT * from odbctst.\"LINES\"",
    1587             :                 "Resultset with 4 columns\n"
    1588             :                 "Resultset with 0 rows\n"
    1589             :                 "ORDERID   LINES   PARTID  QUANTITY\n"
    1590             :                 "INTEGER   INTEGER INTEGER DECIMAL(9,3)\n");
    1591           1 :         ret = SQLMoreResults(stmt);
    1592           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLMoreResults()");
    1593           1 :         if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
    1594           1 :                 compareResult(stmt, ret, "TRACE(2) SELECT * from odbctst.\"LINES\"",
    1595             :                     nrServerThreads > 1 ?
    1596             :                         "Resultset with 2 columns\n"
    1597             :                         "Resultset with 12 rows\n"
    1598             :                         "usec      statement\n"
    1599             :                         "BIGINT    WVARCHAR\n"
    1600             :                         "4 variable output\n"
    1601             :                         "4 variable output\n"
    1602             :                         "4 variable output\n"
    1603             :                         "4 variable output\n"
    1604             :                         "4 variable output\n"
    1605             :                         "4 variable output\n"
    1606             :                         "4 variable output\n"
    1607             :                         "4 variable output\n"
    1608             :                         "4 variable output\n"
    1609             :                         "4 variable output\n"
    1610             :                         "4 variable output\n"
    1611             :                         "4 variable output\n"
    1612             :                     :
    1613             :                         "Resultset with 2 columns\n"
    1614             :                         "Resultset with 11 rows\n"
    1615             :                         "usec      statement\n"
    1616             :                         "BIGINT    WVARCHAR\n"
    1617             :                         "4 variable output\n"
    1618             :                         "4 variable output\n"
    1619             :                         "4 variable output\n"
    1620             :                         "4 variable output\n"
    1621             :                         "4 variable output\n"
    1622             :                         "4 variable output\n"
    1623             :                         "4 variable output\n"
    1624             :                         "4 variable output\n"
    1625             :                         "4 variable output\n"
    1626             :                         "4 variable output\n"
    1627             :                         "4 variable output\n");
    1628             :                 /* next is the original output but it is varying a lot on usec values, X_## values and even the order of rows,
    1629             :                    so all data is replaced (see above) for stable output comparison.
    1630             :                         "1     X_1=0@0:void := querylog.define(\"trace select * from odbctst.\\\"LINES\\\";\":str, \"default_pipe\":str, 26:int);\n"
    1631             :                         "9     X_33=[0]:bat[:int] := bat.new(nil:int);\n"
    1632             :                         "8     X_34=[0]:bat[:int] := bat.new(nil:int);\n"
    1633             :                         "7     X_36=[0]:bat[:int] := bat.new(nil:int);\n"
    1634             :                         "6     X_35=[0]:bat[:int] := bat.new(nil:int);\n"
    1635             :                         "8     X_41=[4]:bat[:int] := bat.pack(32:int, 32:int, 32:int, 9:int);\n"
    1636             :                         "13            X_42=[4]:bat[:int] := bat.pack(0:int, 0:int, 0:int, 3:int);\n"
    1637             :                         "14            X_38=[4]:bat[:str] := bat.pack(\"odbctst.LINES\":str, \"odbctst.LINES\":str, \"odbctst.LINES\":str, \"odbctst.LINES\":str);\n"
    1638             :                         "16            X_40=[4]:bat[:str] := bat.pack(\"int\":str, \"int\":str, \"int\":str, \"decimal\":str);\n"
    1639             :                         "15            X_39=[4]:bat[:str] := bat.pack(\"ORDERID\":str, \"LINES\":str, \"PARTID\":str, \"QUANTITY\":str);\n"
    1640             :                         "316       barrier X_106=false:bit := language.dataflow();\n"
    1641             :                         "22            X_37=76:int := sql.resultSet(X_38=[4]:bat[:str], X_39=[4]:bat[:str], X_40=[4]:bat[:str], X_41=[4]:bat[:int], X_42=[4]:bat[:int], X_33=[0]:bat[:int], X_34=[0]:bat[:int], X_35=[0]:bat[:int], X_36=[0]:bat[:int]);\n");
    1642             :                 */
    1643             :         }
    1644             : 
    1645             :         // test DEBUG SELECT query.
    1646             :         // DEBUG statements are *not* supported in ODBC and should produce an Error
    1647           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *) "DEBUG SELECT * from odbctst.\"LINES\";", SQL_NTS);
    1648           1 :         if (ret != SQL_ERROR) {
    1649             :                 /* Error: SQLstate 42000, Errnr 0, Message [MonetDB][ODBC Driver 11.45.0][MonetDB-Test]SQL debugging only supported in interactive mode in: "debug" */
    1650           0 :                 compareResult(stmt, ret, "DEBUG SELECT * from odbctst.\"LINES\"",
    1651             :                         "We do not expect DEBUG to be possible via ODBC API. Only supported in mclient.\n");
    1652             :         }
    1653             : 
    1654             : 
    1655             :         // cleanup
    1656           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *)
    1657             :                 "DROP INDEX odbctst.pk_uc_i;\n"
    1658             :                 "DROP INDEX tmp.tmp_pk_uc_i;\n"
    1659             :                 "DROP INDEX tmp.glbl_pk_uc_i;\n"
    1660             :                 "DROP INDEX odbctst.nopk_twoucs_i;\n"
    1661             :                 "DROP INDEX tmp.tmp_nopk_twoucs_i;\n"
    1662             :                 "DROP INDEX tmp.glbl_nopk_twoucs_i;\n"
    1663             :                 , SQL_NTS);
    1664           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLExecDirect (drop indices script)");
    1665             : 
    1666           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *)
    1667             :                 "DROP TABLE odbctst.pk_uc;\n"
    1668             :                 "DROP TABLE tmp.tmp_pk_uc;\n"
    1669             :                 "DROP TABLE tmp.glbl_pk_uc;\n"
    1670             :                 "DROP TABLE odbctst.nopk_twoucs;\n"
    1671             :                 "DROP TABLE tmp.tmp_nopk_twoucs;\n"
    1672             :                 "DROP TABLE tmp.glbl_nopk_twoucs;\n"
    1673             :                 "DROP TABLE odbctst.\"LINES\";\n"
    1674             :                 "DROP TABLE odbctst.\"ORDERS\";\n"
    1675             :                 "DROP TABLE odbctst.\"CUSTOMERS\";\n"
    1676             :                 "DROP TABLE odbctst.fk2c;\n"
    1677             :                 "DROP TABLE odbctst.pk2c;\n"
    1678             :                 , SQL_NTS);
    1679           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLExecDirect (drop tables script)");
    1680             : 
    1681             :         // All tables in schema odbctst should now be gone, else we missed some DROP statements
    1682           1 :         ret = SQLTables(stmt, NULL, 0,
    1683             :                         (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"%", SQL_NTS,
    1684             :                         NULL, 0);
    1685           1 :         compareResult(stmt, ret, "SQLTables (odbctst, %, NULL)",
    1686             :                 "Resultset with 5 columns\n"
    1687             :                 "Resultset with 0 rows\n"
    1688             :                 "TABLE_CAT TABLE_SCHEM     TABLE_NAME      TABLE_TYPE      REMARKS\n"
    1689             :                 "WVARCHAR(1)       WVARCHAR(1024)  WVARCHAR(1024)  WVARCHAR(25)    WVARCHAR(65000)\n");
    1690             : 
    1691           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *)
    1692             :                 "SET SCHEMA sys;\n"
    1693             :                 "DROP SCHEMA odbctst;\n"
    1694             :                 , SQL_NTS);
    1695           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLExecDirect (drop schema script)");
    1696             : 
    1697           1 :         ret = SQLFreeHandle(SQL_HANDLE_STMT, stmt);
    1698           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLFreeHandle (STMT)");
    1699             : 
    1700           1 :         ret = SQLDisconnect(dbc);
    1701           1 :         check(ret, SQL_HANDLE_DBC, dbc, "SQLDisconnect");
    1702             : 
    1703           1 :         ret = SQLFreeHandle(SQL_HANDLE_DBC, dbc);
    1704           1 :         check(ret, SQL_HANDLE_DBC, dbc, "SQLFreeHandle (DBC)");
    1705             : 
    1706           1 :         ret = SQLFreeHandle(SQL_HANDLE_ENV, env);
    1707           1 :         check(ret, SQL_HANDLE_ENV, env, "SQLFreeHandle (ENV)");
    1708             : 
    1709           1 :         return 0;
    1710             : }

Generated by: LCOV version 1.14