MonetDB: Aug2024 - Fix diagnostic in streamcat
Changeset: f20799ff6a30 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/f20799ff6a30 Modified Files: clients/examples/C/streamcat.c Branch: Aug2024 Log Message: Fix diagnostic in streamcat diffs (12 lines): diff --git a/clients/examples/C/streamcat.c b/clients/examples/C/streamcat.c --- a/clients/examples/C/streamcat.c +++ b/clients/examples/C/streamcat.c @@ -422,7 +422,7 @@ opener_rstream(char *filename) { stream *s = open_rstream(filename); if (!mnstr_isbinary(s)) - croak(2, "open_rastream returned binary stream"); + croak(2, "open_rstream returned text stream"); return s; } ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Test non-NUL-terminated arguments
Changeset: 55b7f9555245 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/55b7f9555245 Modified Files: clients/odbc/tests/odbcconnect.c sql/odbc/tests/Tests/ODBCconnect.py Branch: Aug2024 Log Message: Test non-NUL-terminated arguments diffs (172 lines): diff --git a/clients/odbc/tests/odbcconnect.c b/clients/odbc/tests/odbcconnect.c --- a/clients/odbc/tests/odbcconnect.c +++ b/clients/odbc/tests/odbcconnect.c @@ -17,6 +17,7 @@ #endif #include +#include #include #include #include @@ -33,6 +34,7 @@ static const char *USAGE = "-l List registered drivers and data sources\n" "-u USER\n" "-p PASSWORD\n" + "-0 use counted strings rather than nul-terminated arguments\n" "-v Be verbose\n" "TARGET DSN or with -d and -b, Connection String\n"; @@ -49,10 +51,16 @@ static int do_listdsns(const char *prefi static void ensure_ok(SQLSMALLINT type, SQLHANDLE handle, const char *message, SQLRETURN ret); +#define MARGIN 100 +static SQLCHAR* sqldup_with_margin(const char *str); +static void fuzz_sql_nts(SQLCHAR **str, SQLSMALLINT *len); int verbose = 0; SQLCHAR *user = NULL; +SQLSMALLINT user_len = SQL_NTS; SQLCHAR *password = NULL; +SQLSMALLINT password_len = SQL_NTS; +bool use_counted_strings = false; SQLHANDLE env = NULL; SQLHANDLE conn = NULL; @@ -89,13 +97,15 @@ main(int argc, char **argv) else if (strcmp(arg, "-l") == 0) action = NULL; else if (strcmp(arg, "-u") == 0 && i + 1 < argc) - user = (SQLCHAR*)argv[++i]; + user = sqldup_with_margin(argv[++i]); else if (strcmp(arg, "-p") == 0 && i + 1 < argc) - password = (SQLCHAR*)argv[++i]; + password = sqldup_with_margin(argv[++i]); + else if (strcmp(arg, "-0") == 0) + use_counted_strings = true; else if (strcmp(arg, "-v") == 0) verbose += 1; else if (arg[0] != '-') - targets[ntargets++] = (SQLCHAR*)arg; + targets[ntargets++] = sqldup_with_margin(arg); else { fprintf(stderr, "\nERROR: invalid argument: %s\n%s", arg, USAGE); ret = 1; @@ -111,6 +121,11 @@ main(int argc, char **argv) SQL_HANDLE_ENV, env, "set odbc version", SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0)); + if (use_counted_strings) { + fuzz_sql_nts(&user, &user_len); + fuzz_sql_nts(&password, &password_len); + } + if (action) { if (ntargets == 0) { fprintf(stderr, "\nERROR: pass at least one target\n%s", USAGE); @@ -130,6 +145,10 @@ main(int argc, char **argv) } end: + free(user); + free(password); + for (int i = 0; i < ntargets; i++) + free(targets[i]); free(targets); cleanup(); @@ -207,9 +226,13 @@ do_actions(action_t action, int ntargets static int do_sqlconnect(SQLCHAR *target) { + SQLSMALLINT target_len = SQL_NTS; + if (use_counted_strings) + fuzz_sql_nts(&target, &target_len); + ensure_ok( SQL_HANDLE_DBC, conn, "SQLConnect", - SQLConnect(conn, target, SQL_NTS, user, SQL_NTS, password, SQL_NTS)); + SQLConnect(conn, target, target_len, user, user_len, password, password_len)); printf("OK\n"); return 0; @@ -219,11 +242,15 @@ static int do_sqldriverconnect(SQLCHAR *target) { SQLSMALLINT n; + SQLSMALLINT target_len = SQL_NTS; + if (use_counted_strings) + fuzz_sql_nts(&target, &target_len); + ensure_ok( SQL_HANDLE_DBC, conn, "SQLDriverConnect", SQLDriverConnect( conn, NULL, - target, SQL_NTS, + target, target_len, outbuf, sizeof(outbuf), &n, SQL_DRIVER_NOPROMPT )); @@ -236,9 +263,13 @@ static int do_sqlbrowseconnect(SQLCHAR *target) { SQLSMALLINT n; + SQLSMALLINT target_len = SQL_NTS; + if (use_counted_strings) + fuzz_sql_nts(&target, &target_len); + SQLRETURN ret = SQLBrowseConnect( conn, - target, SQL_NTS, + target, target_len, outbuf, sizeof(outbuf), &n ); ensure_ok(SQL_HANDLE_DBC, conn, "SQLBrowseConnect", ret); @@ -302,3 +333,27 @@ do_listdsns(const char *prefix, SQLSMALL return 0; } + +static SQLCHAR* +sqldup_with_margin(const char *str) +{ + size_t len = strlen(str); + char *buf = malloc(len + MARGIN); +
MonetDB: Aug2024 - Copy data, not the pointer
Changeset: 7177f1898fe2 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/7177f1898fe2 Modified Files: clients/odbc/driver/SQLConnect.c Branch: Aug2024 Log Message: Copy data, not the pointer diffs (12 lines): diff --git a/clients/odbc/driver/SQLConnect.c b/clients/odbc/driver/SQLConnect.c --- a/clients/odbc/driver/SQLConnect.c +++ b/clients/odbc/driver/SQLConnect.c @@ -121,7 +121,7 @@ makeNulTerminated(const SQLCHAR **argume SQLCHAR *value = malloc(argument_len + 1); if (value == NULL) return false; - memmove(value, argument, argument_len); + memmove(value, *argument, argument_len); value[argument_len] = '\0'; *argument = value; ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Test SQLDriverConnect
Changeset: 7e379cfaffaf for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/7e379cfaffaf Modified Files: sql/odbc/tests/Tests/ODBCconnect.py testing/Mtest.py.in Branch: Aug2024 Log Message: Test SQLDriverConnect diffs (121 lines): diff --git a/sql/odbc/tests/Tests/ODBCconnect.py b/sql/odbc/tests/Tests/ODBCconnect.py --- a/sql/odbc/tests/Tests/ODBCconnect.py +++ b/sql/odbc/tests/Tests/ODBCconnect.py @@ -14,9 +14,16 @@ # sqlstate lines of the form '- STATE: MESSAGE'. import atexit +import os import subprocess import sys +dsn = 'MonetDB-Test' +dbname = os.environ.get('TSTDB', 'demo') +user = 'monetdb' +password = 'monetdb' +port = os.environ.get('MAPIPORT', 5) + class Execution: def __init__(self, *odbcconnect_args): @@ -97,38 +104,35 @@ def show_context(): print(ex.report(), file=sys.stderr) -dbname = 'MonetDB-Test' - - -ex = Execution(dbname) +ex = Execution(dsn) ex.expect('OK') ex.end() -ex = Execution(dbname + '-nonexistent') +ex = Execution(dsn + '-nonexistent') ex.expect_fail() ex.expect('Error') ex.expect('IM002:') # IM002 not found ex.end() -ex = Execution(dbname, '-p', 'wrongpassword') +ex = Execution(dsn, '-p', 'wrongpassword') ex.expect_fail() ex.expect('Error') ex.expect('28000:') # 28000 bad credentials ex.end() -ex = Execution(dbname, '-u', 'wronguser') +ex = Execution(dsn, '-u', 'wronguser') ex.expect_fail() ex.expect('Error') ex.expect('28000:') # 28000 bad credentials ex.end() -ex = Execution(dbname, '-p', '') +ex = Execution(dsn, '-p', '') ex.expect_fail() ex.expect('Error') ex.expect('28000:') # 28000 bad credentials ex.end() -ex = Execution(dbname, '-u', '') +ex = Execution(dsn, '-u', '') ex.expect_fail() ex.expect('Error') ex.expect('28000:') # 28000 bad credentials @@ -136,13 +140,33 @@ ex.end() # test non-NUL terminated strings -ex = Execution(dbname, '-0') +ex = Execution(dsn, '-0') +ex.expect('OK') +ex.end() + +ex = Execution(dsn, '-0', '-u', user, '-p', password) +ex.expect('OK') +ex.end() + +# test connection strings + +ex = Execution('-d', f'DSN={dsn}') ex.expect('OK') ex.end() -ex = Execution(dbname, '-0', '-u', 'monetdb', '-p', 'monetdb') +# override things that are already set in the dsn +ex = Execution('-d', f'DSN={dsn}-Wrong;Database={dbname};Uid={user};Pwd={password}') ex.expect('OK') ex.end() +# .. even if the DSN= comes last +ex = Execution('-d', f'Database={dbname};Uid={user};Pwd={password};DSN={dsn}-Wrong') +ex.expect('OK') +ex.end() + +# test without DSN= clause +ex = Execution('-d', f'DRIVER={{MonetDB}};Database={dbname};Uid={user};Pwd={password};Port={port}') +ex.expect('OK') +ex.end() ex = None diff --git a/testing/Mtest.py.in b/testing/Mtest.py.in --- a/testing/Mtest.py.in +++ b/testing/Mtest.py.in @@ -2227,6 +2227,16 @@ Database = {TSTDB} User = {user or "monetdb"} Password = {passwd or "monetdb"} Debug = + +[MonetDB-Test-Wrong] +Description = Wrong values for Database, Uid and Pwd +Driver = {env["LIBDIR"]}/libMonetODBC.so +Setup = {env["LIBDIR"]}/libMonetODBCs.so +Host = localhost +Port = {env["MAPIPORT"]} +Database = {TSTDB}-Wrong +User = {user or "monetdb"}-Wrong +Password = {passwd or "monetdb"}-Wrong ''') f.close() os.environ['ODBCINI'] = os.path.join(TSTTRGDIR, 'odbc.ini') ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Mtest: set ODBCSYSINI instead of ODBCINI
Changeset: 766bdabd4d7c for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/766bdabd4d7c Modified Files: testing/Mtest.py.in Branch: Aug2024 Log Message: Mtest: set ODBCSYSINI instead of ODBCINI And split odbc.ini into odbc.ini and odbcinst.ini This insulates Mtest's odbc setup from whatever else is going on in the system. odbc.ini can now just set Driver=MonetDB and does not need any file system paths diffs (64 lines): diff --git a/testing/Mtest.py.in b/testing/Mtest.py.in --- a/testing/Mtest.py.in +++ b/testing/Mtest.py.in @@ -2215,12 +2215,18 @@ def RunTest(env, TST, COND, oktests, len f.close() if odbc: -f = openutf8('odbc.ini', 'w') -f.write(f'''\ -[MonetDB-Test] +with openutf8('odbcinst.ini', 'w') as f: +f.write(f'''\ +[MonetDB] Description = Test MonetDB Data Source Driver = {env["LIBDIR"]}/libMonetODBC.so Setup = {env["LIBDIR"]}/libMonetODBCs.so +''') +with openutf8('odbc.ini', 'w') as f: +f.write(f'''\ +[MonetDB-Test] +Description = Test MonetDB Data Source +Driver = MonetDB Host = localhost Port = {env["MAPIPORT"]} Database = {TSTDB} @@ -2230,16 +2236,17 @@ Debug = [MonetDB-Test-Wrong] Description = Wrong values for Database, Uid and Pwd -Driver = {env["LIBDIR"]}/libMonetODBC.so -Setup = {env["LIBDIR"]}/libMonetODBCs.so +Driver = MonetDB Host = localhost Port = {env["MAPIPORT"]} Database = {TSTDB}-Wrong User = {user or "monetdb"}-Wrong Password = {passwd or "monetdb"}-Wrong ''') -f.close() -os.environ['ODBCINI'] = os.path.join(TSTTRGDIR, 'odbc.ini') +orig_odbcsysini = os.environ.pop('ODBCSYSINI', None) +orig_odbcini = os.environ.pop('ODBCINI', None) +orig_odbcinstini = os.environ.pop('ODBCINSTINI', None) +os.environ['ODBCSYSINI'] = TSTTRGDIR STABLEout,STABLEerr = StableOutErr(env,par,TST,SYST,RELEASE,DIST,VERSION) TIMEOUT = par['TIMEOUT'] @@ -2268,7 +2275,15 @@ Password = {passwd or "monetdb"}-Wrong print(" %7.3fs " % TX, end='') if odbc: -del os.environ['ODBCINI'] +if orig_odbcsysini is not None: +os.environ['ODBCSYSINI'] = orig_odbcsysini +else: +del os.environ['ODBCSYSINI'] +if orig_odbcini is not None: +os.environ['ODBCINI'] = orig_odbcini +if orig_odbcinstini is not None: +os.environ['ODBCINSTINI'] = orig_odbcinstini + if tres == 'timeout': errcode = F_TIME ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Add tests for SQLBrowseConnect
Changeset: c2718b187150 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/c2718b187150 Modified Files: sql/odbc/tests/Tests/ODBCconnect.py Branch: Aug2024 Log Message: Add tests for SQLBrowseConnect diffs (77 lines): diff --git a/sql/odbc/tests/Tests/ODBCconnect.py b/sql/odbc/tests/Tests/ODBCconnect.py --- a/sql/odbc/tests/Tests/ODBCconnect.py +++ b/sql/odbc/tests/Tests/ODBCconnect.py @@ -56,7 +56,10 @@ class Execution: if self.checks: parts.append('--- test history: ---') for wanted, found in self.checks: -parts.append(f'wanted {wanted!r}, found {found!r}') +if len(wanted) == 1: +parts.append(f'wanted {wanted[0]!r}, found {found!r}') +else: +parts.append(f'wanted all of {wanted!r}, found {found!r}') parts.append('--- end ---') if self.remaining: parts += [ @@ -66,11 +69,13 @@ class Execution: ] return '\n'.join(parts) -def expect(self, pattern): +def expect(self, pattern, *more_patterns): +patterns = [pattern, *more_patterns] line = self.next_line() -self.checks.append((pattern, line)) -if pattern not in line: -raise Exception(f'Wanted {pattern!r}, found {line!r}') +self.checks.append((patterns, line)) +for p in patterns: +if p not in line: +raise Exception(f'Wanted {p!r}, found {line!r}') def next_line(self): if not self.remaining: @@ -169,4 +174,43 @@ ex = Execution('-d', f'DRIVER={{MonetDB} ex.expect('OK') ex.end() +# non-NUL terminated connection string +ex = Execution('-0', '-d', f'DSN={dsn}-Wrong;Database={dbname};Uid={user};Pwd={password}') +ex.expect('OK') +ex.end() + +# Test browsing + +ex = Execution('-b', 'Driver={MonetDB}') +ex.expect('Info') +ex.expect('08001') +# browse not complete, uid and pwd mandatory, database optional +ex.expect('BROWSE', 'UID:User=?', 'PWD:Password=?', '*DATABASE') +ex.end() + +# same as above, but with another iteration of browsing +ex = Execution('-b', 'Driver={MonetDB}', f'Driver={{MonetDB}};UID={user};PWD={password};Port={port}') +# first iteration +ex.expect('Info') +ex.expect('08001') +ex.expect('BROWSE', 'UID:User=?', 'PWD:Password=?', '*DATABASE') +# second iteration +ex.expect('OK', ';', 'HOST=') +ex.end() + +# similar to above, but not NUL-terminated +ex = Execution('-0', '-b', 'Driver={MonetDB}') +ex.expect('Info') +ex.expect('08001') +# browse not complete, uid and pwd mandatory, database optional +ex.expect('BROWSE', 'UID:User=?', 'PWD:Password=?', '*DATABASE') +ex.end() + +# it should also work when the user and password are in the dsn +ex = Execution('-b', f'DSN={dsn}') +ex.expect('OK', ';') +ex.end() + +# clear 'ex', otherwise the atexit handler will write things +# to stderr ex = None ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Close connection handles after use
Changeset: 62dcc4c2 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/62dcc4c2 Modified Files: clients/odbc/tests/odbcconnect.c Branch: Aug2024 Log Message: Close connection handles after use diffs (55 lines): diff --git a/clients/odbc/tests/odbcconnect.c b/clients/odbc/tests/odbcconnect.c --- a/clients/odbc/tests/odbcconnect.c +++ b/clients/odbc/tests/odbcconnect.c @@ -71,6 +71,8 @@ SQLCHAR attrbuf[4096]; static void cleanup(void) { + free(user); + free(password); if (conn) { SQLDisconnect(conn); SQLFreeHandle(SQL_HANDLE_DBC, conn); @@ -145,8 +147,6 @@ main(int argc, char **argv) } end: - free(user); - free(password); for (int i = 0; i < ntargets; i++) free(targets[i]); free(targets); @@ -235,6 +235,10 @@ do_sqlconnect(SQLCHAR *target) SQLConnect(conn, target, target_len, user, user_len, password, password_len)); printf("OK\n"); + ensure_ok( + SQL_HANDLE_DBC, conn, "Banana", + SQLDisconnect(conn)); + return 0; } @@ -256,6 +260,11 @@ do_sqldriverconnect(SQLCHAR *target) )); printf("OK %s\n", outbuf); + + ensure_ok( + SQL_HANDLE_DBC, conn, "Banana", + SQLDisconnect(conn)); + return 0; } @@ -277,6 +286,10 @@ do_sqlbrowseconnect(SQLCHAR *target) ret == SQL_NEED_DATA ? "BROWSE" : "OK", outbuf ); + + // Do not call SQLDisconnect, SQLBrowseConnect is intended to + // be invoked multiple times without disconnecting inbetween + return 0; } ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Show errors that do not set any diagnostics
Changeset: 3da6dc78a5f8 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/3da6dc78a5f8 Modified Files: clients/odbc/tests/odbcconnect.c Branch: Aug2024 Log Message: Show errors that do not set any diagnostics diffs (26 lines): diff --git a/clients/odbc/tests/odbcconnect.c b/clients/odbc/tests/odbcconnect.c --- a/clients/odbc/tests/odbcconnect.c +++ b/clients/odbc/tests/odbcconnect.c @@ -183,6 +183,7 @@ ensure_ok(SQLSMALLINT type, SQLHANDLE ha SQLCHAR explanation[256]; SQLSMALLINT len; + bool printed_something = false; for (int i = 1; ; i++) { SQLRETURN diag_ret = SQLGetDiagRec( type, handle, i, @@ -194,9 +195,14 @@ ensure_ok(SQLSMALLINT type, SQLHANDLE ha class = NULL; } printf("- %s: %s\n", state, explanation); + printed_something = true; } if (!SQL_SUCCEEDED(ret) && ret != SQL_NEED_DATA) { + if (!printed_something) { + printf("%s: %s\n", class, message); + printf("- failed without explanation\n"); + } cleanup(); exit(1); } ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Add option to execute a sql statement after c...
Changeset: f552db6c983d for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/f552db6c983d Modified Files: clients/odbc/tests/odbcconnect.c Branch: Aug2024 Log Message: Add option to execute a sql statement after connecting diffs (193 lines): diff --git a/clients/odbc/tests/odbcconnect.c b/clients/odbc/tests/odbcconnect.c --- a/clients/odbc/tests/odbcconnect.c +++ b/clients/odbc/tests/odbcconnect.c @@ -34,21 +34,23 @@ static const char *USAGE = "-l List registered drivers and data sources\n" "-u USER\n" "-p PASSWORD\n" + "-q SQL Execute SQL statement when connection succeeds\n" "-0 use counted strings rather than nul-terminated arguments\n" "-v Be verbose\n" "TARGET DSN or with -d and -b, Connection String\n"; typedef int (action_t)(SQLCHAR *); -static int do_actions(action_t action, int ntargets, SQLCHAR **targets); - static action_t do_sqlconnect; static action_t do_sqldriverconnect; static action_t do_sqlbrowseconnect; +static int do_actions(action_t action, int ntargets, SQLCHAR **targets); + static int do_listdrivers(void); static int do_listdsns(const char *prefix, SQLSMALLINT dir); +static int do_execute_stmt(void); static void ensure_ok(SQLSMALLINT type, SQLHANDLE handle, const char *message, SQLRETURN ret); #define MARGIN 100 @@ -60,10 +62,13 @@ SQLCHAR *user = NULL; SQLSMALLINT user_len = SQL_NTS; SQLCHAR *password = NULL; SQLSMALLINT password_len = SQL_NTS; +SQLCHAR *query = NULL; +SQLSMALLINT query_len = SQL_NTS; bool use_counted_strings = false; SQLHANDLE env = NULL; SQLHANDLE conn = NULL; +SQLHANDLE stmt = NULL; SQLCHAR outbuf[4096]; SQLCHAR attrbuf[4096]; @@ -73,6 +78,9 @@ cleanup(void) { free(user); free(password); + free(query); + if (stmt) + SQLFreeHandle(SQL_HANDLE_STMT, stmt); if (conn) { SQLDisconnect(conn); SQLFreeHandle(SQL_HANDLE_DBC, conn); @@ -102,6 +110,8 @@ main(int argc, char **argv) user = sqldup_with_margin(argv[++i]); else if (strcmp(arg, "-p") == 0 && i + 1 < argc) password = sqldup_with_margin(argv[++i]); + else if (strcmp(arg, "-q") == 0 && i + 1 < argc) + query = sqldup_with_margin(argv[++i]); else if (strcmp(arg, "-0") == 0) use_counted_strings = true; else if (strcmp(arg, "-v") == 0) @@ -159,7 +169,6 @@ end: static void ensure_ok(SQLSMALLINT type, SQLHANDLE handle, const char *message, SQLRETURN ret) { - char *class = "Info"; switch (ret) { case SQL_SUCCESS: @@ -241,11 +250,13 @@ do_sqlconnect(SQLCHAR *target) SQLConnect(conn, target, target_len, user, user_len, password, password_len)); printf("OK\n"); + int exitcode = do_execute_stmt(); + ensure_ok( - SQL_HANDLE_DBC, conn, "Banana", + SQL_HANDLE_DBC, conn, "SQLDisconnect", SQLDisconnect(conn)); - return 0; + return exitcode; } static int @@ -267,11 +278,13 @@ do_sqldriverconnect(SQLCHAR *target) printf("OK %s\n", outbuf); + int exitcode = do_execute_stmt(); + ensure_ok( - SQL_HANDLE_DBC, conn, "Banana", + SQL_HANDLE_DBC, conn, "SQLDisconnect", SQLDisconnect(conn)); - return 0; + return exitcode; } static int @@ -293,10 +306,15 @@ do_sqlbrowseconnect(SQLCHAR *target) outbuf ); + int exitcode = 0; + if (ret != SQL_NEED_DATA) + exitcode = do_execute_stmt(); + + // Do not call SQLDisconnect, SQLBrowseConnect is intended to // be invoked multiple times without disconnecting inbetween - return 0; + return exitcode; } static int @@ -353,6 +371,64 @@ do_listdsns(const char *prefix, SQLSMALL } +static int +do_execute_stmt(void) +{ + if (query == NULL) + return 0; + + if (verbose) + printf("Statement: %s\n", query); + + if (use_counted_strings) + fuzz_sql_nts(&query, &query_len); + + ensure_ok( + SQL_HANDLE_ENV, conn, "allocate stmt handle", + SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt)); + + ensure_ok( + SQL_HANDLE_STMT, stmt, "SQLExecDirect", + SQLExecDirect(stmt, query, query_len)); + + do { + SQLLEN rowcount = -1; + SQLSMALLINT colcount = -1; + + ensure_ok( + SQL_HANDLE_STMT, stmt, "SQLRowCount", + SQLRowCount(stmt, &rowcount)); + + ensure_ok( + SQL_HANDLE_STMT, stmt, "SQLNumResultCols", + SQL
MonetDB: Aug2024 - Include line numbers in -v output
Changeset: 2cc634740180 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/2cc634740180 Modified Files: clients/odbc/tests/odbcconnect.c Branch: Aug2024 Log Message: Include line numbers in -v output diffs (59 lines): diff --git a/clients/odbc/tests/odbcconnect.c b/clients/odbc/tests/odbcconnect.c --- a/clients/odbc/tests/odbcconnect.c +++ b/clients/odbc/tests/odbcconnect.c @@ -51,7 +51,10 @@ static int do_listdrivers(void); static int do_listdsns(const char *prefix, SQLSMALLINT dir); static int do_execute_stmt(void); -static void ensure_ok(SQLSMALLINT type, SQLHANDLE handle, const char *message, SQLRETURN ret); + +static void ensure_ok_impl(SQLSMALLINT type, SQLHANDLE handle, const char *message, SQLRETURN ret, int lineno); + +#define ensure_ok(type, handle, message, ret)ensure_ok_impl(type, handle, message, ret, __LINE__) #define MARGIN 100 static SQLCHAR* sqldup_with_margin(const char *str); @@ -167,14 +170,23 @@ end: static void -ensure_ok(SQLSMALLINT type, SQLHANDLE handle, const char *message, SQLRETURN ret) +ensure_ok_impl(SQLSMALLINT type, SQLHANDLE handle, const char *message, SQLRETURN ret, int lineno) { + static const char *filename = NULL; + if (!filename) { + filename = __FILE__; + for (const char *p = filename; *p; p++) { + if (*p == '/' || *p == '\\') + filename = p + 1; + } + } + char *class = "Info"; switch (ret) { case SQL_SUCCESS: case SQL_NEED_DATA: if (verbose) - printf("Succeeded: %s\n", message); + printf(" Succeeded: %s (%s:%d)\n", message, filename, lineno); break; case SQL_SUCCESS_WITH_INFO: class = "Warning"; @@ -183,7 +195,7 @@ ensure_ok(SQLSMALLINT type, SQLHANDLE ha class = "Error"; break; default: - printf("Internal error: %s: unknown SQLRETURN %d", message, ret); + printf("Internal error: %s (%s:%d): unknown SQLRETURN %d", message, filename, lineno, ret); break; } @@ -200,7 +212,7 @@ ensure_ok(SQLSMALLINT type, SQLHANDLE ha if (!SQL_SUCCEEDED(diag_ret)) break; if (class) { - printf("%s: %s\n", class, message); + printf("%s: %s (%s:%d)\n", class, message, filename, lineno); class = NULL; } printf("- %s: %s\n", state, explanation); ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Get rid of sql_attr_autocommit
Changeset: e48d017e9a10 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/e48d017e9a10 Modified Files: clients/odbc/driver/ODBCDbc.c clients/odbc/driver/ODBCDbc.h clients/odbc/driver/SQLConnect.c clients/odbc/driver/SQLEndTran.c clients/odbc/driver/SQLGetConnectAttr.c clients/odbc/driver/SQLSetConnectAttr.c sql/odbc/tests/Tests/ODBCconnect.py Branch: Aug2024 Log Message: Get rid of sql_attr_autocommit It's part of the msettings now and shouldn't blindly override those. diffs (111 lines): diff --git a/clients/odbc/driver/ODBCDbc.c b/clients/odbc/driver/ODBCDbc.c --- a/clients/odbc/driver/ODBCDbc.c +++ b/clients/odbc/driver/ODBCDbc.c @@ -80,7 +80,6 @@ newODBCDbc(ODBCEnv *env) *dbc = (ODBCDbc) { .Env = env, .settings = settings, - .sql_attr_autocommit = SQL_AUTOCOMMIT_ON, /* default is autocommit */ .sql_attr_metadata_id = SQL_FALSE, /* add this dbc to start of the administrative linked dbc list */ .next = env->FirstDbc, diff --git a/clients/odbc/driver/ODBCDbc.h b/clients/odbc/driver/ODBCDbc.h --- a/clients/odbc/driver/ODBCDbc.h +++ b/clients/odbc/driver/ODBCDbc.h @@ -59,7 +59,6 @@ typedef struct tODBCDRIVERDBC { bool allow_hugeint; /* whether the application deals with HUGEINT */ bool raw_strings; /* server uses raw strings */ int mapToLongVarchar; /* when > 0 we map WVARCHAR to WLONGVARCHAR, default 0 */ - SQLUINTEGER sql_attr_autocommit; SQLUINTEGER sql_attr_metadata_id; /* MonetDB connection handle & status information */ diff --git a/clients/odbc/driver/SQLConnect.c b/clients/odbc/driver/SQLConnect.c --- a/clients/odbc/driver/SQLConnect.c +++ b/clients/odbc/driver/SQLConnect.c @@ -482,7 +482,6 @@ MNDBConnectSettings(ODBCDbc *dbc, const if (mid) { settings = NULL; // will be free'd as part of 'mid' now mapi_setclientprefix(mid, "ODBC " MONETDB_VERSION); - mapi_setAutocommit(mid, dbc->sql_attr_autocommit == SQL_AUTOCOMMIT_ON); mapi_set_size_header(mid, true); mapi_reconnect(mid); } diff --git a/clients/odbc/driver/SQLEndTran.c b/clients/odbc/driver/SQLEndTran.c --- a/clients/odbc/driver/SQLEndTran.c +++ b/clients/odbc/driver/SQLEndTran.c @@ -119,7 +119,7 @@ MNDBEndTran(SQLSMALLINT HandleType, assert(HandleType == SQL_HANDLE_DBC); - if (dbc->sql_attr_autocommit == SQL_AUTOCOMMIT_ON) { + if (msetting_bool(dbc->settings, MP_AUTOCOMMIT)) { /* nothing to do if in autocommit mode */ return SQL_SUCCESS; } diff --git a/clients/odbc/driver/SQLGetConnectAttr.c b/clients/odbc/driver/SQLGetConnectAttr.c --- a/clients/odbc/driver/SQLGetConnectAttr.c +++ b/clients/odbc/driver/SQLGetConnectAttr.c @@ -64,7 +64,8 @@ MNDBGetConnectAttr(ODBCDbc *dbc, break; case SQL_ATTR_AUTOCOMMIT: /* SQLUINTEGER */ /* SQL_AUTOCOMMIT */ - WriteData(ValuePtr, dbc->sql_attr_autocommit, SQLUINTEGER); + bool autocommit = msetting_bool(dbc->settings, MP_AUTOCOMMIT); + WriteData(ValuePtr, autocommit, SQLUINTEGER); break; case SQL_ATTR_CONNECTION_DEAD: /* SQLUINTEGER */ WriteData(ValuePtr, dbc->mid && mapi_is_connected(dbc->mid) ? SQL_CD_FALSE : SQL_CD_TRUE, SQLUINTEGER); diff --git a/clients/odbc/driver/SQLSetConnectAttr.c b/clients/odbc/driver/SQLSetConnectAttr.c --- a/clients/odbc/driver/SQLSetConnectAttr.c +++ b/clients/odbc/driver/SQLSetConnectAttr.c @@ -47,13 +47,12 @@ MNDBSetConnectAttr(ODBCDbc *dbc, switch ((SQLUINTEGER) (uintptr_t) ValuePtr) { case SQL_AUTOCOMMIT_ON: case SQL_AUTOCOMMIT_OFF: - dbc->sql_attr_autocommit = (SQLUINTEGER) (uintptr_t) ValuePtr; + bool autocommit = (bool) (SQLUINTEGER) (uintptr_t) ValuePtr; #ifdef ODBCDEBUG - ODBCLOG("SQLSetConnectAttr set autocommit %s\n", - dbc->sql_attr_autocommit == SQL_AUTOCOMMIT_ON ? "on" : "off"); + ODBCLOG("SQLSetConnectAttr set autocommit %s\n", autocommit ? "on" : "off"); #endif if (dbc->mid) - mapi_setAutocommit(dbc->mid, dbc->sql_attr_autocommit == SQL_AUTOCOMMIT_ON); + mapi_setAutocommit(dbc->mid, autocommit); break; default: /* Invalid attribute value */ diff --git a/sql/odbc/tests/Tests/ODBCconnect.py b/sql/odbc/tests/Tests/ODBCconnect.py --- a/sql/odbc/tests/Tests/ODBCconnect.py +++ b/sql/odbc/tests/Tests/ODBCconnect.py @@ -179,6 +179,29 @@ ex = Execution('-0', '-d', f'DSN={dsn}-W ex.expect('OK') ex.end() +# test autocommit
MonetDB: Aug2024 - Test that settings do not leak into next conn...
Changeset: f8838596f8c9 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/f8838596f8c9 Modified Files: sql/odbc/tests/Tests/ODBCconnect.py Branch: Aug2024 Log Message: Test that settings do not leak into next connection when a handle is reused diffs (41 lines): diff --git a/sql/odbc/tests/Tests/ODBCconnect.py b/sql/odbc/tests/Tests/ODBCconnect.py --- a/sql/odbc/tests/Tests/ODBCconnect.py +++ b/sql/odbc/tests/Tests/ODBCconnect.py @@ -15,6 +15,7 @@ import atexit import os +import shlex import subprocess import sys @@ -37,7 +38,7 @@ class Execution: self.checks = [] def report(self): -parts = [f'COMMAND: {self.cmd}', +parts = [f'COMMAND: {shlex.join(self.cmd)}', f'EXIT CODE: {self.proc.returncode}', ''] if self.proc.stdout: parts += [ @@ -201,6 +202,20 @@ ex.expect('OK') # connect succee ex.expect('RESULT') # rollback succeeds ex.end() +# test that configuration does not leak to next connection when handle is reused +ex = Execution('-d', +'-q', 'select remark from sys.sessions where sessionid = current_sessionid()', +f'DSN={dsn};Client Remark=banana', +f'DSN={dsn}' +) +ex.expect('OK') +ex.expect('RESULT') +ex.expect('- banana;') # as set by Client Remark property +ex.expect('OK') +ex.expect('RESULT') +ex.expect('- ;') # this connection did not have a Client Remark +ex.end() + # Test browsing ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Comment
Changeset: 0b8f54cd8c3f for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/0b8f54cd8c3f Modified Files: clients/odbc/driver/SQLBrowseConnect.c Branch: Aug2024 Log Message: Comment diffs (11 lines): diff --git a/clients/odbc/driver/SQLBrowseConnect.c b/clients/odbc/driver/SQLBrowseConnect.c --- a/clients/odbc/driver/SQLBrowseConnect.c +++ b/clients/odbc/driver/SQLBrowseConnect.c @@ -116,6 +116,7 @@ MNDBBrowseConnect(ODBCDbc *dbc, size_t cap = 0; suggest_settings(dbc, &buf, &pos, &cap, 2, "");// mandatory first suggest_settings(dbc, &buf, &pos, &cap, 0, "*"); // then optional + // note that we leave out level 1, they have already been provided if (buf && pos) { size_t n = strcpy_len((char*)OutConnectionString, buf, BufferLength); ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Test SQLConnect user/pass parameters take pre...
Changeset: 3f6bfb98715f for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/3f6bfb98715f Modified Files: sql/odbc/tests/Tests/ODBCconnect.py testing/Mtest.py.in Branch: Aug2024 Log Message: Test SQLConnect user/pass parameters take precedence Modify MonetDB-Test-Wrong dsn in Mtest.py to not set DATABASE wrong as there is no way we can override it in with SQLConnect. diffs (41 lines): diff --git a/sql/odbc/tests/Tests/ODBCconnect.py b/sql/odbc/tests/Tests/ODBCconnect.py --- a/sql/odbc/tests/Tests/ODBCconnect.py +++ b/sql/odbc/tests/Tests/ODBCconnect.py @@ -144,6 +144,16 @@ ex.expect('Error') ex.expect('28000:') # 28000 bad credentials ex.end() +# parameters passed directly to SQLConnect override those from the dsn +ex = Execution(dsn + '-Wrong') +ex.expect_fail() +ex.expect('Error') +ex.expect('28000:')# this dsn uses the wrong user name and password +ex.end() +ex = Execution(dsn + '-Wrong', '-u', user, '-p', password) +ex.expect('OK')# but those passes as arguments take precedence +ex.end() + # test non-NUL terminated strings ex = Execution(dsn, '-0') @@ -213,7 +223,7 @@ ex.expect('RESULT') ex.expect('- banana;') # as set by Client Remark property ex.expect('OK') ex.expect('RESULT') -ex.expect('- ;') # this connection did not have a Client Remark +ex.expect('- ;') # the second connection does not have a Client Remark ex.end() diff --git a/testing/Mtest.py.in b/testing/Mtest.py.in --- a/testing/Mtest.py.in +++ b/testing/Mtest.py.in @@ -2239,7 +2239,7 @@ Description = Wrong values for Database, Driver = MonetDB Host = localhost Port = {env["MAPIPORT"]} -Database = {TSTDB}-Wrong +Database = {TSTDB} User = {user or "monetdb"}-Wrong Password = {passwd or "monetdb"}-Wrong ''') ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - ODBCConnectionString is no longer used
Changeset: 4b59dd0861ce for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/4b59dd0861ce Modified Files: clients/odbc/driver/ODBCDbc.h clients/odbc/driver/SQLDriverConnect.c Branch: Aug2024 Log Message: ODBCConnectionString is no longer used instead we have buildConnectionString which takes all msettings into account diffs (199 lines): diff --git a/clients/odbc/driver/ODBCDbc.h b/clients/odbc/driver/ODBCDbc.h --- a/clients/odbc/driver/ODBCDbc.h +++ b/clients/odbc/driver/ODBCDbc.h @@ -141,14 +141,6 @@ ODBCError *getDbcError(ODBCDbc *dbc); void destroyODBCDbc(ODBCDbc *dbc); int ODBCGetKeyAttr(const SQLCHAR **conn, SQLSMALLINT *nconn, char **key, char **attr); -SQLRETURN ODBCConnectionString(SQLRETURN rc, ODBCDbc *dbc, - SQLCHAR *OutConnectionString, - SQLSMALLINT BufferLength, - SQLSMALLINT *StringLength2Ptr, - const char *dsn, const char *uid, - const char *pwd, const char *host, - int port, const char *database, - int mapToLongVarchar); SQLRETURN MNDBAllocStmt(ODBCDbc *dbc, SQLHANDLE *pnOutputHandle); SQLRETURN MNDBConnect(ODBCDbc *dbc, const SQLCHAR *szDataSource, SQLSMALLINT nDataSourceLength, const SQLCHAR *szUID, SQLSMALLINT nUIDLength, diff --git a/clients/odbc/driver/SQLDriverConnect.c b/clients/odbc/driver/SQLDriverConnect.c --- a/clients/odbc/driver/SQLDriverConnect.c +++ b/clients/odbc/driver/SQLDriverConnect.c @@ -105,177 +105,6 @@ ODBCGetKeyAttr(const SQLCHAR **conn, SQL return 1; } -SQLRETURN -ODBCConnectionString(SQLRETURN rc, -ODBCDbc *dbc, -SQLCHAR *OutConnectionString, -SQLSMALLINT BufferLength, -SQLSMALLINT *StringLength2Ptr, -const char *dsn, -const char *uid, -const char *pwd, -const char *host, -int port, -const char *database, -int mapToLongVarchar) -{ - int n; -#ifdef ODBCDEBUG - SQLCHAR *buf = OutConnectionString; - int buflen = BufferLength; -#endif - - if (OutConnectionString == NULL) - BufferLength = -1; - if (BufferLength > 0) { - n = snprintf((char *) OutConnectionString, BufferLength, -"DSN=%s;", dsn ? dsn : "DEFAULT"); - /* some snprintf's return -1 if buffer too small */ - if (n < 0) - n = BufferLength + 1; /* make sure it becomes < 0 */ - BufferLength -= n; - OutConnectionString += n; - } else { - BufferLength = -1; - } - if (uid) { - if (BufferLength > 0) { - n = snprintf((char *) OutConnectionString, -BufferLength, "UID=%s;", uid); - if (n < 0) - n = BufferLength + 1; - BufferLength -= n; - OutConnectionString += n; - } else { - BufferLength = -1; - } - } - if (pwd) { - if (BufferLength > 0) { - n = snprintf((char *) OutConnectionString, -BufferLength, "PWD=%s;", pwd); - if (n < 0) - n = BufferLength + 1; - BufferLength -= n; - OutConnectionString += n; - } else { - BufferLength = -1; - } - } - if (host) { - if (BufferLength > 0) { - n = snprintf((char *) OutConnectionString, -BufferLength, "HOST=%s;", host); - if (n < 0) - n = BufferLength + 1; - BufferLength -= n; - OutConnectionString += n; - } else { - BufferLength = -1; - } - } - if (port) { - char portbuf[10]; - - if (BufferLength > 0) { - n = snprintf((char *) OutConnectionString, -BufferLength, "PORT=%d;", port); - if (n < 0) - n = BufferLength + 1; - BufferLength -= n; - OutConnectionString += n; - } else { - BufferLength = -1; - } - port = snprintf(portbuf, sizeof(portbuf), "%d", port); - } - if (database) { - if (BufferLength > 0) { - n = snprintf((char *) OutConnectionS
MonetDB: Aug2024 - Last four parameters of MNDBConnect are now u...
Changeset: 28ad5b5a for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/28ad5b5a Modified Files: clients/odbc/driver/ODBCDbc.h clients/odbc/driver/SQLConnect.c Branch: Aug2024 Log Message: Last four parameters of MNDBConnect are now unused diffs (88 lines): diff --git a/clients/odbc/driver/ODBCDbc.h b/clients/odbc/driver/ODBCDbc.h --- a/clients/odbc/driver/ODBCDbc.h +++ b/clients/odbc/driver/ODBCDbc.h @@ -144,8 +144,7 @@ int ODBCGetKeyAttr(const SQLCHAR **conn, SQLRETURN MNDBAllocStmt(ODBCDbc *dbc, SQLHANDLE *pnOutputHandle); SQLRETURN MNDBConnect(ODBCDbc *dbc, const SQLCHAR *szDataSource, SQLSMALLINT nDataSourceLength, const SQLCHAR *szUID, SQLSMALLINT nUIDLength, - const SQLCHAR *szPWD, SQLSMALLINT nPWDLength, - const char *host, int port, const char *dbname, int mapToLongVarchar); + const SQLCHAR *szPWD, SQLSMALLINT nPWDLength); SQLRETURN MNDBGetConnectAttr(ODBCDbc *dbc, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER BufferLength, SQLINTEGER *StringLength); SQLRETURN MNDBSetConnectAttr(ODBCDbc *dbc, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength); diff --git a/clients/odbc/driver/SQLConnect.c b/clients/odbc/driver/SQLConnect.c --- a/clients/odbc/driver/SQLConnect.c +++ b/clients/odbc/driver/SQLConnect.c @@ -311,17 +311,14 @@ end: SQLRETURN + MNDBConnect(ODBCDbc *dbc, const SQLCHAR *ServerName, SQLSMALLINT NameLength1, const SQLCHAR *UserName, SQLSMALLINT NameLength2, const SQLCHAR *Authentication, - SQLSMALLINT NameLength3, - const char *host, - int port, - const char *dbname, - int mapToLongVarchar) + SQLSMALLINT NameLength3) { // These will be passed to addDbcError if you 'goto failure'. // If unset, 'goto failure' will assume an allocation error. @@ -402,30 +399,12 @@ MNDBConnect(ODBCDbc *dbc, goto failure; } - if (host != NULL) { - error_explanation = msetting_set_string(settings, MP_HOST, host); - if (error_explanation != NULL) - goto failure; - } - mapiport_env = getenv("MAPIPORT"); - if (port > 0) - error_explanation = msetting_set_long(settings, MP_PORT, port); - else if (mapiport_env != NULL) + if (mapiport_env != NULL) error_explanation = msetting_parse(settings, MP_PORT, mapiport_env); if (error_explanation != NULL) goto failure; - if (dbname != NULL) { - error_explanation = msetting_set_string(settings, MP_DATABASE, dbname); - if (error_explanation != NULL) - goto failure; - } - - error_explanation = msetting_set_long(settings, MP_MAPTOLONGVARCHAR, mapToLongVarchar); - if (error_explanation) - goto failure; - #ifdef ODBCDEBUG { free(scratch); @@ -545,8 +524,7 @@ SQLConnect(SQLHDBC ConnectionHandle, return MNDBConnect((ODBCDbc *) ConnectionHandle, ServerName, NameLength1, UserName, NameLength2, - Authentication, NameLength3, - NULL, 0, NULL, 0); + Authentication, NameLength3); } SQLRETURN SQL_API @@ -596,8 +574,7 @@ SQLConnectW(SQLHDBC ConnectionHandle, rc = MNDBConnect(dbc, ds, SQL_NTS, uid, SQL_NTS, -pwd, SQL_NTS, -NULL, 0, NULL, 0); +pwd, SQL_NTS); bailout: if (ds) ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Write SQLConnectA, etc in odbcconnect.c
Changeset: 0fe29b9b9760 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/0fe29b9b9760 Modified Files: clients/odbc/tests/odbcconnect.c Branch: Aug2024 Log Message: Write SQLConnectA, etc in odbcconnect.c diffs (74 lines): diff --git a/clients/odbc/tests/odbcconnect.c b/clients/odbc/tests/odbcconnect.c --- a/clients/odbc/tests/odbcconnect.c +++ b/clients/odbc/tests/odbcconnect.c @@ -24,6 +24,7 @@ #include #include #include +#include static const char *USAGE = "Usage:\n" @@ -206,7 +207,7 @@ ensure_ok_impl(SQLSMALLINT type, SQLHAND bool printed_something = false; for (int i = 1; ; i++) { - SQLRETURN diag_ret = SQLGetDiagRec( + SQLRETURN diag_ret = SQLGetDiagRecA( type, handle, i, state, &error, explanation, sizeof(explanation), &len); if (!SQL_SUCCEEDED(diag_ret)) @@ -259,7 +260,7 @@ do_sqlconnect(SQLCHAR *target) ensure_ok( SQL_HANDLE_DBC, conn, "SQLConnect", - SQLConnect(conn, target, target_len, user, user_len, password, password_len)); + SQLConnectA(conn, target, target_len, user, user_len, password, password_len)); printf("OK\n"); int exitcode = do_execute_stmt(); @@ -281,7 +282,7 @@ do_sqldriverconnect(SQLCHAR *target) ensure_ok( SQL_HANDLE_DBC, conn, "SQLDriverConnect", - SQLDriverConnect( + SQLDriverConnectA( conn, NULL, target, target_len, outbuf, sizeof(outbuf), &n, @@ -307,7 +308,7 @@ do_sqlbrowseconnect(SQLCHAR *target) if (use_counted_strings) fuzz_sql_nts(&target, &target_len); - SQLRETURN ret = SQLBrowseConnect( + SQLRETURN ret = SQLBrowseConnectA( conn, target, target_len, outbuf, sizeof(outbuf), &n @@ -338,7 +339,7 @@ do_listdrivers(void) while (1) { outbuf[0] = attrbuf[0] = '\0'; - SQLRETURN ret = SQLDrivers( + SQLRETURN ret = SQLDriversA( env, dir, outbuf, sizeof(outbuf), &len1, attrbuf, sizeof(attrbuf), &len2 @@ -367,7 +368,7 @@ do_listdsns(const char *prefix, SQLSMALL while (1) { outbuf[0] = attrbuf[0] = '\0'; - SQLRETURN ret = SQLDataSources( + SQLRETURN ret = SQLDataSourcesA( env, dir, outbuf, sizeof(outbuf), &len1, attrbuf, sizeof(attrbuf), &len2 @@ -401,7 +402,7 @@ do_execute_stmt(void) ensure_ok( SQL_HANDLE_STMT, stmt, "SQLExecDirect", - SQLExecDirect(stmt, query, query_len)); + SQLExecDirectA(stmt, query, query_len)); do { SQLLEN rowcount = -1; ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Mark user DNS's as such
Changeset: 327a94079349 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/327a94079349 Modified Files: clients/odbc/tests/odbcconnect.c Branch: Aug2024 Log Message: Mark user DNS's as such diffs (12 lines): diff --git a/clients/odbc/tests/odbcconnect.c b/clients/odbc/tests/odbcconnect.c --- a/clients/odbc/tests/odbcconnect.c +++ b/clients/odbc/tests/odbcconnect.c @@ -157,7 +157,7 @@ main(int argc, char **argv) } ret = do_listdrivers(); ret |= do_listdsns("SYSTEM", SQL_FETCH_FIRST_SYSTEM); - ret |= do_listdsns("SYSTEM", SQL_FETCH_FIRST_USER); + ret |= do_listdsns("USER", SQL_FETCH_FIRST_USER); } end: ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Simplify memory management in odbcconnect.c
Changeset: dd08c6628fb2 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/dd08c6628fb2 Modified Files: clients/odbc/tests/odbcconnect.c Branch: Aug2024 Log Message: Simplify memory management in odbcconnect.c diffs (truncated from 316 to 300 lines): diff --git a/clients/odbc/tests/odbcconnect.c b/clients/odbc/tests/odbcconnect.c --- a/clients/odbc/tests/odbcconnect.c +++ b/clients/odbc/tests/odbcconnect.c @@ -40,13 +40,13 @@ static const char *USAGE = "-v Be verbose\n" "TARGET DSN or with -d and -b, Connection String\n"; -typedef int (action_t)(SQLCHAR *); +typedef int (action_t)(const char *); static action_t do_sqlconnect; static action_t do_sqldriverconnect; static action_t do_sqlbrowseconnect; -static int do_actions(action_t action, int ntargets, SQLCHAR **targets); +static int do_actions(action_t action, int ntargets, char **targets); static int do_listdrivers(void); static int do_listdsns(const char *prefix, SQLSMALLINT dir); @@ -57,17 +57,13 @@ static void ensure_ok_impl(SQLSMALLINT t #define ensure_ok(type, handle, message, ret)ensure_ok_impl(type, handle, message, ret, __LINE__) -#define MARGIN 100 -static SQLCHAR* sqldup_with_margin(const char *str); -static void fuzz_sql_nts(SQLCHAR **str, SQLSMALLINT *len); +static void make_arg(const char *arg, SQLCHAR**bufp, SQLSMALLINT *buflen); + int verbose = 0; -SQLCHAR *user = NULL; -SQLSMALLINT user_len = SQL_NTS; -SQLCHAR *password = NULL; -SQLSMALLINT password_len = SQL_NTS; -SQLCHAR *query = NULL; -SQLSMALLINT query_len = SQL_NTS; +char *user = NULL; +char *password = NULL; +char *query = NULL; bool use_counted_strings = false; SQLHANDLE env = NULL; @@ -77,12 +73,25 @@ SQLHANDLE stmt = NULL; SQLCHAR outbuf[4096]; SQLCHAR attrbuf[4096]; +// This free-list will be processed by cleanup(). +// It is added to by alloc() +unsigned int ngarbage = 0; +void *garbage[100] = { NULL }; + + +static void* +alloc(size_t size) +{ + void *p = calloc(size, 1); + assert(p); + if (ngarbage < sizeof(garbage) / sizeof(garbage[0])) + garbage[ngarbage++] = p; + return p; +} + static void cleanup(void) { - free(user); - free(password); - free(query); if (stmt) SQLFreeHandle(SQL_HANDLE_STMT, stmt); if (conn) { @@ -91,14 +100,18 @@ cleanup(void) } if (env) SQLFreeHandle(SQL_HANDLE_DBC, env); + + while (ngarbage > 0) { + free(garbage[--ngarbage]); + } } int main(int argc, char **argv) { - int (*action)(SQLCHAR *); + int (*action)(const char*); action = do_sqlconnect; - SQLCHAR **targets = calloc(argc, sizeof(argv[0])); + char **targets = alloc(argc * sizeof(argv[0])); int ntargets = 0; int ret; @@ -111,17 +124,17 @@ main(int argc, char **argv) else if (strcmp(arg, "-l") == 0) action = NULL; else if (strcmp(arg, "-u") == 0 && i + 1 < argc) - user = sqldup_with_margin(argv[++i]); + user = argv[++i]; else if (strcmp(arg, "-p") == 0 && i + 1 < argc) - password = sqldup_with_margin(argv[++i]); + password = argv[++i]; else if (strcmp(arg, "-q") == 0 && i + 1 < argc) - query = sqldup_with_margin(argv[++i]); + query = argv[++i]; else if (strcmp(arg, "-0") == 0) use_counted_strings = true; else if (strcmp(arg, "-v") == 0) verbose += 1; else if (arg[0] != '-') - targets[ntargets++] = sqldup_with_margin(arg); + targets[ntargets++] = arg; else { fprintf(stderr, "\nERROR: invalid argument: %s\n%s", arg, USAGE); ret = 1; @@ -137,11 +150,6 @@ main(int argc, char **argv) SQL_HANDLE_ENV, env, "set odbc version", SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0)); - if (use_counted_strings) { - fuzz_sql_nts(&user, &user_len); - fuzz_sql_nts(&password, &password_len); - } - if (action) { if (ntargets == 0) { fprintf(stderr, "\nERROR: pass at least one target\n%s", USAGE); @@ -161,9 +169,6 @@ main(int argc, char **argv) } end: - for (int i = 0; i < ntargets; i++) - free(targets[i]); - free(targets); cleanup(); return ret; @@ -232,14 +237,14 @@ ensure_ok_impl(SQLSMALLINT type, SQLHAND static int -do_actions(action_t action, int ntargets, SQLCHAR **targets) +do_actions(action_t action, int ntargets, char **targets) { ensure_ok( SQL_HANDLE_ENV, env, "al
MonetDB: Aug2024 - Extend odbcconnect with -w to test the Wide API
Changeset: e37e83b564b7 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/e37e83b564b7 Modified Files: clients/odbc/tests/CMakeLists.txt clients/odbc/tests/odbcconnect.c Branch: Aug2024 Log Message: Extend odbcconnect with -w to test the Wide API diffs (truncated from 400 to 300 lines): diff --git a/clients/odbc/tests/CMakeLists.txt b/clients/odbc/tests/CMakeLists.txt --- a/clients/odbc/tests/CMakeLists.txt +++ b/clients/odbc/tests/CMakeLists.txt @@ -44,6 +44,7 @@ add_executable(odbcconnect target_link_libraries(odbcconnect PRIVATE + mutf8 ODBC::ODBC) install(TARGETS diff --git a/clients/odbc/tests/odbcconnect.c b/clients/odbc/tests/odbcconnect.c --- a/clients/odbc/tests/odbcconnect.c +++ b/clients/odbc/tests/odbcconnect.c @@ -26,6 +26,8 @@ #include #include +#include "mutf8.h" + static const char *USAGE = "Usage:\n" "odbcconnect [-d | -c | -b ] [-v] [-u USER] [-p PASSWORD] TARGET..\n" @@ -37,6 +39,7 @@ static const char *USAGE = "-p PASSWORD\n" "-q SQL Execute SQL statement when connection succeeds\n" "-0 use counted strings rather than nul-terminated arguments\n" + "-w use the wide-char (unicode) interface\n" "-v Be verbose\n" "TARGET DSN or with -d and -b, Connection String\n"; @@ -57,7 +60,13 @@ static void ensure_ok_impl(SQLSMALLINT t #define ensure_ok(type, handle, message, ret)ensure_ok_impl(type, handle, message, ret, __LINE__) -static void make_arg(const char *arg, SQLCHAR**bufp, SQLSMALLINT *buflen); +static void make_arg(bool wide, const char *arg, void **bufp, SQLSMALLINT *buflen); +static void make_arga(const char *arg, void **bufp, SQLSMALLINT *buflen); +static void make_argw(const char *arg, void **bufp, SQLSMALLINT *buflen, bool bytes_not_chars); + + +static SQLWCHAR *gen_utf16(SQLWCHAR *dest, const char *src, size_t len); +static void convert_outw_outa(size_t n); int verbose = 0; @@ -65,13 +74,17 @@ char *user = NULL; char *password = NULL; char *query = NULL; bool use_counted_strings = false; +bool use_wide = false; SQLHANDLE env = NULL; SQLHANDLE conn = NULL; SQLHANDLE stmt = NULL; -SQLCHAR outbuf[4096]; +#define OUTBUF_SIZE 4096 SQLCHAR attrbuf[4096]; +SQLCHAR outabuf[OUTBUF_SIZE]; +SQLWCHAR outwbuf[OUTBUF_SIZE]; + // This free-list will be processed by cleanup(). // It is added to by alloc() @@ -131,6 +144,8 @@ main(int argc, char **argv) query = argv[++i]; else if (strcmp(arg, "-0") == 0) use_counted_strings = true; + else if (strcmp(arg, "-w") == 0) + use_wide = true; else if (strcmp(arg, "-v") == 0) verbose += 1; else if (arg[0] != '-') @@ -247,7 +262,8 @@ do_actions(action_t action, int ntargets char *t = targets[i]; if (verbose) printf("\nTarget: %s\n", t); - outbuf[0] = '\0'; + outabuf[0] = '\0'; + outwbuf[0] = 0; int ret = action(t); if (ret) return ret; @@ -259,21 +275,24 @@ do_actions(action_t action, int ntargets static int do_sqlconnect(const char *target) { - SQLCHAR *target_buf; + void *target_buf; SQLSMALLINT target_len = SQL_NTS; - make_arg(target, &target_buf, &target_len); + make_arg(use_wide, target, &target_buf, &target_len); - SQLCHAR *user_buf; + void *user_buf; SQLSMALLINT user_len = SQL_NTS; - make_arg(user, &user_buf, &user_len); + make_arg(use_wide, user, &user_buf, &user_len); - SQLCHAR *password_buf; + void *password_buf; SQLSMALLINT password_len = SQL_NTS; - make_arg(password, &password_buf, &password_len); + make_arg(use_wide, password, &password_buf, &password_len); ensure_ok( SQL_HANDLE_DBC, conn, "SQLConnect", - SQLConnectA(conn, target_buf, target_len, user_buf, user_len, password_buf, password_len)); + use_wide + ? SQLConnectW(conn, target_buf, target_len, user_buf, user_len, password_buf, password_len) + : SQLConnectA(conn, target_buf, target_len, user_buf, user_len, password_buf, password_len) + ); printf("OK\n"); int exitcode = do_execute_stmt(); @@ -288,22 +307,22 @@ do_sqlconnect(const char *target) static int do_sqldriverconnect(const char *target) { - SQLCHAR *target_buf; + void *target_buf; SQLSMALLINT target_len = SQL_NTS; - make_arg(target, &target_buf, &target_len); + make_arg(use_wide, target, &target_buf, &target_len); SQLSMALLINT n; ensure_ok( SQL_HANDLE_DBC, conn, "SQLDriverConnect", -
MonetDB: Aug2024 - SQLDriverConnect: build connection string eve...
Changeset: 89396b04faf9 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/89396b04faf9 Modified Files: clients/odbc/driver/SQLDriverConnect.c Branch: Aug2024 Log Message: SQLDriverConnect: build connection string even with tryOnly It's the only reason tryOnly exists! diffs (56 lines): diff --git a/clients/odbc/driver/SQLDriverConnect.c b/clients/odbc/driver/SQLDriverConnect.c --- a/clients/odbc/driver/SQLDriverConnect.c +++ b/clients/odbc/driver/SQLDriverConnect.c @@ -189,6 +189,18 @@ MNDBDriverConnect(ODBCDbc *dbc, goto end; } + // Build a connect string for the current connection and put it in the out buffer. + scratch_alloc = buildConnectionString(dsn ? dsn : "DEFAULT", settings); + if (!scratch_alloc) + goto failure; + out_len = strcpy_len((char*)OutConnectionString, scratch_alloc, BufferLength); + if (StringLength2Ptr) + *StringLength2Ptr = (SQLSMALLINT)out_len; + if (out_len + 1 > (size_t)BufferLength) { + addDbcError(dbc, "01004", NULL, 0); + rc = SQL_SUCCESS_WITH_INFO; + } + if (tryOnly) { assert(sqlstate == NULL); goto end; @@ -200,23 +212,8 @@ MNDBDriverConnect(ODBCDbc *dbc, rc = MNDBConnectSettings(dbc, dsn, settings); settings = NULL; // do not free now - if (!SQL_SUCCEEDED(rc)) - goto end; // not to 'failure', all errors have already been logged - - // Build a connect string for the current connection - // and put it in the buffer. - scratch_alloc = buildConnectionString(dsn ? dsn : "DEFAULT", dbc->settings); - if (!scratch_alloc) - goto failure; - out_len = strcpy_len((char*)OutConnectionString, scratch_alloc, BufferLength); - if (StringLength2Ptr) - *StringLength2Ptr = (SQLSMALLINT)out_len; - if (out_len + 1 > (size_t)BufferLength) { - addDbcError(dbc, "01004", NULL, 0); - rc = SQL_SUCCESS_WITH_INFO; - } - + // always go to end, MNDBConnectSettings has already logged any failures goto end; failure: @@ -313,7 +310,7 @@ SQLDriverConnectW(SQLHDBC ConnectionHand addDbcError, dbc, return SQL_ERROR); rc = MNDBDriverConnect(dbc, WindowHandle, in, SQL_NTS, NULL, 0, &n, - DriverCompletion, 1); // Try Only + DriverCompletion, 1); // 1 = Try Only if (!SQL_SUCCEEDED(rc)) return rc; clearDbcErrors(dbc); ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Make odbcconnect handle full utf-16, not just...
Changeset: d0a155c796b6 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/d0a155c796b6 Modified Files: clients/odbc/tests/odbcconnect.c Branch: Aug2024 Log Message: Make odbcconnect handle full utf-16, not just ascii-16 diffs (90 lines): diff --git a/clients/odbc/tests/odbcconnect.c b/clients/odbc/tests/odbcconnect.c --- a/clients/odbc/tests/odbcconnect.c +++ b/clients/odbc/tests/odbcconnect.c @@ -338,7 +338,7 @@ do_sqlbrowseconnect(const char *target) { void *target_buf; SQLSMALLINT target_len = SQL_NTS; - make_arg(false, target, &target_buf, &target_len); + make_arg(use_wide, target, &target_buf, &target_len); SQLSMALLINT n; @@ -462,9 +462,13 @@ do_execute_stmt(void) for (int i = 1; i <= colcount; i++) { SQLLEN n; outabuf[0] = '\0'; - SQLRETURN ret = SQLGetData(stmt, i, SQL_C_CHAR, outabuf, OUTBUF_SIZE, &n); + SQLRETURN ret = use_wide + ? SQLGetData(stmt, i, SQL_C_WCHAR, outwbuf, OUTBUF_SIZE * sizeof(SQLWCHAR), &n) + : SQLGetData(stmt, i, SQL_C_CHAR, outabuf, OUTBUF_SIZE, &n); if (!SQL_SUCCEEDED(ret)) ensure_ok(SQL_HANDLE_STMT, stmt, "SQLGetData", ret); + if (use_wide) + convert_outw_outa(n); printf("%s;", outabuf); } printf("\n"); @@ -584,17 +588,54 @@ gen_utf16(SQLWCHAR *dest, const char *sr return p; } +static inline SQLCHAR +continuation_byte(uint32_t val, int n) +{ + val >>= 6 * n; // chop off right hand bits + val &= 0x3F; // chop off left hand bits + val |= 0x80; // add continuation marker bit + return val; +} + static void convert_outw_outa(size_t n) { - // outw mostly holds connection strings and those are mostly ascii - for (size_t i = 0; i < n; i++) { - SQLWCHAR w = outwbuf[i]; - if (w > 127) { - fprintf(stderr, "Sorry, this test is lazy and should be extended to non-ascii utf-16\n"); - exit(1); + SQLWCHAR *end = &outwbuf[n]; + SQLWCHAR *in = &outwbuf[0]; + SQLCHAR *out = &outabuf[0]; + + while (in < end) { + SQLWCHAR w = *in++; + uint32_t codepoint; + if (w < 0xD800 || w >= 0xE000) { + codepoint = w; + } else if (w < 0xDC00 && in < end && *in >= 0xDC00 && *in < 0xE000) { + uint32_t hi = w - 0xD800; + uint32_t lo = *in++ - 0xDC00; + codepoint = 0x1 + (hi << 10) + lo; + } else { + strcpy((char*)out, "!!INVALID UTF-16 OR A BUG IN THE TEST ITSELF!!"); + break; } - outabuf[i] = (SQLCHAR)w; + if (codepoint == 0xFEFF && out == &outabuf[0]) { + // skip the BOM + } else if (codepoint < 0x80) { + *out++ = codepoint; + } else if (codepoint < 0x800) { + *out++ = 0xC0 | (codepoint >> 6); + *out++ = continuation_byte(codepoint, 0); + } else if (codepoint < 0x1) { + *out++ = 0xE0 | (codepoint >> 12); + *out++ = continuation_byte(codepoint, 1); + *out++ = continuation_byte(codepoint, 0); + } else { + assert(codepoint < 0x11); + *out++ = 0xF0 | (codepoint >> 18); + *out++ = continuation_byte(codepoint, 2); + *out++ = continuation_byte(codepoint, 1); + *out++ = continuation_byte(codepoint, 0); + } } - outabuf[n] = '\0'; + + *out = '\0'; } ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Include wide character tests in sql/odbc/test...
Changeset: c85461b96b69 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/c85461b96b69 Modified Files: sql/odbc/tests/Tests/ODBCconnect.py Branch: Aug2024 Log Message: Include wide character tests in sql/odbc/tests/ODBCconnect diffs (109 lines): diff --git a/sql/odbc/tests/Tests/ODBCconnect.py b/sql/odbc/tests/Tests/ODBCconnect.py --- a/sql/odbc/tests/Tests/ODBCconnect.py +++ b/sql/odbc/tests/Tests/ODBCconnect.py @@ -25,6 +25,10 @@ user = 'monetdb' password = 'monetdb' port = os.environ.get('MAPIPORT', 5) +# \u{E1} is LATIN SMALL LETTER A WITH ACUTE +unicode_text = 'R\u00E1inbow' +# \u{1F308} is RAINBOW EMOJI +#unicode_text += '\U0001F308' class Execution: def __init__(self, *odbcconnect_args): @@ -110,6 +114,10 @@ def show_context(): print(ex.report(), file=sys.stderr) +### +# Test SQLConnect +### + ex = Execution(dsn) ex.expect('OK') ex.end() @@ -164,7 +172,21 @@ ex = Execution(dsn, '-0', '-u', user, '- ex.expect('OK') ex.end() -# test connection strings +# test wide characters +ex = Execution('-w', dsn + '-Wrong', '-u', user, '-p', password) +ex.expect('OK') +ex.end() + +# test wide characters in combination with non-NUL +ex = Execution('-0', '-w', dsn + '-Wrong', '-u', user, '-p', password) +ex.expect('OK') +ex.end() + + + +### +# Test SQLDriverConnect +### ex = Execution('-d', f'DSN={dsn}') ex.expect('OK') @@ -226,8 +248,15 @@ ex.expect('RESULT') ex.expect('- ;') # the second connection does not have a Client Remark ex.end() +# test wide characters +ex = Execution('-w', '-d', f'DSN={dsn};Client Remark={unicode_text}') +# expect OK followed by connection string containing the rainbow +ex.expect('OK', f'CLIENTREMARK={unicode_text}') +ex.end() -# Test browsing +### +# Test SQLBrowseConnect +### ex = Execution('-b', 'Driver={MonetDB}') ex.expect('Info') @@ -259,6 +288,41 @@ ex = Execution('-b', f'DSN={dsn}') ex.expect('OK', ';') ex.end() -# clear 'ex', otherwise the atexit handler will write things -# to stderr +# test wide characters +ex = Execution('-w', '-b', f'DSN={dsn}') +ex.expect('OK', ';') +ex.end() + +ex = Execution('-w', '-b', f'DSN={dsn};Client Remark={unicode_text}') +ex.expect('OK', f';CLIENTREMARK={unicode_text}') +ex.expect +ex.end() + +# also with non-NUL terminated strings +ex = Execution('-0', '-w', '-b', f'DSN={dsn}') +ex.expect('OK', ';') +ex.end() + +ex = Execution('-0', '-w', '-b', f'DSN={dsn};Client Remark={unicode_text}') +ex.expect('OK', f';CLIENTREMARK={unicode_text}') +ex.expect +ex.end() + +# Also test that queries return unicode ok +ex = Execution( +'-w', +'-b', f'DSN={dsn};Client Remark={unicode_text}', +'-q', 'select remark from sys.sessions where sessionid = current_sessionid()', +) +ex.expect('OK', f';CLIENTREMARK={unicode_text}') +ex.expect('RESULT') +ex.expect(unicode_text) +ex.end() + + +### +# +# clear 'ex', otherwise the atexit handler will write things to stderr +# +### ex = None ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Show output of odbcconnect -l when test fails
Changeset: 1f00aade5a18 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/1f00aade5a18 Modified Files: sql/odbc/tests/Tests/ODBCconnect.py Branch: Aug2024 Log Message: Show output of odbcconnect -l when test fails diffs (23 lines): diff --git a/sql/odbc/tests/Tests/ODBCconnect.py b/sql/odbc/tests/Tests/ODBCconnect.py --- a/sql/odbc/tests/Tests/ODBCconnect.py +++ b/sql/odbc/tests/Tests/ODBCconnect.py @@ -101,6 +101,10 @@ class Execution: raise Exception( f'Process exited with code {code!r}, expected {expected!r}') +# Grab the output of 'odbcconnect -l' so we can show it if a test fails +list_output = None +ex = Execution('-l') +list_output = ex.proc.stdout ex = None @@ -112,6 +116,8 @@ def show_context(): # ex.end() print(file=sys.stderr) print(ex.report(), file=sys.stderr) +if list_output: +print(f'\n--- output of odbcconnect -l ---\n{list_output}--- end ---', file=sys.stderr) ### ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Fix SQLErrorW: odbc errors start at 1, not 0
Changeset: 1962142fc6d2 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/1962142fc6d2 Modified Files: clients/odbc/driver/SQLError.c sql/odbc/tests/Tests/ODBCconnect.py Branch: Aug2024 Log Message: Fix SQLErrorW: odbc errors start at 1, not 0 diffs (51 lines): diff --git a/clients/odbc/driver/SQLError.c b/clients/odbc/driver/SQLError.c --- a/clients/odbc/driver/SQLError.c +++ b/clients/odbc/driver/SQLError.c @@ -125,19 +125,19 @@ SQLErrorW(SQLHENV EnvironmentHandle, if (StatementHandle) rc = MNDBGetDiagRec(SQL_HANDLE_STMT, StatementHandle, - ((ODBCStmt *) StatementHandle)->RetrievedErrors, + ++((ODBCStmt *) StatementHandle)->RetrievedErrors, state, NativeErrorPtr, errmsg, (SQLSMALLINT) sizeof(errmsg), &n); else if (ConnectionHandle) rc = MNDBGetDiagRec(SQL_HANDLE_DBC, ConnectionHandle, - ((ODBCDbc *) ConnectionHandle)->RetrievedErrors, + ++((ODBCDbc *) ConnectionHandle)->RetrievedErrors, state, NativeErrorPtr, errmsg, (SQLSMALLINT) sizeof(errmsg), &n); else if (EnvironmentHandle) rc = MNDBGetDiagRec(SQL_HANDLE_ENV, EnvironmentHandle, - ((ODBCEnv *) EnvironmentHandle)->RetrievedErrors, + ++((ODBCEnv *) EnvironmentHandle)->RetrievedErrors, state, NativeErrorPtr, errmsg, (SQLSMALLINT) sizeof(errmsg), &n); else diff --git a/sql/odbc/tests/Tests/ODBCconnect.py b/sql/odbc/tests/Tests/ODBCconnect.py --- a/sql/odbc/tests/Tests/ODBCconnect.py +++ b/sql/odbc/tests/Tests/ODBCconnect.py @@ -254,6 +254,21 @@ ex.expect('RESULT') ex.expect('- ;') # the second connection does not have a Client Remark ex.end() +# test error handling when -w is given + +# first without the -w to demonstrate the expected behavior +ex = Execution('-d', f'Driver={{MonetDB}};User={user};Password={password};Database={dbname + "-Wrong"}') +ex.expect_fail() +ex.expect('Error') +ex.expect('08001') # something wrong with the database +ex.end() +# then with the -w +ex = Execution('-w', '-d', f'Driver={{MonetDB}};User={user};Password={password};Database={dbname + "-Wrong"}') +ex.expect_fail() +ex.expect('Error') +ex.expect('08001') # something wrong with the database +ex.end() + # test wide characters ex = Execution('-w', '-d', f'DSN={dsn};Client Remark={unicode_text}') # expect OK followed by connection string containing the rainbow ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Fix uninitialized use
Changeset: 3b49dad3d4f7 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/3b49dad3d4f7 Modified Files: clients/odbc/tests/odbcconnect.c Branch: Aug2024 Log Message: Fix uninitialized use Hadn't realized mutf8 decode() reads the *codepoint without writing it first diffs (14 lines): diff --git a/clients/odbc/tests/odbcconnect.c b/clients/odbc/tests/odbcconnect.c --- a/clients/odbc/tests/odbcconnect.c +++ b/clients/odbc/tests/odbcconnect.c @@ -559,9 +559,9 @@ gen_utf16(SQLWCHAR *dest, const char *sr { SQLWCHAR *p = dest; uint32_t state = UTF8_ACCEPT; + uint32_t codepoint = UTF8_ACCEPT; for (size_t i = 0; i < len; i++) { unsigned char byte = (unsigned char)src[i]; - uint32_t codepoint; switch (decode(&state, &codepoint, byte)) { case UTF8_ACCEPT: if (codepoint <= 0x) { ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Print more info when ODBCconnect.py fails
Changeset: b87fb6cce3e5 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/b87fb6cce3e5 Modified Files: sql/odbc/tests/Tests/ODBCconnect.py Branch: Aug2024 Log Message: Print more info when ODBCconnect.py fails diffs (19 lines): diff --git a/sql/odbc/tests/Tests/ODBCconnect.py b/sql/odbc/tests/Tests/ODBCconnect.py --- a/sql/odbc/tests/Tests/ODBCconnect.py +++ b/sql/odbc/tests/Tests/ODBCconnect.py @@ -118,6 +118,15 @@ def show_context(): print(ex.report(), file=sys.stderr) if list_output: print(f'\n--- output of odbcconnect -l ---\n{list_output}--- end ---', file=sys.stderr) +odbcini = os.getenv('ODBCINI', 'odbc.ini') +sysini = os.getenv('ODBCSYSINI', os.getenv('TSTTRGDIR')) +fullpath = os.path.join(sysini, odbcini) +try: +with open(fullpath) as f: +content = f.read() +print(f'\n--- content of {fullpath} ---\n{content}\n--- end ---', file=sys.stderr) +except FileNotFoundError: +pass ### ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Restore mapToLongVarchar setting
Changeset: 90b3c951a5ec for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/90b3c951a5ec Modified Files: clients/odbc/driver/ODBCAttrs.c clients/odbc/driver/SQLBrowseConnect.c clients/odbc/tests/odbcconnect.c sql/odbc/tests/Tests/ODBCconnect.py Branch: Aug2024 Log Message: Restore mapToLongVarchar setting It was available on the URL but not in ODBC diffs (109 lines): diff --git a/clients/odbc/driver/ODBCAttrs.c b/clients/odbc/driver/ODBCAttrs.c --- a/clients/odbc/driver/ODBCAttrs.c +++ b/clients/odbc/driver/ODBCAttrs.c @@ -50,6 +50,7 @@ const struct attr_setting attr_settings[ { "CLIENTINFO", "Send Client Info", MP_CLIENT_INFO }, { "APPNAME", "Application Name", MP_CLIENT_APPLICATION }, { "CLIENTREMARK", "Client Remark", MP_CLIENT_REMARK }, + { "MAPTOLONGVARCHAR", NULL, MP_MAPTOLONGVARCHAR }, }; const int attr_setting_count = sizeof(attr_settings) / sizeof(attr_settings[0]); diff --git a/clients/odbc/driver/SQLBrowseConnect.c b/clients/odbc/driver/SQLBrowseConnect.c --- a/clients/odbc/driver/SQLBrowseConnect.c +++ b/clients/odbc/driver/SQLBrowseConnect.c @@ -53,7 +53,12 @@ suggest_settings(ODBCDbc *dbc, char **bu mparm parm = entry->parm; if (dbc->setting_touched[(int)parm] == touched_as) { const char *sep = *pos > 0 ? ";" : ""; - reallocprintf(buf, pos, cap, "%s%s%s:%s=?", sep, prefix, entry->name, entry->alt_name); + reallocprintf( + buf, pos, cap, + "%s%s%s%s%s=?", + sep, prefix, entry->name, + entry->alt_name ? ":" : "", + entry->alt_name ? entry->alt_name : ""); if (entry->is_enum) { assert(entry->values != NULL); *pos -= 1; // eat the '?' diff --git a/clients/odbc/tests/odbcconnect.c b/clients/odbc/tests/odbcconnect.c --- a/clients/odbc/tests/odbcconnect.c +++ b/clients/odbc/tests/odbcconnect.c @@ -455,7 +455,45 @@ do_execute_stmt(void) SQL_HANDLE_STMT, stmt, "SQLNumResultCols", SQLNumResultCols(stmt, &colcount)); - printf("RESULT rows=%ld cols=%d \n", rowcount, colcount); + printf("RESULT rows=%ld: ", rowcount); + char *sep = ""; + for (int i = 1; i <= colcount; i++) { + printf("%s", sep); + sep = "; "; + SQLSMALLINT n; + ensure_ok( + SQL_HANDLE_STMT, stmt, "SQLColAttributeW SQL_DESC_NAME", + SQLColAttributeW(stmt, i, SQL_DESC_NAME, outwbuf, sizeof(outwbuf) /* in bytes! */, &n, NULL)); + convert_outw_outa(n); + printf("%s", outabuf); + SQLLEN typenr; + ensure_ok( + SQL_HANDLE_STMT, stmt, "SQLColAttributeW SQL_DESC_TYPE", + SQLColAttributeW(stmt, i, SQL_DESC_CONCISE_TYPE, NULL, 0, NULL, &typenr)); + ensure_ok( + SQL_HANDLE_STMT, stmt, "SQLColAttributeW SQL_DESC_TYPE_NAME", + SQLColAttributeW(stmt, i, SQL_DESC_TYPE_NAME, outwbuf, sizeof(outwbuf) /* in bytes! */, &n, NULL)); + convert_outw_outa(n); + char *marker = typenr == SQL_LONGVARCHAR || typenr == SQL_WLONGVARCHAR ? "*" : ""; + printf(":%s%s", marker, outabuf); + SQLLEN fixed, len, scale; + ensure_ok( + SQL_HANDLE_STMT, stmt, "SQLColAttributeW SQL_DESC_LENGTH", + SQLColAttributeW(stmt, i, SQL_DESC_FIXED_PREC_SCALE, NULL, 0, NULL, &fixed)); + ensure_ok( + SQL_HANDLE_STMT, stmt, "SQLColAttributeW SQL_DESC_LENGTH", + SQLColAttributeW(stmt, i, SQL_DESC_LENGTH, NULL, 0, NULL, &len)); + ensure_ok( + SQL_HANDLE_STMT, stmt, "SQLColAttributeW SQL_DESC_SCALE", + SQLColAttributeW(stmt, i, SQL_DESC_SCALE, NULL, 0, NULL, &scale)); + if (!fixed || scale) { + if (scale > 0) + printf("(%ld,%ld)", len, scale); + else + printf("(%ld)", len); + } + } + printf("\n"); while (colcount > 0 && SQL_SUCCEEDED(SQLFetch(stmt))) { printf("- "); diff --git a/sql/odbc/tests/Tests/ODBCconnect.py b/sql/od