diff --git a/scripts/sqllogictest/parser/parser.py b/scripts/sqllogictest/parser/parser.py index 9484b3492131..fd2a16c32676 100644 --- a/scripts/sqllogictest/parser/parser.py +++ b/scripts/sqllogictest/parser/parser.py @@ -356,6 +356,8 @@ def statement_load(self, header: Token) -> Optional[BaseStatement]: statement = Load(header, self.current_line + 1) if len(header.parameters) > 1 and header.parameters[1] == "readonly": statement.set_readonly() + if len(header.parameters) > 2: + statement.set_version(header.parameters[2]) return statement def statement_loop(self, header: Token) -> Optional[BaseStatement]: diff --git a/scripts/sqllogictest/result.py b/scripts/sqllogictest/result.py index 1c74e82c97df..93b8c4683898 100644 --- a/scripts/sqllogictest/result.py +++ b/scripts/sqllogictest/result.py @@ -63,9 +63,6 @@ def __init__(self, type: "ExecuteResult.Type"): BUILTIN_EXTENSIONS = [ 'json', - 'fts', - 'tpcds', - 'tpch', 'parquet', 'icu', ] @@ -823,6 +820,9 @@ def execute_load(self, load: Load): else: additional_config['access_mode'] = 'automatic' + if load.version: + additional_config['storage_compatibility_version'] = str(load.version) + self.pool = None self.runner.database = None self.runner.database = SQLLogicDatabase(dbpath, self, additional_config) @@ -958,13 +958,20 @@ def execute_restart(self, statement: Restart): def execute_set(self, statement: Set): option = statement.header.parameters[0] - string_set = ( - self.runner.ignore_error_messages - if option == "ignore_error_messages" - else self.runner.always_fail_error_messages - ) - string_set.clear() - string_set = statement.error_messages + if option == 'ignore_error_messages': + string_set = ( + self.runner.ignore_error_messages + if option == "ignore_error_messages" + else self.runner.always_fail_error_messages + ) + string_set.clear() + string_set = statement.error_messages + elif option == 'seed': + con = self.get_connection() + con.execute(f"SELECT SETSEED({statement.header.parameters[1]})") + self.runner.skip_reload = True + else: + self.skiptest(f"SET '{option}' is not implemented!") def execute_hash_threshold(self, statement: HashThreshold): self.runner.hash_threshold = statement.threshold diff --git a/scripts/sqllogictest/statement/load.py b/scripts/sqllogictest/statement/load.py index 642b9f6f715f..98ac08439836 100644 --- a/scripts/sqllogictest/statement/load.py +++ b/scripts/sqllogictest/statement/load.py @@ -6,6 +6,10 @@ class Load(BaseStatement): def __init__(self, header: Token, line: int): super().__init__(header, line) self.readonly: bool = False + self.version: Optional[int] = None def set_readonly(self): self.readonly = True + + def set_version(self, version: str): + self.version = version diff --git a/tools/pythonpkg/sqllogic/conftest.py b/tools/pythonpkg/sqllogic/conftest.py index c5cc59fe57b7..fbe55f270338 100644 --- a/tools/pythonpkg/sqllogic/conftest.py +++ b/tools/pythonpkg/sqllogic/conftest.py @@ -5,6 +5,7 @@ import re import typing import warnings +import glob from .skipped_tests import SKIPPED_TESTS SQLLOGIC_TEST_CASE_NAME = "test_sqllogic" @@ -22,6 +23,13 @@ def pytest_addoption(parser: pytest.Parser): dest="test_dirs", help="Path to one or more directories containing SQLLogic test scripts", ) + parser.addoption( + "--path", + type=str, + default=None, + dest="path", + help="Path (or glob) of the tests to run", + ) parser.addoption( "--build-dir", type=str, @@ -96,6 +104,15 @@ def get_test_marks(path: pathlib.Path, root_dir: pathlib.Path, config: pytest.Co return marks +def create_parameters_from_paths(paths, root_dir: pathlib.Path, config: pytest.Config) -> typing.Iterator[typing.Any]: + return map( + lambda path: pytest.param( + path.absolute(), id=get_test_id(path, root_dir, config), marks=get_test_marks(path, root_dir, config) + ), + paths, + ) + + def scan_for_test_scripts(root_dir: pathlib.Path, config: pytest.Config) -> typing.Iterator[typing.Any]: """ Scans for .test files in the given directory and its subdirectories. @@ -105,30 +122,35 @@ def scan_for_test_scripts(root_dir: pathlib.Path, config: pytest.Config) -> typi # TODO: Add tests from extensions test_script_extensions = [".test", ".test_slow", ".test_coverage"] it = itertools.chain.from_iterable(root_dir.rglob(f"*{ext}") for ext in test_script_extensions) - return map( - lambda path: pytest.param( - path.absolute(), id=get_test_id(path, root_dir, config), marks=get_test_marks(path, root_dir, config) - ), - it, - ) + return create_parameters_from_paths(it, root_dir, config) def pytest_generate_tests(metafunc: pytest.Metafunc): # test_sqllogic (a.k.a SQLLOGIC_TEST_CASE_NAME) is defined in test_sqllogic.py - if metafunc.definition.name == SQLLOGIC_TEST_CASE_NAME: - test_dirs: typing.List[pathlib.Path] = metafunc.config.getoption("test_dirs") - if len(test_dirs) == 0: - # Use DuckDB's test directory as the default when --test-dir not specified - test_dirs = [DUCKDB_ROOT_DIR / "test"] + if metafunc.definition.name != SQLLOGIC_TEST_CASE_NAME: + return - parameters = [] - for test_dir in test_dirs: - # Create absolute & normalized path - test_dir = test_dir.resolve() - assert test_dir.is_dir() - parameters.extend(scan_for_test_scripts(test_dir, metafunc.config)) + test_dirs: typing.List[pathlib.Path] = metafunc.config.getoption("test_dirs") + test_glob: typing.Optional[pathlib.Path] = metafunc.config.getoption("path") + + parameters = [] + + if test_glob: + test_paths = DUCKDB_ROOT_DIR.rglob(test_glob) + parameters.extend(create_parameters_from_paths(test_paths, DUCKDB_ROOT_DIR, metafunc.config)) + + for test_dir in test_dirs: + # Create absolute & normalized path + test_dir = test_dir.resolve() + assert test_dir.is_dir() + parameters.extend(scan_for_test_scripts(test_dir, metafunc.config)) + + if parameters == []: + if len(test_dirs) == 0: + # Use DuckDB's test directory as the default when no paths are provided + parameters.extend(scan_for_test_scripts(DUCKDB_ROOT_DIR / "test", metafunc.config)) - metafunc.parametrize(SQLLOGIC_TEST_PARAMETER, parameters) + metafunc.parametrize(SQLLOGIC_TEST_PARAMETER, parameters) # Execute last, after pytest has already deselected tests based on -k and -m parameters