MonetDB: Aug2024 - Add test for clientinfo
Changeset: 42d6226ac18f for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/42d6226ac18f Added Files: sql/test/mapi/Tests/clientinfo-mclient.SQL.py Modified Files: sql/test/mapi/Tests/All Branch: Aug2024 Log Message: Add test for clientinfo It uses mclient so it doesn't require pymonetdb updates diffs (67 lines): diff --git a/sql/test/mapi/Tests/All b/sql/test/mapi/Tests/All --- a/sql/test/mapi/Tests/All +++ b/sql/test/mapi/Tests/All @@ -9,3 +9,4 @@ HAVE_HGE?sql_int128 HAVE_HGE?python3_int128 HAVE_HGE?sql_dec38 HAVE_HGE?python3_dec38 +clientinfo-mclient diff --git a/sql/test/mapi/Tests/clientinfo-mclient.SQL.py b/sql/test/mapi/Tests/clientinfo-mclient.SQL.py new file mode 100644 --- /dev/null +++ b/sql/test/mapi/Tests/clientinfo-mclient.SQL.py @@ -0,0 +1,54 @@ +import os +import subprocess + +TSTDB = os.environ['TSTDB'] +MAPIPORT = os.environ['MAPIPORT'] + +QUERY = """\ +SELECT * +FROM sys.sessions +WHERE sessionid = current_sessionid() +""" + +cmd = [ +'mclient', +'-d', TSTDB, +'-p', MAPIPORT, +'-fexpanded', +'-s', QUERY, +] + +out = subprocess.check_output(cmd, encoding='latin1') + +# print(out) + +fields = dict() +for line in out.splitlines()[1:]: +line = line.strip() +if line: +k, v = line.split('|', 1) +k = k.strip() +v = v.strip() +fields[k] = v + +assert fields['language'] == 'sql',\ +f'Found {fields["language"]!r}' + +assert fields['peer'] == '' or ']:' in fields['peer'],\ +f'Found {fields["peer"]!r}' + +assert fields['hostname'] != 'null',\ +f'Found {fields["hostname"]!r}' + +# could be mclient-11.51.0, mclient.exe, or whatever +assert fields['application'].startswith('mclient'),\ +f'Found {fields["application"]!r}' + +assert fields['client'].startswith('libmapi '),\ +f'Found {fields["client"]!r}' + +assert fields['clientpid'] != 'null' and int(fields['clientpid']) > 0,\ +f'Found {fields["clientpid"]!r}' + +assert fields['remark'] == 'null',\ +f'Found {fields["remark"]!r}' ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Simplify mclient flush test
Changeset: e55267399f84 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/e55267399f84 Modified Files: sql/test/BugTracker-2024/Tests/7536-mclient-forgets-to-flush.SQL.py Branch: Aug2024 Log Message: Simplify mclient flush test diffs (34 lines): diff --git a/sql/test/BugTracker-2024/Tests/7536-mclient-forgets-to-flush.SQL.py b/sql/test/BugTracker-2024/Tests/7536-mclient-forgets-to-flush.SQL.py --- a/sql/test/BugTracker-2024/Tests/7536-mclient-forgets-to-flush.SQL.py +++ b/sql/test/BugTracker-2024/Tests/7536-mclient-forgets-to-flush.SQL.py @@ -6,7 +6,7 @@ import subprocess # This SQL script redirects the output to a file (the %s). # We will check that all output arrives there, even if it's a gzipped file. -SCRIPT = f"""\ +SCRIPT = """\ \>%s SELECT 'Donald Knuth'; """ @@ -19,16 +19,13 @@ with tempfile.TemporaryDirectory('mtest' with open(inputfile, 'w') as f: f.write(SCRIPT % outputfile) -with open(inputfile) as f: -subprocess.check_call([ -'mclient', '-i', -inputfile, -'-p', os.environ['MAPIPORT'], -]) +subprocess.check_call([ +'mclient', '-i', +'-p', os.environ['MAPIPORT'], +inputfile, +]) with gzip.open(outputfile, 'rt', encoding='utf-8') as f: content = f.read() -# print(content) - assert 'Donald Knuth' in content ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Incorporate TLSTester in Mtest.py
Changeset: 9b8c0e6feeb5 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/9b8c0e6feeb5 Modified Files: clients/mapilib/Tests/tlssecurity.py testing/Mtest.py.in testing/tlstester.py Branch: Aug2024 Log Message: Incorporate TLSTester in Mtest.py diffs (196 lines): diff --git a/clients/mapilib/Tests/tlssecurity.py b/clients/mapilib/Tests/tlssecurity.py --- a/clients/mapilib/Tests/tlssecurity.py +++ b/clients/mapilib/Tests/tlssecurity.py @@ -14,7 +14,7 @@ import os import re import subprocess import sys -import threading +import urllib.request from MonetDBtesting import tlstester @@ -26,45 +26,64 @@ if '-v' in sys.argv: #level = logging.DEBUG logging.basicConfig(level=level) +# A tmpdir to write certificates to tgtdir = os.environ['TSTTRGDIR'] assert os.path.isdir(tgtdir) +scratchdir = os.path.join(tgtdir, "scratch") +logging.debug(f"scratchdir={scratchdir}") -hostnames = ['localhost'] -# Generate certificates and write them to the scratch dir -# Write them to the scratch dir for inspection by the user. -certs = tlstester.Certs(hostnames) -certsdir = os.path.join(tgtdir, "certs") -try: -os.mkdir(certsdir) -except FileExistsError: -pass -count = 0 -for name, content in certs.all().items(): -with open(os.path.join(certsdir, name), "wb") as a: -a.write(content) -count += 1 -logging.debug(f"Wrote {count} files to {certsdir}") +class TLSTesterClient: +"""Connect to TLSTester to figure out port numbers and download certificates""" +def __init__(self, scratchdir, base_port=None, host='localhost'): +if not base_port: +base_port = os.environ['TST_TLSTESTERPORT'] +self.url = f'http://{host}:{base_port}/' +self.scratch = scratchdir +try: +os.mkdir(scratchdir) +except FileExistsError: +pass +self.filenames = dict() +self.contents = dict() +self.portmap = dict() +for line in self.fetch('').splitlines(): +name, port = str(line, 'ascii').split(':', 1) +self.portmap[name] = int(port) +logging.debug(f'port {name} = {port}') + +def get_port(self, name): +return self.portmap[name] + +def fetch(self, name): +cached = self.contents.get(name) +if cached is not None: +return cached +url = self.url + name +logging.debug(f'fetch {url}') +with urllib.request.urlopen(url) as response: +content = response.read() +self.contents[name] = content +return content + +def download(self, name): +cached = self.filenames.get(name) +if cached: +return cached +content = self.fetch(name) +path = os.path.join(self.scratch, name) +with open(path, 'wb') as f: +f.write(content) +self.filenames[name] = path +return path + +tlstester = TLSTesterClient(scratchdir) + def certpath(name): -return os.path.join(certsdir, name) -def certbytes(name): -filename = certpath(name) -with open(filename, 'rb') as f: -return f.read() - -# Start the worker threads - -server = tlstester.TLSTester( -certs=certs, -listen_addr='127.0.0.1', -preassigned=dict(), -sequential=False, -hostnames=hostnames) -server_thread = threading.Thread(target=server.serve_forever, daemon=True) -server_thread.start() +return tlstester.download(name) def attempt(experiment: str, portname: str, expected_error_regex: str, tls=True, host='localhost', **params): -port = server.get_port(portname) +port = tlstester.get_port(portname) scheme = 'monetdbs' if tls else 'monetdb' url = f"{scheme}://{host}:{port}/demo" if params: @@ -196,7 +215,7 @@ attempt('connect_server_name', 'sni', No # Connect to port 'server1' over TLS, with certhash set to a prefix of the hash # of the server certificate in DER form. Have a succesful MAPI exchange. -server1hash = sha256(certs.get_file('server1.der')).hexdigest() +server1hash = sha256(tlstester.fetch('server1.der')).hexdigest() attempt('connect_right_hash', 'server1', None, certhash='sha256:' + server1hash[:6]) # connect_wrong_hash @@ -217,7 +236,7 @@ attempt('connect_wrong_hash', 'server1', # Connect to port 'server1' over TLS, with certhash set to a prefix of the hash # of the CA1 certificate in DER form. This should fail. -ca1hash = sha256(certs.get_file('ca1.der')).hexdigest() +ca1hash = sha256(tlstester.fetch('ca1.der')).hexdigest() attempt('connect_ca_hash', 'server1', "does not match certhash", certhash='sha256:' + ca1hash[:6]) diff --git a/testing/Mtest.py.in b/testing/Mtest.py.in --- a/testing/Mtest.py.in +++ b/testing/Mtest.py.in @@ -3240,6 +3240,36 @@ def SetExecEnv(exe,port,verbose) : print(end='', flush=True) ### SetExecEnv(exe,port,procdebug) # +def StartTlsTester(tsttrgdir): +try: +import cryptography +except: +# co
MonetDB: Aug2024 - Move odbcconnect from clients/odbc/samples to...
Changeset: e8186ee84c8e for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/e8186ee84c8e Added Files: clients/odbc/tests/odbcconnect.c Removed Files: clients/odbc/samples/odbcconnect.c Modified Files: clients/odbc/samples/CMakeLists.txt clients/odbc/tests/CMakeLists.txt Branch: Aug2024 Log Message: Move odbcconnect from clients/odbc/samples to clients/odbc/tests diffs (63 lines): diff --git a/clients/odbc/samples/CMakeLists.txt b/clients/odbc/samples/CMakeLists.txt --- a/clients/odbc/samples/CMakeLists.txt +++ b/clients/odbc/samples/CMakeLists.txt @@ -26,17 +26,9 @@ target_link_libraries(arraytest PRIVATE ODBC::ODBC) -add_executable(odbcconnect - odbcconnect.c) - -target_link_libraries(odbcconnect - PRIVATE - ODBC::ODBC) - install(TARGETS odbcsample1 arraytest - odbcconnect RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} @@ -46,7 +38,6 @@ if(WIN32) install(FILES $ $ -$ DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) endif() 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 @@ -39,11 +39,19 @@ target_link_libraries(ODBCtester PRIVATE ODBC::ODBC) +add_executable(odbcconnect + odbcconnect.c) + +target_link_libraries(odbcconnect + PRIVATE + ODBC::ODBC) + install(TARGETS ODBCgetInfo ODBCStmtAttr ODBCmetadata ODBCtester + odbcconnect RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} @@ -55,6 +63,7 @@ if(WIN32) $ $ $ +$ DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) endif() diff --git a/clients/odbc/samples/odbcconnect.c b/clients/odbc/tests/odbcconnect.c rename from clients/odbc/samples/odbcconnect.c rename to clients/odbc/tests/odbcconnect.c ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Run a dummy server if the cryptography module...
Changeset: 6d3098fd2db1 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/6d3098fd2db1 Modified Files: testing/Mtest.py.in Branch: Aug2024 Log Message: Run a dummy server if the cryptography module cannot be found diffs (52 lines): diff --git a/testing/Mtest.py.in b/testing/Mtest.py.in --- a/testing/Mtest.py.in +++ b/testing/Mtest.py.in @@ -35,6 +35,8 @@ import socket import struct import signal import fnmatch +import http +import http.server import glob import pymonetdb # check for pymonetdb early: it is essential for our work @@ -3240,13 +3242,26 @@ def SetExecEnv(exe,port,verbose) : print(end='', flush=True) ### SetExecEnv(exe,port,procdebug) # -def StartTlsTester(tsttrgdir): +def DummyTlsTester(): +class DummyHTTPRequestHandler(http.server.BaseHTTPRequestHandler): +def handle(self): +self.requestline = '' +self.request_version = '' +self.command = '' +self.send_error(http.HTTPStatus.INTERNAL_SERVER_ERROR, f"{sys.argv[0]} is not running TLSTestter because the 'cryptography' module is not present") +server = http.server.HTTPServer(('localhost', 0), DummyHTTPRequestHandler) +port = server.server_address[1] +server_thread = threading.Thread(target=server.serve_forever, daemon=True) +server_thread.start() +return port +### DummyTlsTester(exe,port,procdebug) # + +def StartTlsTester(): try: import cryptography except: -# continue without so we can at least run the other tests -print("cryptography not found!", file=sys.stderr) -return None +# Start a dummy server that only returns errors. +return DummyTlsTester() from MonetDBtesting import tlstester hostnames = ['localhost'] certs = tlstester.Certs(hostnames) @@ -3808,7 +3823,7 @@ def main(argv) : # start tlstester if not env.get('TST_TLSTESTERPORT'): -tlstester_port = StartTlsTester(os.path.join(TSTTRGBASE, TSTPREF)) +tlstester_port = StartTlsTester() if tlstester_port: env['TST_TLSTESTERPORT'] = str(tlstester_port) if env.get('TST_TLSTESTERPORT'): ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - ODBCtester.SQL.sh does not need to create odb...
Changeset: e88194ba7d08 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/e88194ba7d08 Modified Files: sql/odbc/tests/Tests/ODBCtester.SQL.sh Branch: Aug2024 Log Message: ODBCtester.SQL.sh does not need to create odbc.ini Mtest takes care of that diffs (23 lines): diff --git a/sql/odbc/tests/Tests/ODBCtester.SQL.sh b/sql/odbc/tests/Tests/ODBCtester.SQL.sh --- a/sql/odbc/tests/Tests/ODBCtester.SQL.sh +++ b/sql/odbc/tests/Tests/ODBCtester.SQL.sh @@ -1,19 +1,3 @@ #!/bin/sh -ODBCINI=$PWD/odbc.ini -trap "rm $ODBCINI" 0 15 -cat > $ODBCINI <
MonetDB: Aug2024 - Make odbcconnect flags more straightforward
Changeset: 48e8d738ef63 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/48e8d738ef63 Modified Files: clients/odbc/tests/odbcconnect.c Branch: Aug2024 Log Message: Make odbcconnect flags more straightforward -d for driver, -b for browse diffs (29 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 @@ -28,14 +28,13 @@ static const char *USAGE = "Usage:\n" "odbcconnect [-d | -c | -b ] [-v] [-u USER] [-p PASSWORD] TARGET..\n" "Options:\n" - "-d Target is DSN, call SQLConnect()\n" - "-c Target is connection string, call SQLDriverConnect()\n" + "-d Target is connection string, call SQLDriverConnect()\n" "-b Target is connection string, call SQLBrowseConnect()\n" "-l List registered drivers and data sources\n" "-u USER\n" "-p PASSWORD\n" "-v Be verbose\n" - "TARGET Connection String or DSN\n"; + "TARGET DSN or with -d and -b, Connection String\n"; typedef int (action_t)(SQLCHAR *); @@ -84,8 +83,6 @@ main(int argc, char **argv) for (int i = 1; i < argc; i++) { char *arg = argv[i]; if (strcmp(arg, "-d") == 0) - action = do_sqlconnect; - else if (strcmp(arg, "-c") == 0) action = do_sqldriverconnect; else if (strcmp(arg, "-b") == 0) action = do_sqlbrowseconnect; ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - odbc: Map InvalidCredentialsException to SQLS...
Changeset: 58c7bfa4dbc9 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/58c7bfa4dbc9 Modified Files: clients/odbc/driver/SQLConnect.c Branch: Aug2024 Log Message: odbc: Map InvalidCredentialsException to SQLSTATE 28000 diffs (17 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 @@ -487,8 +487,12 @@ MNDBConnectSettings(ODBCDbc *dbc, const mapi_reconnect(mid); } if (mid == NULL || mapi_error(mid)) { - const char *error_state = "08001"; + const char *error_state; const char *error_explanation = mid ? mapi_error_str(mid) : NULL; + if (error_explanation && strncmp(error_explanation, "InvalidCredentialsException:", 28) == 0) + error_state = "28000"; + else + error_state = "08001"; addDbcError(dbc, error_state, error_explanation, 0); if (mid) mapi_destroy(mid); ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Use raw string to suppress Python warning
Changeset: 750de1fa87e2 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/750de1fa87e2 Modified Files: sql/test/BugTracker-2024/Tests/7536-mclient-forgets-to-flush.SQL.py Branch: Aug2024 Log Message: Use raw string to suppress Python warning diffs (12 lines): diff --git a/sql/test/BugTracker-2024/Tests/7536-mclient-forgets-to-flush.SQL.py b/sql/test/BugTracker-2024/Tests/7536-mclient-forgets-to-flush.SQL.py --- a/sql/test/BugTracker-2024/Tests/7536-mclient-forgets-to-flush.SQL.py +++ b/sql/test/BugTracker-2024/Tests/7536-mclient-forgets-to-flush.SQL.py @@ -6,7 +6,7 @@ import subprocess # This SQL script redirects the output to a file (the %s). # We will check that all output arrives there, even if it's a gzipped file. -SCRIPT = """\ +SCRIPT = r""" \>%s SELECT 'Donald Knuth'; """ ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Add tests for client_{info,application,remark...
Changeset: f17ab4c9405d for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/f17ab4c9405d Modified Files: sql/test/mapi/Tests/clientinfo-mclient.SQL.py Branch: Aug2024 Log Message: Add tests for client_{info,application,remark} properties diffs (116 lines): diff --git a/sql/test/mapi/Tests/clientinfo-mclient.SQL.py b/sql/test/mapi/Tests/clientinfo-mclient.SQL.py --- a/sql/test/mapi/Tests/clientinfo-mclient.SQL.py +++ b/sql/test/mapi/Tests/clientinfo-mclient.SQL.py @@ -1,5 +1,6 @@ import os import subprocess +import urllib.parse TSTDB = os.environ['TSTDB'] MAPIPORT = os.environ['MAPIPORT'] @@ -10,26 +11,27 @@ FROM sys.sessions WHERE sessionid = current_sessionid() """ -cmd = [ -'mclient', -'-d', TSTDB, -'-p', MAPIPORT, -'-fexpanded', -'-s', QUERY, -] - -out = subprocess.check_output(cmd, encoding='latin1') +def run_mclient(**extra_args): +url = f'monetdb://localhost:{MAPIPORT}/{TSTDB}' +if extra_args: +url += '?' + urllib.parse.urlencode(extra_args) +cmd = [ 'mclient', '-d', url, '-fexpanded', '-s', QUERY ] +out = subprocess.check_output(cmd, encoding='latin1') +fields = dict() +for line in out.splitlines()[1:]: +line = line.strip() +if line: +k, v = line.split('|', 1) +k = k.strip() +v = v.strip() +fields[k] = v +return fields -# print(out) -fields = dict() -for line in out.splitlines()[1:]: -line = line.strip() -if line: -k, v = line.split('|', 1) -k = k.strip() -v = v.strip() -fields[k] = v +### +# By default, most fields get filled in + +fields = run_mclient() assert fields['language'] == 'sql',\ f'Found {fields["language"]!r}' @@ -52,3 +54,59 @@ assert fields['clientpid'] != 'null' and assert fields['remark'] == 'null',\ f'Found {fields["remark"]!r}' + + +### +# client_info=off suppresses everything sent by the client. +# Server still fills in language and peer + +fields = run_mclient(client_info='off') + +assert fields['language'] == 'sql',\ +f'Found {fields["language"]!r}' + +assert fields['peer'] == '' or ']:' in fields['peer'],\ +f'Found {fields["peer"]!r}' + +assert fields['hostname'] == 'null',\ +f'Found {fields["hostname"]!r}' + +# could be mclient-11.51.0, mclient.exe, or whatever +assert fields['application'] == 'null',\ +f'Found {fields["application"]!r}' + +assert fields['client'] == 'null',\ +f'Found {fields["client"]!r}' + +assert fields['clientpid'] == 'null',\ +f'Found {fields["clientpid"]!r}' + +assert fields['remark'] == 'null',\ +f'Found {fields["remark"]!r}' + +### +# We can override application and remark + +fields = run_mclient(client_application='app', client_remark='mark') + +# could be mclient-11.51.0, mclient.exe, or whatever +assert fields['application'] == 'app',\ +f'Found {fields["application"]!r}' + +assert fields['remark'] == 'mark',\ +f'Found {fields["remark"]!r}' + + +### +# We can override application and remark, but client_info=off +# suppresses that. + +fields = run_mclient(client_application='app', client_remark='mark', client_info='off') + +# could be mclient-11.51.0, mclient.exe, or whatever +assert fields['application'] == 'null',\ +f'Found {fields["application"]!r}' + +assert fields['remark'] == 'null',\ +f'Found {fields["remark"]!r}' + ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Add test for SQLConnect/DriverConnect/BrowseC...
Changeset: 0ad8b1cc201d for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/0ad8b1cc201d Added Files: sql/odbc/tests/Tests/ODBCconnect.py Modified Files: sql/odbc/tests/Tests/All Branch: Aug2024 Log Message: Add test for SQLConnect/DriverConnect/BrowseConnect still incomplete diffs (149 lines): diff --git a/sql/odbc/tests/Tests/All b/sql/odbc/tests/Tests/All --- a/sql/odbc/tests/Tests/All +++ b/sql/odbc/tests/Tests/All @@ -2,4 +2,5 @@ HAVE_ODBC?ODBCgetInfo HAVE_ODBC?ODBCmetadata HAVE_ODBC?ODBCStmtAttr HAVE_ODBC?ODBCtester +HAVE_ODBC?ODBCconnect HAVE_PYODBC&!SANITIZER?pyodbc-test diff --git a/sql/odbc/tests/Tests/ODBCconnect.py b/sql/odbc/tests/Tests/ODBCconnect.py new file mode 100755 --- /dev/null +++ b/sql/odbc/tests/Tests/ODBCconnect.py @@ -0,0 +1,135 @@ +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# Copyright 2024 MonetDB Foundation; +# Copyright August 2008 - 2023 MonetDB B.V.; +# Copyright 1997 - July 2008 CWI. + + +# For each target, odbcconnect first prints a status line, +# either 'OK' or 'Error FUNCNAME', followed by zero or more +# sqlstate lines of the form '- STATE: MESSAGE'. + +import atexit +import subprocess +import sys + + +class Execution: +def __init__(self, *odbcconnect_args): +cmd = self.cmd = ['odbcconnect', *odbcconnect_args] +proc = self.proc = subprocess.run( +cmd, capture_output=True, encoding='utf-8') +self.expected_exitcode = 0 +self.remaining = proc.stdout.splitlines() +self.checks = [] + +def report(self): +parts = [f'COMMAND: {self.cmd}', + f'EXIT CODE: {self.proc.returncode}', ''] +if self.proc.stdout: +parts += [ +'--- stdout: ---', +self.proc.stdout.rstrip(), +'--- end ---', +'' +] +if self.proc.stderr: +parts += [ +'--- stderr: ---', +self.proc.stderr.rstrip(), +'--- end ---', +'' +] +if self.checks: +parts.append('--- test history: ---') +for wanted, found in self.checks: +parts.append(f'wanted {wanted!r}, found {found!r}') +parts.append('--- end ---') +if self.remaining: +parts += [ +'--- remaining output: ---', +*self.remaining, +'--- end ---' +] +return '\n'.join(parts) + +def expect(self, pattern): +line = self.next_line() +self.checks.append((pattern, line)) +if pattern not in line: +raise Exception(f'Wanted {pattern!r}, found {line!r}') + +def next_line(self): +if not self.remaining: +raise Exception(f"Unexpected end of output") +line = self.remaining[0] +del self.remaining[0] +return line + +def expect_fail(self, exitcode=1): +self.expected_exitcode = exitcode + +def end(self): +if self.remaining: +raise Exception(f'Unexpected output remaining: {self.remaining}') +code = self.proc.returncode +expected = self.expected_exitcode +if code != expected: +raise Exception( +f'Process exited with code {code!r}, expected {expected!r}') + + +ex = None + + +@atexit.register +def show_context(): +global ex +if ex: +# ex.end() +print(file=sys.stderr) +print(ex.report(), file=sys.stderr) + + +dbname = 'MonetDB-Test' + + +ex = Execution(dbname) +ex.expect('OK') +ex.end() + +ex = Execution(dbname + '-nonexistent') +ex.expect_fail() +ex.expect('Error') +ex.expect('IM002:') # IM002 not found +ex.end() + +ex = Execution(dbname, '-p', 'wrongpassword') +ex.expect_fail() +ex.expect('Error') +ex.expect('28000:') # 28000 bad credentials +ex.end() + +ex = Execution(dbname, '-u', 'wronguser') +ex.expect_fail() +ex.expect('Error') +ex.expect('28000:') # 28000 bad credentials +ex.end() + +ex = Execution(dbname, '-p', '') +ex.expect_fail() +ex.expect('Error') +ex.expect('28000:') # 28000 bad credentials +ex.end() + +ex = Execution(dbname, '-u', '') +ex.expect_fail() +ex.expect('Error') +ex.expect('28000:') # 28000 bad credentials +ex.end() + +ex = None ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Move TLSTesterClient from tlssecurity,py to t...
Changeset: 61f71d59ed8d for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/61f71d59ed8d Modified Files: clients/mapilib/Tests/tlssecurity.py testing/tlstester.py Branch: Aug2024 Log Message: Move TLSTesterClient from tlssecurity,py to testing/tlstester.py So we can use it from other tests as well diffs (129 lines): diff --git a/clients/mapilib/Tests/tlssecurity.py b/clients/mapilib/Tests/tlssecurity.py --- a/clients/mapilib/Tests/tlssecurity.py +++ b/clients/mapilib/Tests/tlssecurity.py @@ -14,9 +14,8 @@ import os import re import subprocess import sys -import urllib.request -from MonetDBtesting import tlstester +from MonetDBtesting.tlstester import TLSTesterClient level = logging.WARNING # if sys.platform == 'win32': @@ -32,50 +31,6 @@ assert os.path.isdir(tgtdir) scratchdir = os.path.join(tgtdir, "scratch") logging.debug(f"scratchdir={scratchdir}") -class TLSTesterClient: -"""Connect to TLSTester to figure out port numbers and download certificates""" -def __init__(self, scratchdir, base_port=None, host='localhost'): -if not base_port: -base_port = os.environ['TST_TLSTESTERPORT'] -self.url = f'http://{host}:{base_port}/' -self.scratch = scratchdir -try: -os.mkdir(scratchdir) -except FileExistsError: -pass -self.filenames = dict() -self.contents = dict() -self.portmap = dict() -for line in self.fetch('').splitlines(): -name, port = str(line, 'ascii').split(':', 1) -self.portmap[name] = int(port) -logging.debug(f'port {name} = {port}') - -def get_port(self, name): -return self.portmap[name] - -def fetch(self, name): -cached = self.contents.get(name) -if cached is not None: -return cached -url = self.url + name -logging.debug(f'fetch {url}') -with urllib.request.urlopen(url) as response: -content = response.read() -self.contents[name] = content -return content - -def download(self, name): -cached = self.filenames.get(name) -if cached: -return cached -content = self.fetch(name) -path = os.path.join(self.scratch, name) -with open(path, 'wb') as f: -f.write(content) -self.filenames[name] = path -return path - tlstester = TLSTesterClient(scratchdir) diff --git a/testing/tlstester.py b/testing/tlstester.py --- a/testing/tlstester.py +++ b/testing/tlstester.py @@ -27,6 +27,7 @@ import tempfile from threading import Thread import threading from typing import Any, Callable, Dict, List, Optional, Tuple, Union +import urllib.request # Our TLS implementation never uses anything less than TLSv1.3. assert ssl.HAS_TLSv1_3 @@ -98,6 +99,52 @@ argparser.add_argument( ) + +class TLSTesterClient: +"""Connect to TLSTester to figure out port numbers and download certificates""" +def __init__(self, scratchdir, base_port=None, host='localhost'): +if not base_port: +base_port = os.environ['TST_TLSTESTERPORT'] +self.url = f'http://{host}:{base_port}/' +self.scratch = scratchdir +try: +os.mkdir(scratchdir) +except FileExistsError: +pass +self.filenames = dict() +self.contents = dict() +self.portmap = dict() +for line in self.fetch('').splitlines(): +name, port = str(line, 'ascii').split(':', 1) +self.portmap[name] = int(port) +logging.debug(f'port {name} = {port}') + +def get_port(self, name): +return self.portmap[name] + +def fetch(self, name): +cached = self.contents.get(name) +if cached is not None: +return cached +url = self.url + name +logging.debug(f'fetch {url}') +with urllib.request.urlopen(url) as response: +content = response.read() +self.contents[name] = content +return content + +def download(self, name): +cached = self.filenames.get(name) +if cached: +return cached +content = self.fetch(name) +path = os.path.join(self.scratch, name) +with open(path, 'wb') as f: +f.write(content) +self.filenames[name] = path +return path + + class Certs: hostnames: str _files: Dict[str, bytes] ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Move tlstester to testing/ directory
Changeset: d3c75b4b83c6 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/d3c75b4b83c6 Added Files: testing/tlstester.py Removed Files: clients/mapilib/Tests/tlstester.py Modified Files: clients/mapilib/Tests/tlssecurity.py testing/CMakeLists.txt Branch: Aug2024 Log Message: Move tlstester to testing/ directory diffs (27 lines): diff --git a/clients/mapilib/Tests/tlssecurity.py b/clients/mapilib/Tests/tlssecurity.py --- a/clients/mapilib/Tests/tlssecurity.py +++ b/clients/mapilib/Tests/tlssecurity.py @@ -16,8 +16,7 @@ import subprocess import sys import threading -sys.path.append(os.environ.get('TSTSRCDIR','.')) -import tlstester +from MonetDBtesting import tlstester level = logging.WARNING # if sys.platform == 'win32': diff --git a/testing/CMakeLists.txt b/testing/CMakeLists.txt --- a/testing/CMakeLists.txt +++ b/testing/CMakeLists.txt @@ -147,6 +147,7 @@ if(PYTHON3_LIBDIR) malmapi.py helpers.py sqltest.py +tlstester.py utils.py DESTINATION ${PYTHON3_LIBDIR}/MonetDBtesting COMPONENT pytesting) diff --git a/clients/mapilib/Tests/tlstester.py b/testing/tlstester.py rename from clients/mapilib/Tests/tlstester.py rename to testing/tlstester.py ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Use Mtest's TLSTester to test JDBC TLS
Changeset: e0c0dbd3e852 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/e0c0dbd3e852 Added Files: sql/jdbc/tests/Tests/TLSTester.py Modified Files: sql/jdbc/tests/Tests/All Branch: Aug2024 Log Message: Use Mtest's TLSTester to test JDBC TLS diffs (32 lines): diff --git a/sql/jdbc/tests/Tests/All b/sql/jdbc/tests/Tests/All --- a/sql/jdbc/tests/Tests/All +++ b/sql/jdbc/tests/Tests/All @@ -1,4 +1,5 @@ HAVE_JDBCTESTS?JDBC_API_Tester +HAVE_JDBCTESTS?TLSTester HAVE_JDBCTESTS?OnClientTester HAVE_JDBCCLIENT_JAR?Test_JdbcClient # next test should be done AFTER all the other tests have completed diff --git a/sql/jdbc/tests/Tests/TLSTester.py b/sql/jdbc/tests/Tests/TLSTester.py new file mode 100644 --- /dev/null +++ b/sql/jdbc/tests/Tests/TLSTester.py @@ -0,0 +1,18 @@ +import os, sys +from subprocess import run, PIPE, CalledProcessError + +PORT=os.environ['TST_TLSTESTERPORT'] + +cmd = [ +'java', 'TLSTester', +# '-v', +f'localhost:{PORT}', +'-a', 'localhost.localdomain' +] +try: +p = run(cmd, stdout=PIPE, stderr=PIPE, check=True, encoding='utf-8') +sys.stderr.write(p.stdout) +sys.stderr.write(p.stderr) +except CalledProcessError as e: +raise SystemExit(e.stderr) + ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Don't write certs to TSTTRGDIR, it may not ex...
Changeset: 5eb6a7727787 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/5eb6a7727787 Modified Files: testing/Mtest.py.in Branch: Aug2024 Log Message: Don't write certs to TSTTRGDIR, it may not exist yet diffs (26 lines): diff --git a/testing/Mtest.py.in b/testing/Mtest.py.in --- a/testing/Mtest.py.in +++ b/testing/Mtest.py.in @@ -3250,14 +3250,6 @@ def StartTlsTester(tsttrgdir): from MonetDBtesting import tlstester hostnames = ['localhost'] certs = tlstester.Certs(hostnames) -certsdir = os.path.join(tsttrgdir, "certs") -try: -os.mkdir(certsdir) -except FileExistsError: -pass -for name, content in certs.all().items(): -with open(os.path.join(certsdir, name), "wb") as f: -f.write(content) server = tlstester.TLSTester( certs = certs, listen_addr='localhost', @@ -3267,7 +3259,6 @@ def StartTlsTester(tsttrgdir): server_thread = threading.Thread(target=server.serve_forever, daemon=True) server_thread.start() return server.get_port('base') - ### StartTlsTester() # # ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - Add list drivers and list dns's to odbcconnect
Changeset: 230778a77ea1 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/230778a77ea1 Modified Files: clients/odbc/samples/odbcconnect.c Branch: Aug2024 Log Message: Add list drivers and list dns's to odbcconnect Fix a small memory leak in the process diffs (204 lines): diff --git a/clients/odbc/samples/odbcconnect.c b/clients/odbc/samples/odbcconnect.c --- a/clients/odbc/samples/odbcconnect.c +++ b/clients/odbc/samples/odbcconnect.c @@ -15,6 +15,8 @@ #include #endif + +#include #include #include #include @@ -29,14 +31,22 @@ static const char *USAGE = "-d Target is DSN, call SQLConnect()\n" "-c Target is connection string, call SQLDriverConnect()\n" "-b Target is connection string, call SQLBrowseConnect()\n" + "-l List registered drivers and data sources\n" "-u USER\n" "-p PASSWORD\n" "-v Be verbose\n" "TARGET Connection String or DSN\n"; -static int do_sqlconnect(SQLCHAR *target); -static int do_sqldriverconnect(SQLCHAR *target); -static int do_sqlbrowseconnect(SQLCHAR *target); +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_listdrivers(void); +static int do_listdsns(const char *prefix, SQLSMALLINT dir); static void ensure_ok(SQLSMALLINT type, SQLHANDLE handle, const char *message, SQLRETURN ret); @@ -49,6 +59,7 @@ SQLHANDLE env = NULL; SQLHANDLE conn = NULL; SQLCHAR outbuf[4096]; +SQLCHAR attrbuf[4096]; static void cleanup(void) @@ -68,7 +79,7 @@ main(int argc, char **argv) action = do_sqlconnect; SQLCHAR **targets = calloc(argc, sizeof(argv[0])); int ntargets = 0; - int ret = 0; + int ret; for (int i = 1; i < argc; i++) { char *arg = argv[i]; @@ -78,6 +89,8 @@ main(int argc, char **argv) action = do_sqldriverconnect; else if (strcmp(arg, "-b") == 0) action = do_sqlbrowseconnect; + else if (strcmp(arg, "-l") == 0) + action = NULL; else if (strcmp(arg, "-u") == 0 && i + 1 < argc) user = (SQLCHAR*)argv[++i]; else if (strcmp(arg, "-p") == 0 && i + 1 < argc) @@ -88,15 +101,11 @@ main(int argc, char **argv) targets[ntargets++] = (SQLCHAR*)arg; else { fprintf(stderr, "\nERROR: invalid argument: %s\n%s", arg, USAGE); - return 1; + ret = 1; + goto end; } } - if (ntargets == 0) { - fprintf(stderr, "\nERROR: pass at least one target\n%s", USAGE); - return 1; - } - ensure_ok( SQL_HANDLE_ENV, NULL, "allocate env handle", SQLAllocHandle(SQL_HANDLE_ENV, NULL, &env)); @@ -105,20 +114,25 @@ main(int argc, char **argv) SQL_HANDLE_ENV, env, "set odbc version", SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0)); - ensure_ok( - SQL_HANDLE_ENV, env, "allocate conn handle", - SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); - - for (int i = 0; i < ntargets; i++) { - SQLCHAR *t = targets[i]; - if (verbose) - printf("\nTarget: %s\n", t); - outbuf[0] = '\0'; - int ret = action(t); - if (ret) - break; + if (action) { + if (ntargets == 0) { + fprintf(stderr, "\nERROR: pass at least one target\n%s", USAGE); + ret = 1; + goto end; + } + ret = do_actions(action, ntargets, targets); + } else { + if (ntargets != 0) { + fprintf(stderr, "\nERROR: -l does not take arguments\n%s", USAGE); + ret = 1; + goto end; + } + ret = do_listdrivers(); + ret |= do_listdsns("SYSTEM", SQL_FETCH_FIRST_SYSTEM); + ret |= do_listdsns("SYSTEM", SQL_FETCH_FIRST_USER); } +end: free(targets); cleanup(); @@ -174,6 +188,26 @@ ensure_ok(SQLSMALLINT type, SQLHANDLE ha static int +do_actions(action_t action, int ntargets, SQLCHAR **targets) +{ + ensure_ok( + SQL_HANDLE_ENV, env, "allocate conn handle", + SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); + + for (int i = 0; i < ntargets; i++) { + SQLCHAR *t = targets[i]; + if (verbose) +
MonetDB: default - Implements break for expressions list (by def...
Changeset: efd0930c1c01 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/efd0930c1c01 Modified Files: sql/server/rel_dump.c Branch: default Log Message: Implements break for expressions list (by default is off) If you want to have it enabled change the expbrk arg of exps_print() in rel_print_rel() to 1 for the operator that you are interested in diffs (192 lines): diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c --- a/sql/server/rel_dump.c +++ b/sql/server/rel_dump.c @@ -110,7 +110,7 @@ dump_sql_subtype(allocator *sa, sql_subt return sa_strdup(sa, buf); } -static void exps_print(mvc *sql, stream *fout, list *exps, int depth, list *refs, int alias, int brackets, int decorate); +static void exps_print(mvc *sql, stream *fout, list *exps, int depth, list *refs, int alias, int brackets, int decorate, int expbrk); static void rel_print_rel(mvc *sql, stream *fout, sql_rel *rel, int depth, list *refs, int decorate); @@ -153,14 +153,14 @@ exp_print(mvc *sql, stream *fout, sql_ex } else if (e->flag & PSM_WHILE) { mnstr_printf(fout, "while "); exp_print(sql, fout, e->l, depth, refs, 0, 0, decorate); - exps_print(sql, fout, e->r, depth, refs, 0, 0, decorate); + exps_print(sql, fout, e->r, depth, refs, 0, 0, decorate, 0); alias = 0; } else if (e->flag & PSM_IF) { mnstr_printf(fout, "if "); exp_print(sql, fout, e->l, depth, refs, 0, 0, decorate); - exps_print(sql, fout, e->r, depth, refs, 0, 0, decorate); + exps_print(sql, fout, e->r, depth, refs, 0, 0, decorate, 0); if (e->f) - exps_print(sql, fout, e->f, depth, refs, 0, 0, decorate); + exps_print(sql, fout, e->f, depth, refs, 0, 0, decorate, 0); alias = 0; } else if (e->flag & PSM_REL) { rel_print_rel(sql, fout, e->l, depth+10, refs, 1); @@ -209,7 +209,7 @@ exp_print(mvc *sql, stream *fout, sql_ex mnstr_printf(fout, "\"%s\"", dump_escape_ident(sql->ta, vname->name)); } else if (e->f) { /* values list */ list *l = e->f; - exps_print(sql, fout, l, depth, refs, 0, 0, decorate); + exps_print(sql, fout, l, depth, refs, 0, 0, decorate, 0); } else { /* numbered arguments */ mnstr_printf(fout, "A%u", e->flag); } @@ -220,11 +220,11 @@ exp_print(mvc *sql, stream *fout, sql_ex mnstr_printf(fout, "\"%s\".\"%s\"", f->func->s?dump_escape_ident(sql->ta, f->func->s->base.name):"sys", dump_escape_ident(sql->ta, f->func->base.name)); - exps_print(sql, fout, e->l, depth, refs, 0, 1, decorate); + exps_print(sql, fout, e->l, depth, refs, 0, 1, decorate, 0); if (e->r) { /* list of optional lists */ list *l = e->r; for(node *n = l->h; n; n = n->next) - exps_print(sql, fout, n->data, depth, refs, 0, 1, decorate); + exps_print(sql, fout, n->data, depth, refs, 0, 1, decorate, 0); } if (e->flag && is_compare_func(f)) mnstr_printf(fout, " %s", e->flag==1?"ANY":"ALL"); @@ -241,7 +241,7 @@ exp_print(mvc *sql, stream *fout, sql_ex if (zero_if_empty(e)) mnstr_printf(fout, " zero if empty "); if (e->l) - exps_print(sql, fout, e->l, depth, refs, 0, 1, decorate); + exps_print(sql, fout, e->l, depth, refs, 0, 1, decorate, 0); else mnstr_printf(fout, "()"); } break; @@ -268,23 +268,23 @@ exp_print(mvc *sql, stream *fout, sql_ex if (is_anti(e)) mnstr_printf(fout, " !"); cmp_print(sql, fout, e->flag); - exps_print(sql, fout, e->r, depth, refs, 0, 1, decorate); + exps_print(sql, fout, e->r, depth, refs, 0, 1, decorate, 0); } else if (e->flag == cmp_or) { - exps_print(sql, fout, e->l, depth, refs, 0, 1, decorate); + exps_print(sql, fout, e->l, depth, refs, 0, 1, decorate, 0); if (is_anti(e)) mnstr_printf(fout, " !"); cmp_print(sql, fout, e->flag); - exps_print(sql, fout, e->r, depth, refs, 0, 1, decorate); +
MonetDB: default - When breaking list of exps with single entry ...
Changeset: 7bdc764bbe7c for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/7bdc764bbe7c Modified Files: sql/server/rel_dump.c Branch: default Log Message: When breaking list of exps with single entry don't ident the closing bracket diffs (19 lines): diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c --- a/sql/server/rel_dump.c +++ b/sql/server/rel_dump.c @@ -431,12 +431,13 @@ exps_print(mvc *sql, stream *fout, list if (expbrk && en->next!=NULL) print_indent(sql, fout, depth+2, decorate); } - if (expbrk) + int multi_exps = expbrk && (list_length(exps) > 1); + if (multi_exps) print_indent(sql, fout, depth+1, decorate); if (brackets) mnstr_printf(fout, ")"); else - mnstr_printf(fout, expbrk?"]":" ]"); + mnstr_printf(fout, multi_exps?"]":" ]"); } static int ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: default - introduced vacuum_tab/vacuum_col for variable...
Changeset: 960fa2655454 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/960fa2655454 Modified Files: clients/Tests/MAL-signatures-hge.test clients/Tests/MAL-signatures.test sql/backends/monet5/sql.c sql/backends/monet5/sql.h sql/server/sql_parser.y sql/storage/bat/bat_storage.c sql/storage/bat/bat_storage.h sql/storage/sql_storage.h sql/storage/store.c sql/test/sysmon/vacuum/Tests/test_vacuum.SQL.py Branch: default Log Message: introduced vacuum_tab/vacuum_col for variable size data types diffs (truncated from 803 to 300 lines): diff --git a/clients/Tests/MAL-signatures-hge.test b/clients/Tests/MAL-signatures-hge.test --- a/clients/Tests/MAL-signatures-hge.test +++ b/clients/Tests/MAL-signatures-hge.test @@ -49805,8 +49805,13 @@ SQLstddev_pop; return the standard deviation population of groups sql stop_vacuum +unsafe pattern sql.stop_vacuum(X_0:str, X_1:str):void +SQLstr_stop_vacuum; +stop auto vacuum +sql +stop_vacuum unsafe pattern sql.stop_vacuum(X_0:str, X_1:str, X_2:str):void -SQLstr_column_stop_vacuum; +SQLstr_stop_vacuum; stop auto vacuum sql storage @@ -49965,8 +49970,13 @@ SYSupdate_tables; Procedure triggered on update of the sys._tables table sql vacuum +unsafe pattern sql.vacuum(X_0:str, X_1:str, X_2:int):void +SQLstr_auto_vacuum; +auto vacuum string column of given table with interval(sec) +sql +vacuum unsafe pattern sql.vacuum(X_0:str, X_1:str, X_2:str, X_3:int):void -SQLstr_column_auto_vacuum; +SQLstr_auto_vacuum; auto vacuum string column with interval(sec) sql vacuum diff --git a/clients/Tests/MAL-signatures.test b/clients/Tests/MAL-signatures.test --- a/clients/Tests/MAL-signatures.test +++ b/clients/Tests/MAL-signatures.test @@ -38215,8 +38215,13 @@ SQLstddev_pop; return the standard deviation population of groups sql stop_vacuum +unsafe pattern sql.stop_vacuum(X_0:str, X_1:str):void +SQLstr_stop_vacuum; +stop auto vacuum +sql +stop_vacuum unsafe pattern sql.stop_vacuum(X_0:str, X_1:str, X_2:str):void -SQLstr_column_stop_vacuum; +SQLstr_stop_vacuum; stop auto vacuum sql storage @@ -38350,8 +38355,13 @@ SYSupdate_tables; Procedure triggered on update of the sys._tables table sql vacuum +unsafe pattern sql.vacuum(X_0:str, X_1:str, X_2:int):void +SQLstr_auto_vacuum; +auto vacuum string column of given table with interval(sec) +sql +vacuum unsafe pattern sql.vacuum(X_0:str, X_1:str, X_2:str, X_3:int):void -SQLstr_column_auto_vacuum; +SQLstr_auto_vacuum; auto vacuum string column with interval(sec) sql vacuum diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c --- a/sql/backends/monet5/sql.c +++ b/sql/backends/monet5/sql.c @@ -4928,40 +4928,40 @@ finalize: } static str -do_str_column_vacuum(sql_trans *tr, sql_column *c, char *sname, char *tname, char *cname) +do_str_column_vacuum(sql_trans *tr, sql_column *c) { - int res; - int access = 0; - BAT* b = NULL; - BAT* bn = NULL; - sqlstore *store = tr->store; - - if ((b = store->storage_api.bind_col(tr, c, access)) == NULL) - throw(SQL, "do_str_column_vacuum", SQLSTATE(42S22) "storage_api.bind_col failed for %s.%s.%s", sname, tname, cname); - // vacuum varsized bats if (ATOMvarsized(c->type.type->localtype)) { - // TODO check for num of updates on the BAT against some threshold - // and decide whether to proceed - if ((bn = COLcopy(b, b->ttype, true, PERSISTENT)) == NULL) { - BBPunfix(b->batCacheid); - throw(SQL, "do_str_column_vacuum", SQLSTATE(42S22) "COLcopy failed for %s.%s.%s", sname, tname, cname); + int res = 0; + sqlstore *store = tr->store; + + if ((res = (int) store->storage_api.vacuum_col(tr, c)) != LOG_OK) { + if (res == LOG_CONFLICT) + throw(SQL, "do_str_column_vacuum", SQLSTATE(25S01) "TRANSACTION CONFLICT in storage_api.vacuum_col %s.%s.%s", c->t->s->base.name, c->t->base.name, c->base.name); + if (res == LOG_ERR) + throw(SQL, "do_str_column_vacuum", SQLSTATE(HY000) "LOG ERROR in storage_api.vacuum_col %s.%s.%s", c->t->s->base.name, c->t->base.name, c->base.name); + throw(SQL, "do_str_column_vacuum", SQLSTATE(HY000) "ERROR in storage_api.vacuum_col %s.%s.%s", c->t->s->base.name, c->t->base.name, c->base.name); } - if ((res = (int) store->storage_api.swap_bats(tr, c, bn)) != LOG_OK) { - BBPreclaim(bn); - BBPunfix(b->batCacheid); - if (res == LOG_CONFLICT) - throw(SQL, "do_str_column_vacuum", SQLSTATE(25S01) "TRANSACTION CONFLICT in storage_api.swap_bats %s.%s.%s", sname, tname, cname); - if (res == LOG_ERR) -
MonetDB: default - add missing sql interfaces
Changeset: d74cd175f7f1 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/d74cd175f7f1 Modified Files: sql/scripts/26_sysmon.sql Branch: default Log Message: add missing sql interfaces diffs (12 lines): diff --git a/sql/scripts/26_sysmon.sql b/sql/scripts/26_sysmon.sql --- a/sql/scripts/26_sysmon.sql +++ b/sql/scripts/26_sysmon.sql @@ -79,3 +79,8 @@ create procedure sys.vacuum(sname string external name sql.vacuum; create procedure sys.stop_vacuum(sname string, tname string, cname string) external name sql.stop_vacuum; + +create procedure sys.vacuum(sname string, tname string, interval int) +external name sql.vacuum; +create procedure sys.stop_vacuum(sname string, tname string) +external name sql.stop_vacuum; ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: default - add direct interface for table vacuum
Changeset: 2af293dc3d14 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/2af293dc3d14 Modified Files: clients/Tests/MAL-signatures-hge.test sql/backends/monet5/sql.c sql/scripts/26_sysmon.sql Branch: default Log Message: add direct interface for table vacuum diffs (108 lines): diff --git a/clients/Tests/MAL-signatures-hge.test b/clients/Tests/MAL-signatures-hge.test --- a/clients/Tests/MAL-signatures-hge.test +++ b/clients/Tests/MAL-signatures-hge.test @@ -49980,8 +49980,13 @@ SQLstr_auto_vacuum; auto vacuum string column with interval(sec) sql vacuum +unsafe pattern sql.vacuum(X_0:str, X_1:str):void +SQLstr_vacuum; +vacuum a string column +sql +vacuum unsafe pattern sql.vacuum(X_0:str, X_1:str, X_2:str):void -SQLstr_column_vacuum; +SQLstr_vacuum; vacuum a string column sql variance diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c --- a/sql/backends/monet5/sql.c +++ b/sql/backends/monet5/sql.c @@ -4962,13 +4962,15 @@ do_str_table_vacuum(sql_trans *tr, sql_t } static str -SQLstr_column_vacuum(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) +SQLstr_vacuum(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { mvc *m = NULL; str msg = NULL; char *sname = *getArgReference_str(stk, pci, 1); char *tname = *getArgReference_str(stk, pci, 2); - char *cname = *getArgReference_str(stk, pci, 3); + char *cname = NULL; + if (pci->argc == 4) + cname = *getArgReference_str(stk, pci, 3); if ((msg = getSQLContext(cntxt, mb, &m, NULL)) != NULL) return msg; @@ -4981,26 +4983,31 @@ SQLstr_column_vacuum(Client cntxt, MalBl sql_column *c = NULL; if (strNil(sname)) - throw(SQL, "sql.str_column_vacuum", SQLSTATE(42000) "Schema name cannot be NULL"); + throw(SQL, "sql.str_vacuum", SQLSTATE(42000) "Schema name cannot be NULL"); if (strNil(tname)) - throw(SQL, "sql.str_column_vacuum", SQLSTATE(42000) "Table name cannot be NULL"); + throw(SQL, "sql.str_vacuum", SQLSTATE(42000) "Table name cannot be NULL"); if (strNil(cname)) - throw(SQL, "sql.str_column_vacuum", SQLSTATE(42000) "Column name cannot be NULL"); + throw(SQL, "sql.str_vacuum", SQLSTATE(42000) "Column name cannot be NULL"); if ((s = mvc_bind_schema(m, sname)) == NULL) - throw(SQL, "sql.str_column_vacuum", SQLSTATE(3F000) "Invalid or missing schema %s",sname); + throw(SQL, "sql.str_vacuum", SQLSTATE(3F000) "Invalid or missing schema %s",sname); if ((t = mvc_bind_table(m, s, tname)) == NULL) - throw(SQL, "sql.str_column_vacuum", SQLSTATE(42S02) "Invalid or missing table %s.%s",sname,tname); + throw(SQL, "sql.str_vacuum", SQLSTATE(42S02) "Invalid or missing table %s.%s",sname,tname); if (!isTable(t)) - throw(SQL, "sql.str_column_vacuum", SQLSTATE(42000) "%s '%s' is not persistent", + throw(SQL, "sql.str_vacuum", SQLSTATE(42000) "%s '%s' is not persistent", TABLE_TYPE_DESCRIPTION(t->type, t->properties), t->base.name); if (isTempTable(t)) - throw(SQL, "sql.str_column_vacuum", SQLSTATE(42000) "Cannot vacuum column from temporary table"); - if ((c = mvc_bind_column(m, t, cname)) == NULL) - throw(SQL, "sql.str_column_vacuum", SQLSTATE(42S22) "Column not found in %s.%s.%s",sname,tname,cname); - if (c->storage_type) - throw(SQL, "sql.str_column_vacuum", SQLSTATE(42000) "Cannot vacuum compressed column"); - - return do_str_column_vacuum(tr, c); + throw(SQL, "sql.str_vacuum", SQLSTATE(42000) "Cannot vacuum column from temporary table"); + if (cname) { + if ((c = mvc_bind_column(m, t, cname)) == NULL) + throw(SQL, "sql.str_vacuum", SQLSTATE(42S22) "Column not found in %s.%s.%s",sname,tname,cname); + if (c->storage_type) + throw(SQL, "sql.str_vacuum", SQLSTATE(42000) "Cannot vacuum compressed column"); + } + + if (c) + return do_str_column_vacuum(tr, c); + else + return do_str_table_vacuum(tr, t); } @@ -6223,9 +6230,10 @@ static mel_func sql_init_funcs[] = { pattern("sql", "corr", SQLcorr, false, "return the correlation value of groups", args(1,8, arg("",dbl),arg("b",hge),arg("c",hge),arg("p",bit),arg("o",bit),arg("t",int),arg("s",oid),arg("e",oid))), pattern("batsql", "corr", SQLcorr, false, "return the correlation value of groups", args(1,8, batarg("",dbl),optbatarg("b",hge),optbatarg("c",hge),optbatarg("p",bit),optbatarg("o",bit),arg("t",int),optbatarg("s",oid),optbatarg("e",oid))), #endif - pattern("sql", "vacuum", SQLstr_column_vacuum, true, "vacuum a string column", args(0,3, arg("sname",str),arg("tname",str),arg("cname",str))), + p
MonetDB: Dec2023 - small cleanup/comment added
Changeset: 9b75c288d86c for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/9b75c288d86c Modified Files: sql/storage/store.c Branch: Dec2023 Log Message: small cleanup/comment added diffs (20 lines): diff --git a/sql/storage/store.c b/sql/storage/store.c --- a/sql/storage/store.c +++ b/sql/storage/store.c @@ -6286,6 +6286,7 @@ sql_trans_alter_null(sql_trans *tr, sql_ if ((res = new_column(tr, col, &dup))) return res; + col = dup; dup->null = isnull; /* disallow concurrent updates on the column if not null is set */ @@ -6296,7 +6297,7 @@ sql_trans_alter_null(sql_trans *tr, sql_ return res; if ((res = store_reset_sql_functions(tr, col->t->base.id))) /* reset sql functions depending on the table */ return res; - if (isNew(col) || isnull) + if (isNew(col) || isnull) /* new ie can still change, or persistent only widen semantics */ store->storage_api.col_not_null(tr, col, !isnull); } return res; ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - merged with dec2023
Changeset: 50a123e080b0 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/50a123e080b0 Modified Files: gdk/gdk.h gdk/gdk_utils.c monetdb5/modules/mal/txtsim.c sql/storage/store.c Branch: Aug2024 Log Message: merged with dec2023 diffs (120 lines): diff --git a/clients/odbc/driver/ODBCError.c b/clients/odbc/driver/ODBCError.c --- a/clients/odbc/driver/ODBCError.c +++ b/clients/odbc/driver/ODBCError.c @@ -373,27 +373,6 @@ appendODBCError(ODBCError **head, ODBCEr } -#if 0 /* unused */ -/* - * Prepends a valid ODBCError object 'err' to the front of the list - * of a valid ODBCError object 'head' and return the new head. - * - * Precondition: both head and err must be valid (non NULL) - * Returns: the new head (which is the same as the prepended 'err'). - */ -void -prependODBCError(ODBCError **head, ODBCError *err) -{ - assert(head); - assert(err); - assert(err->next == NULL); - - err->next = *head; - *head = err; -} -#endif - - /* * Frees the ODBCError object including its linked ODBCError objects. * diff --git a/clients/odbc/driver/ODBCError.h b/clients/odbc/driver/ODBCError.h --- a/clients/odbc/driver/ODBCError.h +++ b/clients/odbc/driver/ODBCError.h @@ -110,18 +110,6 @@ int getErrorRecCount(ODBCError *error); void appendODBCError(ODBCError **head, ODBCError *err); -#if 0 /* unused */ -/* - * Prepends a valid ODBCError object 'this' to the front of the list - * of a valid ODBCError object 'head' and return the new head. - * - * Precondition: both head and this must be valid (non NULL) - * Returns: the new head (which is the same as the prepended 'this'). - */ -void prependODBCError(ODBCError **head, ODBCError *err); -#endif - - /* * Frees the ODBCError object including its linked ODBCError objects. * diff --git a/gdk/gdk.h b/gdk/gdk.h --- a/gdk/gdk.h +++ b/gdk/gdk.h @@ -1087,7 +1087,7 @@ bat_iterator_nolock(BAT *b) { /* does not get matched by bat_iterator_end */ if (b) { - bool isview = VIEWtparent(b); + const bool isview = VIEWtparent(b) != 0; return (BATiter) { .b = b, .h = b->theap, diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c --- a/gdk/gdk_utils.c +++ b/gdk/gdk_utils.c @@ -378,19 +378,7 @@ GDKlog(FILE *lockFile, const char *forma /* * @+ Interrupt handling - * The current version simply catches signals and prints a warning. - * It should be extended to cope with the specifics of the interrupt - * received. */ -#if 0 /* these are unused */ -static void -BATSIGignore(int nr) -{ - (void) nr; - GDKsyserror("! ERROR signal %d caught by thread %zu\n", nr, (size_t) MT_getpid()); -} -#endif - #ifdef WIN32 static void BATSIGabort(int nr) diff --git a/monetdb5/modules/mal/txtsim.c b/monetdb5/modules/mal/txtsim.c --- a/monetdb5/modules/mal/txtsim.c +++ b/monetdb5/modules/mal/txtsim.c @@ -247,7 +247,7 @@ levenshtein(int *res, const char *x, con throw(MAL, "txtsim.levenshtein", "Illegal unicode code point"); } -/* Levenshtein OP but with column externaly allocated */ +/* Levenshtein OP but with column externally allocated */ static inline int levenshtein2(const char *x, const char *y, const size_t xlen, const size_t ylen, unsigned int *column, const int insdel_cost, diff --git a/sql/storage/store.c b/sql/storage/store.c --- a/sql/storage/store.c +++ b/sql/storage/store.c @@ -6330,6 +6330,7 @@ sql_trans_alter_null(sql_trans *tr, sql_ if ((res = new_column(tr, col, &dup))) return res; + col = dup; dup->null = isnull; /* disallow concurrent updates on the column if not null is set */ @@ -6340,7 +6341,7 @@ sql_trans_alter_null(sql_trans *tr, sql_ return res; if ((res = store_reset_sql_functions(tr, col->t->base.id))) /* reset sql functions depending on the table */ return res; - if (isNew(col) || isnull) + if (isNew(col) || isnull) /* new ie can still change, or persistent only widen semantics */ store->storage_api.col_not_null(tr, col, !isnull); } return res; ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Aug2024 - fall back to type STRING on only NULL's
Changeset: 6b8fe0152645 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/6b8fe0152645 Modified Files: sql/backends/monet5/vaults/csv/csv.c Branch: Aug2024 Log Message: fall back to type STRING on only NULL's diffs (16 lines): diff --git a/sql/backends/monet5/vaults/csv/csv.c b/sql/backends/monet5/vaults/csv/csv.c --- a/sql/backends/monet5/vaults/csv/csv.c +++ b/sql/backends/monet5/vaults/csv/csv.c @@ -344,6 +344,12 @@ detect_types(const char *buf, char delim types = ntypes; nr_lines++; } + if (types) { /* NULL -> STRING */ + for(int i = 0; i
MonetDB: Aug2024 - Remove fancy type signature
Changeset: f66c54d25182 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/f66c54d25182 Modified Files: testing/tlstester.py Branch: Aug2024 Log Message: Remove fancy type signature Old Python versions don't support it diffs (12 lines): diff --git a/testing/tlstester.py b/testing/tlstester.py --- a/testing/tlstester.py +++ b/testing/tlstester.py @@ -542,7 +542,7 @@ class WebHandler(http.server.BaseHTTPReq self.end_headers() self.wfile.write(content) -def log_request(self, code: int | str = "-", size: int | str = "-") -> None: +def log_request(self, code = "-", size = "-"): # be silent pass ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org