diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index f610aa66b..831bf5ffa 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -170,15 +170,14 @@ jobs: - name: Install dependencies run: uv sync --extra snowflake --extra dev - - name: Install fakesnow - run: uv pip install "fakesnow==0.11.11" - - name: Run Snowflake integration tests env: SNOWFLAKE_TEST: "1" run: | - uv run pytest --test-engine python -m integration tests/db/test_snowflake_integration.py -v - uv run pytest --test-engine rust -m integration tests/db/test_snowflake_integration.py -v + # Resolve fakesnow with its compatible SQLGlot version on every run; + # a preceding uv pip install is undone by the locked project sync. + uv run --with "fakesnow==0.11.11" pytest --test-engine python -m integration tests/db/test_snowflake_integration.py -v + uv run --with "fakesnow==0.11.11" pytest --test-engine rust -m integration tests/db/test_snowflake_integration.py -v - name: Save completed build caches if: ${{ !cancelled() }} diff --git a/docs/rust-parity-exceptions.json b/docs/rust-parity-exceptions.json new file mode 100644 index 000000000..7cba1fd4b --- /dev/null +++ b/docs/rust-parity-exceptions.json @@ -0,0 +1,16011 @@ +{ + "schema_version": 3, + "summary": { + "source_records": 740, + "by_kind": { + "engine-control": 244, + "engine-matrix": 94, + "implementation-import": 83, + "importorskip": 202, + "integration-marker": 13, + "legacy-adapter-import": 6, + "public-layer-import": 20, + "skip": 65, + "skipif": 13 + }, + "exception_records": 366, + "observation_records": 374, + "exceptions_by_category": { + "external-service": 42, + "intentional-Python-only": 35, + "optional-host": 235, + "real-gap": 54 + }, + "exceptions_by_direction": { + "both-engines": 279, + "python-only-exclusion": 14, + "rust-coverage-exclusion": 73 + }, + "declared_test_functions": 6511, + "collected_nodeids": 11876, + "direct_helper_tests": { + "native_counterpart_or_route": 84, + "intentional_python_implementation": 126, + "unresolved_native_coverage": 129 + } + }, + "limitations": [ + "Static source inventory, not execution results or proof of product defects.", + "Declared scope expansion follows local fixture/helper references conservatively; dynamic imports, cross-module fixtures, and generated parity cases require collection/runtime evidence.", + "Engine-aware imports and explicit Rust/differential routing are observations with is_exception=false and category=null.", + "real-gap includes Python-only omissions and unproven Rust coverage, not only confirmed Rust failures.", + "Module dependency gates and integration deselection can overlap behavioral omissions; records are not additive test counts.", + "Only actual exclusions appear in exceptions. affected_scope=self means the source test; module means its module; subtree means the conftest directory (conservative); other values reference affected_scopes. rationale references explanations. Routing observations contribute counts only. Empty conditions are omitted. Helper assessments retain native counterpart evidence." + ], + "selection_rules": [ + { + "path": "pyproject.toml", + "source": "-m 'not integration' --cov=sidemantic --cov-report=term-missing", + "category": "external-service" + }, + { + "path": ".github/workflows/ci.yml", + "line": 19, + "source": "SIDEMANTIC_ENGINE: ${{ matrix.engine }}" + }, + { + "path": ".github/workflows/ci.yml", + "line": 24, + "source": "engine: [python]" + }, + { + "path": ".github/workflows/ci.yml", + "line": 27, + "source": "engine: rust" + }, + { + "path": ".github/workflows/ci.yml", + "line": 101, + "source": "run: uv run --with adbc-driver-sqlite pytest -v --test-engine python --cov-fail-under=76 --junitxml=test-results.xml" + }, + { + "path": ".github/workflows/ci.yml", + "line": 105, + "source": "run: uv run --with adbc-driver-sqlite pytest -v --test-engine rust --no-cov --junitxml=test-results.xml" + }, + { + "path": ".github/workflows/ci.yml", + "line": 185, + "source": "uv run --no-sync pytest" + }, + { + "path": ".github/workflows/ci.yml", + "line": 193, + "source": "-o addopts=\"-m 'not integration'\"" + }, + { + "path": ".github/workflows/ci.yml", + "line": 366, + "source": "run: uv run pytest tests/native_compat -v" + }, + { + "path": ".github/workflows/ci.yml", + "line": 712, + "source": "import pytest" + }, + { + "path": ".github/workflows/ci.yml", + "line": 718, + "source": "raise SystemExit(pytest.main([\"--no-cov\", \"-q\", \"tests/semantic_conformance\"]))" + }, + { + "path": ".github/workflows/integration.yml", + "line": 68, + "source": "uv run pytest --test-engine python -m integration tests/db/test_postgres_integration.py -v" + }, + { + "path": ".github/workflows/integration.yml", + "line": 69, + "source": "uv run pytest --test-engine rust -m integration tests/db/test_postgres_integration.py -v" + }, + { + "path": ".github/workflows/integration.yml", + "line": 80, + "source": "uv run pytest --test-engine python -m integration tests/db/test_postgres_cli_e2e.py -v" + }, + { + "path": ".github/workflows/integration.yml", + "line": 81, + "source": "uv run pytest --test-engine rust -m integration tests/db/test_postgres_cli_e2e.py -v" + }, + { + "path": ".github/workflows/integration.yml", + "line": 135, + "source": "uv run pytest --test-engine python -m integration tests/db/test_bigquery_integration.py -v" + }, + { + "path": ".github/workflows/integration.yml", + "line": 136, + "source": "uv run pytest --test-engine rust -m integration tests/db/test_bigquery_integration.py -v" + }, + { + "path": ".github/workflows/integration.yml", + "line": 179, + "source": "uv run --with \"fakesnow==0.11.11\" pytest --test-engine python -m integration tests/db/test_snowflake_integration.py -v" + }, + { + "path": ".github/workflows/integration.yml", + "line": 180, + "source": "uv run --with \"fakesnow==0.11.11\" pytest --test-engine rust -m integration tests/db/test_snowflake_integration.py -v" + }, + { + "path": ".github/workflows/integration.yml", + "line": 240, + "source": "uv run pytest --test-engine python -m integration tests/db/test_clickhouse_integration.py -v" + }, + { + "path": ".github/workflows/integration.yml", + "line": 241, + "source": "uv run pytest --test-engine rust -m integration tests/db/test_clickhouse_integration.py -v" + }, + { + "path": ".github/workflows/integration.yml", + "line": 351, + "source": "uv run pytest --test-engine python -m integration tests/db/test_adbc_ci_smoke.py -v" + }, + { + "path": ".github/workflows/integration.yml", + "line": 352, + "source": "uv run pytest --test-engine rust -m integration tests/db/test_adbc_ci_smoke.py -v" + }, + { + "path": ".github/workflows/publish.yml", + "line": 180, + "source": "uv run pytest -v --cov-fail-under=76" + }, + { + "path": ".github/workflows/wasm-package-release.yml", + "line": 86, + "source": "bun pm pack --ignore-scripts --filename sidemantic-wasm.tgz" + }, + { + "path": ".github/workflows/wasm-package-release.yml", + "line": 113, + "source": "npm publish sidemantic-wasm.tgz --access public --ignore-scripts" + }, + { + "path": ".github/workflows/yardstick-upstream.yml", + "line": 65, + "source": "run: uv run pytest -q tests/queries/test_yardstick_measures_replay.py -m yardstick_upstream" + } + ], + "exceptions": [ + { + "path": "tests/adapters/bsl/test_parsing.py", + "line": 1021, + "scope": "TestBSLCurrentSyntaxSupport::test_deferred_calculated_measure_compiles", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-1" + }, + { + "path": "tests/adapters/bsl/test_parsing.py", + "line": 1058, + "scope": "TestBSLCurrentSyntaxSupport::test_all_calculated_measure_compiles_to_window_total", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-2" + }, + { + "path": "tests/adapters/bsl/test_parsing.py", + "line": 1094, + "scope": "TestBSLCurrentSyntaxSupport::test_qualified_calculated_measure_compiles_joined_measure", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-3" + }, + { + "path": "tests/adapters/bsl/test_parsing.py", + "line": 1228, + "scope": "TestBSLCurrentSyntaxSupport::test_join_aliases_self_join_and_how_roundtrip", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-4" + }, + { + "path": "tests/adapters/bsl/test_parsing.py", + "line": 1306, + "scope": "TestBSLCurrentSyntaxSupport::test_reused_join_aliases_scope_to_source_model", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-5" + }, + { + "path": "tests/adapters/bsl/test_parsing.py", + "line": 1440, + "scope": "TestBSLCurrentSyntaxSupport::test_cross_join_compiles", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-6" + }, + { + "path": "tests/adapters/cube/test_fixtures.py", + "line": 868, + "scope": "TestTesseractFeatures::test_aggregate_complete_measures_queryable", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-7" + }, + { + "path": "tests/adapters/cube/test_fixtures.py", + "line": 900, + "scope": "TestTesseractFeatures::test_plain_non_numeric_measures_queryable", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-8" + }, + { + "path": "tests/adapters/cube/test_fixtures.py", + "line": 930, + "scope": "TestTesseractFeatures::test_complete_measure_preserves_raw_timestamp", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-9" + }, + { + "path": "tests/adapters/cube/test_fixtures.py", + "line": 963, + "scope": "TestTesseractFeatures::test_complete_measure_applies_filters", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-10" + }, + { + "path": "tests/adapters/cube/test_fixtures.py", + "line": 1000, + "scope": "TestTesseractFeatures::test_plain_complete_measure_grouped_by_other_dimension", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-11" + }, + { + "path": "tests/adapters/metricflow/test_parsing.py", + "line": 10, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-12" + }, + { + "path": "tests/adapters/osi/conftest.py", + "line": 55, + "scope": "_backend_is_rust", + "kind": "engine-control", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "os.environ.get(\"SIDEMANTIC_OSI_BACKEND\", \"python\")", + "rationale": "reason-3", + "affected_scope": "scope-13" + }, + { + "path": "tests/adapters/osi/conftest.py", + "line": 63, + "scope": "_osi_backend", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-13" + }, + { + "path": "tests/adapters/osi/test_parsing.py", + "line": 10, + "scope": "", + "kind": "legacy-adapter-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.adapters.osi import LegacyOSIAdapter as OSIAdapter", + "rationale": "reason-5", + "affected_scope": "scope-14" + }, + { + "path": "tests/adapters/osi/test_query_execution.py", + "line": 9, + "scope": "", + "kind": "legacy-adapter-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.adapters.osi import LegacyOSIAdapter as OSIAdapter", + "rationale": "reason-5", + "affected_scope": "scope-15" + }, + { + "path": "tests/adapters/osi/test_rust_parity.py", + "line": 15, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-16" + }, + { + "path": "tests/adapters/sidemantic_adapter/test_parsing.py", + "line": 1325, + "scope": "test_dimension_window_in_sql_generation", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-17" + }, + { + "path": "tests/adapters/tableau/test_real_world.py", + "line": 8, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-18" + }, + { + "path": "tests/adapters/tableau/test_real_world.py", + "line": 20, + "scope": "_skip_if_missing", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "not REAL_WORLD.exists()" + ], + "source": "pytest.skip(\"real_world fixtures not present\")", + "rationale": "reason-6", + "affected_scope": "scope-19" + }, + { + "path": "tests/adapters/tableau/test_relation_types.py", + "line": 200, + "scope": "test_legacy_object_graph_has_no_semantic_metadata", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "not real_world.exists()" + ], + "source": "pytest.skip(\"real_world fixtures not present\")", + "rationale": "reason-6", + "affected_scope": "scope-20" + }, + { + "path": "tests/adapters/test_added_fixture_coverage.py", + "line": 23, + "scope": "", + "kind": "legacy-adapter-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.adapters.osi import LegacyOSIAdapter as OSIAdapter", + "rationale": "reason-5", + "affected_scope": "scope-21" + }, + { + "path": "tests/adapters/test_added_fixture_coverage.py", + "line": 29, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-22" + }, + { + "path": "tests/adapters/test_fixture_functionality_contracts.py", + "line": 21, + "scope": "", + "kind": "legacy-adapter-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.adapters.osi import LegacyOSIAdapter as OSIAdapter", + "rationale": "reason-5", + "affected_scope": "scope-23" + }, + { + "path": "tests/adapters/test_fixture_functionality_contracts.py", + "line": 27, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-24" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 25, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-25" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 487, + "scope": "test_tmdl_parses_dax_ast_when_available", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.skip(\"sidemantic_dax not installed\")", + "rationale": "reason-6", + "affected_scope": "scope-26" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 493, + "scope": "test_tmdl_parses_dax_ast_when_available", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'native module is not available' in str(exc)" + ], + "source": "pytest.skip(\"sidemantic_dax native module not available\")", + "rationale": "reason-6", + "affected_scope": "scope-26" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 920, + "scope": "test_tmdl_inactive_relationship_is_preserved_and_excluded_from_graph_paths", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-27" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 947, + "scope": "test_tmdl_invalid_relationship_edges_are_skipped", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-28" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 1145, + "scope": "test_tmdl_warning_fixture_collects_relationship_warnings", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-29" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 2110, + "scope": "test_tmdl_export_preserves_native_dax_authored_sources", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-30" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 2894, + "scope": "test_tmdl_dax_reduction_semantics", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-31" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 2947, + "scope": "test_tmdl_real_fixture_reductions_reference_real_columns", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-32" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 2960, + "scope": "test_tmdl_deeply_nested_dax_does_not_crash_import", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-33" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 2996, + "scope": "test_tmdl_keyless_many_to_many_joins_without_keying_off_endpoints", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-34" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 3058, + "scope": "test_tmdl_keyless_many_to_many_metric_raises_clear_error", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-35" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 3108, + "scope": "test_tmdl_many_to_many_on_non_primary_key_column", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-36" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 3173, + "scope": "test_tmdl_one_to_one_recovers_keyless_source_key", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-37" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 3229, + "scope": "test_tmdl_one_to_one_alternate_key_does_not_shadow_real_key", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-38" + }, + { + "path": "tests/adapters/tmdl/test_parsing.py", + "line": 3297, + "scope": "test_tmdl_ambiguous_one_side_target_not_recovered_from_endpoint", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-39" + }, + { + "path": "tests/core/test_cross_surface_equivalence.py", + "line": 34, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"fastapi\")", + "rationale": "reason-4", + "affected_scope": "scope-40" + }, + { + "path": "tests/core/test_cross_surface_equivalence.py", + "line": 35, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"httpx\")", + "rationale": "reason-4", + "affected_scope": "scope-40" + }, + { + "path": "tests/core/test_cross_surface_equivalence.py", + "line": 336, + "scope": "test_pg_server_executes_previewed_sql", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"riffq\", reason=\"PG wire server requires the optional 'riffq' dependency\")", + "rationale": "reason-4", + "affected_scope": "scope-41" + }, + { + "path": "tests/core/test_cross_surface_equivalence.py", + "line": 337, + "scope": "test_pg_server_executes_previewed_sql", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-41" + }, + { + "path": "tests/core/test_invariant_filters.py", + "line": 221, + "scope": "test_legacy_python_sql_generator_falls_back_for_invariants", + "kind": "engine-control", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "_layer(engine=\"python\")", + "rationale": "reason-8", + "affected_scope": "scope-42" + }, + { + "path": "tests/core/test_relationship_role_aliases.py", + "line": 13, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-43" + }, + { + "path": "tests/core/test_relationship_role_aliases.py", + "line": 329, + "scope": "test_optional_rust_modes_fall_back_when_backend_rejects_roles", + "kind": "engine-control", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "SemanticLayer(engine=\"python\")", + "rationale": "reason-8", + "affected_scope": "scope-44" + }, + { + "path": "tests/core/test_relationship_role_aliases.py", + "line": 352, + "scope": "test_strict_rust_modes_propagate_backend_role_rejection", + "kind": "engine-control", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "SemanticLayer(engine=\"python\")", + "rationale": "reason-8", + "affected_scope": "scope-45" + }, + { + "path": "tests/core/test_result_cache.py", + "line": 12, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-46" + }, + { + "path": "tests/core/test_runtime_defaults.py", + "line": 75, + "scope": "test_missing_explicit_rust_runtime_does_not_silently_fall_back", + "kind": "engine-control", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "SemanticLayer(engine=\"python\")", + "rationale": "reason-8", + "affected_scope": "scope-47" + }, + { + "path": "tests/core/test_rust_engine_mode.py", + "line": 45, + "scope": "test_semantic_layer_python_engine_ignores_rust_env_flags", + "kind": "engine-control", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "SemanticLayer(engine=\"python\")", + "rationale": "reason-8", + "affected_scope": "scope-48" + }, + { + "path": "tests/core/test_security_advisor_regressions.py", + "line": 260, + "scope": "test_pg_server_refuses_user_attrs_map_without_auth", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "_pytest.importorskip(\"riffq\")", + "rationale": "reason-4", + "affected_scope": "scope-49" + }, + { + "path": "tests/core/test_security_advisor_regressions.py", + "line": 316, + "scope": "test_rewriter_threads_user_attributes", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.query_rewriter import QueryRewriter", + "rationale": "reason-2", + "affected_scope": "scope-50" + }, + { + "path": "tests/dates/test_query_timezone.py", + "line": 8, + "scope": "", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-51" + }, + { + "path": "tests/dates/test_time_comparison.py", + "line": 10, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-52" + }, + { + "path": "tests/dax/test_ast.py", + "line": 7, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax.ast\")", + "rationale": "reason-4", + "affected_scope": "scope-53" + }, + { + "path": "tests/dax/test_ast.py", + "line": 258, + "scope": "test_datetime_literal_native_round_trip", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'native module is not available' in str(exc)" + ], + "source": "pytest.skip(\"sidemantic_dax native module not available\")", + "rationale": "reason-6", + "affected_scope": "scope-54" + }, + { + "path": "tests/dax/test_ast.py", + "line": 280, + "scope": "test_function_parameter_default_native_round_trip", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'native module is not available' in str(exc)" + ], + "source": "pytest.skip(\"sidemantic_dax native module not available\")", + "rationale": "reason-6", + "affected_scope": "scope-55" + }, + { + "path": "tests/dax/test_ast.py", + "line": 309, + "scope": "test_visual_shape_native_round_trip", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'native module is not available' in str(exc)" + ], + "source": "pytest.skip(\"sidemantic_dax native module not available\")", + "rationale": "reason-6", + "affected_scope": "scope-56" + }, + { + "path": "tests/dax/test_ast.py", + "line": 328, + "scope": "test_omitted_function_arguments_native_round_trip", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'native module is not available' in str(exc)" + ], + "source": "pytest.skip(\"sidemantic_dax native module not available\")", + "rationale": "reason-6", + "affected_scope": "scope-57" + }, + { + "path": "tests/dax/test_ast.py", + "line": 349, + "scope": "test_start_at_native_accepts_constants_and_parameters_only", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'native module is not available' in str(exc)" + ], + "source": "pytest.skip(\"sidemantic_dax native module not available\")", + "rationale": "reason-6", + "affected_scope": "scope-58" + }, + { + "path": "tests/dax/test_ast.py", + "line": 369, + "scope": "test_multi_column_in_native_round_trip", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'native module is not available' in str(exc)" + ], + "source": "pytest.skip(\"sidemantic_dax native module not available\")", + "rationale": "reason-6", + "affected_scope": "scope-59" + }, + { + "path": "tests/dax/test_ast.py", + "line": 385, + "scope": "test_datatable_native_round_trip_and_validation", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'native module is not available' in str(exc)" + ], + "source": "pytest.skip(\"sidemantic_dax native module not available\")", + "rationale": "reason-6", + "affected_scope": "scope-60" + }, + { + "path": "tests/dax/test_ast.py", + "line": 405, + "scope": "test_static_validation_native_api", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'native module is not available' in str(exc)" + ], + "source": "pytest.skip(\"sidemantic_dax native module not available\")", + "rationale": "reason-6", + "affected_scope": "scope-61" + }, + { + "path": "tests/dax/test_ast.py", + "line": 433, + "scope": "test_python_dialect_configuration", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'native module is not available' in str(exc)" + ], + "source": "pytest.skip(\"sidemantic_dax native module not available\")", + "rationale": "reason-6", + "affected_scope": "scope-62" + }, + { + "path": "tests/dax/test_ast.py", + "line": 462, + "scope": "test_datetime_literal_native_lexical_validation", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'native module is not available' in str(exc)" + ], + "source": "pytest.skip(\"sidemantic_dax native module not available\")", + "rationale": "reason-6", + "affected_scope": "scope-63" + }, + { + "path": "tests/dax/test_engine_conformance.py", + "line": 28, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax.ast\")", + "rationale": "reason-4", + "affected_scope": "scope-64" + }, + { + "path": "tests/dax/test_engine_conformance.py", + "line": 29, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-64" + }, + { + "path": "tests/dax/test_engine_conformance.py", + "line": 30, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow.ipc\")", + "rationale": "reason-4", + "affected_scope": "scope-64" + }, + { + "path": "tests/dax/test_engine_conformance.py", + "line": 231, + "scope": "_engine_configuration", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "conditions": [ + "os.environ.get('SIDEMANTIC_DAX_ENGINE_CONFORMANCE') != '1'" + ], + "source": "pytest.skip(\"set SIDEMANTIC_DAX_ENGINE_CONFORMANCE=1 to probe Power BI\")", + "rationale": "reason-15", + "affected_scope": "scope-65" + }, + { + "path": "tests/dax/test_engine_conformance.py", + "line": 265, + "scope": "test_local_and_microsoft_engine_conformance", + "kind": "integration-marker", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.integration", + "rationale": "reason-16", + "affected_scope": "scope-65" + }, + { + "path": "tests/dax/test_external_powerbi_fixtures.py", + "line": 8, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-66" + }, + { + "path": "tests/dax/test_external_powerbi_fixtures.py", + "line": 19, + "scope": "_parse_expression", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'native module is not available' in str(exc)" + ], + "source": "pytest.skip(\"sidemantic_dax native module not available\")", + "rationale": "reason-6", + "affected_scope": "scope-66" + }, + { + "path": "tests/dax/test_online_conformance.py", + "line": 9, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax.ast\")", + "rationale": "reason-4", + "affected_scope": "scope-67" + }, + { + "path": "tests/dax/test_online_conformance.py", + "line": 12, + "scope": "", + "kind": "skipif", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skipif(\n os.environ.get(\"SIDEMANTIC_DAX_ONLINE_CONFORMANCE\") != \"1\",\n reason=\"set SIDEMANTIC_DAX_ONLINE_CONFORMANCE=1 to probe DAX Formatter\",\n)", + "rationale": "reason-15", + "affected_scope": "scope-67" + }, + { + "path": "tests/dax/test_query_corpus.py", + "line": 8, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_dax\")", + "rationale": "reason-4", + "affected_scope": "scope-68" + }, + { + "path": "tests/dax/test_query_corpus.py", + "line": 19, + "scope": "_parse_query", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'native module is not available' in str(exc)" + ], + "source": "pytest.skip(\"sidemantic_dax native module not available\")", + "rationale": "reason-6", + "affected_scope": "scope-68" + }, + { + "path": "tests/db/test_adbc_adapter.py", + "line": 66, + "scope": "sqlite_adapter", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "not SQLITE_TESTS_AVAILABLE" + ], + "source": "pytest.skip(SQLITE_TESTS_SKIP_REASON)", + "rationale": "reason-6", + "affected_scope": "scope-69" + }, + { + "path": "tests/db/test_adbc_adapter.py", + "line": 81, + "scope": "test_adbc_adapter_init", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "not SQLITE_TESTS_AVAILABLE" + ], + "source": "pytest.skip(SQLITE_TESTS_SKIP_REASON)", + "rationale": "reason-6", + "affected_scope": "scope-70" + }, + { + "path": "tests/db/test_adbc_adapter.py", + "line": 169, + "scope": "test_adbc_adapter_fetch_record_batch", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-71" + }, + { + "path": "tests/db/test_adbc_adapter.py", + "line": 213, + "scope": "test_adbc_adapter_from_url", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "not SQLITE_TESTS_AVAILABLE" + ], + "source": "pytest.skip(SQLITE_TESTS_SKIP_REASON)", + "rationale": "reason-6", + "affected_scope": "scope-72" + }, + { + "path": "tests/db/test_adbc_adapter.py", + "line": 228, + "scope": "test_adbc_url_resolves_packaged_driver_without_system_install", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"adbc_driver_manager.dbapi\")", + "rationale": "reason-4", + "affected_scope": "scope-73" + }, + { + "path": "tests/db/test_adbc_adapter.py", + "line": 230, + "scope": "test_adbc_url_resolves_packaged_driver_without_system_install", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"adbc_driver_sqlite\")", + "rationale": "reason-4", + "affected_scope": "scope-73" + }, + { + "path": "tests/db/test_adbc_adapter.py", + "line": 288, + "scope": "test_adbc_with_sqlite_driver", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "not SQLITE_TESTS_AVAILABLE" + ], + "source": "pytest.skip(SQLITE_TESTS_SKIP_REASON)", + "rationale": "reason-6", + "affected_scope": "scope-74" + }, + { + "path": "tests/db/test_adbc_adapter.py", + "line": 314, + "scope": "test_adbc_url_scheme_with_driver", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "not SQLITE_TESTS_AVAILABLE" + ], + "source": "pytest.skip(SQLITE_TESTS_SKIP_REASON)", + "rationale": "reason-6", + "affected_scope": "scope-75" + }, + { + "path": "tests/db/test_adbc_adapter.py", + "line": 332, + "scope": "test_semantic_layer_with_adbc_connection", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "not SQLITE_TESTS_AVAILABLE" + ], + "source": "pytest.skip(SQLITE_TESTS_SKIP_REASON)", + "rationale": "reason-6", + "affected_scope": "scope-76" + }, + { + "path": "tests/db/test_adbc_adapter.py", + "line": 426, + "scope": "test_adbc_url_path_based_uri", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "not SQLITE_TESTS_AVAILABLE" + ], + "source": "pytest.skip(SQLITE_TESTS_SKIP_REASON)", + "rationale": "reason-6", + "affected_scope": "scope-77" + }, + { + "path": "tests/db/test_adbc_ci_smoke.py", + "line": 18, + "scope": "", + "kind": "integration-marker", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.integration", + "rationale": "reason-16", + "affected_scope": "scope-78" + }, + { + "path": "tests/db/test_adbc_ci_smoke.py", + "line": 19, + "scope": "", + "kind": "skipif", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skipif(os.getenv(\"ADBC_TEST\") != \"1\", reason=\"Set ADBC_TEST=1 to run ADBC CI smoke tests\")", + "rationale": "reason-15", + "affected_scope": "scope-78" + }, + { + "path": "tests/db/test_adbc_ci_smoke.py", + "line": 26, + "scope": "_adbc_db", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "conditions": [ + "not db" + ], + "source": "pytest.skip(\"ADBC_DB is not set\")", + "rationale": "reason-15", + "affected_scope": "scope-78" + }, + { + "path": "tests/db/test_adbc_ci_smoke.py", + "line": 38, + "scope": "_expected_dialect", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "conditions": [ + "not expected" + ], + "source": "pytest.skip(f\"Unsupported ADBC_DB={db!r}\")", + "rationale": "reason-15", + "affected_scope": "scope-79" + }, + { + "path": "tests/db/test_adbc_ci_smoke.py", + "line": 46, + "scope": "_target_uri", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "conditions": [ + "db == 'postgres'", + "not uri" + ], + "source": "pytest.skip(\"POSTGRES_URL is not set\")", + "rationale": "reason-15", + "affected_scope": "scope-78" + }, + { + "path": "tests/db/test_adbc_ci_smoke.py", + "line": 65, + "scope": "_target_uri", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.skip(f\"Unsupported ADBC_DB={db!r}\")", + "rationale": "reason-15", + "affected_scope": "scope-78" + }, + { + "path": "tests/db/test_adbc_ci_smoke.py", + "line": 129, + "scope": "adbc_layer", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.skip(f\"No working ADBC driver for {db!r}. {details}\")", + "rationale": "reason-6", + "affected_scope": "scope-78" + }, + { + "path": "tests/db/test_bigquery_adapter.py", + "line": 274, + "scope": "test_bigquery_fetch_record_batch", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-80" + }, + { + "path": "tests/db/test_bigquery_adapter.py", + "line": 547, + "scope": "test_bigquery_fetch_record_batch_via_adapter", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-81" + }, + { + "path": "tests/db/test_bigquery_cli_e2e.py", + "line": 12, + "scope": "", + "kind": "integration-marker", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.integration", + "rationale": "reason-16", + "affected_scope": "scope-82" + }, + { + "path": "tests/db/test_bigquery_cli_e2e.py", + "line": 13, + "scope": "", + "kind": "skipif", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skipif(\n os.getenv(\"BIGQUERY_TEST\") != \"1\",\n reason=\"Set BIGQUERY_TEST=1 and run docker compose up -d bigquery to run BigQuery integration tests\",\n )", + "rationale": "reason-15", + "affected_scope": "scope-82" + }, + { + "path": "tests/db/test_bigquery_integration.py", + "line": 14, + "scope": "", + "kind": "integration-marker", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.integration", + "rationale": "reason-16", + "affected_scope": "scope-83" + }, + { + "path": "tests/db/test_bigquery_integration.py", + "line": 15, + "scope": "", + "kind": "skipif", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skipif(\n os.getenv(\"BIGQUERY_TEST\") != \"1\",\n reason=\"Set BIGQUERY_TEST=1 and run docker compose up -d bigquery to run BigQuery integration tests\",\n )", + "rationale": "reason-15", + "affected_scope": "scope-83" + }, + { + "path": "tests/db/test_bigquery_integration.py", + "line": 260, + "scope": "test_semantic_layer_date_functions", + "kind": "skip", + "category": "real-gap", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skip(reason=\"FORMAT_DATE appears to hang with BigQuery emulator\")", + "rationale": "reason-17", + "affected_scope": "scope-84" + }, + { + "path": "tests/db/test_clickhouse_adapter.py", + "line": 248, + "scope": "test_clickhouse_execute_native_arrow", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-85" + }, + { + "path": "tests/db/test_clickhouse_adapter.py", + "line": 315, + "scope": "test_clickhouse_result_native_arrow_fetch_record_batch", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-86" + }, + { + "path": "tests/db/test_clickhouse_adapter.py", + "line": 330, + "scope": "test_clickhouse_result_native_arrow_fetchone", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-87" + }, + { + "path": "tests/db/test_clickhouse_adapter.py", + "line": 342, + "scope": "test_clickhouse_result_native_arrow_fetchall", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-88" + }, + { + "path": "tests/db/test_clickhouse_adapter.py", + "line": 356, + "scope": "test_clickhouse_result_native_arrow_empty", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-89" + }, + { + "path": "tests/db/test_clickhouse_adapter.py", + "line": 371, + "scope": "test_clickhouse_executemany_native_arrow", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-90" + }, + { + "path": "tests/db/test_clickhouse_cli_e2e.py", + "line": 12, + "scope": "", + "kind": "integration-marker", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.integration", + "rationale": "reason-16", + "affected_scope": "scope-91" + }, + { + "path": "tests/db/test_clickhouse_cli_e2e.py", + "line": 13, + "scope": "", + "kind": "skipif", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skipif(\n os.getenv(\"CLICKHOUSE_TEST\") != \"1\",\n reason=\"Set CLICKHOUSE_TEST=1 and run docker compose up -d clickhouse to run ClickHouse integration tests\",\n )", + "rationale": "reason-15", + "affected_scope": "scope-91" + }, + { + "path": "tests/db/test_clickhouse_integration.py", + "line": 14, + "scope": "", + "kind": "integration-marker", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.integration", + "rationale": "reason-16", + "affected_scope": "scope-92" + }, + { + "path": "tests/db/test_clickhouse_integration.py", + "line": 15, + "scope": "", + "kind": "skipif", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skipif(\n os.getenv(\"CLICKHOUSE_TEST\") != \"1\",\n reason=\"Set CLICKHOUSE_TEST=1 and run docker compose up -d clickhouse to run ClickHouse integration tests\",\n )", + "rationale": "reason-15", + "affected_scope": "scope-92" + }, + { + "path": "tests/db/test_clickhouse_integration.py", + "line": 257, + "scope": "test_semantic_layer_date_functions", + "kind": "skip", + "category": "real-gap", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skip(reason=\"Date functions test - consistent with BigQuery/Postgres/Snowflake\")", + "rationale": "reason-17", + "affected_scope": "scope-93" + }, + { + "path": "tests/db/test_databricks_adapter.py", + "line": 197, + "scope": "test_databricks_fetch_record_batch_mixed_types", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-94" + }, + { + "path": "tests/db/test_databricks_adapter.py", + "line": 275, + "scope": "test_databricks_fetch_record_batch_native_arrow", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-95" + }, + { + "path": "tests/db/test_databricks_adapter.py", + "line": 295, + "scope": "test_databricks_fetch_record_batch_native_arrow_empty", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-96" + }, + { + "path": "tests/db/test_databricks_adapter.py", + "line": 313, + "scope": "test_databricks_fetch_record_batch_fallback", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-97" + }, + { + "path": "tests/db/test_databricks_integration.py", + "line": 17, + "scope": "", + "kind": "integration-marker", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.integration", + "rationale": "reason-16", + "affected_scope": "scope-98" + }, + { + "path": "tests/db/test_databricks_integration.py", + "line": 18, + "scope": "", + "kind": "skipif", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skipif(\n os.getenv(\"DATABRICKS_TEST\") != \"1\",\n reason=\"Set DATABRICKS_TEST=1 and DATABRICKS_URL to run Databricks integration tests (requires real Databricks workspace)\",\n )", + "rationale": "reason-15", + "affected_scope": "scope-98" + }, + { + "path": "tests/db/test_databricks_integration.py", + "line": 27, + "scope": "", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "conditions": [ + "not DATABRICKS_URL and os.getenv('DATABRICKS_TEST') == '1'" + ], + "source": "pytest.skip(\"DATABRICKS_URL must be set to run Databricks tests\", allow_module_level=True)", + "rationale": "reason-15", + "affected_scope": "scope-98" + }, + { + "path": "tests/db/test_duckdb_adapter.py", + "line": 104, + "scope": "test_duckdb_adapter_fetch_record_batch", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-99" + }, + { + "path": "tests/db/test_postgres_adapter.py", + "line": 336, + "scope": "test_postgres_fetch_record_batch", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-100" + }, + { + "path": "tests/db/test_postgres_adapter.py", + "line": 350, + "scope": "test_postgres_result_fetch_record_batch_empty", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-101" + }, + { + "path": "tests/db/test_postgres_cli_e2e.py", + "line": 12, + "scope": "", + "kind": "integration-marker", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.integration", + "rationale": "reason-16", + "affected_scope": "scope-102" + }, + { + "path": "tests/db/test_postgres_cli_e2e.py", + "line": 13, + "scope": "", + "kind": "skipif", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skipif(\n os.getenv(\"POSTGRES_TEST\") != \"1\",\n reason=\"Set POSTGRES_TEST=1 to run Postgres integration tests\",\n )", + "rationale": "reason-15", + "affected_scope": "scope-102" + }, + { + "path": "tests/db/test_postgres_integration.py", + "line": 14, + "scope": "", + "kind": "integration-marker", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.integration", + "rationale": "reason-16", + "affected_scope": "scope-103" + }, + { + "path": "tests/db/test_postgres_integration.py", + "line": 15, + "scope": "", + "kind": "skipif", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skipif(\n os.getenv(\"POSTGRES_TEST\") != \"1\",\n reason=\"Set POSTGRES_TEST=1 and run docker compose up -d to run Postgres integration tests\",\n )", + "rationale": "reason-15", + "affected_scope": "scope-103" + }, + { + "path": "tests/db/test_semantic_layer_adapters.py", + "line": 99, + "scope": "test_postgres_url_recognized", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.skip(\"PostgreSQL adapter available, tested in integration tests\")", + "rationale": "reason-18", + "affected_scope": "scope-104" + }, + { + "path": "tests/db/test_snowflake_adapter.py", + "line": 188, + "scope": "test_snowflake_fetch_record_batch_mixed_types", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-105" + }, + { + "path": "tests/db/test_snowflake_adapter.py", + "line": 456, + "scope": "test_snowflake_fetch_record_batch_empty", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-106" + }, + { + "path": "tests/db/test_snowflake_adapter.py", + "line": 489, + "scope": "test_snowflake_fetch_record_batch_native_arrow", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-107" + }, + { + "path": "tests/db/test_snowflake_adapter.py", + "line": 509, + "scope": "test_snowflake_fetch_record_batch_native_arrow_empty", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-108" + }, + { + "path": "tests/db/test_snowflake_adapter.py", + "line": 527, + "scope": "test_snowflake_fetch_record_batch_fallback", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-109" + }, + { + "path": "tests/db/test_snowflake_cli_e2e.py", + "line": 11, + "scope": "", + "kind": "integration-marker", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.integration", + "rationale": "reason-16", + "affected_scope": "scope-110" + }, + { + "path": "tests/db/test_snowflake_cli_e2e.py", + "line": 12, + "scope": "", + "kind": "skipif", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skipif(\n os.getenv(\"SNOWFLAKE_TEST\") != \"1\",\n reason=\"Set SNOWFLAKE_TEST=1 to run Snowflake integration tests with fakesnow\",\n )", + "rationale": "reason-15", + "affected_scope": "scope-110" + }, + { + "path": "tests/db/test_snowflake_cli_e2e.py", + "line": 53, + "scope": "test_cli_query_uses_snowflake_connection", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"snowflake.connector\")", + "rationale": "reason-4", + "affected_scope": "scope-110" + }, + { + "path": "tests/db/test_snowflake_integration.py", + "line": 14, + "scope": "", + "kind": "integration-marker", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.integration", + "rationale": "reason-16", + "affected_scope": "scope-111" + }, + { + "path": "tests/db/test_snowflake_integration.py", + "line": 15, + "scope": "", + "kind": "skipif", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skipif(\n os.getenv(\"SNOWFLAKE_TEST\") != \"1\",\n reason=\"Set SNOWFLAKE_TEST=1 to run Snowflake integration tests with fakesnow\",\n )", + "rationale": "reason-15", + "affected_scope": "scope-111" + }, + { + "path": "tests/db/test_snowflake_integration.py", + "line": 28, + "scope": "patch_snowflake", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.skip(f\"fakesnow not compatible with installed sqlglot: {exc}\")", + "rationale": "reason-6", + "affected_scope": "scope-111" + }, + { + "path": "tests/db/test_snowflake_integration.py", + "line": 35, + "scope": "patch_snowflake", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'WITH ORDINALITY not implemented' in str(exc)" + ], + "source": "pytest.skip(f\"fakesnow not compatible with installed DuckDB: {exc}\")", + "rationale": "reason-6", + "affected_scope": "scope-111" + }, + { + "path": "tests/db/test_snowflake_integration.py", + "line": 53, + "scope": "patch_snowflake", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "'WITH ORDINALITY not implemented' in str(exc)" + ], + "source": "pytest.skip(f\"fakesnow not compatible with installed DuckDB: {exc}\")", + "rationale": "reason-6", + "affected_scope": "scope-111" + }, + { + "path": "tests/db/test_snowflake_integration.py", + "line": 298, + "scope": "test_semantic_layer_date_functions", + "kind": "skip", + "category": "real-gap", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skip(reason=\"Date functions test - consistent with BigQuery/Postgres\")", + "rationale": "reason-17", + "affected_scope": "scope-112" + }, + { + "path": "tests/db/test_spark_adapter.py", + "line": 149, + "scope": "test_spark_fetch_record_batch_mixed_types", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-113" + }, + { + "path": "tests/db/test_spark_cli_e2e.py", + "line": 12, + "scope": "", + "kind": "integration-marker", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.integration", + "rationale": "reason-16", + "affected_scope": "scope-114" + }, + { + "path": "tests/db/test_spark_cli_e2e.py", + "line": 13, + "scope": "", + "kind": "skipif", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skipif(\n os.getenv(\"SPARK_TEST\") != \"1\",\n reason=\"Set SPARK_TEST=1 and run docker compose up -d spark to run Spark integration tests\",\n )", + "rationale": "reason-15", + "affected_scope": "scope-114" + }, + { + "path": "tests/db/test_spark_integration.py", + "line": 14, + "scope": "", + "kind": "integration-marker", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.integration", + "rationale": "reason-16", + "affected_scope": "scope-115" + }, + { + "path": "tests/db/test_spark_integration.py", + "line": 15, + "scope": "", + "kind": "skipif", + "category": "external-service", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skipif(\n os.getenv(\"SPARK_TEST\") != \"1\",\n reason=\"Set SPARK_TEST=1 and run docker compose up -d spark to run Spark integration tests\",\n )", + "rationale": "reason-15", + "affected_scope": "scope-115" + }, + { + "path": "tests/db/test_spark_integration.py", + "line": 342, + "scope": "test_semantic_layer_date_functions", + "kind": "skip", + "category": "real-gap", + "exclusion_direction": "both-engines", + "source": "pytest.mark.skip(reason=\"Date functions test - consistent with BigQuery/Postgres/Snowflake\")", + "rationale": "reason-17", + "affected_scope": "scope-116" + }, + { + "path": "tests/interchange/ossie/test_ossie_engine_conformance.py", + "line": 72, + "scope": "_query", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "route == 'public_rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires a source-built Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-117" + }, + { + "path": "tests/interchange/ossie/test_ossie_engine_conformance.py", + "line": 338, + "scope": "test_cli_ossie_query_and_rewrite_execute_same_results", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "engine == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires a source-built Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-118" + }, + { + "path": "tests/metrics/test_advanced.py", + "line": 10, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-119" + }, + { + "path": "tests/metrics/test_cohort.py", + "line": 10, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-120" + }, + { + "path": "tests/metrics/test_conversion_source_parity.py", + "line": 52, + "scope": "test_conversion_sql_source_expressions", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "python-only-exclusion", + "conditions": [ + "engine == 'python'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-121" + }, + { + "path": "tests/metrics/test_conversion_source_parity.py", + "line": 65, + "scope": "test_rust_two_event_conversion_projects_source_aliases", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-122" + }, + { + "path": "tests/metrics/test_conversion_source_parity.py", + "line": 128, + "scope": "test_conversion_fill_is_accepted_without_changing_empty_result", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "python-only-exclusion", + "conditions": [ + "engine == 'python'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-123" + }, + { + "path": "tests/metrics/test_conversion_source_parity.py", + "line": 160, + "scope": "test_two_event_conversion_uses_last_time_dimension_instead_of_default", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "python-only-exclusion", + "conditions": [ + "engine == 'python'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-124" + }, + { + "path": "tests/metrics/test_cumulative.py", + "line": 480, + "scope": "test_time_comparison_over_derived_cumulative_chain", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-125" + }, + { + "path": "tests/metrics/test_cumulative.py", + "line": 540, + "scope": "test_time_comparison_over_ratio_cumulative_chain", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-126" + }, + { + "path": "tests/metrics/test_cumulative.py", + "line": 600, + "scope": "test_time_comparison_with_dependency_free_expression_metric", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-127" + }, + { + "path": "tests/metrics/test_filters.py", + "line": 7, + "scope": "", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-128" + }, + { + "path": "tests/metrics/test_non_additive_guard.py", + "line": 22, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-129" + }, + { + "path": "tests/metrics/test_retention.py", + "line": 10, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-130" + }, + { + "path": "tests/metrics/test_snapshot_wrapper_parity.py", + "line": 12, + "scope": "test_snapshot_wrappers_preserve_leaf_populations", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "engine == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-131" + }, + { + "path": "tests/metrics/test_snapshot_wrapper_parity.py", + "line": 53, + "scope": "test_snapshot_wrapper_defaults_apply_after_leaf_selection", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "engine == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-132" + }, + { + "path": "tests/metrics/test_symmetric_aggs.py", + "line": 10, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-133" + }, + { + "path": "tests/queries/test_cross_model_calculated_grain.py", + "line": 7, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-134" + }, + { + "path": "tests/queries/test_deterministic_join_anchor.py", + "line": 4, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-135" + }, + { + "path": "tests/queries/test_relationship_key_validation.py", + "line": 12, + "scope": "test_declared_foreign_key_groups_without_dimension", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "engine == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-136" + }, + { + "path": "tests/queries/test_rust_query_rewriter_route.py", + "line": 8, + "scope": "", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.query_rewriter import QueryRewriter", + "rationale": "reason-2", + "affected_scope": "scope-137" + }, + { + "path": "tests/queries/test_rust_sql_rewriter_parity.py", + "line": 19, + "scope": "strict_rust", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires the built Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-138" + }, + { + "path": "tests/queries/test_rust_yardstick_parity.py", + "line": 36, + "scope": "strict_rust", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires the built Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-139" + }, + { + "path": "tests/queries/test_semantic_sql_planner.py", + "line": 16, + "scope": "", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.query_rewriter import QueryRewriter", + "rationale": "reason-2", + "affected_scope": "scope-140" + }, + { + "path": "tests/queries/test_sql_fallback_policy.py", + "line": 11, + "scope": "", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.query_rewriter import QueryRewriter", + "rationale": "reason-2", + "affected_scope": "scope-141" + }, + { + "path": "tests/queries/test_temporal_sql_projection.py", + "line": 6, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.query_rewriter import QueryRewriter", + "rationale": "reason-2", + "affected_scope": "scope-142" + }, + { + "path": "tests/queries/test_yardstick_measures_replay.py", + "line": 108, + "scope": "_yardstick_upstream_checkout", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "conditions": [ + "not _env_flag('SIDEMANTIC_YARDSTICK_UPSTREAM_TESTS')" + ], + "source": "pytest.skip(\"Set SIDEMANTIC_YARDSTICK_UPSTREAM_TESTS=1 to fetch and replay live upstream Yardstick tests\")", + "rationale": "reason-15", + "affected_scope": "scope-143" + }, + { + "path": "tests/queries/test_yardstick_measures_replay.py", + "line": 774, + "scope": "_replay_yardstick_sql_test", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "not path.exists()" + ], + "source": "pytest.skip(f\"Yardstick SQL test file not found: {path}\")", + "rationale": "reason-6", + "affected_scope": "scope-144" + }, + { + "path": "tests/semantic_conformance/test_absent_counts.py", + "line": 11, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Absent count acceptance requires the installed Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-145" + }, + { + "path": "tests/semantic_conformance/test_active_consumption_cli.py", + "line": 18, + "scope": "project", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"CLI acceptance requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-146" + }, + { + "path": "tests/semantic_conformance/test_active_explores.py", + "line": 23, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Explore acceptance requires the real extension\")", + "rationale": "reason-4", + "affected_scope": "scope-147" + }, + { + "path": "tests/semantic_conformance/test_aggregate_aliases.py", + "line": 12, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Alias acceptance requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-148" + }, + { + "path": "tests/semantic_conformance/test_aggregate_aliases.py", + "line": 144, + "scope": "test_same_owner_duplicate_child_output_remains_explicitly_unsupported", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Alias rejection requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-149" + }, + { + "path": "tests/semantic_conformance/test_aggregate_breadth_parity.py", + "line": 11, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-150" + }, + { + "path": "tests/semantic_conformance/test_approximate_distinct.py", + "line": 12, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-151" + }, + { + "path": "tests/semantic_conformance/test_approximate_distinct.py", + "line": 186, + "scope": "test_approximate_dialect_rendering_and_population_results", + "kind": "skip", + "category": "real-gap", + "exclusion_direction": "python-only-exclusion", + "conditions": [ + "layer.engine == 'python' and shape in {'complete', 'complete_filtered', 'nested_complete'} and (dialect == 'redshift')" + ], + "source": "pytest.skip(\"Python reparses completed Redshift aggregates with its generic SQL parser\")", + "rationale": "reason-17", + "affected_scope": "scope-152" + }, + { + "path": "tests/semantic_conformance/test_approximate_distinct.py", + "line": 288, + "scope": "test_redshift_nested_approximate_expressions_use_independent_parser", + "kind": "skip", + "category": "real-gap", + "exclusion_direction": "python-only-exclusion", + "conditions": [ + "layer.engine != 'rust'" + ], + "source": "pytest.skip(\"Rust target emission; Python reparses Redshift using its generic parser\")", + "rationale": "reason-17", + "affected_scope": "scope-153" + }, + { + "path": "tests/semantic_conformance/test_cli.py", + "line": 63, + "scope": "test_cli_rewrite_executes_imported_query", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "engine == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"The real Rust extension must be installed for acceptance\")", + "rationale": "reason-4", + "affected_scope": "scope-154" + }, + { + "path": "tests/semantic_conformance/test_cohort_parity.py", + "line": 16, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "engine == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Cohort acceptance requires the real extension\")", + "rationale": "reason-4", + "affected_scope": "scope-155" + }, + { + "path": "tests/semantic_conformance/test_complete_filters.py", + "line": 14, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Complete filter acceptance requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-156" + }, + { + "path": "tests/semantic_conformance/test_complete_filters.py", + "line": 146, + "scope": "test_unproven_complete_filter_shapes_fail_explicitly", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Complete filter rejection requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-157" + }, + { + "path": "tests/semantic_conformance/test_complete_filters.py", + "line": 183, + "scope": "test_complete_filter_formulas_execute_with_physical_inputs", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "engine == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-158" + }, + { + "path": "tests/semantic_conformance/test_complete_filters.py", + "line": 215, + "scope": "test_invalid_complete_sql_keeps_database_validation", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "engine == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-159" + }, + { + "path": "tests/semantic_conformance/test_complete_filters.py", + "line": 235, + "scope": "test_foreign_filter_population_fails_explicitly", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Complete filter rejection requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-160" + }, + { + "path": "tests/semantic_conformance/test_complete_filters.py", + "line": 575, + "scope": "test_complete_row_count_generator_reuse_observes_graph_changes", + "kind": "engine-matrix", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "pytest.mark.parametrize(\"layer\", [\"python\"], indirect=True)", + "rationale": "reason-91", + "affected_scope": "scope-161" + }, + { + "path": "tests/semantic_conformance/test_complete_filters.py", + "line": 577, + "scope": "test_complete_row_count_generator_reuse_observes_graph_changes", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-161" + }, + { + "path": "tests/semantic_conformance/test_complete_filters.py", + "line": 628, + "scope": "test_complete_row_count_role_queries_preserve_caller_caches", + "kind": "engine-matrix", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "pytest.mark.parametrize(\"layer\", [\"python\"], indirect=True)", + "rationale": "reason-92", + "affected_scope": "scope-162" + }, + { + "path": "tests/semantic_conformance/test_complete_filters.py", + "line": 630, + "scope": "test_complete_row_count_role_queries_preserve_caller_caches", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-162" + }, + { + "path": "tests/semantic_conformance/test_complete_filters.py", + "line": 665, + "scope": "test_unowned_graph_complete_count_remains_explicitly_unsupported", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-163" + }, + { + "path": "tests/semantic_conformance/test_complete_filters.py", + "line": 679, + "scope": "test_tsql_complete_row_count_retains_existing_path", + "kind": "engine-matrix", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "pytest.mark.parametrize(\"layer\", [\"python\"], indirect=True)", + "rationale": "reason-93", + "affected_scope": "scope-164" + }, + { + "path": "tests/semantic_conformance/test_complete_filters.py", + "line": 682, + "scope": "test_tsql_complete_row_count_retains_existing_path", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-164" + }, + { + "path": "tests/semantic_conformance/test_complete_filters_postgres.py", + "line": 31, + "scope": "test_complete_filters_preserve_identifier_identity", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "conditions": [ + "not dsn" + ], + "source": "pytest.skip(\"PostgreSQL execution requires SIDEMANTIC_TEST_POSTGRES_DSN\")", + "rationale": "reason-15", + "affected_scope": "scope-165" + }, + { + "path": "tests/semantic_conformance/test_complete_filters_postgres.py", + "line": 61, + "scope": "test_postgres_filtered_float_fanout_average_preserves_values", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "conditions": [ + "not dsn" + ], + "source": "pytest.skip(\"PostgreSQL execution requires SIDEMANTIC_TEST_POSTGRES_DSN\")", + "rationale": "reason-15", + "affected_scope": "scope-166" + }, + { + "path": "tests/semantic_conformance/test_complete_filters_postgres.py", + "line": 134, + "scope": "test_postgres_filtered_complete_row_count", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "conditions": [ + "not dsn" + ], + "source": "pytest.skip(\"PostgreSQL execution requires SIDEMANTIC_TEST_POSTGRES_DSN\")", + "rationale": "reason-15", + "affected_scope": "scope-167" + }, + { + "path": "tests/semantic_conformance/test_complete_filters_postgres.py", + "line": 177, + "scope": "test_postgres_filtered_owned_count_family", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "conditions": [ + "not dsn" + ], + "source": "pytest.skip(\"PostgreSQL execution requires SIDEMANTIC_TEST_POSTGRES_DSN\")", + "rationale": "reason-15", + "affected_scope": "scope-168" + }, + { + "path": "tests/semantic_conformance/test_computed_keys.py", + "line": 13, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Computed-key acceptance requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-169" + }, + { + "path": "tests/semantic_conformance/test_computed_keys.py", + "line": 220, + "scope": "test_omitted_native_relationship_key_does_not_classify_ordinary_id", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-170" + }, + { + "path": "tests/semantic_conformance/test_conversion_parity.py", + "line": 12, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Conversion acceptance requires the real extension\")", + "rationale": "reason-4", + "affected_scope": "scope-171" + }, + { + "path": "tests/semantic_conformance/test_cross_relationship_parity.py", + "line": 11, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Cross relationship parity requires the real extension\")", + "rationale": "reason-4", + "affected_scope": "scope-172" + }, + { + "path": "tests/semantic_conformance/test_cross_source_windows.py", + "line": 15, + "scope": "test_native_window_expression_preserves_quoted_input_across_dialects", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-173" + }, + { + "path": "tests/semantic_conformance/test_cross_source_windows.py", + "line": 43, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Cross-source window acceptance requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-174" + }, + { + "path": "tests/semantic_conformance/test_default_time_differential.py", + "line": 7, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-175" + }, + { + "path": "tests/semantic_conformance/test_default_time_differential.py", + "line": 14, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires real native extension\")", + "rationale": "reason-4", + "affected_scope": "scope-176" + }, + { + "path": "tests/semantic_conformance/test_dialect_boundary.py", + "line": 16, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires matching native extension\")", + "rationale": "reason-4", + "affected_scope": "scope-177" + }, + { + "path": "tests/semantic_conformance/test_dialect_boundary.py", + "line": 57, + "scope": "test_native_declared_graph_and_query_syntax", + "kind": "skip", + "category": "intentional-Python-only", + "exclusion_direction": "python-only-exclusion", + "conditions": [ + "layer.engine != 'rust'" + ], + "source": "pytest.skip(\"Native boundary syntax contract; target-dialect result oracle is shared above\")", + "rationale": "reason-95", + "affected_scope": "scope-178" + }, + { + "path": "tests/semantic_conformance/test_dialect_boundary.py", + "line": 80, + "scope": "test_native_rewrite_syntax_and_policy_context", + "kind": "skip", + "category": "intentional-Python-only", + "exclusion_direction": "python-only-exclusion", + "conditions": [ + "layer.engine != 'rust'" + ], + "source": "pytest.skip(\"Native rewrite boundary contract\")", + "rationale": "reason-95", + "affected_scope": "scope-179" + }, + { + "path": "tests/semantic_conformance/test_dialect_boundary.py", + "line": 95, + "scope": "test_native_fragment_framing_and_source_snapshot", + "kind": "skip", + "category": "intentional-Python-only", + "exclusion_direction": "python-only-exclusion", + "conditions": [ + "layer.engine != 'rust'" + ], + "source": "pytest.skip(\"Native input validation contract\")", + "rationale": "reason-95", + "affected_scope": "scope-180" + }, + { + "path": "tests/semantic_conformance/test_dialect_boundary.py", + "line": 113, + "scope": "test_source_dialect_preserves_typed_policy_and_parameter_values", + "kind": "skip", + "category": "intentional-Python-only", + "exclusion_direction": "python-only-exclusion", + "conditions": [ + "layer.engine != 'rust'" + ], + "source": "pytest.skip(\"Native source-dialect literal contract\")", + "rationale": "reason-95", + "affected_scope": "scope-181" + }, + { + "path": "tests/semantic_conformance/test_direct_many_relationships.py", + "line": 11, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Direct relationship parity requires the real extension\")", + "rationale": "reason-4", + "affected_scope": "scope-182" + }, + { + "path": "tests/semantic_conformance/test_feature_parity.py", + "line": 24, + "scope": "engine", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Migration acceptance requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-183" + }, + { + "path": "tests/semantic_conformance/test_filtered_count_family.py", + "line": 16, + "scope": "engine", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Count family acceptance requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-184" + }, + { + "path": "tests/semantic_conformance/test_filtered_count_family.py", + "line": 228, + "scope": "test_owned_count_generator_sees_live_graph_changes", + "kind": "engine-matrix", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "pytest.mark.parametrize(\"engine\", [\"python\"])", + "rationale": "reason-91", + "affected_scope": "scope-185" + }, + { + "path": "tests/semantic_conformance/test_filtered_count_family.py", + "line": 230, + "scope": "test_owned_count_generator_sees_live_graph_changes", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-185" + }, + { + "path": "tests/semantic_conformance/test_filtered_count_family.py", + "line": 270, + "scope": "test_count_family_does_not_admit_other_filter_scopes", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-186" + }, + { + "path": "tests/semantic_conformance/test_filtered_row_expressions.py", + "line": 26, + "scope": "engine", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Row-expression acceptance requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-187" + }, + { + "path": "tests/semantic_conformance/test_filtered_row_expressions.py", + "line": 189, + "scope": "test_postgres_filtered_row_expression_oracles", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "conditions": [ + "not dsn" + ], + "source": "pytest.skip(\"PostgreSQL execution requires SIDEMANTIC_TEST_POSTGRES_DSN\")", + "rationale": "reason-15", + "affected_scope": "scope-188" + }, + { + "path": "tests/semantic_conformance/test_generated_differential.py", + "line": 33, + "scope": "runner", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "os.environ.get('SIDEMANTIC_DIFFERENTIAL_REQUIRE_RUST', '0') == '1'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Differential execution requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-189" + }, + { + "path": "tests/semantic_conformance/test_graph_population_ownership.py", + "line": 17, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-190" + }, + { + "path": "tests/semantic_conformance/test_graph_population_ownership.py", + "line": 70, + "scope": "test_native_dotted_graph_population_visibility", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-191" + }, + { + "path": "tests/semantic_conformance/test_many_role_results.py", + "line": 13, + "scope": "rust", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-192" + }, + { + "path": "tests/semantic_conformance/test_multistep_conversion_parity.py", + "line": 13, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Funnel acceptance requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-193" + }, + { + "path": "tests/semantic_conformance/test_nested_policy_sql.py", + "line": 19, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Nested policy SQL requires the installed Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-194" + }, + { + "path": "tests/semantic_conformance/test_null_fill.py", + "line": 11, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Null-fill acceptance requires the matching Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-195" + }, + { + "path": "tests/semantic_conformance/test_ossie_aggregate_inputs.py", + "line": 21, + "scope": "load_layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires the source-built Rust runtime\")", + "rationale": "reason-4", + "affected_scope": "scope-196" + }, + { + "path": "tests/semantic_conformance/test_ossie_aggregate_inputs.py", + "line": 206, + "scope": "test_graph_measures_preserve_input_scope", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-197" + }, + { + "path": "tests/semantic_conformance/test_parameterized_segments.py", + "line": 15, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires matching native extension\")", + "rationale": "reason-4", + "affected_scope": "scope-198" + }, + { + "path": "tests/semantic_conformance/test_policy_aggregate_parity.py", + "line": 17, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Population acceptance requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-199" + }, + { + "path": "tests/semantic_conformance/test_policy_cli.py", + "line": 26, + "scope": "installed_rust", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Policy CLI acceptance requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-200" + }, + { + "path": "tests/semantic_conformance/test_postgres_policies.py", + "line": 20, + "scope": "postgres", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "conditions": [ + "not dsn" + ], + "source": "pytest.skip(\"PostgreSQL policy execution requires SIDEMANTIC_TEST_POSTGRES_DSN\")", + "rationale": "reason-15", + "affected_scope": "scope-201" + }, + { + "path": "tests/semantic_conformance/test_query_catalogs.py", + "line": 17, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Catalog acceptance requires the real extension\")", + "rationale": "reason-4", + "affected_scope": "scope-202" + }, + { + "path": "tests/semantic_conformance/test_query_catalogs.py", + "line": 126, + "scope": "test_raw_active_catalog_requests_are_never_ignored", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-203" + }, + { + "path": "tests/semantic_conformance/test_query_catalogs.py", + "line": 140, + "scope": "test_invalid_catalog_identity_is_rejected", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-204" + }, + { + "path": "tests/semantic_conformance/test_query_options_parity.py", + "line": 14, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires the actual Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-205" + }, + { + "path": "tests/semantic_conformance/test_query_timezone_parity.py", + "line": 12, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-206" + }, + { + "path": "tests/semantic_conformance/test_reference.py", + "line": 41, + "scope": "test_compiler_results", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "engine == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"The real Rust extension must be installed for acceptance\")", + "rationale": "reason-4", + "affected_scope": "scope-207" + }, + { + "path": "tests/semantic_conformance/test_relationship_role_parity.py", + "line": 17, + "scope": "layer_for", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Scoped role acceptance requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-208" + }, + { + "path": "tests/semantic_conformance/test_relative_date_operators.py", + "line": 11, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires the built Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-209" + }, + { + "path": "tests/semantic_conformance/test_retention_parity.py", + "line": 25, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Retention parity requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-210" + }, + { + "path": "tests/semantic_conformance/test_rewriter_ci_regressions.py", + "line": 11, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-211" + }, + { + "path": "tests/semantic_conformance/test_rewriter_ci_regressions.py", + "line": 115, + "scope": "test_subquery_local_alias_can_shadow_outer_semantic_source", + "kind": "skip", + "category": "intentional-Python-only", + "exclusion_direction": "python-only-exclusion", + "conditions": [ + "layer.engine != 'rust'" + ], + "source": "pytest.skip(\"Native subquery scope regression\")", + "rationale": "reason-95", + "affected_scope": "scope-212" + }, + { + "path": "tests/semantic_conformance/test_rewriter_count_keys.py", + "line": 11, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-213" + }, + { + "path": "tests/semantic_conformance/test_rollup_reconstruction.py", + "line": 14, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Rollup execution requires the matching Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-214" + }, + { + "path": "tests/semantic_conformance/test_rollup_reconstruction.py", + "line": 66, + "scope": "build", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "rust" + ], + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-215" + }, + { + "path": "tests/semantic_conformance/test_rollup_reconstruction.py", + "line": 342, + "scope": "test_postgres_rollup_reconstruction_executes", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "conditions": [ + "not dsn" + ], + "source": "pytest.skip(\"PostgreSQL execution requires SIDEMANTIC_TEST_POSTGRES_DSN\")", + "rationale": "reason-15", + "affected_scope": "scope-216" + }, + { + "path": "tests/semantic_conformance/test_rollup_reconstruction.py", + "line": 449, + "scope": "test_colliding_join_dimension_outputs_keep_raw_contract", + "kind": "skip", + "category": "intentional-Python-only", + "exclusion_direction": "python-only-exclusion", + "conditions": [ + "layer.engine != 'rust'" + ], + "source": "pytest.skip(\"Native output-name collision contract\")", + "rationale": "reason-95", + "affected_scope": "scope-217" + }, + { + "path": "tests/semantic_conformance/test_rollup_reconstruction.py", + "line": 466, + "scope": "test_join_rollup_preserves_local_and_role_source_population", + "kind": "skip", + "category": "intentional-Python-only", + "exclusion_direction": "python-only-exclusion", + "conditions": [ + "layer.engine != 'rust'" + ], + "source": "pytest.skip(\"Native effective-anchor routing regression\")", + "rationale": "reason-95", + "affected_scope": "scope-218" + }, + { + "path": "tests/semantic_conformance/test_rollup_routing.py", + "line": 15, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Rollup acceptance requires the matching Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-219" + }, + { + "path": "tests/semantic_conformance/test_selected_table_calculations.py", + "line": 20, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires real native extension\")", + "rationale": "reason-4", + "affected_scope": "scope-220" + }, + { + "path": "tests/semantic_conformance/test_selected_table_calculations.py", + "line": 172, + "scope": "test_canonical_validation_checks_active_calculations", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires real native extension\")", + "rationale": "reason-4", + "affected_scope": "scope-221" + }, + { + "path": "tests/semantic_conformance/test_selected_table_calculations.py", + "line": 202, + "scope": "test_postgres_calculation_results_match_processor", + "kind": "skip", + "category": "external-service", + "exclusion_direction": "both-engines", + "conditions": [ + "not dsn" + ], + "source": "pytest.skip(\"PostgreSQL execution requires SIDEMANTIC_TEST_POSTGRES_DSN\")", + "rationale": "reason-15", + "affected_scope": "scope-222" + }, + { + "path": "tests/semantic_conformance/test_semantic_sql_binding.py", + "line": 14, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires the built Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-223" + }, + { + "path": "tests/semantic_conformance/test_sibling_fanout_parity.py", + "line": 11, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Sibling fanout acceptance requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-224" + }, + { + "path": "tests/semantic_conformance/test_snapshot_parity.py", + "line": 18, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Snapshot parity requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-225" + }, + { + "path": "tests/semantic_conformance/test_snowflake_dates.py", + "line": 32, + "scope": "test_snowflake_date_differences", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires matching native extension\")", + "rationale": "reason-4", + "affected_scope": "scope-226" + }, + { + "path": "tests/semantic_conformance/test_source_null_ordering.py", + "line": 13, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires real native extension\")", + "rationale": "reason-4", + "affected_scope": "scope-227" + }, + { + "path": "tests/semantic_conformance/test_source_null_ordering.py", + "line": 79, + "scope": "test_minimized_nullable_fanout_case", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires real native extension\")", + "rationale": "reason-4", + "affected_scope": "scope-228" + }, + { + "path": "tests/semantic_conformance/test_special_population.py", + "line": 12, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Population parity requires the real Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-229" + }, + { + "path": "tests/semantic_conformance/test_temporal_dialect_fallback.py", + "line": 13, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Temporal dialect parity requires the Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-230" + }, + { + "path": "tests/semantic_conformance/test_temporal_null_fill.py", + "line": 11, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Temporal fill requires matching installed Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-231" + }, + { + "path": "tests/semantic_conformance/test_time_key_projection.py", + "line": 12, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\")", + "rationale": "reason-4", + "affected_scope": "scope-232" + }, + { + "path": "tests/semantic_conformance/test_time_key_projection.py", + "line": 68, + "scope": "test_time_identity_stays_unbucketed_for_join_and_fanout", + "kind": "skip", + "category": "real-gap", + "exclusion_direction": "python-only-exclusion", + "conditions": [ + "layer.engine != 'rust'" + ], + "source": "pytest.skip(\"Python joins physical keys; native computed-key identity has its own independent oracle\")", + "rationale": "reason-17", + "affected_scope": "scope-233" + }, + { + "path": "tests/semantic_conformance/test_window_output_parity.py", + "line": 14, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Window acceptance requires the Rust extension\")", + "rationale": "reason-4", + "affected_scope": "scope-234" + }, + { + "path": "tests/semantic_conformance/test_window_output_parity.py", + "line": 263, + "scope": "rust_layer", + "kind": "skip", + "category": "intentional-Python-only", + "exclusion_direction": "python-only-exclusion", + "conditions": [ + "layer.engine != 'rust'" + ], + "source": "pytest.skip(\"Strict Rust compiler validation contract\")", + "rationale": "reason-95", + "affected_scope": "scope-235" + }, + { + "path": "tests/semantic_conformance/test_yardstick_source_dialects.py", + "line": 14, + "scope": "layer", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "request.param == 'rust'" + ], + "source": "pytest.importorskip(\"sidemantic_rs\", reason=\"Requires matching native extension\")", + "rationale": "reason-4", + "affected_scope": "scope-236" + }, + { + "path": "tests/semantic_conformance/test_yardstick_source_dialects.py", + "line": 121, + "scope": "test_native_ordinary_statement_batches_retain_both_results", + "kind": "skip", + "category": "intentional-Python-only", + "exclusion_direction": "both-engines", + "conditions": [ + "layer.engine != 'rust'" + ], + "source": "pytest.skip(\"Existing native direct-call batch contract; public Python rejects strict batches\")", + "rationale": "reason-95", + "affected_scope": "scope-237" + }, + { + "path": "tests/server/test_api_security.py", + "line": 21, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"fastapi\")", + "rationale": "reason-4", + "affected_scope": "scope-238" + }, + { + "path": "tests/server/test_api_security.py", + "line": 22, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-238" + }, + { + "path": "tests/server/test_api_security.py", + "line": 23, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"httpx\")", + "rationale": "reason-4", + "affected_scope": "scope-238" + }, + { + "path": "tests/server/test_api_server.py", + "line": 13, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"fastapi\")", + "rationale": "reason-4", + "affected_scope": "scope-239" + }, + { + "path": "tests/server/test_api_server.py", + "line": 14, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-239" + }, + { + "path": "tests/server/test_api_server.py", + "line": 15, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"httpx\")", + "rationale": "reason-4", + "affected_scope": "scope-239" + }, + { + "path": "tests/server/test_api_server.py", + "line": 306, + "scope": "test_serve_ui_serves_spa_and_keeps_api_gated", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "not ui_static_dir().joinpath('index.html').exists()" + ], + "source": "pytest.skip(\"web UI bundle not built (run scripts/build_webapp.py)\")", + "rationale": "reason-6", + "affected_scope": "scope-240" + }, + { + "path": "tests/server/test_concurrency.py", + "line": 21, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"fastapi\")", + "rationale": "reason-4", + "affected_scope": "scope-241" + }, + { + "path": "tests/server/test_concurrency.py", + "line": 22, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-241" + }, + { + "path": "tests/server/test_concurrency.py", + "line": 23, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"httpx\")", + "rationale": "reason-4", + "affected_scope": "scope-241" + }, + { + "path": "tests/server/test_connection.py", + "line": 9, + "scope": "test_handle_auth", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"riffq\")", + "rationale": "reason-4", + "affected_scope": "scope-242" + }, + { + "path": "tests/server/test_connection.py", + "line": 10, + "scope": "test_handle_auth", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-242" + }, + { + "path": "tests/server/test_connection.py", + "line": 29, + "scope": "test_handle_auth_partial_config_fails_closed", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"riffq\")", + "rationale": "reason-4", + "affected_scope": "scope-243" + }, + { + "path": "tests/server/test_connection.py", + "line": 30, + "scope": "test_handle_auth_partial_config_fails_closed", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-243" + }, + { + "path": "tests/server/test_connection.py", + "line": 47, + "scope": "test_handle_system_queries", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"riffq\")", + "rationale": "reason-4", + "affected_scope": "scope-244" + }, + { + "path": "tests/server/test_connection.py", + "line": 48, + "scope": "test_handle_system_queries", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-244" + }, + { + "path": "tests/server/test_connection.py", + "line": 103, + "scope": "test_dml_passthrough", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"riffq\")", + "rationale": "reason-4", + "affected_scope": "scope-245" + }, + { + "path": "tests/server/test_connection.py", + "line": 104, + "scope": "test_dml_passthrough", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-245" + }, + { + "path": "tests/server/test_connection.py", + "line": 125, + "scope": "test_query_error_raises_exception", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"riffq\")", + "rationale": "reason-4", + "affected_scope": "scope-246" + }, + { + "path": "tests/server/test_connection.py", + "line": 126, + "scope": "test_query_error_raises_exception", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-246" + }, + { + "path": "tests/server/test_connection.py", + "line": 153, + "scope": "test_user_attributes_lookup_by_session_user", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"riffq\")", + "rationale": "reason-4", + "affected_scope": "scope-247" + }, + { + "path": "tests/server/test_connection.py", + "line": 154, + "scope": "test_user_attributes_lookup_by_session_user", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-247" + }, + { + "path": "tests/server/test_connection.py", + "line": 177, + "scope": "test_enforce_pg_access_denies_secured_model_without_attrs", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"riffq\")", + "rationale": "reason-4", + "affected_scope": "scope-248" + }, + { + "path": "tests/server/test_connection.py", + "line": 178, + "scope": "test_enforce_pg_access_denies_secured_model_without_attrs", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-248" + }, + { + "path": "tests/server/test_connection.py", + "line": 216, + "scope": "secured_pg_connection", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"riffq\")", + "rationale": "reason-4", + "affected_scope": "scope-249" + }, + { + "path": "tests/server/test_connection.py", + "line": 217, + "scope": "secured_pg_connection", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-249" + }, + { + "path": "tests/server/test_connection.py", + "line": 308, + "scope": "test_empty_pg_catalog_is_valid", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"riffq\")", + "rationale": "reason-4", + "affected_scope": "scope-250" + }, + { + "path": "tests/server/test_connection.py", + "line": 309, + "scope": "test_empty_pg_catalog_is_valid", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-250" + }, + { + "path": "tests/server/test_transport_security_parity.py", + "line": 13, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"fastapi\")", + "rationale": "reason-4", + "affected_scope": "scope-251" + }, + { + "path": "tests/server/test_transport_security_parity.py", + "line": 14, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"httpx\")", + "rationale": "reason-4", + "affected_scope": "scope-251" + }, + { + "path": "tests/server/test_transport_security_parity.py", + "line": 15, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-251" + }, + { + "path": "tests/templates/test_parameters.py", + "line": 9, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-252" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 58, + "scope": "TestSemanticLayerAdapterInterface::test_layer_adapter_fetch_record_batch", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-253" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 79, + "scope": "TestServerConnectionAdapterIntegration::test_connection_handler_uses_adapter_for_dml", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"riffq\")", + "rationale": "reason-4", + "affected_scope": "scope-254" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 80, + "scope": "TestServerConnectionAdapterIntegration::test_connection_handler_uses_adapter_for_dml", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-254" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 133, + "scope": "TestServerConnectionAdapterIntegration::test_connection_handler_uses_adapter_for_system_queries", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"riffq\")", + "rationale": "reason-4", + "affected_scope": "scope-255" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 134, + "scope": "TestServerConnectionAdapterIntegration::test_connection_handler_uses_adapter_for_system_queries", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-255" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 183, + "scope": "TestServerConnectionAdapterIntegration::test_connection_handler_uses_adapter_for_pg_namespace", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"riffq\")", + "rationale": "reason-4", + "affected_scope": "scope-256" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 184, + "scope": "TestServerConnectionAdapterIntegration::test_connection_handler_uses_adapter_for_pg_namespace", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-256" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 237, + "scope": "TestServerCatalogAdapterIntegration::test_start_server_uses_adapter_for_catalog_queries", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"riffq\")", + "rationale": "reason-4", + "affected_scope": "scope-257" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 307, + "scope": "TestMCPServerAdapterIntegration::test_mcp_run_query_uses_adapter", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"mcp\")", + "rationale": "reason-4", + "affected_scope": "scope-258" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 405, + "scope": "TestWorkbenchAdapterIntegration::test_workbench_command_wiring", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"textual\")", + "rationale": "reason-4", + "affected_scope": "scope-259" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 466, + "scope": "TestWidgetAdapterIntegration::test_widget_generator_uses_layer_dialect", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-260" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 467, + "scope": "TestWidgetAdapterIntegration::test_widget_generator_uses_layer_dialect", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"anywidget\")", + "rationale": "reason-4", + "affected_scope": "scope-260" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 514, + "scope": "TestWidgetAdapterIntegration::test_widget_date_range_query_handles_qualified_table", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-261" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 515, + "scope": "TestWidgetAdapterIntegration::test_widget_date_range_query_handles_qualified_table", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"anywidget\")", + "rationale": "reason-4", + "affected_scope": "scope-261" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 550, + "scope": "TestWidgetAdapterIntegration::test_widget_sets_time_series_column_in_config", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-262" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 551, + "scope": "TestWidgetAdapterIntegration::test_widget_sets_time_series_column_in_config", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"anywidget\")", + "rationale": "reason-4", + "affected_scope": "scope-262" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 583, + "scope": "TestWidgetAdapterIntegration::test_widget_binary_transport_populates_binary_traits", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-263" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 584, + "scope": "TestWidgetAdapterIntegration::test_widget_binary_transport_populates_binary_traits", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"anywidget\")", + "rationale": "reason-4", + "affected_scope": "scope-263" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 620, + "scope": "TestWidgetAdapterIntegration::test_widget_uses_adapter_in_layer_mode", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-264" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 621, + "scope": "TestWidgetAdapterIntegration::test_widget_uses_adapter_in_layer_mode", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"anywidget\")", + "rationale": "reason-4", + "affected_scope": "scope-264" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 659, + "scope": "TestWidgetAdapterIntegration::test_widget_execute_routes_through_adapter", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-265" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 660, + "scope": "TestWidgetAdapterIntegration::test_widget_execute_routes_through_adapter", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"anywidget\")", + "rationale": "reason-4", + "affected_scope": "scope-265" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 715, + "scope": "TestWidgetAdapterIntegration::test_widget_dataframe_mode_uses_raw_connection", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-266" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 716, + "scope": "TestWidgetAdapterIntegration::test_widget_dataframe_mode_uses_raw_connection", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"anywidget\")", + "rationale": "reason-4", + "affected_scope": "scope-266" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 717, + "scope": "TestWidgetAdapterIntegration::test_widget_dataframe_mode_uses_raw_connection", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"polars\")", + "rationale": "reason-4", + "affected_scope": "scope-266" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 747, + "scope": "TestWidgetAdapterIntegration::test_widget_execute_arrow_uses_fetch_record_batch", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-267" + }, + { + "path": "tests/test_adapter_integration.py", + "line": 748, + "scope": "TestWidgetAdapterIntegration::test_widget_execute_arrow_uses_fetch_record_batch", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"anywidget\")", + "rationale": "reason-4", + "affected_scope": "scope-267" + }, + { + "path": "tests/test_bugfix_batch.py", + "line": 15, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-268" + }, + { + "path": "tests/test_charts.py", + "line": 13, + "scope": "test_chart_generation_available", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.skip(\"altair not installed - chart generation unavailable\")", + "rationale": "reason-6", + "affected_scope": "scope-269" + }, + { + "path": "tests/test_charts.py", + "line": 26, + "scope": "test_format_label", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.skip(\"altair not installed\")", + "rationale": "reason-6", + "affected_scope": "scope-270" + }, + { + "path": "tests/test_charts.py", + "line": 39, + "scope": "test_color_palette", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.skip(\"altair not installed\")", + "rationale": "reason-6", + "affected_scope": "scope-271" + }, + { + "path": "tests/test_cli_commands.py", + "line": 442, + "scope": "test_workbench_calls_runner", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"textual\")", + "rationale": "reason-4", + "affected_scope": "scope-272" + }, + { + "path": "tests/test_cli_commands.py", + "line": 722, + "scope": "test_api_serve_calls_start_server", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"fastapi\")", + "rationale": "reason-4", + "affected_scope": "scope-273" + }, + { + "path": "tests/test_cli_commands.py", + "line": 787, + "scope": "test_api_serve_legacy_warning_precedes_start_server", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"fastapi\")", + "rationale": "reason-4", + "affected_scope": "scope-274" + }, + { + "path": "tests/test_cli_commands.py", + "line": 1091, + "scope": "test_http_entrypoints_forward_trusted_identity", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"fastapi\")", + "rationale": "reason-4", + "affected_scope": "scope-275" + }, + { + "path": "tests/test_cli_contract.py", + "line": 917, + "scope": "test_api_auth_token_can_be_read_from_stdin", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"fastapi\")", + "rationale": "reason-4", + "affected_scope": "scope-276" + }, + { + "path": "tests/test_cli_project_contract.py", + "line": 287, + "scope": "test_dashboard_serve_discovers_default_spec_and_project", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"fastapi\")", + "rationale": "reason-4", + "affected_scope": "scope-277" + }, + { + "path": "tests/test_cli_t2_contract.py", + "line": 459, + "scope": "test_format_default_does_not_suppress_unstructured_server_status", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"fastapi\")", + "rationale": "reason-4", + "affected_scope": "scope-278" + }, + { + "path": "tests/test_dashboard.py", + "line": 150, + "scope": "test_crossfilter_dashboard_asgi_app_routes_requests_without_eager_preagg", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"fastapi\")", + "rationale": "reason-4", + "affected_scope": "scope-279" + }, + { + "path": "tests/test_dashboard.py", + "line": 151, + "scope": "test_crossfilter_dashboard_asgi_app_routes_requests_without_eager_preagg", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"httpx\")", + "rationale": "reason-4", + "affected_scope": "scope-279" + }, + { + "path": "tests/test_dashboard.py", + "line": 182, + "scope": "test_crossfilter_dashboard_asgi_app_loads_non_initial_tab_specs_lazily", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"fastapi\")", + "rationale": "reason-4", + "affected_scope": "scope-280" + }, + { + "path": "tests/test_dashboard.py", + "line": 183, + "scope": "test_crossfilter_dashboard_asgi_app_loads_non_initial_tab_specs_lazily", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"httpx\")", + "rationale": "reason-4", + "affected_scope": "scope-280" + }, + { + "path": "tests/test_mcp_apps.py", + "line": 7, + "scope": "", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"mcp\")", + "rationale": "reason-4", + "affected_scope": "scope-281" + }, + { + "path": "tests/test_native_build_cache.py", + "line": 69, + "scope": "test_native_source_changes_invalidate_uv_wheels", + "kind": "skip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "conditions": [ + "uv is None" + ], + "source": "pytest.skip(\"uv is required to exercise its wheel cache\")", + "rationale": "reason-6", + "affected_scope": "scope-282" + }, + { + "path": "tests/test_performance.py", + "line": 131, + "scope": "test_simple_rewrite_performance", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.query_rewriter import QueryRewriter", + "rationale": "reason-2", + "affected_scope": "scope-283" + }, + { + "path": "tests/test_performance.py", + "line": 151, + "scope": "test_complex_rewrite_performance", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.query_rewriter import QueryRewriter", + "rationale": "reason-2", + "affected_scope": "scope-284" + }, + { + "path": "tests/test_performance.py", + "line": 180, + "scope": "test_sql_generation_performance", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-285" + }, + { + "path": "tests/test_performance.py", + "line": 203, + "scope": "test_multi_join_generation_performance", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-286" + }, + { + "path": "tests/test_performance.py", + "line": 248, + "scope": "test_filter_parsing_performance", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-287" + }, + { + "path": "tests/test_performance.py", + "line": 278, + "scope": "test_query_rewriter_warm_vs_cold", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.query_rewriter import QueryRewriter", + "rationale": "reason-2", + "affected_scope": "scope-288" + }, + { + "path": "tests/test_performance.py", + "line": 310, + "scope": "test_parameter_substitution_performance", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-289" + }, + { + "path": "tests/test_query_fragment_boundary.py", + "line": 196, + "scope": "test_rewriter_cte_scope_does_not_authorize_structured_or_later_calls", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.query_rewriter import QueryRewriter", + "rationale": "reason-2", + "affected_scope": "scope-290" + }, + { + "path": "tests/test_query_fragment_boundary.py", + "line": 212, + "scope": "test_cte_scope_allows_expression_plan_and_identifier_folding", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.query_rewriter import QueryRewriter", + "rationale": "reason-2", + "affected_scope": "scope-291" + }, + { + "path": "tests/test_sql_generation_security.py", + "line": 355, + "scope": "test_conversion_invalid_entity_rejected", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-292" + }, + { + "path": "tests/test_sql_generation_security.py", + "line": 389, + "scope": "test_conversion_invalid_window_rejected", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-293" + }, + { + "path": "tests/test_sql_generation_security.py", + "line": 423, + "scope": "test_conversion_event_name_quotes_escaped", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-294" + }, + { + "path": "tests/test_sql_generation_security.py", + "line": 534, + "scope": "test_build_interval_duckdb", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-295" + }, + { + "path": "tests/test_sql_generation_security.py", + "line": 544, + "scope": "test_build_interval_bigquery", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-296" + }, + { + "path": "tests/test_sql_generation_security.py", + "line": 555, + "scope": "test_build_interval_postgres", + "kind": "implementation-import", + "category": "intentional-Python-only", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.generator import SQLGenerator", + "rationale": "reason-2", + "affected_scope": "scope-297" + }, + { + "path": "tests/test_workbench_demo.py", + "line": 8, + "scope": "", + "kind": "implementation-import", + "category": "real-gap", + "exclusion_direction": "rust-coverage-exclusion", + "source": "from sidemantic.sql.query_rewriter import QueryRewriter", + "rationale": "reason-2", + "affected_scope": "scope-298" + }, + { + "path": "tests/widget/test_widget_examples.py", + "line": 95, + "scope": "test_build_auto_model_sets_simple_aggs", + "kind": "importorskip", + "category": "optional-host", + "exclusion_direction": "both-engines", + "source": "pytest.importorskip(\"pyarrow\")", + "rationale": "reason-4", + "affected_scope": "scope-299" + } + ], + "execution_evidence": { + "label": "PR 409 review working tree based on 5ca50124, Python 3.13 / DuckDB 1.5.6 / rebuilt native engine. Full Rust shared lane before the final Python local-calculation and funnel DATE-expectation fixes: 11724 passed, 147 skipped, 2 failed. Both failures were the funnel DATE expectation; after repair its full module passed 45 tests. Final calculation follow-ups: 2913 conformance passes plus those two repaired assertions, 958 metric/query passes, and 520/520 generated inputs agreed.", + "testcases": 11873, + "skipped": 147, + "failures": 2, + "errors": 0, + "skip_reasons": { + "Existing native direct-call batch contract; public Python rejects strict batches": 2, + "Native boundary syntax contract; target-dialect result oracle is shared above": 5, + "Native effective-anchor routing regression": 2, + "Native input validation contract": 1, + "Native output-name collision contract": 1, + "Native rewrite boundary contract": 3, + "Native source-dialect literal contract": 12, + "Native subquery scope regression": 1, + "PostgreSQL adapter available, tested in integration tests": 1, + "PostgreSQL execution requires SIDEMANTIC_TEST_POSTGRES_DSN": 44, + "PostgreSQL policy execution requires SIDEMANTIC_TEST_POSTGRES_DSN": 36, + "Python joins physical keys; native computed-key identity has its own independent oracle": 1, + "Python reparses completed Redshift aggregates with its generic SQL parser": 3, + "Rust target emission; Python reparses Redshift using its generic parser": 3, + "Set SIDEMANTIC_YARDSTICK_UPSTREAM_TESTS=1 to fetch and replay live upstream Yardstick tests": 2, + "Strict Rust compiler validation contract": 9, + "could not import 'anywidget': No module named 'anywidget'": 8, + "could not import 'textual': No module named 'textual'": 2, + "set SIDEMANTIC_DAX_ONLINE_CONFORMANCE=1 to probe DAX Formatter": 11 + }, + "limitations": "JUnit does not enumerate deselected tests. Historical results do not validate current edits.", + "omissions_by_reason": { + "set SIDEMANTIC_DAX_ONLINE_CONFORMANCE=1 to probe DAX Formatter": { + "category": "external-service", + "type": "pytest.skip", + "tests": [ + "tests.dax.test_online_conformance::test_stable_syntax_matches_dax_formatter[expression-=sumx(filter('Sales','Sales'[Amount]>100),'Sales'[Amount])]", + "tests.dax.test_online_conformance::test_stable_syntax_matches_dax_formatter[query-EVALUATE {(1,2),(3,4)}]", + "tests.dax.test_online_conformance::test_stable_syntax_matches_dax_formatter[query-DEFINE MEASURE 'S'[M]=SUM('S'[A]) VAR threshold=10 EVALUATE ROW(\"m\",[M])]", + "tests.dax.test_online_conformance::test_stable_syntax_matches_dax_formatter[query-DEFINE FUNCTION myUdf=(x:NUMERIC)=>x EVALUATE {myUdf(1)}]", + "tests.dax.test_online_conformance::test_stable_syntax_matches_dax_formatter[query-DEFINE TABLE data=ROW(\"Year\",2000,\"IsTotal\",FALSE()) WITH VISUAL SHAPE AXIS ROWS GROUP [Year] TOTAL [IsTotal] ORDER BY [Year] DENSIFY \"IsDensified\" EVALUATE data]", + "tests.dax.test_online_conformance::test_stable_syntax_is_accepted_by_dax_formatter[=dt\"2020-12-15T12:30:59\"]", + "tests.dax.test_online_conformance::test_stable_syntax_is_accepted_by_dax_formatter[EVALUATE DATATABLE(\"A\", INTEGER, \"B\", STRING, {{1, \"x\"}, {2,}})]", + "tests.dax.test_online_conformance::test_stable_syntax_is_accepted_by_dax_formatter[EVALUATE FILTER('Product', ('Product'[Color], 'Product'[Brand]) IN {(\"Red\", \"Contoso\")})]", + "tests.dax.test_online_conformance::test_stable_syntax_is_accepted_by_dax_formatter[\\n DEFINE\\n TABLE data = ROW(\"Year\", 2000, \"IsTotal\", FALSE())\\n WITH VISUAL SHAPE\\n AXIS ROWS GROUP [Year] TOTAL [IsTotal] ORDER BY [Year]\\n DENSIFY \"IsDensified\"\\n EVALUATE data\\n ]", + "tests.dax.test_online_conformance::test_udf_defaults_are_known_sqlbi_lag", + "tests.dax.test_online_conformance::test_local_semantic_checks_are_stricter_than_formatter" + ] + }, + "PostgreSQL adapter available, tested in integration tests": { + "category": "external-service", + "type": "pytest.skip", + "tests": [ + "tests.db.test_semantic_layer_adapters::test_postgres_url_recognized" + ] + }, + "Set SIDEMANTIC_YARDSTICK_UPSTREAM_TESTS=1 to fetch and replay live upstream Yardstick tests": { + "category": "external-service", + "type": "pytest.skip", + "tests": [ + "tests.queries.test_yardstick_measures_replay::test_yardstick_upstream_create_view_definitions", + "tests.queries.test_yardstick_measures_replay::test_yardstick_upstream_sql_replay" + ] + }, + "Python reparses completed Redshift aggregates with its generic SQL parser": { + "category": "real-gap", + "type": "pytest.skip", + "tests": [ + "tests.semantic_conformance.test_approximate_distinct::test_approximate_dialect_rendering_and_population_results[python-complete-redshift-APPROXIMATE COUNT]", + "tests.semantic_conformance.test_approximate_distinct::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-redshift-APPROXIMATE COUNT]", + "tests.semantic_conformance.test_approximate_distinct::test_approximate_dialect_rendering_and_population_results[python-nested_complete-redshift-APPROXIMATE COUNT]" + ] + }, + "Rust target emission; Python reparses Redshift using its generic parser": { + "category": "real-gap", + "type": "pytest.skip", + "tests": [ + "tests.semantic_conformance.test_approximate_distinct::test_redshift_nested_approximate_expressions_use_independent_parser[python-ROUND(COALESCE(APPROX_COUNT_DISTINCT(user_id), 0), 0)]", + "tests.semantic_conformance.test_approximate_distinct::test_redshift_nested_approximate_expressions_use_independent_parser[python-GREATEST(APPROX_COUNT_DISTINCT(user_id), 0)]", + "tests.semantic_conformance.test_approximate_distinct::test_redshift_nested_approximate_expressions_use_independent_parser[python-NULLIF(APPROX_COUNT_DISTINCT(user_id), 0)]" + ] + }, + "PostgreSQL execution requires SIDEMANTIC_TEST_POSTGRES_DSN": { + "category": "external-service", + "type": "pytest.skip", + "tests": [ + "tests.semantic_conformance.test_complete_filters_postgres::test_complete_filters_preserve_identifier_identity[SUM(orders.Amount)-orders.Amount > 0-5]", + "tests.semantic_conformance.test_complete_filters_postgres::test_complete_filters_preserve_identifier_identity[SUM(orders.\"Amount\")-orders.\"Amount\" > 0-30]", + "tests.semantic_conformance.test_complete_filters_postgres::test_complete_filters_preserve_identifier_identity[AVG(orders.Amount)-orders.Amount > 0-2.5]", + "tests.semantic_conformance.test_complete_filters_postgres::test_complete_filters_preserve_identifier_identity[AVG(orders.\"Amount\")-orders.\"Amount\" > 0-15]", + "tests.semantic_conformance.test_complete_filters_postgres::test_complete_filters_preserve_identifier_identity[COUNT(DISTINCT orders.\"Amount\")-orders.\"Amount\" > 0-2]", + "tests.semantic_conformance.test_complete_filters_postgres::test_complete_filters_preserve_identifier_identity[COUNT(DISTINCT orders.Amount)-orders.Amount > 0-2]", + "tests.semantic_conformance.test_complete_filters_postgres::test_complete_filters_preserve_identifier_identity[SUM(orders.Amount)-orders.Amount > 0 AND orders.\"Amount\" = 10 AND orders.label = 'orders.Amount'-2]", + "tests.semantic_conformance.test_complete_filters_postgres::test_postgres_filtered_float_fanout_average_preserves_values[none]", + "tests.semantic_conformance.test_complete_filters_postgres::test_postgres_filtered_float_fanout_average_preserves_values[average]", + "tests.semantic_conformance.test_complete_filters_postgres::test_postgres_filtered_float_fanout_average_preserves_values[sum]", + "tests.semantic_conformance.test_complete_filters_postgres::test_postgres_filtered_complete_row_count[grouped]", + "tests.semantic_conformance.test_complete_filters_postgres::test_postgres_filtered_complete_row_count[no_matches]", + "tests.semantic_conformance.test_complete_filters_postgres::test_postgres_filtered_complete_row_count[empty]", + "tests.semantic_conformance.test_complete_filters_postgres::test_postgres_filtered_owned_count_family[grouped-model]", + "tests.semantic_conformance.test_complete_filters_postgres::test_postgres_filtered_owned_count_family[grouped-graph]", + "tests.semantic_conformance.test_complete_filters_postgres::test_postgres_filtered_owned_count_family[empty-model]", + "tests.semantic_conformance.test_complete_filters_postgres::test_postgres_filtered_owned_count_family[empty-graph]", + "tests.semantic_conformance.test_complete_filters_postgres::test_postgres_filtered_owned_count_family[no_matches-model]", + "tests.semantic_conformance.test_complete_filters_postgres::test_postgres_filtered_owned_count_family[no_matches-graph]", + "tests.semantic_conformance.test_complete_filters_postgres::test_postgres_filtered_owned_count_family[fanout-model]", + "tests.semantic_conformance.test_complete_filters_postgres::test_postgres_filtered_owned_count_family[fanout-graph]", + "tests.semantic_conformance.test_filtered_row_expressions::test_postgres_filtered_row_expression_oracles[False-price * qty - COALESCE(rebate, 0)-expected0-model]", + "tests.semantic_conformance.test_filtered_row_expressions::test_postgres_filtered_row_expression_oracles[False-price * qty - COALESCE(rebate, 0)-expected0-graph]", + "tests.semantic_conformance.test_filtered_row_expressions::test_postgres_filtered_row_expression_oracles[False-COALESCE(price * qty, 7)-expected1-model]", + "tests.semantic_conformance.test_filtered_row_expressions::test_postgres_filtered_row_expression_oracles[False-COALESCE(price * qty, 7)-expected1-graph]", + "tests.semantic_conformance.test_filtered_row_expressions::test_postgres_filtered_row_expression_oracles[False-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2-model]", + "tests.semantic_conformance.test_filtered_row_expressions::test_postgres_filtered_row_expression_oracles[False-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2-graph]", + "tests.semantic_conformance.test_filtered_row_expressions::test_postgres_filtered_row_expression_oracles[True-price * qty - COALESCE(rebate, 0)-expected0-model]", + "tests.semantic_conformance.test_filtered_row_expressions::test_postgres_filtered_row_expression_oracles[True-price * qty - COALESCE(rebate, 0)-expected0-graph]", + "tests.semantic_conformance.test_filtered_row_expressions::test_postgres_filtered_row_expression_oracles[True-COALESCE(price * qty, 7)-expected1-model]", + "tests.semantic_conformance.test_filtered_row_expressions::test_postgres_filtered_row_expression_oracles[True-COALESCE(price * qty, 7)-expected1-graph]", + "tests.semantic_conformance.test_filtered_row_expressions::test_postgres_filtered_row_expression_oracles[True-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2-model]", + "tests.semantic_conformance.test_filtered_row_expressions::test_postgres_filtered_row_expression_oracles[True-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2-graph]", + "tests.semantic_conformance.test_rollup_reconstruction::test_postgres_rollup_reconstruction_executes[direct]", + "tests.semantic_conformance.test_rollup_reconstruction::test_postgres_rollup_reconstruction_executes[join]", + "tests.semantic_conformance.test_rollup_reconstruction::test_postgres_rollup_reconstruction_executes[lambda]", + "tests.semantic_conformance.test_selected_table_calculations::test_postgres_calculation_results_match_processor[python-population0]", + "tests.semantic_conformance.test_selected_table_calculations::test_postgres_calculation_results_match_processor[python-population1]", + "tests.semantic_conformance.test_selected_table_calculations::test_postgres_calculation_results_match_processor[python-population2]", + "tests.semantic_conformance.test_selected_table_calculations::test_postgres_calculation_results_match_processor[python-population3]", + "tests.semantic_conformance.test_selected_table_calculations::test_postgres_calculation_results_match_processor[rust-population0]", + "tests.semantic_conformance.test_selected_table_calculations::test_postgres_calculation_results_match_processor[rust-population1]", + "tests.semantic_conformance.test_selected_table_calculations::test_postgres_calculation_results_match_processor[rust-population2]", + "tests.semantic_conformance.test_selected_table_calculations::test_postgres_calculation_results_match_processor[rust-population3]" + ] + }, + "Native boundary syntax contract; target-dialect result oracle is shared above": { + "category": "intentional-Python-only", + "type": "pytest.skip", + "tests": [ + "tests.semantic_conformance.test_dialect_boundary::test_native_declared_graph_and_query_syntax[python-bigquery-IFNULL(`amount`, 0)-`orders`.`tenant` = 1-`orders`.`label` DESC NULLS LAST]", + "tests.semantic_conformance.test_dialect_boundary::test_native_declared_graph_and_query_syntax[python-mysql-IFNULL(`amount`, 0)-`orders`.`tenant` = 1-`orders`.`label` DESC]", + "tests.semantic_conformance.test_dialect_boundary::test_native_declared_graph_and_query_syntax[python-tsql-ISNULL([amount], 0)-[orders].[tenant] = 1-[orders].[label] DESC]", + "tests.semantic_conformance.test_dialect_boundary::test_native_declared_graph_and_query_syntax[python-snowflake-COALESCE(\"amount\", 0)-\"orders\".\"tenant\" = 1-\"orders\".\"label\" DESC NULLS LAST]", + "tests.semantic_conformance.test_dialect_boundary::test_native_declared_graph_and_query_syntax[python-postgres-COALESCE(\"amount\", 0)-\"orders\".\"tenant\" = 1-\"orders\".\"label\" DESC NULLS LAST]" + ] + }, + "Native rewrite boundary contract": { + "category": "intentional-Python-only", + "type": "pytest.skip", + "tests": [ + "tests.semantic_conformance.test_dialect_boundary::test_native_rewrite_syntax_and_policy_context[python-bigquery-`]", + "tests.semantic_conformance.test_dialect_boundary::test_native_rewrite_syntax_and_policy_context[python-mysql-`]", + "tests.semantic_conformance.test_dialect_boundary::test_native_rewrite_syntax_and_policy_context[python-postgres-\"]" + ] + }, + "Native input validation contract": { + "category": "intentional-Python-only", + "type": "pytest.skip", + "tests": [ + "tests.semantic_conformance.test_dialect_boundary::test_native_fragment_framing_and_source_snapshot[python]" + ] + }, + "Native source-dialect literal contract": { + "category": "intentional-Python-only", + "type": "pytest.skip", + "tests": [ + "tests.semantic_conformance.test_dialect_boundary::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\b-mysql]", + "tests.semantic_conformance.test_dialect_boundary::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\b-bigquery]", + "tests.semantic_conformance.test_dialect_boundary::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\b-snowflake]", + "tests.semantic_conformance.test_dialect_boundary::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\b-spark]", + "tests.semantic_conformance.test_dialect_boundary::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\' OR 1=1 ---mysql]", + "tests.semantic_conformance.test_dialect_boundary::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\' OR 1=1 ---bigquery]", + "tests.semantic_conformance.test_dialect_boundary::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\' OR 1=1 ---snowflake]", + "tests.semantic_conformance.test_dialect_boundary::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\' OR 1=1 ---spark]", + "tests.semantic_conformance.test_dialect_boundary::test_source_dialect_preserves_typed_policy_and_parameter_values[python-O'Brien-mysql]", + "tests.semantic_conformance.test_dialect_boundary::test_source_dialect_preserves_typed_policy_and_parameter_values[python-O'Brien-bigquery]", + "tests.semantic_conformance.test_dialect_boundary::test_source_dialect_preserves_typed_policy_and_parameter_values[python-O'Brien-snowflake]", + "tests.semantic_conformance.test_dialect_boundary::test_source_dialect_preserves_typed_policy_and_parameter_values[python-O'Brien-spark]" + ] + }, + "PostgreSQL policy execution requires SIDEMANTIC_TEST_POSTGRES_DSN": { + "category": "external-service", + "type": "pytest.skip", + "tests": [ + "tests.semantic_conformance.test_postgres_policies::test_postgres_preserves_typed_policy_literals_and_exact_population[alice-True-10-compile]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_preserves_typed_policy_literals_and_exact_population[alice-True-10-rewrite]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_preserves_typed_policy_literals_and_exact_population[O'Brien-True-7-compile]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_preserves_typed_policy_literals_and_exact_population[O'Brien-True-7-rewrite]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_preserves_typed_policy_literals_and_exact_population[x' OR '1'='1-True-11-compile]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_preserves_typed_policy_literals_and_exact_population[x' OR '1'='1-True-11-rewrite]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_preserves_typed_policy_literals_and_exact_population[back\\\\slash' OR TRUE ---True-13-compile]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_preserves_typed_policy_literals_and_exact_population[back\\\\slash' OR TRUE ---True-13-rewrite]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_preserves_typed_policy_literals_and_exact_population[None-False-17-compile]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_preserves_typed_policy_literals_and_exact_population[None-False-17-rewrite]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_policy_denial_produces_no_sql[None-compile]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_policy_denial_produces_no_sql[None-rewrite]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_policy_denial_produces_no_sql[attributes1-compile]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_policy_denial_produces_no_sql[attributes1-rewrite]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_policy_denial_produces_no_sql[attributes2-compile]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_policy_denial_produces_no_sql[attributes2-rewrite]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_policy_denial_produces_no_sql[attributes3-compile]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_policy_denial_produces_no_sql[attributes3-rewrite]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_visibility_is_enforced_only_when_requested[compile]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_visibility_is_enforced_only_when_requested[rewrite]", + "tests.semantic_conformance.test_postgres_policies::test_other_policy_output_dialects_preserve_population[compile]", + "tests.semantic_conformance.test_postgres_policies::test_other_policy_output_dialects_preserve_population[rewrite]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_translates_year_in_policy_and_invariant[compile]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_translates_year_in_policy_and_invariant[rewrite]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_date_diff_policy_is_not_claimed_equivalent[compile]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_date_diff_policy_is_not_claimed_equivalent[rewrite]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_public_paths_reach_rust_with_transport_syntax[compile]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_public_paths_reach_rust_with_transport_syntax[query]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_public_paths_reach_rust_with_transport_syntax[sql]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_public_paths_reach_rust_with_transport_syntax[rewriter]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_public_denial_does_not_fall_back[compile]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_public_denial_does_not_fall_back[sql]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_transport_normalizes_declared_graph_dialect", + "tests.semantic_conformance.test_postgres_policies::test_explicit_postgres_graph_input_preserves_policy_results", + "tests.semantic_conformance.test_postgres_policies::test_postgres_public_null_ordering_matches_adapter[query]", + "tests.semantic_conformance.test_postgres_policies::test_postgres_public_null_ordering_matches_adapter[sql]" + ] + }, + "Native subquery scope regression": { + "category": "intentional-Python-only", + "type": "pytest.skip", + "tests": [ + "tests.semantic_conformance.test_rewriter_ci_regressions::test_subquery_local_alias_can_shadow_outer_semantic_source[python]" + ] + }, + "Native output-name collision contract": { + "category": "intentional-Python-only", + "type": "pytest.skip", + "tests": [ + "tests.semantic_conformance.test_rollup_reconstruction::test_colliding_join_dimension_outputs_keep_raw_contract[python]" + ] + }, + "Native effective-anchor routing regression": { + "category": "intentional-Python-only", + "type": "pytest.skip", + "tests": [ + "tests.semantic_conformance.test_rollup_reconstruction::test_join_rollup_preserves_local_and_role_source_population[python-local-first]", + "tests.semantic_conformance.test_rollup_reconstruction::test_join_rollup_preserves_local_and_role_source_population[python-role-owner]" + ] + }, + "Python joins physical keys; native computed-key identity has its own independent oracle": { + "category": "real-gap", + "type": "pytest.skip", + "tests": [ + "tests.semantic_conformance.test_time_key_projection::test_time_identity_stays_unbucketed_for_join_and_fanout[python]" + ] + }, + "Strict Rust compiler validation contract": { + "category": "intentional-Python-only", + "type": "pytest.skip", + "tests": [ + "tests.semantic_conformance.test_window_output_parity::test_window_dependency_cycles_return_validation_errors[python-references0]", + "tests.semantic_conformance.test_window_output_parity::test_window_dependency_cycles_return_validation_errors[python-references1]", + "tests.semantic_conformance.test_window_output_parity::test_quoted_output_expression_is_generated_for_bigquery[python]", + "tests.semantic_conformance.test_window_output_parity::test_graph_window_rejects_missing_or_ambiguous_period_metric[python-missing]", + "tests.semantic_conformance.test_window_output_parity::test_graph_window_rejects_missing_or_ambiguous_period_metric[python-daily_amount]", + "tests.semantic_conformance.test_window_output_parity::test_scalar_window_expression_is_typed_unsupported[python-base.daily_amount]", + "tests.semantic_conformance.test_window_output_parity::test_scalar_window_expression_is_typed_unsupported[python-base.daily_amount + 1]", + "tests.semantic_conformance.test_window_output_parity::test_scalar_window_expression_is_typed_unsupported[python-SUM(base.daily_amount) + 1]", + "tests.semantic_conformance.test_window_output_parity::test_scalar_window_expression_is_typed_unsupported[python-ABS(base.daily_amount)]" + ] + }, + "Existing native direct-call batch contract; public Python rejects strict batches": { + "category": "intentional-Python-only", + "type": "pytest.skip", + "tests": [ + "tests.semantic_conformance.test_yardstick_source_dialects::test_native_ordinary_statement_batches_retain_both_results[python-bigquery-`]", + "tests.semantic_conformance.test_yardstick_source_dialects::test_native_ordinary_statement_batches_retain_both_results[python-snowflake-\"]" + ] + }, + "could not import 'textual': No module named 'textual'": { + "category": "optional-host", + "type": "pytest.skip", + "tests": [ + "tests.test_adapter_integration.TestWorkbenchAdapterIntegration::test_workbench_command_wiring", + "tests.test_cli_commands::test_workbench_calls_runner" + ] + }, + "could not import 'anywidget': No module named 'anywidget'": { + "category": "optional-host", + "type": "pytest.skip", + "tests": [ + "tests.test_adapter_integration.TestWidgetAdapterIntegration::test_widget_generator_uses_layer_dialect", + "tests.test_adapter_integration.TestWidgetAdapterIntegration::test_widget_date_range_query_handles_qualified_table", + "tests.test_adapter_integration.TestWidgetAdapterIntegration::test_widget_sets_time_series_column_in_config", + "tests.test_adapter_integration.TestWidgetAdapterIntegration::test_widget_binary_transport_populates_binary_traits", + "tests.test_adapter_integration.TestWidgetAdapterIntegration::test_widget_uses_adapter_in_layer_mode", + "tests.test_adapter_integration.TestWidgetAdapterIntegration::test_widget_execute_routes_through_adapter", + "tests.test_adapter_integration.TestWidgetAdapterIntegration::test_widget_dataframe_mode_uses_raw_connection", + "tests.test_adapter_integration.TestWidgetAdapterIntegration::test_widget_execute_arrow_uses_fetch_record_batch" + ] + } + } + }, + "affected_scopes": { + "scope-1": { + "path": "tests/adapters/bsl/test_parsing.py", + "declared_tests": [ + "TestBSLCurrentSyntaxSupport::test_deferred_calculated_measure_compiles" + ], + "collected_tests": [ + "tests/adapters/bsl/test_parsing.py::TestBSLCurrentSyntaxSupport::test_deferred_calculated_measure_compiles" + ] + }, + "scope-2": { + "path": "tests/adapters/bsl/test_parsing.py", + "declared_tests": [ + "TestBSLCurrentSyntaxSupport::test_all_calculated_measure_compiles_to_window_total" + ], + "collected_tests": [ + "tests/adapters/bsl/test_parsing.py::TestBSLCurrentSyntaxSupport::test_all_calculated_measure_compiles_to_window_total" + ] + }, + "scope-3": { + "path": "tests/adapters/bsl/test_parsing.py", + "declared_tests": [ + "TestBSLCurrentSyntaxSupport::test_qualified_calculated_measure_compiles_joined_measure" + ], + "collected_tests": [ + "tests/adapters/bsl/test_parsing.py::TestBSLCurrentSyntaxSupport::test_qualified_calculated_measure_compiles_joined_measure" + ] + }, + "scope-4": { + "path": "tests/adapters/bsl/test_parsing.py", + "declared_tests": [ + "TestBSLCurrentSyntaxSupport::test_join_aliases_self_join_and_how_roundtrip" + ], + "collected_tests": [ + "tests/adapters/bsl/test_parsing.py::TestBSLCurrentSyntaxSupport::test_join_aliases_self_join_and_how_roundtrip" + ] + }, + "scope-5": { + "path": "tests/adapters/bsl/test_parsing.py", + "declared_tests": [ + "TestBSLCurrentSyntaxSupport::test_reused_join_aliases_scope_to_source_model" + ], + "collected_tests": [ + "tests/adapters/bsl/test_parsing.py::TestBSLCurrentSyntaxSupport::test_reused_join_aliases_scope_to_source_model" + ] + }, + "scope-6": { + "path": "tests/adapters/bsl/test_parsing.py", + "declared_tests": [ + "TestBSLCurrentSyntaxSupport::test_cross_join_compiles" + ], + "collected_tests": [ + "tests/adapters/bsl/test_parsing.py::TestBSLCurrentSyntaxSupport::test_cross_join_compiles" + ] + }, + "scope-7": { + "path": "tests/adapters/cube/test_fixtures.py", + "declared_tests": [ + "TestTesseractFeatures::test_aggregate_complete_measures_queryable" + ], + "collected_tests": [ + "tests/adapters/cube/test_fixtures.py::TestTesseractFeatures::test_aggregate_complete_measures_queryable" + ] + }, + "scope-8": { + "path": "tests/adapters/cube/test_fixtures.py", + "declared_tests": [ + "TestTesseractFeatures::test_plain_non_numeric_measures_queryable" + ], + "collected_tests": [ + "tests/adapters/cube/test_fixtures.py::TestTesseractFeatures::test_plain_non_numeric_measures_queryable" + ] + }, + "scope-9": { + "path": "tests/adapters/cube/test_fixtures.py", + "declared_tests": [ + "TestTesseractFeatures::test_complete_measure_preserves_raw_timestamp" + ], + "collected_tests": [ + "tests/adapters/cube/test_fixtures.py::TestTesseractFeatures::test_complete_measure_preserves_raw_timestamp" + ] + }, + "scope-10": { + "path": "tests/adapters/cube/test_fixtures.py", + "declared_tests": [ + "TestTesseractFeatures::test_complete_measure_applies_filters" + ], + "collected_tests": [ + "tests/adapters/cube/test_fixtures.py::TestTesseractFeatures::test_complete_measure_applies_filters" + ] + }, + "scope-11": { + "path": "tests/adapters/cube/test_fixtures.py", + "declared_tests": [ + "TestTesseractFeatures::test_plain_complete_measure_grouped_by_other_dimension" + ], + "collected_tests": [ + "tests/adapters/cube/test_fixtures.py::TestTesseractFeatures::test_plain_complete_measure_grouped_by_other_dimension" + ] + }, + "scope-12": { + "path": "tests/adapters/metricflow/test_parsing.py", + "declared_tests": [ + "test_metricflow_adapter_join_discovery", + "test_metricflow_derived_non_offset_aliases_queryable", + "test_metricflow_disabled_model_skips_inline_metrics", + "test_metricflow_inline_constant_count_anchored_to_model", + "test_metricflow_inline_exprless_non_count_uses_metric_column", + "test_metricflow_keyless_inline_count_planner_contract", + "test_metricflow_latest_spec_inline_metric_queryable_alone" + ], + "collected_tests": [ + "tests/adapters/metricflow/test_parsing.py::test_metricflow_adapter_join_discovery", + "tests/adapters/metricflow/test_parsing.py::test_metricflow_latest_spec_inline_metric_queryable_alone", + "tests/adapters/metricflow/test_parsing.py::test_metricflow_inline_constant_count_anchored_to_model", + "tests/adapters/metricflow/test_parsing.py::test_metricflow_keyless_inline_count_planner_contract", + "tests/adapters/metricflow/test_parsing.py::test_metricflow_inline_exprless_non_count_uses_metric_column", + "tests/adapters/metricflow/test_parsing.py::test_metricflow_derived_non_offset_aliases_queryable", + "tests/adapters/metricflow/test_parsing.py::test_metricflow_disabled_model_skips_inline_metrics" + ] + }, + "scope-13": { + "path": "tests/adapters/osi/conftest.py", + "declared_tests": [ + "tests/adapters/osi/test_ossie_adapter.py::test_historical_osi_class_spelling_routes_to_canonical_adapter", + "tests/adapters/osi/test_ossie_adapter.py::test_parse_document_returns_preserved_source_and_scoped_catalog", + "tests/adapters/osi/test_ossie_adapter.py::test_legacy_parse_surface_requires_scope_selection_when_ambiguous", + "tests/adapters/osi/test_ossie_adapter.py::test_directory_scopes_are_qualified_and_generated_directories_are_skipped", + "tests/adapters/osi/test_ossie_adapter.py::test_validation_failure_is_not_silently_lowered_through_legacy_surface", + "tests/adapters/osi/test_ossie_adapter.py::test_ontology_only_document_reports_no_executable_scope", + "tests/adapters/osi/test_ossie_adapter.py::test_ontology_document_canonical_serialization_preserves_ontology_data", + "tests/adapters/osi/test_ossie_adapter.py::test_ontology_document_exact_source_round_trip_reuses_original_bytes", + "tests/adapters/osi/test_ossie_adapter.py::test_export_document_reuses_exact_validated_source_bytes", + "tests/adapters/osi/test_ossie_adapter.py::test_dbt_alias_profile_survives_parse_lower_and_document_export", + "tests/adapters/osi/test_ossie_adapter.py::test_graph_export_requires_explicit_scope_and_dialect", + "tests/adapters/osi/test_ossie_adapter.py::test_graph_export_refuses_unidentified_relationships", + "tests/adapters/osi/test_ossie_adapter.py::test_filtered_metric_export_roundtrip_executes", + "tests/adapters/osi/test_ossie_adapter.py::test_native_metric_portable_export_refusal_preserves_existing_output", + "tests/adapters/osi/test_parsing.py::test_import_simple_osi_example", + "tests/adapters/osi/test_parsing.py::test_import_current_version_and_semantic_model_metadata", + "tests/adapters/osi/test_parsing.py::test_import_ontology_mapping_semantic_model", + "tests/adapters/osi/test_parsing.py::test_import_ecommerce_osi_example", + "tests/adapters/osi/test_parsing.py::test_import_osi_with_metrics", + "tests/adapters/osi/test_parsing.py::test_import_kitchen_sink", + "tests/adapters/osi/test_parsing.py::test_osi_dimension_type_mapping", + "tests/adapters/osi/test_parsing.py::test_osi_multi_dialect_prefers_ansi", + "tests/adapters/osi/test_parsing.py::test_osi_relationship_parsing", + "tests/adapters/osi/test_parsing.py::test_osi_relationship_metadata_roundtrip", + "tests/adapters/osi/test_parsing.py::test_osi_multiple_relationships", + "tests/adapters/osi/test_parsing.py::test_osi_metric_aggregation_detection", + "tests/adapters/osi/test_parsing.py::test_osi_complex_metric_expressions", + "tests/adapters/osi/test_parsing.py::test_osi_parse_empty_file", + "tests/adapters/osi/test_parsing.py::test_osi_parse_nonexistent_file", + "tests/adapters/osi/test_parsing.py::test_osi_parse_nonexistent_directory", + "tests/adapters/osi/test_parsing.py::test_osi_dataset_without_name", + "tests/adapters/osi/test_parsing.py::test_osi_field_without_name", + "tests/adapters/osi/test_parsing.py::test_osi_metric_without_expression", + "tests/adapters/osi/test_parsing.py::test_osi_export_simple_model", + "tests/adapters/osi/test_parsing.py::test_osi_export_with_relationships", + "tests/adapters/osi/test_parsing.py::test_osi_roundtrip", + "tests/adapters/osi/test_parsing.py::test_osi_directory_parsing", + "tests/adapters/osi/test_parsing.py::test_import_composite_primary_key", + "tests/adapters/osi/test_parsing.py::test_import_unique_keys", + "tests/adapters/osi/test_parsing.py::test_import_ai_context", + "tests/adapters/osi/test_parsing.py::test_import_multi_column_relationship", + "tests/adapters/osi/test_parsing.py::test_export_multi_dialect", + "tests/adapters/osi/test_parsing.py::test_export_composite_primary_key", + "tests/adapters/osi/test_parsing.py::test_export_unique_keys", + "tests/adapters/osi/test_parsing.py::test_export_meta_as_ai_context", + "tests/adapters/osi/test_parsing.py::test_roundtrip_preserves_meta", + "tests/adapters/osi/test_parsing.py::test_export_multi_column_relationship", + "tests/adapters/osi/test_parsing.py::test_export_empty_dialects_list", + "tests/adapters/osi/test_parsing.py::test_export_unknown_dialect_raises", + "tests/adapters/osi/test_parsing.py::test_import_empty_ai_context", + "tests/adapters/osi/test_parsing.py::test_import_single_column_primary_key_as_string", + "tests/adapters/osi/test_parsing.py::test_sqlglot_transpilation_actually_transpiles", + "tests/adapters/osi/test_parsing.py::test_nested_custom_extensions", + "tests/adapters/osi/test_parsing.py::test_import_released_json_fixture", + "tests/adapters/osi/test_parsing.py::test_export_released_json_profile", + "tests/adapters/osi/test_parsing.py::test_export_json_inferred_from_extension", + "tests/adapters/osi/test_parsing.py::test_export_released_json_roundtrip", + "tests/adapters/osi/test_parsing.py::test_export_explicit_json_version", + "tests/adapters/osi/test_parsing.py::test_export_json_rejects_dev_version", + "tests/adapters/osi/test_parsing.py::test_export_released_json_coerces_unsupported_extension_vendor", + "tests/adapters/osi/test_parsing.py::test_released_json_extension_roundtrip_restores_original", + "tests/adapters/osi/test_parsing.py::test_released_json_named_vendor_roundtrip_restores_original", + "tests/adapters/osi/test_parsing.py::test_export_released_json_preserves_dbt_extension_vendor", + "tests/adapters/osi/test_parsing.py::test_export_yaml_preserves_unsupported_extension_vendor", + "tests/adapters/osi/test_parsing.py::test_export_yaml_still_default", + "tests/adapters/osi/test_parsing.py::test_export_unknown_format_raises", + "tests/adapters/osi/test_parsing.py::test_parse_directory_with_json_and_yaml", + "tests/adapters/osi/test_parsing.py::test_parse_directory_skips_generated_osi_artifacts", + "tests/adapters/osi/test_parsing.py::test_parse_directory_skips_non_osi_json", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_composite_primary_key", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_unique_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_single_column_primary_key", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_store_sales_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_customer_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_date_dim_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_store_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_item_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_time_dimension_date_dim", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_default_time_dimension", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_computed_field_multi_dialect", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_computed_field_label", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationships_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationship_targets", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationship_foreign_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationship_primary_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationship_type", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_total_sales", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_total_profit", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_customer_lifetime_value", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_store_productivity", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_ai_context_on_dataset", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_ai_context_on_field", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_ai_context_on_metric", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_ai_context_on_multiple_datasets", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_model_level_custom_extensions", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_dimension_tables_have_no_relationships", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_count", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_composite_primary_key", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_multiple_unique_keys", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_shipments_field_count", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_multi_dialect_computed_field", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_time_dimensions", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_default_time_dimension_is_first", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_relationships_count", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_relationship_targets", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_total_shipment_cost", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_with_count_distinct", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_ratio_with_nullif", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_multi_dialect", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_ai_context_on_shipments", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_ai_context_on_field", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_ai_context_on_metric", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_dimension_tables_no_relationships", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_warehouse_dimensions", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_supplier_dimensions", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_model_level_custom_extensions", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_metric_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_composite_primary_key", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_unique_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_single_column_pks", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_store_sales_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_date_dim_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_customer_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_item_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_store_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_relationships_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_relationship_targets", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_relationship_foreign_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_relationship_primary_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_all_relationships_many_to_one", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_dimension_tables_have_no_relationships", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_time_dimension_d_date", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_time_dimensions_d_year_quarter_month", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_computed_field_customer_full_name", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_ai_context_on_datasets", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_ai_context_store_sales_synonyms", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_ai_context_on_fields", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_ai_context_on_metrics", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_metric_total_sales", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_metric_customer_lifetime_value", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_metric_store_productivity", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_custom_extensions_salesforce_dbt", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_count", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_nonstandard_relationships_skipped", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_actor_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_actor_birth_year_is_time", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_movie_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_movie_year_is_time", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_director_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_genre_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_user_preference_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_primary_keys", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_ai_context_on_all_datasets", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_actor_synonyms_extensive", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_genre_synonyms_include_genre_names", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_field_level_ai_context", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_movies_watched", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_favorite_count", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_genre_diversity", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_ai_context", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_no_metrics", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_nonstandard_relationships_skipped", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_single_field_datasets", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_user_preference_has_two_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_primary_keys", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_ai_context_on_all_datasets", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_field_ai_context", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_concept_dataset", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_person_dataset", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_event_dataset", + "tests/adapters/osi/test_query_execution.py::test_osi_ecommerce_metrics_execute", + "tests/adapters/osi/test_query_execution.py::test_osi_adtech_example_cross_model_metrics_execute", + "tests/adapters/osi/test_rust_ossie_forward_parity.py::test_rust_and_python_match_shared_fixture_outcomes", + "tests/adapters/osi/test_rust_ossie_forward_parity.py::test_selected_scope_shape_preserves_parity_fields_and_target_selection", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_resolves_model_inheritance" + ], + "collected_tests": [ + "tests/adapters/osi/test_ossie_adapter.py::test_historical_osi_class_spelling_routes_to_canonical_adapter", + "tests/adapters/osi/test_ossie_adapter.py::test_parse_document_returns_preserved_source_and_scoped_catalog", + "tests/adapters/osi/test_ossie_adapter.py::test_legacy_parse_surface_requires_scope_selection_when_ambiguous", + "tests/adapters/osi/test_ossie_adapter.py::test_directory_scopes_are_qualified_and_generated_directories_are_skipped", + "tests/adapters/osi/test_ossie_adapter.py::test_validation_failure_is_not_silently_lowered_through_legacy_surface", + "tests/adapters/osi/test_ossie_adapter.py::test_ontology_only_document_reports_no_executable_scope", + "tests/adapters/osi/test_ossie_adapter.py::test_ontology_document_canonical_serialization_preserves_ontology_data", + "tests/adapters/osi/test_ossie_adapter.py::test_ontology_document_exact_source_round_trip_reuses_original_bytes", + "tests/adapters/osi/test_ossie_adapter.py::test_export_document_reuses_exact_validated_source_bytes", + "tests/adapters/osi/test_ossie_adapter.py::test_dbt_alias_profile_survives_parse_lower_and_document_export", + "tests/adapters/osi/test_ossie_adapter.py::test_graph_export_requires_explicit_scope_and_dialect", + "tests/adapters/osi/test_ossie_adapter.py::test_graph_export_refuses_unidentified_relationships", + "tests/adapters/osi/test_ossie_adapter.py::test_filtered_metric_export_roundtrip_executes[OssieAdapter]", + "tests/adapters/osi/test_ossie_adapter.py::test_filtered_metric_export_roundtrip_executes[OSIAdapter]", + "tests/adapters/osi/test_ossie_adapter.py::test_native_metric_portable_export_refusal_preserves_existing_output[OssieAdapter]", + "tests/adapters/osi/test_ossie_adapter.py::test_native_metric_portable_export_refusal_preserves_existing_output[OSIAdapter]", + "tests/adapters/osi/test_parsing.py::test_import_simple_osi_example", + "tests/adapters/osi/test_parsing.py::test_import_current_version_and_semantic_model_metadata", + "tests/adapters/osi/test_parsing.py::test_import_ontology_mapping_semantic_model", + "tests/adapters/osi/test_parsing.py::test_import_ecommerce_osi_example", + "tests/adapters/osi/test_parsing.py::test_import_osi_with_metrics", + "tests/adapters/osi/test_parsing.py::test_import_kitchen_sink", + "tests/adapters/osi/test_parsing.py::test_osi_dimension_type_mapping", + "tests/adapters/osi/test_parsing.py::test_osi_multi_dialect_prefers_ansi", + "tests/adapters/osi/test_parsing.py::test_osi_relationship_parsing", + "tests/adapters/osi/test_parsing.py::test_osi_relationship_metadata_roundtrip", + "tests/adapters/osi/test_parsing.py::test_osi_multiple_relationships", + "tests/adapters/osi/test_parsing.py::test_osi_metric_aggregation_detection", + "tests/adapters/osi/test_parsing.py::test_osi_complex_metric_expressions", + "tests/adapters/osi/test_parsing.py::test_osi_parse_empty_file", + "tests/adapters/osi/test_parsing.py::test_osi_parse_nonexistent_file", + "tests/adapters/osi/test_parsing.py::test_osi_parse_nonexistent_directory", + "tests/adapters/osi/test_parsing.py::test_osi_dataset_without_name", + "tests/adapters/osi/test_parsing.py::test_osi_field_without_name", + "tests/adapters/osi/test_parsing.py::test_osi_metric_without_expression", + "tests/adapters/osi/test_parsing.py::test_osi_export_simple_model", + "tests/adapters/osi/test_parsing.py::test_osi_export_with_relationships", + "tests/adapters/osi/test_parsing.py::test_osi_roundtrip", + "tests/adapters/osi/test_parsing.py::test_osi_directory_parsing", + "tests/adapters/osi/test_parsing.py::test_import_composite_primary_key", + "tests/adapters/osi/test_parsing.py::test_import_unique_keys", + "tests/adapters/osi/test_parsing.py::test_import_ai_context", + "tests/adapters/osi/test_parsing.py::test_import_multi_column_relationship", + "tests/adapters/osi/test_parsing.py::test_export_multi_dialect", + "tests/adapters/osi/test_parsing.py::test_export_composite_primary_key", + "tests/adapters/osi/test_parsing.py::test_export_unique_keys", + "tests/adapters/osi/test_parsing.py::test_export_meta_as_ai_context", + "tests/adapters/osi/test_parsing.py::test_roundtrip_preserves_meta", + "tests/adapters/osi/test_parsing.py::test_export_multi_column_relationship", + "tests/adapters/osi/test_parsing.py::test_export_empty_dialects_list", + "tests/adapters/osi/test_parsing.py::test_export_unknown_dialect_raises", + "tests/adapters/osi/test_parsing.py::test_import_empty_ai_context", + "tests/adapters/osi/test_parsing.py::test_import_single_column_primary_key_as_string", + "tests/adapters/osi/test_parsing.py::test_sqlglot_transpilation_actually_transpiles", + "tests/adapters/osi/test_parsing.py::test_nested_custom_extensions", + "tests/adapters/osi/test_parsing.py::test_import_released_json_fixture", + "tests/adapters/osi/test_parsing.py::test_export_released_json_profile", + "tests/adapters/osi/test_parsing.py::test_export_json_inferred_from_extension", + "tests/adapters/osi/test_parsing.py::test_export_released_json_roundtrip", + "tests/adapters/osi/test_parsing.py::test_export_explicit_json_version", + "tests/adapters/osi/test_parsing.py::test_export_json_rejects_dev_version", + "tests/adapters/osi/test_parsing.py::test_export_released_json_coerces_unsupported_extension_vendor", + "tests/adapters/osi/test_parsing.py::test_released_json_extension_roundtrip_restores_original", + "tests/adapters/osi/test_parsing.py::test_released_json_named_vendor_roundtrip_restores_original", + "tests/adapters/osi/test_parsing.py::test_export_released_json_preserves_dbt_extension_vendor", + "tests/adapters/osi/test_parsing.py::test_export_yaml_preserves_unsupported_extension_vendor", + "tests/adapters/osi/test_parsing.py::test_export_yaml_still_default", + "tests/adapters/osi/test_parsing.py::test_export_unknown_format_raises", + "tests/adapters/osi/test_parsing.py::test_parse_directory_with_json_and_yaml", + "tests/adapters/osi/test_parsing.py::test_parse_directory_skips_generated_osi_artifacts", + "tests/adapters/osi/test_parsing.py::test_parse_directory_skips_non_osi_json", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_composite_primary_key", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_unique_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_single_column_primary_key", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_store_sales_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_customer_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_date_dim_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_store_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_item_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_time_dimension_date_dim", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_default_time_dimension", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_computed_field_multi_dialect", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_computed_field_label", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationships_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationship_targets", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationship_foreign_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationship_primary_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationship_type", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_total_sales", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_total_profit", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_customer_lifetime_value", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_store_productivity", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_ai_context_on_dataset", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_ai_context_on_field", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_ai_context_on_metric", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_ai_context_on_multiple_datasets", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_model_level_custom_extensions", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_dimension_tables_have_no_relationships", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_count", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_composite_primary_key", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_multiple_unique_keys", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_shipments_field_count", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_multi_dialect_computed_field", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_time_dimensions", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_default_time_dimension_is_first", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_relationships_count", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_relationship_targets", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_total_shipment_cost", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_with_count_distinct", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_ratio_with_nullif", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_multi_dialect", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_ai_context_on_shipments", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_ai_context_on_field", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_ai_context_on_metric", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_dimension_tables_no_relationships", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_warehouse_dimensions", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_supplier_dimensions", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_model_level_custom_extensions", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_metric_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_composite_primary_key", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_unique_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_single_column_pks", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_store_sales_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_date_dim_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_customer_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_item_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_store_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_relationships_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_relationship_targets", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_relationship_foreign_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_relationship_primary_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_all_relationships_many_to_one", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_dimension_tables_have_no_relationships", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_time_dimension_d_date", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_time_dimensions_d_year_quarter_month", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_computed_field_customer_full_name", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_ai_context_on_datasets", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_ai_context_store_sales_synonyms", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_ai_context_on_fields", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_ai_context_on_metrics", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_metric_total_sales", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_metric_customer_lifetime_value", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_metric_store_productivity", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_custom_extensions_salesforce_dbt", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_count", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_nonstandard_relationships_skipped", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_actor_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_actor_birth_year_is_time", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_movie_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_movie_year_is_time", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_director_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_genre_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_user_preference_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_primary_keys", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_ai_context_on_all_datasets", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_actor_synonyms_extensive", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_genre_synonyms_include_genre_names", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_field_level_ai_context", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_movies_watched", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_favorite_count", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_genre_diversity", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_ai_context", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_no_metrics", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_nonstandard_relationships_skipped", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_single_field_datasets", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_user_preference_has_two_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_primary_keys", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_ai_context_on_all_datasets", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_field_ai_context", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_concept_dataset", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_person_dataset", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_event_dataset", + "tests/adapters/osi/test_query_execution.py::test_osi_ecommerce_metrics_execute", + "tests/adapters/osi/test_query_execution.py::test_osi_adtech_example_cross_model_metrics_execute", + "tests/adapters/osi/test_rust_ossie_forward_parity.py::test_rust_and_python_match_shared_fixture_outcomes", + "tests/adapters/osi/test_rust_ossie_forward_parity.py::test_selected_scope_shape_preserves_parity_fields_and_target_selection", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[ecommerce.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[kitchen_sink.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[mdb_member_knowledge.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[mdb_movies.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[simple.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[supply_chain.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[tpcds_osi_official.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[tpcds_retail.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[ecommerce.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[kitchen_sink.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[mdb_member_knowledge.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[mdb_movies.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[simple.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[supply_chain.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[tpcds_osi_official.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[tpcds_retail.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[ecommerce.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[kitchen_sink.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[mdb_member_knowledge.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[mdb_movies.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[simple.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[supply_chain.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[tpcds_osi_official.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[tpcds_retail.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_resolves_model_inheritance" + ] + }, + "scope-14": { + "path": "tests/adapters/osi/test_parsing.py", + "declared_tests": [ + "TestMdbMemberKnowledgeFixture::test_ai_context_on_all_datasets", + "TestMdbMemberKnowledgeFixture::test_concept_dataset", + "TestMdbMemberKnowledgeFixture::test_dataset_count", + "TestMdbMemberKnowledgeFixture::test_event_dataset", + "TestMdbMemberKnowledgeFixture::test_field_ai_context", + "TestMdbMemberKnowledgeFixture::test_no_metrics", + "TestMdbMemberKnowledgeFixture::test_nonstandard_relationships_skipped", + "TestMdbMemberKnowledgeFixture::test_parses_without_errors", + "TestMdbMemberKnowledgeFixture::test_person_dataset", + "TestMdbMemberKnowledgeFixture::test_primary_keys", + "TestMdbMemberKnowledgeFixture::test_single_field_datasets", + "TestMdbMemberKnowledgeFixture::test_source_tables", + "TestMdbMemberKnowledgeFixture::test_user_preference_has_two_fields", + "TestMdbMoviesFixture::test_actor_birth_year_is_time", + "TestMdbMoviesFixture::test_actor_fields", + "TestMdbMoviesFixture::test_actor_synonyms_extensive", + "TestMdbMoviesFixture::test_ai_context_on_all_datasets", + "TestMdbMoviesFixture::test_dataset_count", + "TestMdbMoviesFixture::test_director_fields", + "TestMdbMoviesFixture::test_field_level_ai_context", + "TestMdbMoviesFixture::test_genre_fields", + "TestMdbMoviesFixture::test_genre_synonyms_include_genre_names", + "TestMdbMoviesFixture::test_metric_ai_context", + "TestMdbMoviesFixture::test_metric_count", + "TestMdbMoviesFixture::test_metric_favorite_count", + "TestMdbMoviesFixture::test_metric_genre_diversity", + "TestMdbMoviesFixture::test_metric_movies_watched", + "TestMdbMoviesFixture::test_movie_fields", + "TestMdbMoviesFixture::test_movie_year_is_time", + "TestMdbMoviesFixture::test_nonstandard_relationships_skipped", + "TestMdbMoviesFixture::test_parses_without_errors", + "TestMdbMoviesFixture::test_primary_keys", + "TestMdbMoviesFixture::test_source_tables", + "TestMdbMoviesFixture::test_user_preference_fields", + "TestSupplyChainFixture::test_ai_context_on_field", + "TestSupplyChainFixture::test_ai_context_on_metric", + "TestSupplyChainFixture::test_ai_context_on_shipments", + "TestSupplyChainFixture::test_composite_primary_key", + "TestSupplyChainFixture::test_dataset_count", + "TestSupplyChainFixture::test_default_time_dimension_is_first", + "TestSupplyChainFixture::test_dimension_tables_no_relationships", + "TestSupplyChainFixture::test_metric_count", + "TestSupplyChainFixture::test_metric_multi_dialect", + "TestSupplyChainFixture::test_metric_ratio_with_nullif", + "TestSupplyChainFixture::test_metric_total_shipment_cost", + "TestSupplyChainFixture::test_metric_with_count_distinct", + "TestSupplyChainFixture::test_model_level_custom_extensions", + "TestSupplyChainFixture::test_multi_dialect_computed_field", + "TestSupplyChainFixture::test_multiple_unique_keys", + "TestSupplyChainFixture::test_parses_without_errors", + "TestSupplyChainFixture::test_relationship_targets", + "TestSupplyChainFixture::test_relationships_count", + "TestSupplyChainFixture::test_shipments_field_count", + "TestSupplyChainFixture::test_source_tables", + "TestSupplyChainFixture::test_supplier_dimensions", + "TestSupplyChainFixture::test_time_dimensions", + "TestSupplyChainFixture::test_warehouse_dimensions", + "TestTpcdsOsiOfficialFixture::test_ai_context_on_datasets", + "TestTpcdsOsiOfficialFixture::test_ai_context_on_fields", + "TestTpcdsOsiOfficialFixture::test_ai_context_on_metrics", + "TestTpcdsOsiOfficialFixture::test_ai_context_store_sales_synonyms", + "TestTpcdsOsiOfficialFixture::test_all_relationships_many_to_one", + "TestTpcdsOsiOfficialFixture::test_composite_primary_key", + "TestTpcdsOsiOfficialFixture::test_computed_field_customer_full_name", + "TestTpcdsOsiOfficialFixture::test_custom_extensions_salesforce_dbt", + "TestTpcdsOsiOfficialFixture::test_customer_field_count", + "TestTpcdsOsiOfficialFixture::test_dataset_count", + "TestTpcdsOsiOfficialFixture::test_date_dim_field_count", + "TestTpcdsOsiOfficialFixture::test_dimension_tables_have_no_relationships", + "TestTpcdsOsiOfficialFixture::test_item_field_count", + "TestTpcdsOsiOfficialFixture::test_metric_count", + "TestTpcdsOsiOfficialFixture::test_metric_customer_lifetime_value", + "TestTpcdsOsiOfficialFixture::test_metric_store_productivity", + "TestTpcdsOsiOfficialFixture::test_metric_total_sales", + "TestTpcdsOsiOfficialFixture::test_parses_without_errors", + "TestTpcdsOsiOfficialFixture::test_relationship_foreign_keys", + "TestTpcdsOsiOfficialFixture::test_relationship_primary_keys", + "TestTpcdsOsiOfficialFixture::test_relationship_targets", + "TestTpcdsOsiOfficialFixture::test_relationships_count", + "TestTpcdsOsiOfficialFixture::test_single_column_pks", + "TestTpcdsOsiOfficialFixture::test_source_tables", + "TestTpcdsOsiOfficialFixture::test_store_field_count", + "TestTpcdsOsiOfficialFixture::test_store_sales_field_count", + "TestTpcdsOsiOfficialFixture::test_time_dimension_d_date", + "TestTpcdsOsiOfficialFixture::test_time_dimensions_d_year_quarter_month", + "TestTpcdsOsiOfficialFixture::test_unique_keys", + "TestTpcdsRetailFixture::test_ai_context_on_dataset", + "TestTpcdsRetailFixture::test_ai_context_on_field", + "TestTpcdsRetailFixture::test_ai_context_on_metric", + "TestTpcdsRetailFixture::test_ai_context_on_multiple_datasets", + "TestTpcdsRetailFixture::test_composite_primary_key", + "TestTpcdsRetailFixture::test_computed_field_label", + "TestTpcdsRetailFixture::test_computed_field_multi_dialect", + "TestTpcdsRetailFixture::test_customer_dimension_count", + "TestTpcdsRetailFixture::test_dataset_count", + "TestTpcdsRetailFixture::test_date_dim_dimension_count", + "TestTpcdsRetailFixture::test_default_time_dimension", + "TestTpcdsRetailFixture::test_dimension_tables_have_no_relationships", + "TestTpcdsRetailFixture::test_item_dimension_count", + "TestTpcdsRetailFixture::test_metric_count", + "TestTpcdsRetailFixture::test_metric_customer_lifetime_value", + "TestTpcdsRetailFixture::test_metric_store_productivity", + "TestTpcdsRetailFixture::test_metric_total_profit", + "TestTpcdsRetailFixture::test_metric_total_sales", + "TestTpcdsRetailFixture::test_model_level_custom_extensions", + "TestTpcdsRetailFixture::test_parses_without_errors", + "TestTpcdsRetailFixture::test_relationship_foreign_keys", + "TestTpcdsRetailFixture::test_relationship_primary_keys", + "TestTpcdsRetailFixture::test_relationship_targets", + "TestTpcdsRetailFixture::test_relationship_type", + "TestTpcdsRetailFixture::test_relationships_count", + "TestTpcdsRetailFixture::test_single_column_primary_key", + "TestTpcdsRetailFixture::test_source_tables", + "TestTpcdsRetailFixture::test_store_dimension_count", + "TestTpcdsRetailFixture::test_store_sales_dimension_count", + "TestTpcdsRetailFixture::test_time_dimension_date_dim", + "TestTpcdsRetailFixture::test_unique_keys", + "test_export_composite_primary_key", + "test_export_empty_dialects_list", + "test_export_explicit_json_version", + "test_export_json_inferred_from_extension", + "test_export_json_rejects_dev_version", + "test_export_meta_as_ai_context", + "test_export_multi_column_relationship", + "test_export_multi_dialect", + "test_export_released_json_coerces_unsupported_extension_vendor", + "test_export_released_json_preserves_dbt_extension_vendor", + "test_export_released_json_profile", + "test_export_released_json_roundtrip", + "test_export_unique_keys", + "test_export_unknown_dialect_raises", + "test_export_unknown_format_raises", + "test_export_yaml_preserves_unsupported_extension_vendor", + "test_export_yaml_still_default", + "test_import_ai_context", + "test_import_composite_primary_key", + "test_import_current_version_and_semantic_model_metadata", + "test_import_ecommerce_osi_example", + "test_import_empty_ai_context", + "test_import_kitchen_sink", + "test_import_multi_column_relationship", + "test_import_ontology_mapping_semantic_model", + "test_import_osi_with_metrics", + "test_import_released_json_fixture", + "test_import_simple_osi_example", + "test_import_single_column_primary_key_as_string", + "test_import_unique_keys", + "test_nested_custom_extensions", + "test_osi_complex_metric_expressions", + "test_osi_dataset_without_name", + "test_osi_dimension_type_mapping", + "test_osi_directory_parsing", + "test_osi_export_simple_model", + "test_osi_export_with_relationships", + "test_osi_field_without_name", + "test_osi_metric_aggregation_detection", + "test_osi_metric_without_expression", + "test_osi_multi_dialect_prefers_ansi", + "test_osi_multiple_relationships", + "test_osi_parse_empty_file", + "test_osi_parse_nonexistent_directory", + "test_osi_parse_nonexistent_file", + "test_osi_relationship_metadata_roundtrip", + "test_osi_relationship_parsing", + "test_osi_roundtrip", + "test_parse_directory_skips_generated_osi_artifacts", + "test_parse_directory_skips_non_osi_json", + "test_parse_directory_with_json_and_yaml", + "test_released_json_extension_roundtrip_restores_original", + "test_released_json_named_vendor_roundtrip_restores_original", + "test_roundtrip_preserves_meta", + "test_sqlglot_transpilation_actually_transpiles" + ], + "collected_tests": [ + "tests/adapters/osi/test_parsing.py::test_import_simple_osi_example", + "tests/adapters/osi/test_parsing.py::test_import_current_version_and_semantic_model_metadata", + "tests/adapters/osi/test_parsing.py::test_import_ontology_mapping_semantic_model", + "tests/adapters/osi/test_parsing.py::test_import_ecommerce_osi_example", + "tests/adapters/osi/test_parsing.py::test_import_osi_with_metrics", + "tests/adapters/osi/test_parsing.py::test_import_kitchen_sink", + "tests/adapters/osi/test_parsing.py::test_osi_dimension_type_mapping", + "tests/adapters/osi/test_parsing.py::test_osi_multi_dialect_prefers_ansi", + "tests/adapters/osi/test_parsing.py::test_osi_relationship_parsing", + "tests/adapters/osi/test_parsing.py::test_osi_relationship_metadata_roundtrip", + "tests/adapters/osi/test_parsing.py::test_osi_multiple_relationships", + "tests/adapters/osi/test_parsing.py::test_osi_metric_aggregation_detection", + "tests/adapters/osi/test_parsing.py::test_osi_complex_metric_expressions", + "tests/adapters/osi/test_parsing.py::test_osi_parse_empty_file", + "tests/adapters/osi/test_parsing.py::test_osi_parse_nonexistent_file", + "tests/adapters/osi/test_parsing.py::test_osi_parse_nonexistent_directory", + "tests/adapters/osi/test_parsing.py::test_osi_dataset_without_name", + "tests/adapters/osi/test_parsing.py::test_osi_field_without_name", + "tests/adapters/osi/test_parsing.py::test_osi_metric_without_expression", + "tests/adapters/osi/test_parsing.py::test_osi_export_simple_model", + "tests/adapters/osi/test_parsing.py::test_osi_export_with_relationships", + "tests/adapters/osi/test_parsing.py::test_osi_roundtrip", + "tests/adapters/osi/test_parsing.py::test_osi_directory_parsing", + "tests/adapters/osi/test_parsing.py::test_import_composite_primary_key", + "tests/adapters/osi/test_parsing.py::test_import_unique_keys", + "tests/adapters/osi/test_parsing.py::test_import_ai_context", + "tests/adapters/osi/test_parsing.py::test_import_multi_column_relationship", + "tests/adapters/osi/test_parsing.py::test_export_multi_dialect", + "tests/adapters/osi/test_parsing.py::test_export_composite_primary_key", + "tests/adapters/osi/test_parsing.py::test_export_unique_keys", + "tests/adapters/osi/test_parsing.py::test_export_meta_as_ai_context", + "tests/adapters/osi/test_parsing.py::test_roundtrip_preserves_meta", + "tests/adapters/osi/test_parsing.py::test_export_multi_column_relationship", + "tests/adapters/osi/test_parsing.py::test_export_empty_dialects_list", + "tests/adapters/osi/test_parsing.py::test_export_unknown_dialect_raises", + "tests/adapters/osi/test_parsing.py::test_import_empty_ai_context", + "tests/adapters/osi/test_parsing.py::test_import_single_column_primary_key_as_string", + "tests/adapters/osi/test_parsing.py::test_sqlglot_transpilation_actually_transpiles", + "tests/adapters/osi/test_parsing.py::test_nested_custom_extensions", + "tests/adapters/osi/test_parsing.py::test_import_released_json_fixture", + "tests/adapters/osi/test_parsing.py::test_export_released_json_profile", + "tests/adapters/osi/test_parsing.py::test_export_json_inferred_from_extension", + "tests/adapters/osi/test_parsing.py::test_export_released_json_roundtrip", + "tests/adapters/osi/test_parsing.py::test_export_explicit_json_version", + "tests/adapters/osi/test_parsing.py::test_export_json_rejects_dev_version", + "tests/adapters/osi/test_parsing.py::test_export_released_json_coerces_unsupported_extension_vendor", + "tests/adapters/osi/test_parsing.py::test_released_json_extension_roundtrip_restores_original", + "tests/adapters/osi/test_parsing.py::test_released_json_named_vendor_roundtrip_restores_original", + "tests/adapters/osi/test_parsing.py::test_export_released_json_preserves_dbt_extension_vendor", + "tests/adapters/osi/test_parsing.py::test_export_yaml_preserves_unsupported_extension_vendor", + "tests/adapters/osi/test_parsing.py::test_export_yaml_still_default", + "tests/adapters/osi/test_parsing.py::test_export_unknown_format_raises", + "tests/adapters/osi/test_parsing.py::test_parse_directory_with_json_and_yaml", + "tests/adapters/osi/test_parsing.py::test_parse_directory_skips_generated_osi_artifacts", + "tests/adapters/osi/test_parsing.py::test_parse_directory_skips_non_osi_json", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_composite_primary_key", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_unique_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_single_column_primary_key", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_store_sales_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_customer_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_date_dim_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_store_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_item_dimension_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_time_dimension_date_dim", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_default_time_dimension", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_computed_field_multi_dialect", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_computed_field_label", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationships_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationship_targets", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationship_foreign_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationship_primary_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_relationship_type", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_total_sales", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_total_profit", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_customer_lifetime_value", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_metric_store_productivity", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_ai_context_on_dataset", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_ai_context_on_field", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_ai_context_on_metric", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_ai_context_on_multiple_datasets", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_model_level_custom_extensions", + "tests/adapters/osi/test_parsing.py::TestTpcdsRetailFixture::test_dimension_tables_have_no_relationships", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_count", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_composite_primary_key", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_multiple_unique_keys", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_shipments_field_count", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_multi_dialect_computed_field", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_time_dimensions", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_default_time_dimension_is_first", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_relationships_count", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_relationship_targets", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_total_shipment_cost", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_with_count_distinct", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_ratio_with_nullif", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_metric_multi_dialect", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_ai_context_on_shipments", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_ai_context_on_field", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_ai_context_on_metric", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_dimension_tables_no_relationships", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_warehouse_dimensions", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_supplier_dimensions", + "tests/adapters/osi/test_parsing.py::TestSupplyChainFixture::test_model_level_custom_extensions", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_metric_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_composite_primary_key", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_unique_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_single_column_pks", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_store_sales_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_date_dim_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_customer_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_item_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_store_field_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_relationships_count", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_relationship_targets", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_relationship_foreign_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_relationship_primary_keys", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_all_relationships_many_to_one", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_dimension_tables_have_no_relationships", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_time_dimension_d_date", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_time_dimensions_d_year_quarter_month", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_computed_field_customer_full_name", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_ai_context_on_datasets", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_ai_context_store_sales_synonyms", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_ai_context_on_fields", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_ai_context_on_metrics", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_metric_total_sales", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_metric_customer_lifetime_value", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_metric_store_productivity", + "tests/adapters/osi/test_parsing.py::TestTpcdsOsiOfficialFixture::test_custom_extensions_salesforce_dbt", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_count", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_nonstandard_relationships_skipped", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_actor_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_actor_birth_year_is_time", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_movie_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_movie_year_is_time", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_director_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_genre_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_user_preference_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_primary_keys", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_ai_context_on_all_datasets", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_actor_synonyms_extensive", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_genre_synonyms_include_genre_names", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_field_level_ai_context", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_movies_watched", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_favorite_count", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_genre_diversity", + "tests/adapters/osi/test_parsing.py::TestMdbMoviesFixture::test_metric_ai_context", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_parses_without_errors", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_dataset_count", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_no_metrics", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_nonstandard_relationships_skipped", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_single_field_datasets", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_user_preference_has_two_fields", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_primary_keys", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_source_tables", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_ai_context_on_all_datasets", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_field_ai_context", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_concept_dataset", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_person_dataset", + "tests/adapters/osi/test_parsing.py::TestMdbMemberKnowledgeFixture::test_event_dataset" + ] + }, + "scope-15": { + "path": "tests/adapters/osi/test_query_execution.py", + "declared_tests": [ + "test_osi_adtech_example_cross_model_metrics_execute", + "test_osi_ecommerce_metrics_execute" + ], + "collected_tests": [ + "tests/adapters/osi/test_query_execution.py::test_osi_ecommerce_metrics_execute", + "tests/adapters/osi/test_query_execution.py::test_osi_adtech_example_cross_model_metrics_execute" + ] + }, + "scope-16": { + "path": "tests/adapters/osi/test_rust_parity.py", + "declared_tests": [ + "test_osi_export_parity", + "test_osi_export_resolves_model_inheritance", + "test_osi_import_parity", + "test_osi_roundtrip_parity" + ], + "collected_tests": [ + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[ecommerce.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[kitchen_sink.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[mdb_member_knowledge.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[mdb_movies.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[simple.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[supply_chain.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[tpcds_osi_official.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_import_parity[tpcds_retail.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[ecommerce.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[kitchen_sink.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[mdb_member_knowledge.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[mdb_movies.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[simple.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[supply_chain.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[tpcds_osi_official.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_parity[tpcds_retail.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[ecommerce.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[kitchen_sink.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[mdb_member_knowledge.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[mdb_movies.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[simple.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[supply_chain.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[tpcds_osi_official.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_roundtrip_parity[tpcds_retail.yaml]", + "tests/adapters/osi/test_rust_parity.py::test_osi_export_resolves_model_inheritance" + ] + }, + "scope-17": { + "path": "tests/adapters/sidemantic_adapter/test_parsing.py", + "declared_tests": [ + "test_dimension_window_in_sql_generation" + ], + "collected_tests": [ + "tests/adapters/sidemantic_adapter/test_parsing.py::test_dimension_window_in_sql_generation" + ] + }, + "scope-18": { + "path": "tests/adapters/tableau/test_real_world.py", + "declared_tests": [ + "test_sf_trial_joined_metric_uses_collection_sql", + "test_shapes_joined_dimension_uses_collection_sql" + ], + "collected_tests": [ + "tests/adapters/tableau/test_real_world.py::test_sf_trial_joined_metric_uses_collection_sql", + "tests/adapters/tableau/test_real_world.py::test_shapes_joined_dimension_uses_collection_sql" + ] + }, + "scope-19": { + "path": "tests/adapters/tableau/test_real_world.py", + "declared_tests": [ + "test_cast_calcs_table_and_fields", + "test_data_connections_relationships", + "test_data_connections_scale", + "test_filtering_calculated_dimension", + "test_filtering_groups_as_segments", + "test_filtering_table_found", + "test_minimal_tableau10", + "test_minimal_tableau93", + "test_multiple_connections_join", + "test_nested_calculated_fields", + "test_nested_table_found", + "test_server_insights_content_calculated", + "test_server_insights_content_hidden", + "test_server_insights_content_lod_preserved", + "test_server_insights_content_relationships", + "test_server_insights_content_scale", + "test_sf_trial_all_labeled", + "test_sf_trial_collection_builds_join_sql", + "test_sf_trial_joined_metric_uses_collection_sql", + "test_sf_trial_object_graph_relationships", + "test_sf_trial_primary_key_projected", + "test_shapes_hidden_fields", + "test_shapes_joined_dimension_uses_collection_sql", + "test_shapes_labels", + "test_shapes_object_graph_relationships", + "test_shapes_orphan_columns_imported", + "test_shapes_table_found", + "test_unicode_content", + "test_world_all_metrics" + ], + "collected_tests": [ + "tests/adapters/tableau/test_real_world.py::test_cast_calcs_table_and_fields", + "tests/adapters/tableau/test_real_world.py::test_filtering_table_found", + "tests/adapters/tableau/test_real_world.py::test_filtering_groups_as_segments", + "tests/adapters/tableau/test_real_world.py::test_filtering_calculated_dimension", + "tests/adapters/tableau/test_real_world.py::test_shapes_table_found", + "tests/adapters/tableau/test_real_world.py::test_shapes_hidden_fields", + "tests/adapters/tableau/test_real_world.py::test_shapes_labels", + "tests/adapters/tableau/test_real_world.py::test_nested_table_found", + "tests/adapters/tableau/test_real_world.py::test_nested_calculated_fields", + "tests/adapters/tableau/test_real_world.py::test_world_all_metrics", + "tests/adapters/tableau/test_real_world.py::test_server_insights_content_scale", + "tests/adapters/tableau/test_real_world.py::test_server_insights_content_hidden", + "tests/adapters/tableau/test_real_world.py::test_server_insights_content_calculated", + "tests/adapters/tableau/test_real_world.py::test_server_insights_content_relationships", + "tests/adapters/tableau/test_real_world.py::test_server_insights_content_lod_preserved", + "tests/adapters/tableau/test_real_world.py::test_data_connections_scale", + "tests/adapters/tableau/test_real_world.py::test_data_connections_relationships", + "tests/adapters/tableau/test_real_world.py::test_sf_trial_collection_builds_join_sql", + "tests/adapters/tableau/test_real_world.py::test_sf_trial_primary_key_projected", + "tests/adapters/tableau/test_real_world.py::test_sf_trial_all_labeled", + "tests/adapters/tableau/test_real_world.py::test_sf_trial_object_graph_relationships", + "tests/adapters/tableau/test_real_world.py::test_sf_trial_joined_metric_uses_collection_sql", + "tests/adapters/tableau/test_real_world.py::test_shapes_object_graph_relationships", + "tests/adapters/tableau/test_real_world.py::test_shapes_joined_dimension_uses_collection_sql", + "tests/adapters/tableau/test_real_world.py::test_shapes_orphan_columns_imported", + "tests/adapters/tableau/test_real_world.py::test_multiple_connections_join", + "tests/adapters/tableau/test_real_world.py::test_minimal_tableau10", + "tests/adapters/tableau/test_real_world.py::test_minimal_tableau93", + "tests/adapters/tableau/test_real_world.py::test_unicode_content" + ] + }, + "scope-20": { + "path": "tests/adapters/tableau/test_relation_types.py", + "declared_tests": [ + "test_legacy_object_graph_has_no_semantic_metadata" + ], + "collected_tests": [ + "tests/adapters/tableau/test_relation_types.py::test_legacy_object_graph_has_no_semantic_metadata" + ] + }, + "scope-21": { + "path": "tests/adapters/test_added_fixture_coverage.py", + "declared_tests": [ + "test_added_fixtures_execute_sql_for_execution_candidates", + "test_added_fixtures_generate_sql_for_compile_candidates", + "test_added_fixtures_parse_with_graph_contracts", + "test_added_fixtures_raise_expected_parse_failures" + ], + "collected_tests": [ + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[dataset_dim_date.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[dataset_dim_geography.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[dataset_dim_product.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[dataset_fact_internet_sales.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[dataset_user_country_mapping.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[dimension_date.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[dimension_geography.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[dimension_product.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[metric_orderquantity.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[metric_salesamount.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[model_internet_sales.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[row_security_country.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[flights.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[ga_sessions.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[healthcare.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[nyc_taxi.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[yaml_example_filter.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[case_switch_ownership.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[custom_calendar.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[folders.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[pre_aggregation_types.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[rbac_customers.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[rbac_policy_overlap.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[rbac_views.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[switch_dimension.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[visitors_geo_subquery.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[ecommerce_demo_ldm.json]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[sdk_declarative_ldm.json]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[sdk_declarative_ldm_with_sql_dataset.json]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[employees.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[inventory.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[page_views.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[support_tickets.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[events.model.aml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[imports.aml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[role_playing.aml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[transactions.dataset.aml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[user_sessions.model.aml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[ga360_ga_block.view.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[lkml2cube_constants.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[lkml_liquid_templating.model.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[lkml_model_all_fields.model.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[lkml_ndt_bind_filters.model.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[lkml_parameter_join.model.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[lkml_view_all_fields.view.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[node_lookml_refinement_merging.model.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[node_lookml_refinement_sequencing.model.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[pylookml_aggregate_tables.model.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[pylookml_manifest.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[pylookml_sql_preamble.view.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[segment_attribution_conversion.view.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[segment_attribution_manifest.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[segment_attribution_model.model.lkml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[bigquery_jobs.malloy]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[bigquery_jobs_config.malloy]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[ecommerce_malloydata.malloy]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[flights_cube.malloy]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[flights_docs.malloy]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[flights_docs_airports.malloy]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[ga4.malloy]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[ga4_config.malloy]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[hackernews.malloy]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[hackernews_faang.malloy]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[test_persist.malloy]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[the_met.malloy]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[ambiguous_resolution_manifest.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[cyclic_join_manifest.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[extended_date_manifest.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[latest_spec_models.yml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[name_edge_case_manifest.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[scd_listings.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[scd_metrics.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[simple_manifest_buys_source.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[simple_manifest_metrics.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[simple_manifest_saved_queries.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[model.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[relationships.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[snap_user_rfm.view.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[Customers.topic.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[Events.topic.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[sessions.topic.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[dim_categories.view.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[dim_products.view.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[dim_user_rfm.view.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[dim_users.view.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[fct_events.view.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[fct_sessions.view.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[mdb_member_knowledge.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[mdb_movies.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[tpcds_osi_official.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[ad_bids_advanced.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[ad_bids_policy.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[bids_canvas.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[bids_explore.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[metrics_annotations.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[metrics_geospatial.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[metrics_null_filling.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[nyc_trips_dashboard.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[query_log_metrics.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[customer_loyalty_metrics.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[ecommerce_analytics.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[supply_chain.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[support_tickets.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[birth_france_by_region.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[fcc_new_coder_survey.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[international_sales.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[project_management.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[sales_dashboard.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[usa_birth_names.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[video_game_sales.yaml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[orders.tds]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[sales_calcs.tds]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[kitchen_sink.tds]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[multi_join.tds]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[tpch_customer.table.tml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[tpch_lineitem.table.tml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[tpch_liveboard.liveboard.tml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[tpch_nation.table.tml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[tpch_orders.table.tml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[tpch_part.table.tml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[tpch_partsupp.table.tml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[tpch_region.table.tml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[tpch_supplier.table.tml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_parse_with_graph_contracts[tpch_worksheet.worksheet.tml]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_raise_expected_parse_failures[ecommerce_demo_analytics.json]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_raise_expected_parse_failures[sdk_declarative_analytics_model.json]", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_generate_sql_for_compile_candidates", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_execute_sql_for_execution_candidates" + ] + }, + "scope-22": { + "path": "tests/adapters/test_added_fixture_coverage.py", + "declared_tests": [ + "test_added_fixtures_execute_sql_for_execution_candidates", + "test_added_fixtures_generate_sql_for_compile_candidates" + ], + "collected_tests": [ + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_generate_sql_for_compile_candidates", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_execute_sql_for_execution_candidates" + ] + }, + "scope-23": { + "path": "tests/adapters/test_fixture_functionality_contracts.py", + "declared_tests": [ + "test_execution_candidate_materializes_invariant_filter_columns", + "test_fixture_adapter_exact_execution_semantics", + "test_fixture_parse_and_graph_contracts", + "test_fixture_query_compilation_coverage", + "test_fixture_query_execution_coverage", + "test_fixture_representative_execution_semantics", + "test_non_executable_fixture_reason_contracts" + ], + "collected_tests": [ + "tests/adapters/test_fixture_functionality_contracts.py::test_execution_candidate_materializes_invariant_filter_columns", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml/catalog.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml/connection_demo.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml/dataset_dim_customers.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml/dataset_dim_regions.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml/dataset_fact_sales.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml/dimension_customers.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml/dimension_order_date.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml/dimension_regions.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml/metric_avg_order_value.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml/metric_order_count.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml/metric_sales_median.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml/metric_sales_stddev.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml/metric_total_sales.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml/model_sales.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/atscale.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/connection_core.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dataset_dim_customers.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dataset_dim_date.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dataset_dim_dates.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dataset_dim_geography.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dataset_dim_product.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dataset_dim_promos.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dataset_fact_internet_sales.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dataset_fact_orders.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dataset_fact_returns.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dataset_user_country_mapping.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dimension_customer.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dimension_date.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dimension_geography.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dimension_order_date.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dimension_order_status.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dimension_product.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/dimension_promo.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/metric_amount_median.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/metric_amount_p75.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/metric_amount_p90.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/metric_amount_stddev.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/metric_avg_order_value.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/metric_order_count.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/metric_orderquantity.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/metric_return_count.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/metric_salesamount.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/metric_total_amount.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/metric_total_amount_distinct.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/metric_unique_customers.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/model_internet_sales.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/model_orders.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/model_returns.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/package_shared_dims.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/packages/shared_repos.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/atscale_sml_kitchen_sink/row_security_country.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/bsl/flights.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/bsl/ga_sessions.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/bsl/healthcare.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/bsl/nyc_taxi.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/bsl/order_items.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/bsl/orders.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/bsl/yaml_example_filter.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/case_switch_ownership.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/custom_calendar.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/diamond_join.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/ecommerce_multi_cube.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/edge_cases.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/extends_and_hierarchies.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/financial_analytics.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/folders.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/healthcare_patients.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/iot_sensors.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/kitchen_sink.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/logistics_shipping.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/multi_stage_time_shift.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/orders.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/orders_with_preagg.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/pre_aggregation_types.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/rbac_customers.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/rbac_policy_overlap.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/rbac_views.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/retail_analytics.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/saas_analytics.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/stripe_saas_metrics.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/switch_dimension.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/tesseract_features.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/views_includes_excludes.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/visitors_geo_subquery.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/cube/web_analytics.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/gooddata/cloud_kitchen_sink.json]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/gooddata/cloud_ldm.json]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/gooddata/ecommerce_demo_analytics.json]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/gooddata/ecommerce_demo_ldm.json]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/gooddata/legacy_kitchen_sink.json]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/gooddata/legacy_project_model.json]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/gooddata/sdk_declarative_analytics_model.json]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/gooddata/sdk_declarative_ldm.json]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/gooddata/sdk_declarative_ldm_with_sql_dataset.json]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/hex/employees.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/hex/inventory.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/hex/orders.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/hex/organizations.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/hex/page_views.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/hex/product_events.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/hex/saas_analytics.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/hex/subscriptions_project.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/hex/support_tickets.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/hex/users.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics/accounts.model.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics/ecommerce.dataset.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics/orders.model.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics/relationships.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics/users.model.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/constants.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/customers.model.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/events.model.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/extensions.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/imports.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/kitchen_sink.dataset.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/metric_store.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/modules/finance/models/refunds.model.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/order_summary.model.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/orders.model.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/products.model.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/relationships.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/role_playing.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/transactions.dataset.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/holistics_kitchen_sink/user_sessions.model.aml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/advanced_measure_types.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/advanced_measures.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/bq_thelook_derived_table.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/bq_thelook_distribution_centers.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/bq_thelook_events.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/bq_thelook_inventory.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/bq_thelook_user_facts.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/derived_tables.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/ecommerce.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/ecommerce_explores.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/edge_cases_actions.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/edge_cases_explores.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/edge_cases_extends.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/edge_cases_filters.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/edge_cases_liquid.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/edge_cases_special_types.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/edge_cases_sql.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/ga360_ga_block.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/kitchen_sink.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/kitchen_sink_explores.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/lkml2cube_constants.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/lkml_liquid_templating.model.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/lkml_model_all_fields.model.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/lkml_ndt_bind_filters.model.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/lkml_parameter_join.model.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/lkml_view_all_fields.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/node_lookml_refinement_merging.model.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/node_lookml_refinement_sequencing.model.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/orders.explore.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/orders.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/pylookml_aggregate_tables.model.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/pylookml_manifest.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/pylookml_sql_preamble.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/realworld_bq_thelook_sessions.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/realworld_date_comparison.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/realworld_google_ads.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/realworld_pylookml_kitchen_sink.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/realworld_redshift_admin.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/realworld_snowflake_geo.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/segment_attribution_conversion.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/segment_attribution_manifest.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/segment_attribution_model.model.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/thelook_inventory_items.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/thelook_order_items.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/thelook_orders.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/thelook_products.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/lookml/thelook_users.view.lkml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/airports.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/annotations.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/bigquery_jobs.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/bigquery_jobs_config.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/ecommerce.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/ecommerce_malloydata.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/edge_cases.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/expression_transforms.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/flights.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/flights_cube.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/flights_docs.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/flights_docs_airports.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/ga4.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/ga4_config.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/hackernews.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/hackernews_faang.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/imdb.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/imports/aliased_import.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/imports/base.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/imports/circular_a.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/imports/circular_b.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/imports/multi_level.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/imports/named_import.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/imports/orders.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/kitchen_sink.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/names.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/new_statements.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/retail_analytics.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/saas_metrics.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/sql_sources.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/syntax_error.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/test_persist.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/malloy/the_met.malloy]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/accounts_source.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/advanced_dimensions.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/advanced_metrics.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/ambiguous_resolution_manifest.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/bookings_source.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/coalesce_2023_customers.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/coalesce_2023_order_items.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/coalesce_2023_orders.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/conversion_metrics.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/cumulative_metrics_grain_to_date.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/cyclic_join_manifest.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/ecommerce_multi_model.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/extended_date_manifest.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/jaffle_sl_testing_order_items.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/latest_spec_models.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/multi_hop_joins.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/name_edge_case_manifest.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/saved_queries_example.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/scd_listings.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/scd_metrics.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/scd_type_ii.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/semantic_models.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/simple_manifest_buys_source.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/simple_manifest_metrics.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/simple_manifest_saved_queries.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/sub_daily_grain_to_date_hour.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/sub_daily_granularities.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/metricflow/sub_daily_millisecond.yml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/estore/model.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/estore/relationships.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/estore/snapshots/snap_user_rfm.view.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/estore/topics/Customers.topic.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/estore/topics/Events.topic.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/estore/topics/sessions.topic.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/estore/views/dim_categories.view.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/estore/views/dim_products.view.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/estore/views/dim_user_rfm.view.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/estore/views/dim_users.view.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/estore/views/fct_events.view.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/estore/views/fct_sessions.view.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/model.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/views/customers.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/omni/views/orders.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/osi/ecommerce.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/osi/kitchen_sink.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/osi/mdb_member_knowledge.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/osi/mdb_movies.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/osi/simple.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/osi/supply_chain.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/osi/tpcds_osi_official.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/osi/tpcds_retail.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/ad_bids_advanced.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/ad_bids_policy.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/bids_canvas.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/bids_explore.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/cost_monitoring.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/derived_metrics.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/kitchen_sink.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/medicaid_spending.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/metrics_annotations.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/metrics_geospatial.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/metrics_null_filling.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/mobile_events.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/nyc_trips_dashboard.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/orders.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/parent_metrics.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/query_log_metrics.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/sales.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/rill/users.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/snowflake/cortex_features.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/snowflake/customer_loyalty_metrics.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/snowflake/ecommerce_analytics.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/snowflake/revenue_timeseries.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/snowflake/supply_chain.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/snowflake/support_tickets.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/superset/birth_france_by_region.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/superset/covid_dashboard.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/superset/ecommerce_products.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/superset/fcc_new_coder_survey.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/superset/international_sales.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/superset/multi_catalog_revenue.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/superset/orders.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/superset/project_management.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/superset/sales_dashboard.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/superset/sales_summary.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/superset/usa_birth_names.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/superset/video_game_sales.yaml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/batch_union.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/kitchen_sink.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/multi_join.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/orders.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/pivot.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/project.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/real_world/connector_sdk_cast_calcs.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/real_world/connector_sdk_staples_postgres.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/real_world/document_api_datasource_test.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/real_world/document_api_field_change.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/real_world/document_api_nested.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/real_world/document_api_tableau10.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/real_world/document_api_tableau93.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/real_world/document_api_unicode.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/real_world/document_api_world.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/real_world/thoughtspot_sf_trial.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/sales_calcs.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/semantic_layer.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/spatial_proc.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/subquery.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/text_transform.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/tableau/union.tds]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/kitchen_sink.table.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/kitchen_sink.worksheet.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_alias.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_aliased_table_id_ref.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_base_alias.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_composite_key.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_join_target_by_id.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_joined_id_key.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_measure_key.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_name_collision.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_nested_formula.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_non_equi_join.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_non_id_key.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_one_to_many.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_one_to_one.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_parenthesized_join.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_range_only_join.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_relationship_fk.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_renamed_formula.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_renamed_id_key.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_single_table_alias.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_single_table_renamed_formula.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_unqualified_formula.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/model_wrapped_join_key.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/orders.table.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/role_playing.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/sales.model.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/sales.worksheet.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/table_db_column_properties.table.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/table_joins.table.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/tpch_customer.table.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/tpch_lineitem.table.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/tpch_liveboard.liveboard.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/tpch_nation.table.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/tpch_orders.table.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/tpch_part.table.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/tpch_partsupp.table.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/tpch_region.table.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/tpch_supplier.table.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/tpch_worksheet.worksheet.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/worksheet_formula_name.worksheet.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/worksheet_ids.worksheet.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/worksheet_multi_join.worksheet.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_parse_and_graph_contracts[tests/fixtures/thoughtspot/worksheet_unbracketed_expr.worksheet.tml]", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_query_compilation_coverage", + "tests/adapters/test_fixture_functionality_contracts.py::test_non_executable_fixture_reason_contracts", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_query_execution_coverage", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_representative_execution_semantics", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_adapter_exact_execution_semantics" + ] + }, + "scope-24": { + "path": "tests/adapters/test_fixture_functionality_contracts.py", + "declared_tests": [ + "test_fixture_adapter_exact_execution_semantics", + "test_fixture_query_compilation_coverage", + "test_fixture_query_execution_coverage", + "test_fixture_representative_execution_semantics" + ], + "collected_tests": [ + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_query_compilation_coverage", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_query_execution_coverage", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_representative_execution_semantics", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_adapter_exact_execution_semantics" + ] + }, + "scope-25": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_dax_only_calculated_table_is_not_compiled_as_sql", + "test_tmdl_untranslated_dax_dimension_is_not_compiled_as_sql" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_untranslated_dax_dimension_is_not_compiled_as_sql", + "tests/adapters/tmdl/test_parsing.py::test_tmdl_dax_only_calculated_table_is_not_compiled_as_sql" + ] + }, + "scope-26": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_parses_dax_ast_when_available" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_parses_dax_ast_when_available" + ] + }, + "scope-27": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_inactive_relationship_is_preserved_and_excluded_from_graph_paths" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_inactive_relationship_is_preserved_and_excluded_from_graph_paths" + ] + }, + "scope-28": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_invalid_relationship_edges_are_skipped" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_invalid_relationship_edges_are_skipped" + ] + }, + "scope-29": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_warning_fixture_collects_relationship_warnings" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_warning_fixture_collects_relationship_warnings" + ] + }, + "scope-30": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_export_preserves_native_dax_authored_sources" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_export_preserves_native_dax_authored_sources" + ] + }, + "scope-31": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_dax_reduction_semantics" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_dax_reduction_semantics" + ] + }, + "scope-32": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_real_fixture_reductions_reference_real_columns" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_real_fixture_reductions_reference_real_columns" + ] + }, + "scope-33": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_deeply_nested_dax_does_not_crash_import" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_deeply_nested_dax_does_not_crash_import" + ] + }, + "scope-34": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_keyless_many_to_many_joins_without_keying_off_endpoints" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_keyless_many_to_many_joins_without_keying_off_endpoints" + ] + }, + "scope-35": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_keyless_many_to_many_metric_raises_clear_error" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_keyless_many_to_many_metric_raises_clear_error" + ] + }, + "scope-36": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_many_to_many_on_non_primary_key_column" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_many_to_many_on_non_primary_key_column" + ] + }, + "scope-37": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_one_to_one_recovers_keyless_source_key" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_one_to_one_recovers_keyless_source_key" + ] + }, + "scope-38": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_one_to_one_alternate_key_does_not_shadow_real_key" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_one_to_one_alternate_key_does_not_shadow_real_key" + ] + }, + "scope-39": { + "path": "tests/adapters/tmdl/test_parsing.py", + "declared_tests": [ + "test_tmdl_ambiguous_one_side_target_not_recovered_from_endpoint" + ], + "collected_tests": [ + "tests/adapters/tmdl/test_parsing.py::test_tmdl_ambiguous_one_side_target_not_recovered_from_endpoint" + ] + }, + "scope-40": { + "path": "tests/core/test_cross_surface_equivalence.py", + "declared_tests": [ + "test_execution_results_match_across_surfaces", + "test_pg_server_executes_previewed_sql", + "test_sql_compile_endpoint_matches_after_semicolon_normalization", + "test_sql_first_rewrite_is_byte_identical", + "test_structured_compile_is_byte_identical", + "test_structured_ratio_metric_compile_is_byte_identical" + ], + "collected_tests": [ + "tests/core/test_cross_surface_equivalence.py::test_sql_first_rewrite_is_byte_identical[simple_aggregation]", + "tests/core/test_cross_surface_equivalence.py::test_sql_first_rewrite_is_byte_identical[metric_dimension_filter]", + "tests/core/test_cross_surface_equivalence.py::test_sql_first_rewrite_is_byte_identical[time_granularity]", + "tests/core/test_cross_surface_equivalence.py::test_sql_first_rewrite_is_byte_identical[join_across_relationship]", + "tests/core/test_cross_surface_equivalence.py::test_sql_first_rewrite_is_byte_identical[order_by_limit]", + "tests/core/test_cross_surface_equivalence.py::test_sql_first_rewrite_is_byte_identical[ratio_metric]", + "tests/core/test_cross_surface_equivalence.py::test_sql_compile_endpoint_matches_after_semicolon_normalization", + "tests/core/test_cross_surface_equivalence.py::test_structured_compile_is_byte_identical[simple_aggregation]", + "tests/core/test_cross_surface_equivalence.py::test_structured_compile_is_byte_identical[metric_dimension_filter]", + "tests/core/test_cross_surface_equivalence.py::test_structured_compile_is_byte_identical[time_granularity]", + "tests/core/test_cross_surface_equivalence.py::test_structured_compile_is_byte_identical[join_across_relationship]", + "tests/core/test_cross_surface_equivalence.py::test_structured_compile_is_byte_identical[order_by_limit]", + "tests/core/test_cross_surface_equivalence.py::test_structured_compile_is_byte_identical[ratio_metric]", + "tests/core/test_cross_surface_equivalence.py::test_structured_ratio_metric_compile_is_byte_identical", + "tests/core/test_cross_surface_equivalence.py::test_execution_results_match_across_surfaces[simple_aggregation]", + "tests/core/test_cross_surface_equivalence.py::test_execution_results_match_across_surfaces[metric_dimension_filter]", + "tests/core/test_cross_surface_equivalence.py::test_execution_results_match_across_surfaces[time_granularity]", + "tests/core/test_cross_surface_equivalence.py::test_execution_results_match_across_surfaces[join_across_relationship]", + "tests/core/test_cross_surface_equivalence.py::test_execution_results_match_across_surfaces[order_by_limit]", + "tests/core/test_cross_surface_equivalence.py::test_execution_results_match_across_surfaces[ratio_metric]", + "tests/core/test_cross_surface_equivalence.py::test_pg_server_executes_previewed_sql[simple_aggregation]", + "tests/core/test_cross_surface_equivalence.py::test_pg_server_executes_previewed_sql[metric_dimension_filter]", + "tests/core/test_cross_surface_equivalence.py::test_pg_server_executes_previewed_sql[time_granularity]", + "tests/core/test_cross_surface_equivalence.py::test_pg_server_executes_previewed_sql[join_across_relationship]", + "tests/core/test_cross_surface_equivalence.py::test_pg_server_executes_previewed_sql[order_by_limit]", + "tests/core/test_cross_surface_equivalence.py::test_pg_server_executes_previewed_sql[ratio_metric]" + ] + }, + "scope-41": { + "path": "tests/core/test_cross_surface_equivalence.py", + "declared_tests": [ + "test_pg_server_executes_previewed_sql" + ], + "collected_tests": [ + "tests/core/test_cross_surface_equivalence.py::test_pg_server_executes_previewed_sql[simple_aggregation]", + "tests/core/test_cross_surface_equivalence.py::test_pg_server_executes_previewed_sql[metric_dimension_filter]", + "tests/core/test_cross_surface_equivalence.py::test_pg_server_executes_previewed_sql[time_granularity]", + "tests/core/test_cross_surface_equivalence.py::test_pg_server_executes_previewed_sql[join_across_relationship]", + "tests/core/test_cross_surface_equivalence.py::test_pg_server_executes_previewed_sql[order_by_limit]", + "tests/core/test_cross_surface_equivalence.py::test_pg_server_executes_previewed_sql[ratio_metric]" + ] + }, + "scope-42": { + "path": "tests/core/test_invariant_filters.py", + "declared_tests": [ + "test_legacy_python_sql_generator_falls_back_for_invariants" + ], + "collected_tests": [ + "tests/core/test_invariant_filters.py::test_legacy_python_sql_generator_falls_back_for_invariants" + ] + }, + "scope-43": { + "path": "tests/core/test_relationship_role_aliases.py", + "declared_tests": [ + "test_many_to_many_through_column_check_uses_scoped_target_instance", + "test_nested_role_alias_is_scoped_to_parent_instance", + "test_role_alias_one_to_many_keeps_base_measure_fanout_safe", + "test_two_roles_to_same_target_use_distinct_join_instances" + ], + "collected_tests": [ + "tests/core/test_relationship_role_aliases.py::test_two_roles_to_same_target_use_distinct_join_instances", + "tests/core/test_relationship_role_aliases.py::test_nested_role_alias_is_scoped_to_parent_instance", + "tests/core/test_relationship_role_aliases.py::test_role_alias_one_to_many_keeps_base_measure_fanout_safe", + "tests/core/test_relationship_role_aliases.py::test_many_to_many_through_column_check_uses_scoped_target_instance" + ] + }, + "scope-44": { + "path": "tests/core/test_relationship_role_aliases.py", + "declared_tests": [ + "test_optional_rust_modes_fall_back_when_backend_rejects_roles" + ], + "collected_tests": [ + "tests/core/test_relationship_role_aliases.py::test_optional_rust_modes_fall_back_when_backend_rejects_roles" + ] + }, + "scope-45": { + "path": "tests/core/test_relationship_role_aliases.py", + "declared_tests": [ + "test_strict_rust_modes_propagate_backend_role_rejection" + ], + "collected_tests": [ + "tests/core/test_relationship_role_aliases.py::test_strict_rust_modes_propagate_backend_role_rejection[validation]", + "tests/core/test_relationship_role_aliases.py::test_strict_rust_modes_propagate_backend_role_rejection[generation]" + ] + }, + "scope-46": { + "path": "tests/core/test_result_cache.py", + "declared_tests": [ + "test_build_result_key_generation_changes_key", + "test_build_result_key_user_attributes_change_key", + "test_hit_and_miss_counts", + "test_invalidate_all", + "test_lru_eviction_by_bytes", + "test_semantic_layer_generation_bump_changes_key", + "test_semantic_layer_user_attributes_change_key", + "test_singleflight_compute_raises_propagates_without_deadlock", + "test_singleflight_runs_compute_once", + "test_ttl_expiry_via_injected_clock" + ], + "collected_tests": [ + "tests/core/test_result_cache.py::test_hit_and_miss_counts", + "tests/core/test_result_cache.py::test_lru_eviction_by_bytes", + "tests/core/test_result_cache.py::test_ttl_expiry_via_injected_clock", + "tests/core/test_result_cache.py::test_invalidate_all", + "tests/core/test_result_cache.py::test_singleflight_runs_compute_once", + "tests/core/test_result_cache.py::test_singleflight_compute_raises_propagates_without_deadlock", + "tests/core/test_result_cache.py::test_build_result_key_user_attributes_change_key", + "tests/core/test_result_cache.py::test_build_result_key_generation_changes_key", + "tests/core/test_result_cache.py::test_semantic_layer_generation_bump_changes_key", + "tests/core/test_result_cache.py::test_semantic_layer_user_attributes_change_key" + ] + }, + "scope-47": { + "path": "tests/core/test_runtime_defaults.py", + "declared_tests": [ + "test_missing_explicit_rust_runtime_does_not_silently_fall_back" + ], + "collected_tests": [ + "tests/core/test_runtime_defaults.py::test_missing_explicit_rust_runtime_does_not_silently_fall_back" + ] + }, + "scope-48": { + "path": "tests/core/test_rust_engine_mode.py", + "declared_tests": [ + "test_semantic_layer_python_engine_ignores_rust_env_flags" + ], + "collected_tests": [ + "tests/core/test_rust_engine_mode.py::test_semantic_layer_python_engine_ignores_rust_env_flags" + ] + }, + "scope-49": { + "path": "tests/core/test_security_advisor_regressions.py", + "declared_tests": [ + "test_pg_server_refuses_user_attrs_map_without_auth" + ], + "collected_tests": [ + "tests/core/test_security_advisor_regressions.py::test_pg_server_refuses_user_attrs_map_without_auth" + ] + }, + "scope-50": { + "path": "tests/core/test_security_advisor_regressions.py", + "declared_tests": [ + "test_rewriter_threads_user_attributes" + ], + "collected_tests": [ + "tests/core/test_security_advisor_regressions.py::test_rewriter_threads_user_attributes" + ] + }, + "scope-51": { + "path": "tests/dates/test_query_timezone.py", + "declared_tests": [ + "test_generator_timezone_bypasses_preagg_routing", + "test_timezone_dialect_specific_sql", + "test_timezone_value_is_validated_against_injection" + ], + "collected_tests": [ + "tests/dates/test_query_timezone.py::test_timezone_dialect_specific_sql", + "tests/dates/test_query_timezone.py::test_generator_timezone_bypasses_preagg_routing", + "tests/dates/test_query_timezone.py::test_timezone_value_is_validated_against_injection" + ] + }, + "scope-52": { + "path": "tests/dates/test_time_comparison.py", + "declared_tests": [ + "test_model_level_conversion_metric", + "test_model_level_time_comparison_metric", + "test_named_calendar_comparison_without_declared_granularity" + ], + "collected_tests": [ + "tests/dates/test_time_comparison.py::test_named_calendar_comparison_without_declared_granularity[dod-2024-03-01-2024-03-02]", + "tests/dates/test_time_comparison.py::test_named_calendar_comparison_without_declared_granularity[wow-2024-03-01-2024-03-08]", + "tests/dates/test_time_comparison.py::test_named_calendar_comparison_without_declared_granularity[mom-2024-03-01-2024-04-01]", + "tests/dates/test_time_comparison.py::test_named_calendar_comparison_without_declared_granularity[qoq-2024-03-01-2024-06-01]", + "tests/dates/test_time_comparison.py::test_named_calendar_comparison_without_declared_granularity[yoy-2023-03-01-2024-03-01]", + "tests/dates/test_time_comparison.py::test_model_level_time_comparison_metric", + "tests/dates/test_time_comparison.py::test_model_level_conversion_metric" + ] + }, + "scope-53": { + "path": "tests/dax/test_ast.py", + "declared_tests": [ + "test_completed_static_validation_codes_are_exposed", + "test_datatable_native_round_trip_and_validation", + "test_datetime_literal_native_lexical_validation", + "test_datetime_literal_native_round_trip", + "test_formatter_native_canonical_and_localized_round_trip", + "test_formatter_native_sqlbi_preserves_formula_marker_after_comments", + "test_formatter_native_sqlbi_profile_exact_goldens", + "test_formatter_native_sqlbi_visual_shape_golden", + "test_from_raw_datetime_token", + "test_from_raw_definition_function", + "test_from_raw_definition_table_visual_shape", + "test_from_raw_definition_table_without_visual_shape", + "test_from_raw_expr_datatable", + "test_from_raw_expr_datetime_literal", + "test_from_raw_expr_function_call", + "test_from_raw_expr_hierarchy_ref", + "test_from_raw_expr_omitted_is_distinct_from_blank", + "test_from_raw_expr_parameter", + "test_from_raw_expr_tuple", + "test_from_raw_query_define_evaluate", + "test_from_raw_tokens", + "test_function_parameter_default_native_round_trip", + "test_lossless_native_spans_and_comments_round_trip", + "test_model_validation_native_uses_typed_metadata_and_issues", + "test_multi_column_in_native_round_trip", + "test_native_spans_use_python_string_indices_after_unicode", + "test_omitted_function_arguments_native_round_trip", + "test_public_exports_include_all_python_api_families", + "test_python_dialect_configuration", + "test_recovery_native_returns_typed_items_and_diagnostics", + "test_recovery_spans_use_python_string_indices_after_unicode", + "test_start_at_native_accepts_constants_and_parameters_only", + "test_static_validation_native_api", + "test_visual_shape_native_round_trip" + ], + "collected_tests": [ + "tests/dax/test_ast.py::test_public_exports_include_all_python_api_families", + "tests/dax/test_ast.py::test_from_raw_expr_function_call", + "tests/dax/test_ast.py::test_from_raw_query_define_evaluate", + "tests/dax/test_ast.py::test_from_raw_expr_parameter", + "tests/dax/test_ast.py::test_from_raw_expr_omitted_is_distinct_from_blank", + "tests/dax/test_ast.py::test_from_raw_expr_tuple", + "tests/dax/test_ast.py::test_from_raw_expr_datetime_literal", + "tests/dax/test_ast.py::test_from_raw_expr_datatable", + "tests/dax/test_ast.py::test_from_raw_expr_hierarchy_ref", + "tests/dax/test_ast.py::test_from_raw_definition_function", + "tests/dax/test_ast.py::test_from_raw_definition_table_visual_shape", + "tests/dax/test_ast.py::test_from_raw_definition_table_without_visual_shape", + "tests/dax/test_ast.py::test_from_raw_tokens", + "tests/dax/test_ast.py::test_from_raw_datetime_token", + "tests/dax/test_ast.py::test_datetime_literal_native_round_trip", + "tests/dax/test_ast.py::test_function_parameter_default_native_round_trip", + "tests/dax/test_ast.py::test_visual_shape_native_round_trip", + "tests/dax/test_ast.py::test_omitted_function_arguments_native_round_trip", + "tests/dax/test_ast.py::test_start_at_native_accepts_constants_and_parameters_only", + "tests/dax/test_ast.py::test_multi_column_in_native_round_trip", + "tests/dax/test_ast.py::test_datatable_native_round_trip_and_validation", + "tests/dax/test_ast.py::test_static_validation_native_api", + "tests/dax/test_ast.py::test_python_dialect_configuration", + "tests/dax/test_ast.py::test_datetime_literal_native_lexical_validation", + "tests/dax/test_ast.py::test_formatter_native_canonical_and_localized_round_trip", + "tests/dax/test_ast.py::test_formatter_native_sqlbi_profile_exact_goldens", + "tests/dax/test_ast.py::test_formatter_native_sqlbi_preserves_formula_marker_after_comments[/* note */ = SUM(1)]", + "tests/dax/test_ast.py::test_formatter_native_sqlbi_preserves_formula_marker_after_comments[-- note\\n= SUM(1)]", + "tests/dax/test_ast.py::test_formatter_native_sqlbi_preserves_formula_marker_after_comments[// note\\n= SUM(1)]", + "tests/dax/test_ast.py::test_formatter_native_sqlbi_visual_shape_golden", + "tests/dax/test_ast.py::test_lossless_native_spans_and_comments_round_trip", + "tests/dax/test_ast.py::test_native_spans_use_python_string_indices_after_unicode", + "tests/dax/test_ast.py::test_recovery_native_returns_typed_items_and_diagnostics", + "tests/dax/test_ast.py::test_recovery_spans_use_python_string_indices_after_unicode", + "tests/dax/test_ast.py::test_model_validation_native_uses_typed_metadata_and_issues", + "tests/dax/test_ast.py::test_completed_static_validation_codes_are_exposed" + ] + }, + "scope-54": { + "path": "tests/dax/test_ast.py", + "declared_tests": [ + "test_datetime_literal_native_round_trip" + ], + "collected_tests": [ + "tests/dax/test_ast.py::test_datetime_literal_native_round_trip" + ] + }, + "scope-55": { + "path": "tests/dax/test_ast.py", + "declared_tests": [ + "test_function_parameter_default_native_round_trip" + ], + "collected_tests": [ + "tests/dax/test_ast.py::test_function_parameter_default_native_round_trip" + ] + }, + "scope-56": { + "path": "tests/dax/test_ast.py", + "declared_tests": [ + "test_visual_shape_native_round_trip" + ], + "collected_tests": [ + "tests/dax/test_ast.py::test_visual_shape_native_round_trip" + ] + }, + "scope-57": { + "path": "tests/dax/test_ast.py", + "declared_tests": [ + "test_omitted_function_arguments_native_round_trip" + ], + "collected_tests": [ + "tests/dax/test_ast.py::test_omitted_function_arguments_native_round_trip" + ] + }, + "scope-58": { + "path": "tests/dax/test_ast.py", + "declared_tests": [ + "test_start_at_native_accepts_constants_and_parameters_only" + ], + "collected_tests": [ + "tests/dax/test_ast.py::test_start_at_native_accepts_constants_and_parameters_only" + ] + }, + "scope-59": { + "path": "tests/dax/test_ast.py", + "declared_tests": [ + "test_multi_column_in_native_round_trip" + ], + "collected_tests": [ + "tests/dax/test_ast.py::test_multi_column_in_native_round_trip" + ] + }, + "scope-60": { + "path": "tests/dax/test_ast.py", + "declared_tests": [ + "test_datatable_native_round_trip_and_validation" + ], + "collected_tests": [ + "tests/dax/test_ast.py::test_datatable_native_round_trip_and_validation" + ] + }, + "scope-61": { + "path": "tests/dax/test_ast.py", + "declared_tests": [ + "test_static_validation_native_api" + ], + "collected_tests": [ + "tests/dax/test_ast.py::test_static_validation_native_api" + ] + }, + "scope-62": { + "path": "tests/dax/test_ast.py", + "declared_tests": [ + "test_python_dialect_configuration" + ], + "collected_tests": [ + "tests/dax/test_ast.py::test_python_dialect_configuration" + ] + }, + "scope-63": { + "path": "tests/dax/test_ast.py", + "declared_tests": [ + "test_datetime_literal_native_lexical_validation" + ], + "collected_tests": [ + "tests/dax/test_ast.py::test_datetime_literal_native_lexical_validation" + ] + }, + "scope-64": { + "path": "tests/dax/test_engine_conformance.py", + "declared_tests": [ + "test_arrow_error_stream_is_a_rejection", + "test_local_and_microsoft_engine_conformance", + "test_local_conformance_expectations_are_current" + ], + "collected_tests": [ + "tests/dax/test_engine_conformance.py::test_arrow_error_stream_is_a_rejection", + "tests/dax/test_engine_conformance.py::test_local_conformance_expectations_are_current[row]", + "tests/dax/test_engine_conformance.py::test_local_conformance_expectations_are_current[datetime_literal]", + "tests/dax/test_engine_conformance.py::test_local_conformance_expectations_are_current[function_default]", + "tests/dax/test_engine_conformance.py::test_local_conformance_expectations_are_current[visual_shape]", + "tests/dax/test_engine_conformance.py::test_local_conformance_expectations_are_current[start_at_constant]", + "tests/dax/test_engine_conformance.py::test_local_conformance_expectations_are_current[evaluate_scalar]", + "tests/dax/test_engine_conformance.py::test_local_conformance_expectations_are_current[unknown_function]", + "tests/dax/test_engine_conformance.py::test_local_conformance_expectations_are_current[invalid_arity]", + "tests/dax/test_engine_conformance.py::test_local_conformance_expectations_are_current[sumx_ignores_text]", + "tests/dax/test_engine_conformance.py::test_local_conformance_expectations_are_current[datatable_row_width]", + "tests/dax/test_engine_conformance.py::test_local_conformance_expectations_are_current[start_at_expression]", + "tests/dax/test_engine_conformance.py::test_local_conformance_expectations_are_current[malformed_parenthesis]" + ] + }, + "scope-65": { + "path": "tests/dax/test_engine_conformance.py", + "declared_tests": [ + "test_local_and_microsoft_engine_conformance" + ], + "collected_tests": [] + }, + "scope-66": { + "path": "tests/dax/test_external_powerbi_fixtures.py", + "declared_tests": [ + "test_external_powerbi_dax_measure_file_parses" + ], + "collected_tests": [ + "tests/dax/test_external_powerbi_fixtures.py::test_external_powerbi_dax_measure_file_parses" + ] + }, + "scope-67": { + "path": "tests/dax/test_online_conformance.py", + "declared_tests": [ + "test_local_semantic_checks_are_stricter_than_formatter", + "test_stable_syntax_is_accepted_by_dax_formatter", + "test_stable_syntax_matches_dax_formatter", + "test_udf_defaults_are_known_sqlbi_lag" + ], + "collected_tests": [ + "tests/dax/test_online_conformance.py::test_stable_syntax_matches_dax_formatter[expression-=sumx(filter('Sales','Sales'[Amount]>100),'Sales'[Amount])]", + "tests/dax/test_online_conformance.py::test_stable_syntax_matches_dax_formatter[query-EVALUATE {(1,2),(3,4)}]", + "tests/dax/test_online_conformance.py::test_stable_syntax_matches_dax_formatter[query-DEFINE MEASURE 'S'[M]=SUM('S'[A]) VAR threshold=10 EVALUATE ROW(\"m\",[M])]", + "tests/dax/test_online_conformance.py::test_stable_syntax_matches_dax_formatter[query-DEFINE FUNCTION myUdf=(x:NUMERIC)=>x EVALUATE {myUdf(1)}]", + "tests/dax/test_online_conformance.py::test_stable_syntax_matches_dax_formatter[query-DEFINE TABLE data=ROW(\"Year\",2000,\"IsTotal\",FALSE()) WITH VISUAL SHAPE AXIS ROWS GROUP [Year] TOTAL [IsTotal] ORDER BY [Year] DENSIFY \"IsDensified\" EVALUATE data]", + "tests/dax/test_online_conformance.py::test_stable_syntax_is_accepted_by_dax_formatter[=dt\"2020-12-15T12:30:59\"]", + "tests/dax/test_online_conformance.py::test_stable_syntax_is_accepted_by_dax_formatter[EVALUATE DATATABLE(\"A\", INTEGER, \"B\", STRING, {{1, \"x\"}, {2,}})]", + "tests/dax/test_online_conformance.py::test_stable_syntax_is_accepted_by_dax_formatter[EVALUATE FILTER('Product', ('Product'[Color], 'Product'[Brand]) IN {(\"Red\", \"Contoso\")})]", + "tests/dax/test_online_conformance.py::test_stable_syntax_is_accepted_by_dax_formatter[\\n DEFINE\\n TABLE data = ROW(\"Year\", 2000, \"IsTotal\", FALSE())\\n WITH VISUAL SHAPE\\n AXIS ROWS GROUP [Year] TOTAL [IsTotal] ORDER BY [Year]\\n DENSIFY \"IsDensified\"\\n EVALUATE data\\n ]", + "tests/dax/test_online_conformance.py::test_udf_defaults_are_known_sqlbi_lag", + "tests/dax/test_online_conformance.py::test_local_semantic_checks_are_stricter_than_formatter" + ] + }, + "scope-68": { + "path": "tests/dax/test_query_corpus.py", + "declared_tests": [ + "test_parse_query_corpus_define_examples", + "test_parse_query_corpus_evaluate_examples", + "test_parse_query_corpus_order_by_examples", + "test_parse_query_corpus_start_at_examples" + ], + "collected_tests": [ + "tests/dax/test_query_corpus.py::test_parse_query_corpus_evaluate_examples", + "tests/dax/test_query_corpus.py::test_parse_query_corpus_define_examples", + "tests/dax/test_query_corpus.py::test_parse_query_corpus_order_by_examples", + "tests/dax/test_query_corpus.py::test_parse_query_corpus_start_at_examples" + ] + }, + "scope-69": { + "path": "tests/db/test_adbc_adapter.py", + "declared_tests": [ + "test_adbc_adapter_close", + "test_adbc_adapter_execute", + "test_adbc_adapter_fetch_record_batch", + "test_adbc_adapter_fetchall", + "test_adbc_adapter_fetchone", + "test_adbc_adapter_get_columns", + "test_adbc_adapter_get_tables", + "test_adbc_adapter_injection_attempt_in_schema_is_rejected", + "test_adbc_adapter_injection_attempt_in_table_name_is_rejected", + "test_adbc_adapter_valid_table_names_accepted" + ], + "collected_tests": [ + "tests/db/test_adbc_adapter.py::test_adbc_adapter_execute", + "tests/db/test_adbc_adapter.py::test_adbc_adapter_fetchall", + "tests/db/test_adbc_adapter.py::test_adbc_adapter_fetchone", + "tests/db/test_adbc_adapter.py::test_adbc_adapter_get_tables", + "tests/db/test_adbc_adapter.py::test_adbc_adapter_get_columns", + "tests/db/test_adbc_adapter.py::test_adbc_adapter_close", + "tests/db/test_adbc_adapter.py::test_adbc_adapter_fetch_record_batch", + "tests/db/test_adbc_adapter.py::test_adbc_adapter_injection_attempt_in_table_name_is_rejected", + "tests/db/test_adbc_adapter.py::test_adbc_adapter_injection_attempt_in_schema_is_rejected[main; DROP SCHEMA x;--]", + "tests/db/test_adbc_adapter.py::test_adbc_adapter_injection_attempt_in_schema_is_rejected[default; --]", + "tests/db/test_adbc_adapter.py::test_adbc_adapter_injection_attempt_in_schema_is_rejected[analytics'); DROP TABLE t;--]", + "tests/db/test_adbc_adapter.py::test_adbc_adapter_valid_table_names_accepted[orders]", + "tests/db/test_adbc_adapter.py::test_adbc_adapter_valid_table_names_accepted[my_table]", + "tests/db/test_adbc_adapter.py::test_adbc_adapter_valid_table_names_accepted[Table123]", + "tests/db/test_adbc_adapter.py::test_adbc_adapter_valid_table_names_accepted[_private_table]" + ] + }, + "scope-70": { + "path": "tests/db/test_adbc_adapter.py", + "declared_tests": [ + "test_adbc_adapter_init" + ], + "collected_tests": [ + "tests/db/test_adbc_adapter.py::test_adbc_adapter_init" + ] + }, + "scope-71": { + "path": "tests/db/test_adbc_adapter.py", + "declared_tests": [ + "test_adbc_adapter_fetch_record_batch" + ], + "collected_tests": [ + "tests/db/test_adbc_adapter.py::test_adbc_adapter_fetch_record_batch" + ] + }, + "scope-72": { + "path": "tests/db/test_adbc_adapter.py", + "declared_tests": [ + "test_adbc_adapter_from_url" + ], + "collected_tests": [ + "tests/db/test_adbc_adapter.py::test_adbc_adapter_from_url" + ] + }, + "scope-73": { + "path": "tests/db/test_adbc_adapter.py", + "declared_tests": [ + "test_adbc_url_resolves_packaged_driver_without_system_install" + ], + "collected_tests": [ + "tests/db/test_adbc_adapter.py::test_adbc_url_resolves_packaged_driver_without_system_install[sqlite:///:memory:]", + "tests/db/test_adbc_adapter.py::test_adbc_url_resolves_packaged_driver_without_system_install[adbc://sqlite/:memory:]" + ] + }, + "scope-74": { + "path": "tests/db/test_adbc_adapter.py", + "declared_tests": [ + "test_adbc_with_sqlite_driver" + ], + "collected_tests": [ + "tests/db/test_adbc_adapter.py::test_adbc_with_sqlite_driver" + ] + }, + "scope-75": { + "path": "tests/db/test_adbc_adapter.py", + "declared_tests": [ + "test_adbc_url_scheme_with_driver" + ], + "collected_tests": [ + "tests/db/test_adbc_adapter.py::test_adbc_url_scheme_with_driver" + ] + }, + "scope-76": { + "path": "tests/db/test_adbc_adapter.py", + "declared_tests": [ + "test_semantic_layer_with_adbc_connection" + ], + "collected_tests": [ + "tests/db/test_adbc_adapter.py::test_semantic_layer_with_adbc_connection" + ] + }, + "scope-77": { + "path": "tests/db/test_adbc_adapter.py", + "declared_tests": [ + "test_adbc_url_path_based_uri" + ], + "collected_tests": [ + "tests/db/test_adbc_adapter.py::test_adbc_url_path_based_uri" + ] + }, + "scope-78": { + "path": "tests/db/test_adbc_ci_smoke.py", + "declared_tests": [ + "test_adbc_smoke_basic_execute", + "test_adbc_smoke_dialect", + "test_adbc_smoke_semantic_layer_query_sum" + ], + "collected_tests": [] + }, + "scope-79": { + "path": "tests/db/test_adbc_ci_smoke.py", + "declared_tests": [ + "test_adbc_smoke_dialect" + ], + "collected_tests": [] + }, + "scope-80": { + "path": "tests/db/test_bigquery_adapter.py", + "declared_tests": [ + "test_bigquery_fetch_record_batch" + ], + "collected_tests": [ + "tests/db/test_bigquery_adapter.py::test_bigquery_fetch_record_batch" + ] + }, + "scope-81": { + "path": "tests/db/test_bigquery_adapter.py", + "declared_tests": [ + "test_bigquery_fetch_record_batch_via_adapter" + ], + "collected_tests": [ + "tests/db/test_bigquery_adapter.py::test_bigquery_fetch_record_batch_via_adapter" + ] + }, + "scope-82": { + "path": "tests/db/test_bigquery_cli_e2e.py", + "declared_tests": [ + "test_cli_query_uses_bigquery_config" + ], + "collected_tests": [] + }, + "scope-83": { + "path": "tests/db/test_bigquery_integration.py", + "declared_tests": [ + "test_semantic_layer_basic_metric", + "test_semantic_layer_date_functions", + "test_semantic_layer_dimension_grouping", + "test_semantic_layer_filters", + "test_semantic_layer_joins", + "test_semantic_layer_limit", + "test_semantic_layer_multiple_joins", + "test_semantic_layer_multiple_metrics", + "test_semantic_layer_order_by", + "test_semantic_layer_sql_generation", + "test_semantic_layer_symmetric_aggregates" + ], + "collected_tests": [] + }, + "scope-84": { + "path": "tests/db/test_bigquery_integration.py", + "declared_tests": [ + "test_semantic_layer_date_functions" + ], + "collected_tests": [] + }, + "scope-85": { + "path": "tests/db/test_clickhouse_adapter.py", + "declared_tests": [ + "test_clickhouse_execute_native_arrow" + ], + "collected_tests": [ + "tests/db/test_clickhouse_adapter.py::test_clickhouse_execute_native_arrow" + ] + }, + "scope-86": { + "path": "tests/db/test_clickhouse_adapter.py", + "declared_tests": [ + "test_clickhouse_result_native_arrow_fetch_record_batch" + ], + "collected_tests": [ + "tests/db/test_clickhouse_adapter.py::test_clickhouse_result_native_arrow_fetch_record_batch" + ] + }, + "scope-87": { + "path": "tests/db/test_clickhouse_adapter.py", + "declared_tests": [ + "test_clickhouse_result_native_arrow_fetchone" + ], + "collected_tests": [ + "tests/db/test_clickhouse_adapter.py::test_clickhouse_result_native_arrow_fetchone" + ] + }, + "scope-88": { + "path": "tests/db/test_clickhouse_adapter.py", + "declared_tests": [ + "test_clickhouse_result_native_arrow_fetchall" + ], + "collected_tests": [ + "tests/db/test_clickhouse_adapter.py::test_clickhouse_result_native_arrow_fetchall" + ] + }, + "scope-89": { + "path": "tests/db/test_clickhouse_adapter.py", + "declared_tests": [ + "test_clickhouse_result_native_arrow_empty" + ], + "collected_tests": [ + "tests/db/test_clickhouse_adapter.py::test_clickhouse_result_native_arrow_empty" + ] + }, + "scope-90": { + "path": "tests/db/test_clickhouse_adapter.py", + "declared_tests": [ + "test_clickhouse_executemany_native_arrow" + ], + "collected_tests": [ + "tests/db/test_clickhouse_adapter.py::test_clickhouse_executemany_native_arrow" + ] + }, + "scope-91": { + "path": "tests/db/test_clickhouse_cli_e2e.py", + "declared_tests": [ + "test_cli_query_uses_clickhouse_config" + ], + "collected_tests": [] + }, + "scope-92": { + "path": "tests/db/test_clickhouse_integration.py", + "declared_tests": [ + "test_semantic_layer_basic_metric", + "test_semantic_layer_date_functions", + "test_semantic_layer_dimension_grouping", + "test_semantic_layer_filters", + "test_semantic_layer_joins", + "test_semantic_layer_limit", + "test_semantic_layer_multiple_joins", + "test_semantic_layer_multiple_metrics", + "test_semantic_layer_order_by", + "test_semantic_layer_sql_generation", + "test_semantic_layer_symmetric_aggregates" + ], + "collected_tests": [] + }, + "scope-93": { + "path": "tests/db/test_clickhouse_integration.py", + "declared_tests": [ + "test_semantic_layer_date_functions" + ], + "collected_tests": [] + }, + "scope-94": { + "path": "tests/db/test_databricks_adapter.py", + "declared_tests": [ + "test_databricks_fetch_record_batch_mixed_types" + ], + "collected_tests": [ + "tests/db/test_databricks_adapter.py::test_databricks_fetch_record_batch_mixed_types" + ] + }, + "scope-95": { + "path": "tests/db/test_databricks_adapter.py", + "declared_tests": [ + "test_databricks_fetch_record_batch_native_arrow" + ], + "collected_tests": [ + "tests/db/test_databricks_adapter.py::test_databricks_fetch_record_batch_native_arrow" + ] + }, + "scope-96": { + "path": "tests/db/test_databricks_adapter.py", + "declared_tests": [ + "test_databricks_fetch_record_batch_native_arrow_empty" + ], + "collected_tests": [ + "tests/db/test_databricks_adapter.py::test_databricks_fetch_record_batch_native_arrow_empty" + ] + }, + "scope-97": { + "path": "tests/db/test_databricks_adapter.py", + "declared_tests": [ + "test_databricks_fetch_record_batch_fallback" + ], + "collected_tests": [ + "tests/db/test_databricks_adapter.py::test_databricks_fetch_record_batch_fallback" + ] + }, + "scope-98": { + "path": "tests/db/test_databricks_integration.py", + "declared_tests": [ + "test_semantic_layer_basic_metric", + "test_semantic_layer_dimension_grouping", + "test_semantic_layer_sql_generation" + ], + "collected_tests": [] + }, + "scope-99": { + "path": "tests/db/test_duckdb_adapter.py", + "declared_tests": [ + "test_duckdb_adapter_fetch_record_batch" + ], + "collected_tests": [ + "tests/db/test_duckdb_adapter.py::test_duckdb_adapter_fetch_record_batch" + ] + }, + "scope-100": { + "path": "tests/db/test_postgres_adapter.py", + "declared_tests": [ + "test_postgres_fetch_record_batch" + ], + "collected_tests": [ + "tests/db/test_postgres_adapter.py::test_postgres_fetch_record_batch" + ] + }, + "scope-101": { + "path": "tests/db/test_postgres_adapter.py", + "declared_tests": [ + "test_postgres_result_fetch_record_batch_empty" + ], + "collected_tests": [ + "tests/db/test_postgres_adapter.py::test_postgres_result_fetch_record_batch_empty" + ] + }, + "scope-102": { + "path": "tests/db/test_postgres_cli_e2e.py", + "declared_tests": [ + "test_cli_query_uses_postgres_config" + ], + "collected_tests": [] + }, + "scope-103": { + "path": "tests/db/test_postgres_integration.py", + "declared_tests": [ + "test_postgres_adapter_basic_query", + "test_postgres_adapter_create_insert_query", + "test_postgres_adapter_executemany", + "test_postgres_adapter_get_columns", + "test_postgres_adapter_get_tables", + "test_postgres_dialect_inference", + "test_semantic_layer_postgres_compile_method", + "test_semantic_layer_postgres_date_functions", + "test_semantic_layer_postgres_filters", + "test_semantic_layer_postgres_limit", + "test_semantic_layer_postgres_multiple_joins", + "test_semantic_layer_postgres_multiple_metrics", + "test_semantic_layer_postgres_order_by", + "test_semantic_layer_postgres_sql_method", + "test_semantic_layer_postgres_symmetric_aggregates", + "test_semantic_layer_postgres_with_dimensions", + "test_semantic_layer_postgres_with_joins", + "test_semantic_layer_with_postgres_url" + ], + "collected_tests": [] + }, + "scope-104": { + "path": "tests/db/test_semantic_layer_adapters.py", + "declared_tests": [ + "test_postgres_url_recognized" + ], + "collected_tests": [ + "tests/db/test_semantic_layer_adapters.py::test_postgres_url_recognized" + ] + }, + "scope-105": { + "path": "tests/db/test_snowflake_adapter.py", + "declared_tests": [ + "test_snowflake_fetch_record_batch_mixed_types" + ], + "collected_tests": [ + "tests/db/test_snowflake_adapter.py::test_snowflake_fetch_record_batch_mixed_types" + ] + }, + "scope-106": { + "path": "tests/db/test_snowflake_adapter.py", + "declared_tests": [ + "test_snowflake_fetch_record_batch_empty" + ], + "collected_tests": [ + "tests/db/test_snowflake_adapter.py::test_snowflake_fetch_record_batch_empty" + ] + }, + "scope-107": { + "path": "tests/db/test_snowflake_adapter.py", + "declared_tests": [ + "test_snowflake_fetch_record_batch_native_arrow" + ], + "collected_tests": [ + "tests/db/test_snowflake_adapter.py::test_snowflake_fetch_record_batch_native_arrow" + ] + }, + "scope-108": { + "path": "tests/db/test_snowflake_adapter.py", + "declared_tests": [ + "test_snowflake_fetch_record_batch_native_arrow_empty" + ], + "collected_tests": [ + "tests/db/test_snowflake_adapter.py::test_snowflake_fetch_record_batch_native_arrow_empty" + ] + }, + "scope-109": { + "path": "tests/db/test_snowflake_adapter.py", + "declared_tests": [ + "test_snowflake_fetch_record_batch_fallback" + ], + "collected_tests": [ + "tests/db/test_snowflake_adapter.py::test_snowflake_fetch_record_batch_fallback" + ] + }, + "scope-110": { + "path": "tests/db/test_snowflake_cli_e2e.py", + "declared_tests": [ + "test_cli_query_uses_snowflake_connection" + ], + "collected_tests": [] + }, + "scope-111": { + "path": "tests/db/test_snowflake_integration.py", + "declared_tests": [ + "test_semantic_layer_basic_metric", + "test_semantic_layer_catalog_qualified_table", + "test_semantic_layer_catalog_with_cube_import", + "test_semantic_layer_date_functions", + "test_semantic_layer_dimension_grouping", + "test_semantic_layer_filters", + "test_semantic_layer_joins", + "test_semantic_layer_limit", + "test_semantic_layer_multiple_joins", + "test_semantic_layer_multiple_metrics", + "test_semantic_layer_order_by", + "test_semantic_layer_sql_generation", + "test_semantic_layer_symmetric_aggregates" + ], + "collected_tests": [] + }, + "scope-112": { + "path": "tests/db/test_snowflake_integration.py", + "declared_tests": [ + "test_semantic_layer_date_functions" + ], + "collected_tests": [] + }, + "scope-113": { + "path": "tests/db/test_spark_adapter.py", + "declared_tests": [ + "test_spark_fetch_record_batch_mixed_types" + ], + "collected_tests": [ + "tests/db/test_spark_adapter.py::test_spark_fetch_record_batch_mixed_types" + ] + }, + "scope-114": { + "path": "tests/db/test_spark_cli_e2e.py", + "declared_tests": [ + "test_cli_query_uses_spark_config" + ], + "collected_tests": [] + }, + "scope-115": { + "path": "tests/db/test_spark_integration.py", + "declared_tests": [ + "test_semantic_layer_basic_metric", + "test_semantic_layer_date_functions", + "test_semantic_layer_day_time_dimension_executes_on_spark", + "test_semantic_layer_dimension_grouping", + "test_semantic_layer_filters", + "test_semantic_layer_joins", + "test_semantic_layer_limit", + "test_semantic_layer_month_time_dimension_preserves_date_results_on_spark", + "test_semantic_layer_multiple_joins", + "test_semantic_layer_multiple_metrics", + "test_semantic_layer_order_by", + "test_semantic_layer_sql_generation", + "test_semantic_layer_symmetric_aggregates" + ], + "collected_tests": [] + }, + "scope-116": { + "path": "tests/db/test_spark_integration.py", + "declared_tests": [ + "test_semantic_layer_date_functions" + ], + "collected_tests": [] + }, + "scope-117": { + "path": "tests/interchange/ossie/test_ossie_engine_conformance.py", + "declared_tests": [ + "test_joined_population_and_independent_grains", + "test_logical_aggregate_inputs_have_one_meaning", + "test_portable_current_date_and_time_results", + "test_portable_required_expression_results", + "test_qualified_field_sources_have_one_meaning", + "test_quoted_and_regular_names_preserve_separate_identity", + "test_undeclared_physical_aggregate_input_is_preserved" + ], + "collected_tests": [ + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[amount-amount-current-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[amount-amount-current-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[amount-amount-current-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[amount-amount-legacy-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[amount-amount-legacy-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[amount-amount-legacy-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[Amount-amount-current-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[Amount-amount-current-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[Amount-amount-current-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[Amount-amount-legacy-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[Amount-amount-legacy-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[Amount-amount-legacy-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[gross-gross-current-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[gross-gross-current-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[gross-gross-current-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[gross-gross-legacy-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[gross-gross-legacy-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_logical_aggregate_inputs_have_one_meaning[gross-gross-legacy-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_undeclared_physical_aggregate_input_is_preserved[current-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_undeclared_physical_aggregate_input_is_preserved[current-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_undeclared_physical_aggregate_input_is_preserved[current-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_undeclared_physical_aggregate_input_is_preserved[legacy-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_undeclared_physical_aggregate_input_is_preserved[legacy-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_undeclared_physical_aggregate_input_is_preserved[legacy-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_qualified_field_sources_have_one_meaning[raw_orders-current-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_qualified_field_sources_have_one_meaning[raw_orders-current-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_qualified_field_sources_have_one_meaning[raw_orders-current-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_qualified_field_sources_have_one_meaning[raw_orders-legacy-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_qualified_field_sources_have_one_meaning[raw_orders-legacy-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_qualified_field_sources_have_one_meaning[raw_orders-legacy-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_qualified_field_sources_have_one_meaning[SELECT id, amount FROM raw_orders-current-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_qualified_field_sources_have_one_meaning[SELECT id, amount FROM raw_orders-current-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_qualified_field_sources_have_one_meaning[SELECT id, amount FROM raw_orders-current-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_qualified_field_sources_have_one_meaning[SELECT id, amount FROM raw_orders-legacy-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_qualified_field_sources_have_one_meaning[SELECT id, amount FROM raw_orders-legacy-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_qualified_field_sources_have_one_meaning[SELECT id, amount FROM raw_orders-legacy-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_quoted_and_regular_names_preserve_separate_identity[current-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_quoted_and_regular_names_preserve_separate_identity[current-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_quoted_and_regular_names_preserve_separate_identity[current-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_quoted_and_regular_names_preserve_separate_identity[legacy-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_quoted_and_regular_names_preserve_separate_identity[legacy-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_quoted_and_regular_names_preserve_separate_identity[legacy-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_joined_population_and_independent_grains[current-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_joined_population_and_independent_grains[current-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_joined_population_and_independent_grains[current-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_joined_population_and_independent_grains[legacy-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_joined_population_and_independent_grains[legacy-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_joined_population_and_independent_grains[legacy-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[1 + 2 * 3 - 4 / 2 + 7 % 4-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[1 + 2 * 3 - 4 / 2 + 7 % 4-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[1 + 2 * 3 - 4 / 2 + 7 % 4-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NOT (2 BETWEEN 3 AND 5) AND 2 IN (1,2) OR FALSE-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NOT (2 BETWEEN 3 AND 5) AND 2 IN (1,2) OR FALSE-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NOT (2 BETWEEN 3 AND 5) AND 2 IN (1,2) OR FALSE-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[2 NOT IN (1,3) AND 2 <> 3 AND 2 != 3 AND 2 <= 3 AND 3 >= 2-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[2 NOT IN (1,3) AND 2 <> 3 AND 2 != 3 AND 2 <= 3 AND 3 >= 2-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[2 NOT IN (1,3) AND 2 <> 3 AND 2 != 3 AND 2 <= 3 AND 3 >= 2-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NULL IS NULL AND 1 IS NOT NULL-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NULL IS NULL AND 1 IS NOT NULL-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NULL IS NULL AND 1 IS NOT NULL-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NULL IS NOT DISTINCT FROM NULL-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NULL IS NOT DISTINCT FROM NULL-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NULL IS NOT DISTINCT FROM NULL-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[1 IS DISTINCT FROM NULL-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[1 IS DISTINCT FROM NULL-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[1 IS DISTINCT FROM NULL-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CASE WHEN 2 > 1 THEN 7 ELSE 9 END-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CASE WHEN 2 > 1 THEN 7 ELSE 9 END-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CASE WHEN 2 > 1 THEN 7 ELSE 9 END-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CASE 2 WHEN 1 THEN 7 WHEN 2 THEN 9 END-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CASE 2 WHEN 1 THEN 7 WHEN 2 THEN 9 END-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CASE 2 WHEN 1 THEN 7 WHEN 2 THEN 9 END-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_DATE IS NOT NULL-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_DATE IS NOT NULL-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_DATE IS NOT NULL-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_DATE() IS NOT NULL-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_DATE() IS NOT NULL-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_DATE() IS NOT NULL-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_TIME IS NOT NULL-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_TIME IS NOT NULL-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_TIME IS NOT NULL-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_TIME() IS NOT NULL-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_TIME() IS NOT NULL-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_TIME() IS NOT NULL-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_TIMESTAMP IS NOT NULL-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_TIMESTAMP IS NOT NULL-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_TIMESTAMP IS NOT NULL-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_TIMESTAMP() IS NOT NULL-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_TIMESTAMP() IS NOT NULL-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CURRENT_TIMESTAMP() IS NOT NULL-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[YEAR(DATE '2024-03-01')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[YEAR(DATE '2024-03-01')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[YEAR(DATE '2024-03-01')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[QUARTER(DATE '2024-05-01')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[QUARTER(DATE '2024-05-01')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[QUARTER(DATE '2024-05-01')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MONTH(DATE '2024-03-01')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MONTH(DATE '2024-03-01')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MONTH(DATE '2024-03-01')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DAY(DATE '2024-03-01')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DAY(DATE '2024-03-01')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DAY(DATE '2024-03-01')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DAYOFYEAR(DATE '2024-03-01')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DAYOFYEAR(DATE '2024-03-01')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DAYOFYEAR(DATE '2024-03-01')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[HOUR(TIMESTAMP_NTZ '2024-03-01 12:34:56')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[HOUR(TIMESTAMP_NTZ '2024-03-01 12:34:56')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[HOUR(TIMESTAMP_NTZ '2024-03-01 12:34:56')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MINUTE(TIMESTAMP_NTZ '2024-03-01 12:34:56')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MINUTE(TIMESTAMP_NTZ '2024-03-01 12:34:56')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MINUTE(TIMESTAMP_NTZ '2024-03-01 12:34:56')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SECOND(TIMESTAMP_NTZ '2024-03-01 12:34:56')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SECOND(TIMESTAMP_NTZ '2024-03-01 12:34:56')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SECOND(TIMESTAMP_NTZ '2024-03-01 12:34:56')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[EXTRACT(YEAR FROM DATE '2024-03-01')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[EXTRACT(YEAR FROM DATE '2024-03-01')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[EXTRACT(YEAR FROM DATE '2024-03-01')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[EXTRACT(DAYOFYEAR FROM DATE '2024-03-01')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[EXTRACT(DAYOFYEAR FROM DATE '2024-03-01')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[EXTRACT(DAYOFYEAR FROM DATE '2024-03-01')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DATE_PART('month', DATE '2024-03-01')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DATE_PART('month', DATE '2024-03-01')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DATE_PART('month', DATE '2024-03-01')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(DATE_TRUNC('week', DATE '2024-03-03') AS DATE)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(DATE_TRUNC('week', DATE '2024-03-03') AS DATE)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(DATE_TRUNC('week', DATE '2024-03-03') AS DATE)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(DATE_TRUNC('quarter', DATE '2024-05-12') AS DATE)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(DATE_TRUNC('quarter', DATE '2024-05-12') AS DATE)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(DATE_TRUNC('quarter', DATE '2024-05-12') AS DATE)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(DATEADD(day, 7, DATE '2024-02-25') AS DATE)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(DATEADD(day, 7, DATE '2024-02-25') AS DATE)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(DATEADD(day, 7, DATE '2024-02-25') AS DATE)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(DATEADD(month, -1, DATE '2024-03-15') AS DATE)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(DATEADD(month, -1, DATE '2024-03-15') AS DATE)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(DATEADD(month, -1, DATE '2024-03-15') AS DATE)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DATEDIFF(day, DATE '2024-02-25', DATE '2024-03-03')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DATEDIFF(day, DATE '2024-02-25', DATE '2024-03-03')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DATEDIFF(day, DATE '2024-02-25', DATE '2024-03-03')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DATEDIFF(month, DATE '2023-12-31', DATE '2024-02-01')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DATEDIFF(month, DATE '2023-12-31', DATE '2024-02-01')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DATEDIFF(month, DATE '2023-12-31', DATE '2024-02-01')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DATEDIFF(year, DATE '2023-12-31', DATE '2024-01-01')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DATEDIFF(year, DATE '2023-12-31', DATE '2024-01-01')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DATEDIFF(year, DATE '2023-12-31', DATE '2024-01-01')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TIME '12:34:56'-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TIME '12:34:56'-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TIME '12:34:56'-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TO_DATE('2024-03-01')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TO_DATE('2024-03-01')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TO_DATE('2024-03-01')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TO_TIMESTAMP('2024-03-01 12:34:56')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TO_TIMESTAMP('2024-03-01 12:34:56')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TO_TIMESTAMP('2024-03-01 12:34:56')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('2024-03-01 12:34:56' AS TIMESTAMP_NTZ)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('2024-03-01 12:34:56' AS TIMESTAMP_NTZ)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('2024-03-01 12:34:56' AS TIMESTAMP_NTZ)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CONCAT('ab', 'cd', 'ef')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CONCAT('ab', 'cd', 'ef')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CONCAT('ab', 'cd', 'ef')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results['ab' || 'cd'-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results['ab' || 'cd'-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results['ab' || 'cd'-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LENGTH('caf\\xe9')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LENGTH('caf\\xe9')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LENGTH('caf\\xe9')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LOWER('AbC')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LOWER('AbC')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LOWER('AbC')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[UPPER('AbC')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[UPPER('AbC')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[UPPER('AbC')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRIM(' abc ')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRIM(' abc ')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRIM(' abc ')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LTRIM(' abc ')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LTRIM(' abc ')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LTRIM(' abc ')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[RTRIM(' abc ')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[RTRIM(' abc ')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[RTRIM(' abc ')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LEFT('abcdef', 2)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LEFT('abcdef', 2)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LEFT('abcdef', 2)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[RIGHT('abcdef', 2)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[RIGHT('abcdef', 2)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[RIGHT('abcdef', 2)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUBSTRING('abcdef', 2, 3)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUBSTRING('abcdef', 2, 3)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUBSTRING('abcdef', 2, 3)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[REPLACE('aba', 'a', 'x')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[REPLACE('aba', 'a', 'x')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[REPLACE('aba', 'a', 'x')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SPLIT_PART('a-b-c', '-', 2)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SPLIT_PART('a-b-c', '-', 2)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SPLIT_PART('a-b-c', '-', 2)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[POSITION('bc' IN 'abcd')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[POSITION('bc' IN 'abcd')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[POSITION('bc' IN 'abcd')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CHARINDEX('bc', 'abcd')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CHARINDEX('bc', 'abcd')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CHARINDEX('bc', 'abcd')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CONTAINS('Abcd', 'bc')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CONTAINS('Abcd', 'bc')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CONTAINS('Abcd', 'bc')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CONTAINS('Abcd', 'BC')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CONTAINS('Abcd', 'BC')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CONTAINS('Abcd', 'BC')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[STARTSWITH('ab_cd', 'ab_')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[STARTSWITH('ab_cd', 'ab_')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[STARTSWITH('ab_cd', 'ab_')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ENDSWITH('ab_cd', '_cd')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ENDSWITH('ab_cd', '_cd')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ENDSWITH('ab_cd', '_cd')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results['Abcd' LIKE 'A_c%'-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results['Abcd' LIKE 'A_c%'-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results['Abcd' LIKE 'A_c%'-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results['Abcd' ILIKE 'a_c%'-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results['Abcd' ILIKE 'a_c%'-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results['Abcd' ILIKE 'a_c%'-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[REGEXP_LIKE('abcd', '^a.*d$')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[REGEXP_LIKE('abcd', '^a.*d$')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[REGEXP_LIKE('abcd', '^a.*d$')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[REGEXP_LIKE('abcd', 'bc')-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[REGEXP_LIKE('abcd', 'bc')-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[REGEXP_LIKE('abcd', 'bc')-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ABS(-12.3)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ABS(-12.3)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ABS(-12.3)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ROUND(12.345, 2)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ROUND(12.345, 2)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ROUND(12.345, 2)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[FLOOR(-12.3)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[FLOOR(-12.3)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[FLOOR(-12.3)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CEIL(-12.3)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CEIL(-12.3)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CEIL(-12.3)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CEILING(12.3)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CEILING(12.3)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CEILING(12.3)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRUNC(-12.345, 2)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRUNC(-12.345, 2)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRUNC(-12.345, 2)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRUNC(1.15, 2)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRUNC(1.15, 2)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRUNC(1.15, 2)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRUNC(-0.29, 2)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRUNC(-0.29, 2)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRUNC(-0.29, 2)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRUNCATE(123.45, -1)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRUNCATE(123.45, -1)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[TRUNCATE(123.45, -1)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MOD(7, 3)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MOD(7, 3)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MOD(7, 3)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SIGN(-12)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SIGN(-12)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SIGN(-12)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[POWER(2, 3)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[POWER(2, 3)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[POWER(2, 3)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SQRT(9)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SQRT(9)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SQRT(9)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[EXP(0)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[EXP(0)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[EXP(0)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LN(1)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LN(1)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LN(1)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LOG(2, 8)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LOG(2, 8)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LOG(2, 8)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LOG10(100)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LOG10(100)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LOG10(100)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[GREATEST(1, 7, 3)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[GREATEST(1, 7, 3)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[GREATEST(1, 7, 3)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LEAST(1, 7, 3)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LEAST(1, 7, 3)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LEAST(1, 7, 3)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[IF(TRUE, 7, 9)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[IF(TRUE, 7, 9)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[IF(TRUE, 7, 9)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[IFF(FALSE, 7, 9)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[IFF(FALSE, 7, 9)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[IFF(FALSE, 7, 9)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NULLIF(1,1)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NULLIF(1,1)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NULLIF(1,1)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[COALESCE(NULL,NULL,3)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[COALESCE(NULL,NULL,3)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[COALESCE(NULL,NULL,3)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[IFNULL(NULL,3)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[IFNULL(NULL,3)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[IFNULL(NULL,3)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NVL(NULL,3)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NVL(NULL,3)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NVL(NULL,3)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NVL2(NULL,3,7)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NVL2(NULL,3,7)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NVL2(NULL,3,7)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NVL2(1,3,7)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NVL2(1,3,7)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NVL2(1,3,7)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ZEROIFNULL(NULL)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ZEROIFNULL(NULL)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ZEROIFNULL(NULL)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NULLIFZERO(0)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NULLIFZERO(0)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NULLIFZERO(0)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(12 AS VARCHAR)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(12 AS VARCHAR)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST(12 AS VARCHAR)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12' AS STRING)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12' AS STRING)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12' AS STRING)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12' AS INTEGER)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12' AS INTEGER)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12' AS INTEGER)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12' AS BIGINT)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12' AS BIGINT)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12' AS BIGINT)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12.3' AS DECIMAL(5,2))-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12.3' AS DECIMAL(5,2))-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12.3' AS DECIMAL(5,2))-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12.3' AS NUMERIC(5,2))-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12.3' AS NUMERIC(5,2))-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12.3' AS NUMERIC(5,2))-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12.3' AS FLOAT)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12.3' AS FLOAT)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12.3' AS FLOAT)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12.3' AS DOUBLE)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12.3' AS DOUBLE)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12.3' AS DOUBLE)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('true' AS BOOLEAN)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('true' AS BOOLEAN)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('true' AS BOOLEAN)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('2024-03-01' AS DATE)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('2024-03-01' AS DATE)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('2024-03-01' AS DATE)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('2024-03-01 12:34:56' AS TIMESTAMP)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('2024-03-01 12:34:56' AS TIMESTAMP)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('2024-03-01 12:34:56' AS TIMESTAMP)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12:34:56' AS TIME)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12:34:56' AS TIME)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CAST('12:34:56' AS TIME)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[COUNT(x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[COUNT(x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[COUNT(x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[COUNT(*)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[COUNT(*)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[COUNT(*)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[COUNT(DISTINCT x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[COUNT(DISTINCT x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[COUNT(DISTINCT x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(DISTINCT x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(DISTINCT x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(DISTINCT x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[AVG(x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[AVG(x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[AVG(x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MIN(x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MIN(x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MIN(x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MAX(x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MAX(x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MAX(x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[STDDEV(x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[STDDEV(x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[STDDEV(x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[STDDEV_SAMP(x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[STDDEV_SAMP(x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[STDDEV_SAMP(x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[STDDEV_POP(x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[STDDEV_POP(x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[STDDEV_POP(x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[VARIANCE(x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[VARIANCE(x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[VARIANCE(x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[VAR_SAMP(x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[VAR_SAMP(x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[VAR_SAMP(x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[VAR_POP(x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[VAR_POP(x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[VAR_POP(x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MEDIAN(x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MEDIAN(x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[MEDIAN(x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENTILE_DISC(0.25) WITHIN GROUP (ORDER BY x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENTILE_DISC(0.25) WITHIN GROUP (ORDER BY x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENTILE_DISC(0.25) WITHIN GROUP (ORDER BY x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY x DESC)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY x DESC)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY x DESC)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENTILE_DISC(0.25) WITHIN GROUP (ORDER BY x DESC)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENTILE_DISC(0.25) WITHIN GROUP (ORDER BY x DESC)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENTILE_DISC(0.25) WITHIN GROUP (ORDER BY x DESC)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(CASE WHEN x > 1 THEN x ELSE 0 END)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(CASE WHEN x > 1 THEN x ELSE 0 END)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(CASE WHEN x > 1 THEN x ELSE 0 END)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ROW_NUMBER() OVER (ORDER BY x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ROW_NUMBER() OVER (ORDER BY x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[ROW_NUMBER() OVER (ORDER BY x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[RANK() OVER (ORDER BY x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[RANK() OVER (ORDER BY x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[RANK() OVER (ORDER BY x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DENSE_RANK() OVER (ORDER BY x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DENSE_RANK() OVER (ORDER BY x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[DENSE_RANK() OVER (ORDER BY x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NTILE(2) OVER (ORDER BY x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NTILE(2) OVER (ORDER BY x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NTILE(2) OVER (ORDER BY x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENT_RANK() OVER (ORDER BY x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENT_RANK() OVER (ORDER BY x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[PERCENT_RANK() OVER (ORDER BY x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CUME_DIST() OVER (ORDER BY x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CUME_DIST() OVER (ORDER BY x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[CUME_DIST() OVER (ORDER BY x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LAG(x, 1, 0) OVER (ORDER BY x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LAG(x, 1, 0) OVER (ORDER BY x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LAG(x, 1, 0) OVER (ORDER BY x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LEAD(x, 1, 0) OVER (ORDER BY x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LEAD(x, 1, 0) OVER (ORDER BY x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LEAD(x, 1, 0) OVER (ORDER BY x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[FIRST_VALUE(x) OVER (ORDER BY x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[FIRST_VALUE(x) OVER (ORDER BY x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[FIRST_VALUE(x) OVER (ORDER BY x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LAST_VALUE(x) OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LAST_VALUE(x) OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[LAST_VALUE(x) OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NTH_VALUE(x, 2) OVER (ORDER BY x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NTH_VALUE(x, 2) OVER (ORDER BY x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[NTH_VALUE(x, 2) OVER (ORDER BY x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(x) OVER (ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(x) OVER (ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(x) OVER (ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[AVG(x) OVER (ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[AVG(x) OVER (ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[AVG(x) OVER (ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(x) OVER (PARTITION BY x)-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(x) OVER (PARTITION BY x)-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_required_expression_results[SUM(x) OVER (PARTITION BY x)-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_DATE-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_DATE-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_DATE-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_DATE()-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_DATE()-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_DATE()-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_TIME-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_TIME-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_TIME-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_TIME()-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_TIME()-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_TIME()-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_TIMESTAMP-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_TIMESTAMP-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_TIMESTAMP-native_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_TIMESTAMP()-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_TIMESTAMP()-public_rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_portable_current_date_and_time_results[CURRENT_TIMESTAMP()-native_rust]" + ] + }, + "scope-118": { + "path": "tests/interchange/ossie/test_ossie_engine_conformance.py", + "declared_tests": [ + "test_cli_ossie_query_and_rewrite_execute_same_results" + ], + "collected_tests": [ + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_cli_ossie_query_and_rewrite_execute_same_results[current-query-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_cli_ossie_query_and_rewrite_execute_same_results[current-query-rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_cli_ossie_query_and_rewrite_execute_same_results[current-rewrite-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_cli_ossie_query_and_rewrite_execute_same_results[current-rewrite-rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_cli_ossie_query_and_rewrite_execute_same_results[legacy-query-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_cli_ossie_query_and_rewrite_execute_same_results[legacy-query-rust]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_cli_ossie_query_and_rewrite_execute_same_results[legacy-rewrite-python]", + "tests/interchange/ossie/test_ossie_engine_conformance.py::test_cli_ossie_query_and_rewrite_execute_same_results[legacy-rewrite-rust]" + ] + }, + "scope-119": { + "path": "tests/metrics/test_advanced.py", + "declared_tests": [ + "test_conversion_metric", + "test_conversion_metric_backwards_compatible", + "test_conversion_metric_steps_and_base_event", + "test_cumulative_fill_nulls_applies_after_window", + "test_dotted_metric_name_alias", + "test_fill_nulls_with_string", + "test_fill_nulls_with_zero", + "test_filter_dimension_with_model_qualified_sql_expr", + "test_model_measure_null_fill_applies_to_direct_and_dependent_metrics", + "test_mom_difference", + "test_month_comparison_does_not_use_previous_available_sparse_row", + "test_month_to_date_metric", + "test_multistep_conversion_2_steps_via_steps_list", + "test_multistep_conversion_funnel", + "test_multistep_funnel_chronological_order_enforced", + "test_multistep_funnel_expression_timestamp", + "test_multistep_funnel_model_name_prefix_step_predicates", + "test_multistep_funnel_model_placeholder_filter", + "test_multistep_funnel_model_placeholder_step_predicates", + "test_multistep_funnel_model_placeholder_timestamp", + "test_multistep_funnel_monotonic_counts", + "test_multistep_funnel_only_prior_step2_not_counted", + "test_multistep_funnel_or_step_with_filter", + "test_multistep_funnel_order_by_metric_name", + "test_multistep_funnel_qualified_filters", + "test_multistep_funnel_repeated_actions_valid_path", + "test_multistep_funnel_total_excludes_non_entrants", + "test_offset_ratio_fill_nulls_applies_to_missing_prior_period", + "test_offset_ratio_metric", + "test_offset_ratio_metric_multi_period", + "test_offset_ratio_metric_uses_base_granularity", + "test_offset_ratio_metric_year_offset", + "test_time_comparison_fill_nulls_applies_to_missing_prior_period", + "test_wow_percent_change_partitions_by_dimension", + "test_wow_ratio", + "test_year_to_date_metric", + "test_yoy_percent_change" + ], + "collected_tests": [ + "tests/metrics/test_advanced.py::test_month_to_date_metric", + "tests/metrics/test_advanced.py::test_year_to_date_metric", + "tests/metrics/test_advanced.py::test_fill_nulls_with_zero", + "tests/metrics/test_advanced.py::test_model_measure_null_fill_applies_to_direct_and_dependent_metrics[SELECT CAST(NULL AS INTEGER) AS amount-None-0.1]", + "tests/metrics/test_advanced.py::test_model_measure_null_fill_applies_to_direct_and_dependent_metrics[SELECT 10 AS amount-filters1-0.1]", + "tests/metrics/test_advanced.py::test_model_measure_null_fill_applies_to_direct_and_dependent_metrics[SELECT 10 AS amount WHERE false-None-0]", + "tests/metrics/test_advanced.py::test_fill_nulls_with_string", + "tests/metrics/test_advanced.py::test_cumulative_fill_nulls_applies_after_window", + "tests/metrics/test_advanced.py::test_offset_ratio_metric", + "tests/metrics/test_advanced.py::test_offset_ratio_fill_nulls_applies_to_missing_prior_period", + "tests/metrics/test_advanced.py::test_offset_ratio_metric_multi_period", + "tests/metrics/test_advanced.py::test_offset_ratio_metric_uses_base_granularity", + "tests/metrics/test_advanced.py::test_offset_ratio_metric_year_offset", + "tests/metrics/test_advanced.py::test_conversion_metric", + "tests/metrics/test_advanced.py::test_yoy_percent_change", + "tests/metrics/test_advanced.py::test_mom_difference", + "tests/metrics/test_advanced.py::test_time_comparison_fill_nulls_applies_to_missing_prior_period", + "tests/metrics/test_advanced.py::test_month_comparison_does_not_use_previous_available_sparse_row", + "tests/metrics/test_advanced.py::test_dotted_metric_name_alias", + "tests/metrics/test_advanced.py::test_wow_ratio", + "tests/metrics/test_advanced.py::test_wow_percent_change_partitions_by_dimension", + "tests/metrics/test_advanced.py::test_multistep_conversion_funnel", + "tests/metrics/test_advanced.py::test_multistep_conversion_2_steps_via_steps_list", + "tests/metrics/test_advanced.py::test_conversion_metric_backwards_compatible", + "tests/metrics/test_advanced.py::test_conversion_metric_steps_and_base_event", + "tests/metrics/test_advanced.py::test_multistep_funnel_monotonic_counts", + "tests/metrics/test_advanced.py::test_multistep_funnel_total_excludes_non_entrants", + "tests/metrics/test_advanced.py::test_multistep_funnel_chronological_order_enforced", + "tests/metrics/test_advanced.py::test_multistep_funnel_qualified_filters", + "tests/metrics/test_advanced.py::test_filter_dimension_with_model_qualified_sql_expr", + "tests/metrics/test_advanced.py::test_multistep_funnel_repeated_actions_valid_path", + "tests/metrics/test_advanced.py::test_multistep_funnel_only_prior_step2_not_counted", + "tests/metrics/test_advanced.py::test_multistep_funnel_expression_timestamp", + "tests/metrics/test_advanced.py::test_multistep_funnel_or_step_with_filter", + "tests/metrics/test_advanced.py::test_multistep_funnel_model_placeholder_timestamp", + "tests/metrics/test_advanced.py::test_multistep_funnel_model_placeholder_step_predicates", + "tests/metrics/test_advanced.py::test_multistep_funnel_model_name_prefix_step_predicates", + "tests/metrics/test_advanced.py::test_multistep_funnel_model_placeholder_filter", + "tests/metrics/test_advanced.py::test_multistep_funnel_order_by_metric_name" + ] + }, + "scope-120": { + "path": "tests/metrics/test_cohort.py", + "declared_tests": [ + "test_cohort_ambiguous_unqualified_raises", + "test_cohort_basic", + "test_cohort_graph_level_metric", + "test_cohort_mixed_with_conversion_raises", + "test_cohort_model_scoped_unqualified", + "test_cohort_outer_agg_without_sql_raises", + "test_cohort_outer_sql_references_subquery", + "test_cohort_reserved_word_dimension", + "test_cohort_unknown_dimension_raises", + "test_cohort_with_dimension", + "test_cohort_with_time_grain_uses_grained_output_alias" + ], + "collected_tests": [ + "tests/metrics/test_cohort.py::test_cohort_basic", + "tests/metrics/test_cohort.py::test_cohort_graph_level_metric", + "tests/metrics/test_cohort.py::test_cohort_model_scoped_unqualified", + "tests/metrics/test_cohort.py::test_cohort_with_dimension", + "tests/metrics/test_cohort.py::test_cohort_with_time_grain_uses_grained_output_alias", + "tests/metrics/test_cohort.py::test_cohort_outer_agg_without_sql_raises", + "tests/metrics/test_cohort.py::test_cohort_unknown_dimension_raises", + "tests/metrics/test_cohort.py::test_cohort_outer_sql_references_subquery", + "tests/metrics/test_cohort.py::test_cohort_ambiguous_unqualified_raises", + "tests/metrics/test_cohort.py::test_cohort_reserved_word_dimension", + "tests/metrics/test_cohort.py::test_cohort_mixed_with_conversion_raises" + ] + }, + "scope-121": { + "path": "tests/metrics/test_conversion_source_parity.py", + "declared_tests": [ + "test_conversion_sql_source_expressions" + ], + "collected_tests": [ + "tests/metrics/test_conversion_source_parity.py::test_conversion_sql_source_expressions[model-person-python]", + "tests/metrics/test_conversion_source_parity.py::test_conversion_sql_source_expressions[model-person-rust]", + "tests/metrics/test_conversion_source_parity.py::test_conversion_sql_source_expressions[model-events.uid-python]", + "tests/metrics/test_conversion_source_parity.py::test_conversion_sql_source_expressions[model-events.uid-rust]", + "tests/metrics/test_conversion_source_parity.py::test_conversion_sql_source_expressions[model-uid-python]", + "tests/metrics/test_conversion_source_parity.py::test_conversion_sql_source_expressions[model-uid-rust]", + "tests/metrics/test_conversion_source_parity.py::test_conversion_sql_source_expressions[graph-person-python]", + "tests/metrics/test_conversion_source_parity.py::test_conversion_sql_source_expressions[graph-person-rust]", + "tests/metrics/test_conversion_source_parity.py::test_conversion_sql_source_expressions[graph-uid-python]", + "tests/metrics/test_conversion_source_parity.py::test_conversion_sql_source_expressions[graph-uid-rust]" + ] + }, + "scope-122": { + "path": "tests/metrics/test_conversion_source_parity.py", + "declared_tests": [ + "test_rust_two_event_conversion_projects_source_aliases" + ], + "collected_tests": [ + "tests/metrics/test_conversion_source_parity.py::test_rust_two_event_conversion_projects_source_aliases[False]", + "tests/metrics/test_conversion_source_parity.py::test_rust_two_event_conversion_projects_source_aliases[True]" + ] + }, + "scope-123": { + "path": "tests/metrics/test_conversion_source_parity.py", + "declared_tests": [ + "test_conversion_fill_is_accepted_without_changing_empty_result" + ], + "collected_tests": [ + "tests/metrics/test_conversion_source_parity.py::test_conversion_fill_is_accepted_without_changing_empty_result[python]", + "tests/metrics/test_conversion_source_parity.py::test_conversion_fill_is_accepted_without_changing_empty_result[rust]" + ] + }, + "scope-124": { + "path": "tests/metrics/test_conversion_source_parity.py", + "declared_tests": [ + "test_two_event_conversion_uses_last_time_dimension_instead_of_default" + ], + "collected_tests": [ + "tests/metrics/test_conversion_source_parity.py::test_two_event_conversion_uses_last_time_dimension_instead_of_default[python]", + "tests/metrics/test_conversion_source_parity.py::test_two_event_conversion_uses_last_time_dimension_instead_of_default[rust]" + ] + }, + "scope-125": { + "path": "tests/metrics/test_cumulative.py", + "declared_tests": [ + "test_time_comparison_over_derived_cumulative_chain" + ], + "collected_tests": [ + "tests/metrics/test_cumulative.py::test_time_comparison_over_derived_cumulative_chain" + ] + }, + "scope-126": { + "path": "tests/metrics/test_cumulative.py", + "declared_tests": [ + "test_time_comparison_over_ratio_cumulative_chain" + ], + "collected_tests": [ + "tests/metrics/test_cumulative.py::test_time_comparison_over_ratio_cumulative_chain" + ] + }, + "scope-127": { + "path": "tests/metrics/test_cumulative.py", + "declared_tests": [ + "test_time_comparison_with_dependency_free_expression_metric" + ], + "collected_tests": [ + "tests/metrics/test_cumulative.py::test_time_comparison_with_dependency_free_expression_metric" + ] + }, + "scope-128": { + "path": "tests/metrics/test_filters.py", + "declared_tests": [ + "test_filter_classification_and_rewrite_respect_nested_select_alias_scope", + "test_filter_classification_ignores_metric_names_in_non_column_tokens", + "test_where_filter_rewrite_only_changes_semantic_columns" + ], + "collected_tests": [ + "tests/metrics/test_filters.py::test_filter_classification_ignores_metric_names_in_non_column_tokens", + "tests/metrics/test_filters.py::test_where_filter_rewrite_only_changes_semantic_columns", + "tests/metrics/test_filters.py::test_filter_classification_and_rewrite_respect_nested_select_alias_scope" + ] + }, + "scope-129": { + "path": "tests/metrics/test_non_additive_guard.py", + "declared_tests": [ + "test_semi_additive_compiles_without_qualify_on_postgres" + ], + "collected_tests": [ + "tests/metrics/test_non_additive_guard.py::test_semi_additive_compiles_without_qualify_on_postgres" + ] + }, + "scope-130": { + "path": "tests/metrics/test_retention.py", + "declared_tests": [ + "test_retention_aliased_entity_dimension", + "test_retention_ambiguous_model_raises", + "test_retention_day_granularity_results", + "test_retention_default_activity_event", + "test_retention_filter_with_model_qualified_sql_expr", + "test_retention_graph_metric_does_not_bind_to_same_name_model_metric", + "test_retention_metric_level_filters", + "test_retention_mixed_with_regular_metric_raises", + "test_retention_model_level_metric", + "test_retention_model_placeholder_expansion_sql_model", + "test_retention_model_placeholder_expansion_table_model", + "test_retention_model_placeholder_in_time_dimension", + "test_retention_multiple_retention_metrics_raises", + "test_retention_offset_in_sql", + "test_retention_periods_zero_raises_validation_error", + "test_retention_sql_generation", + "test_retention_week_granularity" + ], + "collected_tests": [ + "tests/metrics/test_retention.py::test_retention_sql_generation", + "tests/metrics/test_retention.py::test_retention_day_granularity_results", + "tests/metrics/test_retention.py::test_retention_default_activity_event", + "tests/metrics/test_retention.py::test_retention_model_level_metric", + "tests/metrics/test_retention.py::test_retention_week_granularity", + "tests/metrics/test_retention.py::test_retention_model_placeholder_expansion_sql_model", + "tests/metrics/test_retention.py::test_retention_model_placeholder_expansion_table_model", + "tests/metrics/test_retention.py::test_retention_periods_zero_raises_validation_error", + "tests/metrics/test_retention.py::test_retention_model_placeholder_in_time_dimension", + "tests/metrics/test_retention.py::test_retention_aliased_entity_dimension", + "tests/metrics/test_retention.py::test_retention_metric_level_filters", + "tests/metrics/test_retention.py::test_retention_filter_with_model_qualified_sql_expr", + "tests/metrics/test_retention.py::test_retention_multiple_retention_metrics_raises", + "tests/metrics/test_retention.py::test_retention_mixed_with_regular_metric_raises", + "tests/metrics/test_retention.py::test_retention_offset_in_sql", + "tests/metrics/test_retention.py::test_retention_ambiguous_model_raises", + "tests/metrics/test_retention.py::test_retention_graph_metric_does_not_bind_to_same_name_model_metric" + ] + }, + "scope-131": { + "path": "tests/metrics/test_snapshot_wrapper_parity.py", + "declared_tests": [ + "test_snapshot_wrappers_preserve_leaf_populations" + ], + "collected_tests": [ + "tests/metrics/test_snapshot_wrapper_parity.py::test_snapshot_wrappers_preserve_leaf_populations[min-20-python]", + "tests/metrics/test_snapshot_wrapper_parity.py::test_snapshot_wrappers_preserve_leaf_populations[min-20-rust]", + "tests/metrics/test_snapshot_wrapper_parity.py::test_snapshot_wrappers_preserve_leaf_populations[max-30-python]", + "tests/metrics/test_snapshot_wrapper_parity.py::test_snapshot_wrappers_preserve_leaf_populations[max-30-rust]" + ] + }, + "scope-132": { + "path": "tests/metrics/test_snapshot_wrapper_parity.py", + "declared_tests": [ + "test_snapshot_wrapper_defaults_apply_after_leaf_selection" + ], + "collected_tests": [ + "tests/metrics/test_snapshot_wrapper_parity.py::test_snapshot_wrapper_defaults_apply_after_leaf_selection[python]", + "tests/metrics/test_snapshot_wrapper_parity.py::test_snapshot_wrapper_defaults_apply_after_leaf_selection[rust]" + ] + }, + "scope-133": { + "path": "tests/metrics/test_symmetric_aggs.py", + "declared_tests": [ + "test_derived_and_ratio_metrics_reuse_fanout_safe_leaf_aggregates", + "test_fanout_evaluates_complete_sql_over_deduplicated_entity_rows", + "test_fanout_isolates_typed_entity_rows_for_double_sum_avg_and_nulls", + "test_fanout_join_detection_multiple_joins", + "test_fanout_join_detection_single_join", + "test_fanout_rejects_filtered_unqualified_constant_complete_sql", + "test_fanout_typed_composite_keys_do_not_collide_on_delimiters", + "test_filter_only_sibling_fanout_is_deduplicated_for_non_base_metric", + "test_filtered_count_under_fanout", + "test_model_measure_null_fill_under_fanout", + "test_preagg_grain_preserved_with_filters", + "test_symmetric_aggregates_in_sql_generation", + "test_symmetric_aggregates_with_data" + ], + "collected_tests": [ + "tests/metrics/test_symmetric_aggs.py::test_fanout_join_detection_single_join", + "tests/metrics/test_symmetric_aggs.py::test_fanout_join_detection_multiple_joins", + "tests/metrics/test_symmetric_aggs.py::test_symmetric_aggregates_in_sql_generation", + "tests/metrics/test_symmetric_aggs.py::test_symmetric_aggregates_with_data", + "tests/metrics/test_symmetric_aggs.py::test_fanout_isolates_typed_entity_rows_for_double_sum_avg_and_nulls", + "tests/metrics/test_symmetric_aggs.py::test_fanout_evaluates_complete_sql_over_deduplicated_entity_rows", + "tests/metrics/test_symmetric_aggs.py::test_fanout_rejects_filtered_unqualified_constant_complete_sql", + "tests/metrics/test_symmetric_aggs.py::test_fanout_typed_composite_keys_do_not_collide_on_delimiters", + "tests/metrics/test_symmetric_aggs.py::test_filter_only_sibling_fanout_is_deduplicated_for_non_base_metric", + "tests/metrics/test_symmetric_aggs.py::test_derived_and_ratio_metrics_reuse_fanout_safe_leaf_aggregates", + "tests/metrics/test_symmetric_aggs.py::test_preagg_grain_preserved_with_filters", + "tests/metrics/test_symmetric_aggs.py::test_filtered_count_under_fanout", + "tests/metrics/test_symmetric_aggs.py::test_model_measure_null_fill_under_fanout" + ] + }, + "scope-134": { + "path": "tests/queries/test_cross_model_calculated_grain.py", + "declared_tests": [ + "test_calculated_metrics_preserve_each_source_grain", + "test_cross_model_calculation_output_name_collisions", + "test_filtered_ratio_rejects_unknown_customer_grain", + "test_mixed_row_and_calculation_or_rejected" + ], + "collected_tests": [ + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query0-expected0]", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query1-expected1]", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query2-expected2]", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query3-expected3]", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query4-expected4]", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query5-expected5]", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query6-expected6]", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query7-expected7]", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query8-expected8]", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query9-expected9]", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query10-expected10]", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query11-expected11]", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query12-expected12]", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query13-expected13]", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain[query14-expected14]", + "tests/queries/test_cross_model_calculated_grain.py::test_filtered_ratio_rejects_unknown_customer_grain", + "tests/queries/test_cross_model_calculated_grain.py::test_mixed_row_and_calculation_or_rejected", + "tests/queries/test_cross_model_calculated_grain.py::test_cross_model_calculation_output_name_collisions" + ] + }, + "scope-135": { + "path": "tests/queries/test_deterministic_join_anchor.py", + "declared_tests": [ + "test_graph_metric_sql_reference_order_determines_one_to_one_join_anchor" + ], + "collected_tests": [ + "tests/queries/test_deterministic_join_anchor.py::test_graph_metric_sql_reference_order_determines_one_to_one_join_anchor" + ] + }, + "scope-136": { + "path": "tests/queries/test_relationship_key_validation.py", + "declared_tests": [ + "test_declared_foreign_key_groups_without_dimension" + ], + "collected_tests": [ + "tests/queries/test_relationship_key_validation.py::test_declared_foreign_key_groups_without_dimension[python]", + "tests/queries/test_relationship_key_validation.py::test_declared_foreign_key_groups_without_dimension[rust]" + ] + }, + "scope-137": { + "path": "tests/queries/test_rust_query_rewriter_route.py", + "declared_tests": [ + "test_caller_context_reaches_rust_without_fallback", + "test_cte_collision_binding_belongs_to_contextual_rust", + "test_explicit_python_overrides_legacy_environment", + "test_nonstrict_yardstick_validation_returns_original_sql", + "test_only_typed_failures_allow_fallback", + "test_plain_query_explanation_does_not_claim_rust_compilation", + "test_query_rewriter_passes_unexpanded_graph_metric_to_rust", + "test_rust_route_validates_empty_projection_and_source", + "test_security_errors_never_fall_back", + "test_set_operations_reach_rust_before_python_rewrite", + "test_strict_rust_passes_yardstick_sql_to_rust", + "test_strict_rust_preserves_query_only_validation", + "test_unexpected_compiler_errors_propagate" + ], + "collected_tests": [ + "tests/queries/test_rust_query_rewriter_route.py::test_query_rewriter_passes_unexpanded_graph_metric_to_rust", + "tests/queries/test_rust_query_rewriter_route.py::test_unexpected_compiler_errors_propagate[rewrite-True-error0]", + "tests/queries/test_rust_query_rewriter_route.py::test_unexpected_compiler_errors_propagate[rewrite-True-error1]", + "tests/queries/test_rust_query_rewriter_route.py::test_unexpected_compiler_errors_propagate[rewrite-False-error0]", + "tests/queries/test_rust_query_rewriter_route.py::test_unexpected_compiler_errors_propagate[rewrite-False-error1]", + "tests/queries/test_rust_query_rewriter_route.py::test_unexpected_compiler_errors_propagate[explain-True-error0]", + "tests/queries/test_rust_query_rewriter_route.py::test_unexpected_compiler_errors_propagate[explain-True-error1]", + "tests/queries/test_rust_query_rewriter_route.py::test_unexpected_compiler_errors_propagate[explain-False-error0]", + "tests/queries/test_rust_query_rewriter_route.py::test_unexpected_compiler_errors_propagate[explain-False-error1]", + "tests/queries/test_rust_query_rewriter_route.py::test_only_typed_failures_allow_fallback[True-error0]", + "tests/queries/test_rust_query_rewriter_route.py::test_only_typed_failures_allow_fallback[True-error1]", + "tests/queries/test_rust_query_rewriter_route.py::test_only_typed_failures_allow_fallback[False-error0]", + "tests/queries/test_rust_query_rewriter_route.py::test_only_typed_failures_allow_fallback[False-error1]", + "tests/queries/test_rust_query_rewriter_route.py::test_strict_rust_passes_yardstick_sql_to_rust[rewrite]", + "tests/queries/test_rust_query_rewriter_route.py::test_strict_rust_passes_yardstick_sql_to_rust[explain]", + "tests/queries/test_rust_query_rewriter_route.py::test_rust_route_validates_empty_projection_and_source[SELECT *-requires a FROM clause]", + "tests/queries/test_rust_query_rewriter_route.py::test_rust_route_validates_empty_projection_and_source[SELECT FROM orders-select at least one]", + "tests/queries/test_rust_query_rewriter_route.py::test_nonstrict_yardstick_validation_returns_original_sql", + "tests/queries/test_rust_query_rewriter_route.py::test_caller_context_reaches_rust_without_fallback", + "tests/queries/test_rust_query_rewriter_route.py::test_security_errors_never_fall_back[True]", + "tests/queries/test_rust_query_rewriter_route.py::test_security_errors_never_fall_back[False]", + "tests/queries/test_rust_query_rewriter_route.py::test_explicit_python_overrides_legacy_environment", + "tests/queries/test_rust_query_rewriter_route.py::test_strict_rust_preserves_query_only_validation", + "tests/queries/test_rust_query_rewriter_route.py::test_set_operations_reach_rust_before_python_rewrite[rewrite]", + "tests/queries/test_rust_query_rewriter_route.py::test_set_operations_reach_rust_before_python_rewrite[explain]", + "tests/queries/test_rust_query_rewriter_route.py::test_plain_query_explanation_does_not_claim_rust_compilation", + "tests/queries/test_rust_query_rewriter_route.py::test_cte_collision_binding_belongs_to_contextual_rust[attributes]", + "tests/queries/test_rust_query_rewriter_route.py::test_cte_collision_binding_belongs_to_contextual_rust[visibility]", + "tests/queries/test_rust_query_rewriter_route.py::test_cte_collision_binding_belongs_to_contextual_rust[security]", + "tests/queries/test_rust_query_rewriter_route.py::test_cte_collision_binding_belongs_to_contextual_rust[invariant]", + "tests/queries/test_rust_query_rewriter_route.py::test_cte_collision_binding_belongs_to_contextual_rust[none]" + ] + }, + "scope-138": { + "path": "tests/queries/test_rust_sql_rewriter_parity.py", + "declared_tests": [ + "test_semantic_sql_contract" + ], + "collected_tests": [ + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_simple_metric_query]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_metric_with_dimension]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_metric_with_filter]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewrite_not_equal_relative_date]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewrite_less_than_relative_date]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_multiple_filters]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_order_by]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_limit]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_zero_limit_and_offset_are_preserved]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_join_query]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_join_with_filter]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_invalid_field]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_missing_table_prefix]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_ad_hoc_count_aggregation]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_explicit_join_matching_relationship_supported]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_explicit_join_with_aliases_supported]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_explicit_join_accepts_parenthesized_on_clause]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_explicit_inner_join_preserves_existence_filter]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_explicit_left_join_preserves_base_rows]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_explicit_join_rejects_unsupported_join_type]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_explicit_join_requires_complete_composite_relationship]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewriter_directly]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_dimension_only_query]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewriter_invalid_sql]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewriter_non_select_query]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewriter_non_strict_mode]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewriter_or_filters]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewriter_in_filter]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewriter_having_clause]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewriter_distinct]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_select_star_expansion]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_select_star_without_from]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_column_alias]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_semantic_scalar_expression_over_measures]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_semantic_expression_order_by_projection_alias]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_semantic_scalar_function_over_measure]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_semantic_ad_hoc_aggregate_expression]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_semantic_ad_hoc_aggregate_expression_with_dimension]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_semantic_ad_hoc_aggregate_rejects_joined_model_column]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_graph_level_metrics]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_nested_and_or_filters]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_complex_nested_filters]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_query_without_metrics_or_dimensions]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_unresolvable_column]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_cte_with_semantic_query]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_cte_with_filter_in_outer_query]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_cte_with_aggregation_in_outer_query]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_subquery_with_semantic_query]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_subquery_with_join_to_regular_table]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_multiple_ctes_with_semantic_queries]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_cte_with_limit_in_inner_query]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_nested_subquery]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_cte_referencing_another_cte]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_cte_with_cross_model_query]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_subquery_with_alias]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_cte_mixed_semantic_and_regular]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_from_metrics_table]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_from_metrics_multiple_models]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_from_metrics_requires_qualified_names]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_from_metrics_no_select_star]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_from_metrics_with_filters]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_from_metrics_in_cte]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_from_metrics_allows_graph_level_metrics]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_filter_on_joined_table_without_dimension]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_filter_on_multiple_joined_tables]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_multiple_aliases]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_alias_with_join]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_alias_mixed_with_no_alias]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_time_dimension_with_granularity_syntax]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_time_dimension_multiple_granularities]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_granularity_with_invalid_dimension]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_granularity_on_non_time_dimension]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_postprocess_case_expression]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_postprocess_arithmetic]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_postprocess_window_function]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_postprocess_coalesce]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_postprocess_having]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_postprocess_order_by_in_outer]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_postprocess_limit_in_outer]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_postprocess_zero_limit_and_offset_in_outer]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_postprocess_cross_model_subquery]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_deeply_nested_subquery]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_subquery_in_join]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_compile_post_process]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_query_post_process]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_post_process_missing_placeholder]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_dry_run_with_postprocess_subquery]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_semantic_root_with_join_subquery_rejected]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_semantic_root_with_user_cte_preserved]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_semantic_root_allows_unrelated_generated_cte_name]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_semantic_root_with_recursive_cte_preserved]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_post_process_with_own_ctes]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_post_process_cte_name_collision]", + "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_root_semantic_cte_name_collision]" + ] + }, + "scope-139": { + "path": "tests/queries/test_rust_yardstick_parity.py", + "declared_tests": [ + "test_yardstick_result_contract" + ], + "collected_tests": [ + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_semantic_aggregate_identity]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_schema_qualified_aggregate_function]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_at_all_dimension]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_at_all]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_at_where_and_qualified_reference]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_at_where_without_semantic_prefix]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_at_set_and_current_keyword]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_current_keyword_ambiguous_context_returns_null]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_current_keyword_single_valued_where_context]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_at_visible]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_measure_at_visible_without_aggregate]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_measure_at_where_in_predicate]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_plain_measure_reference_with_where_context]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_curly_measure_reference_without_semantic_prefix-0]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_curly_measure_reference_without_semantic_prefix-1]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_mixed_non_semantic_at_routing]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_listing8_rollup_parity-0]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_listing8_rollup_parity-1]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_listing8_rollup_parity-2]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_listing9_join_parity]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_listing12_wrapperless_measure_at_where]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_chained_at]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_single_clause_all_multiple_dimensions_matches_chained]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_multiple_aggregate_calls_in_expression]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_at_all_year]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_set_constant_correlates_on_remaining_dimensions]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_set_reaches_beyond_outer_where]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_set_in_predicate_form]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_set_then_all_overrides_set]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_where_then_all_keeps_remaining_correlation]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_compound_at_modifiers_set_visible]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_at_visible_without_where_is_identity]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_aggregate_without_semantic_prefix]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_order_by_expression_can_reference_subquery_aliases]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_ctas_and_insert_select_with_aggregate]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_builtin_duckdb_aggregate_function_falls_through]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_scalar_aggregate_without_group_by]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_doubled_aggregate_expression]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_literal_constant_not_grouped]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_ad_hoc_dimension_all_expression]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_ad_hoc_dimension_set_expression]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_derived_measure_profit]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_multi_fact_join]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_multi_fact_join_with_at_all_dimension]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_percent_of_total]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_yoy_change_arithmetic]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_combining_base_with_all_variants]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_set_with_future_year]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_table_alias_modifiers]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_multiple_measures_same_view]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_count_measure_behavior]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_semantic_with_cte]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_index_to_base_period]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_where_complex_conditions]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_three_dimensional_all_semantics]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_difference_from_average]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_group_by_alias_expression_dimension]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_null_dimensions_all_modifiers]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_from_detection_with_lowercase_and_comments]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_group_by_extra_spaces]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_group_by_positional_ordinal]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_multiple_measures_with_different_modifiers]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_yoy_growth_percent]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_min_max_and_negative_values]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_filtered_aggregate_measure]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_count_distinct_and_median_recomputation]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_constants_and_cast]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_join_with_extra_dimension_from_second_table]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_moving_total_with_set]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_case_expression_measure]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_ordered_set_aggregates]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_generate_series_source]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_duckdb_scalar_functions]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_window_measure_direct_and_at_where]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_window_measure_at_all_raises_on_ambiguous_context]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_derived_measure_with_at_all]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_multi_fact_derived_expression]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_visible_with_year_filter]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_scalar_at_all_without_group_by]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_all_year_on_single_dimension_view]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_percent_of_year_total]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_set_correlates_vs_base_value]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_direct_query_baseline_for_distinct_and_median]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_no_semantic_at_where_with_qualified_column]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_unnest_source_relation]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_generate_series_rewrite_uses_subquery_source]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_expression_dimension_rewrite_uses_projection_alias]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_default_alias_not_applied_with_non_semantic_join]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_subquery_placeholder_rewrite_stays_in_inner_scope]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_lost_filter_warns_and_can_be_an_error-0]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_lost_filter_warns_and_can_be_an_error-1]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_lost_filter_warns_and_can_be_an_error-2]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_lost_filter_warns_and_can_be_an_error-3]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_lost_filter_warns_and_can_be_an_error-4]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_lost_filter_warns_and_can_be_an_error-5]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_lost_filter_warns_and_can_be_an_error-6]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_lost_filter_warns_and_can_be_an_error-7]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_lost_filter_warns_and_can_be_an_error-8]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_lost_filter_warns_and_can_be_an_error-9]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_effective_context_preserves_filter-0]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_effective_context_preserves_filter-1]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_effective_context_preserves_filter-2]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_effective_context_preserves_filter-3]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_effective_context_preserves_filter-4]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_grouped_filter_removed_by_all_warns]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_comments_literals_and_nested_sources_do_not_warn-0]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_comments_literals_and_nested_sources_do_not_warn-1]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_comments_literals_and_nested_sources_do_not_warn-2]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_other_joined_source_does_not_warn]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_repeated_layer_execution_observes_new_warning_policy]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_literal_yardstick_table_function_preserves_results_and_warnings]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_table_function_requires_single_literal_read-0]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_table_function_requires_single_literal_read-1]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_table_function_requires_single_literal_read-2]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_table_function_requires_single_literal_read-3]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_wrapper_cannot_bypass_semantic_security-0]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_wrapper_cannot_bypass_semantic_security-1]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_semantic_prefix_inside_yardstick_wrapper]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_wrapper_explanation_matches_rewrite_and_emits_warning]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_parenthesized_current_preserves_context_and_string_literals]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_set_expression_must_encode_actual_outer_filter-0]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_set_expression_must_encode_actual_outer_filter-1]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_set_expression_must_encode_actual_outer_filter-2]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_set_expression_must_encode_actual_outer_filter-3]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_unknown_or_ambiguous_measure_is_a_binding_error-0]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_unknown_or_ambiguous_measure_is_a_binding_error-1]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_unknown_or_ambiguous_measure_is_a_binding_error-2]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_unknown_or_ambiguous_measure_is_a_binding_error-3]", + "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_unknown_or_ambiguous_measure_is_a_binding_error-4]" + ] + }, + "scope-140": { + "path": "tests/queries/test_semantic_sql_planner.py", + "declared_tests": [ + "test_additive_total_union_uses_branch_preaggregations", + "test_aggregate_boundary_count_metric_rollup", + "test_aggregate_boundary_min_max_metric_rollup", + "test_aggregate_boundary_rejects_mismatched_min_rollup", + "test_aggregate_boundary_rejects_non_additive_subtotals", + "test_aggregate_boundary_scalar_sum_rollup", + "test_aggregate_boundary_sum_rollup_drops_finer_dimension", + "test_aggregate_boundary_sum_rollup_uses_preaggregation", + "test_aggregate_boundary_time_grain_rollup_day_to_month", + "test_aggregate_boundary_time_grain_rollup_rejects_unsafe_dimension_expressions", + "test_aggregate_boundary_time_grain_rollup_rejects_week_to_month", + "test_aggregate_boundary_time_grain_rollup_uses_daily_preaggregation", + "test_bi_corpus_acceptance_matrix_records_expected_routes", + "test_bi_corpus_rejection_matrix_records_expected_reasons", + "test_conditional_aggregate_pivot_rejects_count_distinct_metric", + "test_conditional_aggregate_pivot_rejects_unsafe_shapes", + "test_conditional_aggregate_pivot_uses_inner_preaggregation", + "test_conditional_aggregate_pivot_with_outer_row_filter_uses_preaggregation", + "test_count_distinct_exact_grain_preaggregation_candidate", + "test_count_distinct_exact_grain_preaggregation_executes", + "test_count_distinct_rollup_preaggregation_rejected", + "test_derived_table_semantic_island_under_outer_join_uses_preaggregation", + "test_dimension_distinct_remote_dimension_probe_flattens", + "test_dimension_distinct_slicer_preserves_null_filter_order_and_limit", + "test_dimension_distinct_slicer_supports_lower_like_search", + "test_dimension_distinct_wrapper_rejects_computed_projection", + "test_dimension_distinct_wrapper_rejects_hidden_filter", + "test_dimension_distinct_wrapper_rejects_metrics", + "test_dimension_only_distinct_wrapper_flattens", + "test_explain_cte_semantic_query_pushes_metric_filter_to_having", + "test_explain_direct_semantic_query_is_machine_testable", + "test_explain_fanout_preaggregation_candidate", + "test_explain_from_metrics_query_records_metrics_source", + "test_explain_lists_deterministic_candidate_plans", + "test_explain_multiple_semantic_ctes_reports_all_scopes", + "test_explain_passthrough_plain_sql_non_strict", + "test_explain_preaggregation_negative_eligibility_reasons", + "test_explain_root_semantic_query_preserves_user_cte", + "test_explain_rust_rewriter_route", + "test_explain_single_model_preaggregation_candidate", + "test_explain_window_metric_candidate", + "test_explain_yardstick_route", + "test_explanation_can_be_serialized_to_dict", + "test_external_bi_wrapper_corpus_positive_cases", + "test_external_cte_chain_corpus_flattens_linear_steps", + "test_fanout_join_key_preaggregation_rejects_missing_join_key_rollup", + "test_fanout_join_key_preaggregation_rejects_one_to_many_remote_dimension", + "test_fanout_join_key_preaggregation_rolls_orders_to_customer_region", + "test_fetch_first_topn_rewrites_through_limit_pushdown", + "test_global_row_number_between_rewrites_to_limit_offset", + "test_global_row_number_topn_rejects_partitioned_rank", + "test_global_row_number_topn_rewrites_to_order_limit", + "test_global_topn_rejects_outer_projection_of_rank_column", + "test_global_topn_rejects_rank_tie_semantics", + "test_grouping_sets_subtotal_preserves_outer_shape_and_uses_preaggregation", + "test_hex_style_union_preview_cte_preserves_outer_limit", + "test_join_key_preaggregation_joins_remote_sql_source", + "test_join_key_preaggregation_reads_local_time_dimension_from_grain_column", + "test_join_key_preaggregation_reads_ungrained_local_time_dimension_from_grain_column", + "test_linear_cte_chain_rejects_unsafe_steps", + "test_multiple_semantic_cte_islands_use_preaggregations", + "test_one_semantic_cte_island_preserves_plain_cte", + "test_outer_dimension_filter_pushdown_predicate_matrix", + "test_outer_order_limit_pushdown_matrix", + "test_positive_wrapper_rewrites_match_unoptimized_baselines", + "test_projection_width_reduction_keeps_count_distinct_key_state", + "test_projection_width_reduction_keeps_join_keys_for_joined_dimensions", + "test_projection_width_reduction_omits_unused_primary_key", + "test_qualify_row_number_topn_rewrites_to_order_limit", + "test_rewrite_simple_query_still_generates_same_sql", + "test_root_having_metric_filter_uses_preaggregation", + "test_root_semantic_query_allows_redundant_group_by_dimensions", + "test_root_semantic_query_preserves_having_metric_filter", + "test_root_semantic_query_rejects_unsupported_aggregate_clauses", + "test_root_unqualified_dimension_filter_is_qualified_for_pushdown", + "test_safe_outer_filter_pushdown_from_cte_wrapper", + "test_safe_outer_filter_pushdown_rewrites_to_direct_semantic", + "test_safe_outer_order_limit_offset_pushdown", + "test_same_grain_aggregate_wrapper_flattens_without_changing_grouping", + "test_same_grain_aggregate_wrapper_rejects_computed_projection", + "test_semantic_island_with_outer_dependency_is_rejected", + "test_set_operation_branch_order_by_is_rejected", + "test_set_operation_mismatched_branch_projection_is_rejected", + "test_set_operation_preserves_raw_branch", + "test_sql_server_top_n_rewrites_through_limit_pushdown", + "test_trivial_wrapper_uses_direct_semantic_plan", + "test_union_all_semantic_branches_use_preaggregations", + "test_wrapped_fanout_preserves_aliases_and_executes", + "test_wrapped_fanout_strategy_selection", + "test_wrapped_fanout_uses_child_preaggregations", + "test_wrapped_metric_filter_uses_preaggregation_having", + "test_wrapped_optimizer_negative_cases", + "test_wrapped_preaggregation_executes_against_materialized_table", + "test_wrapped_preaggregation_preserves_projection_alias_and_order", + "test_wrapped_preaggregation_route_selection", + "test_wrapped_window_metric_executes_against_baseline", + "test_wrapped_window_metric_uses_inner_preaggregation", + "test_wrapper_metric_filter_over_hidden_metric_stays_postprocess", + "test_wrapper_mixed_and_filter_splits_row_and_metric_stages", + "test_wrapper_mixed_or_filter_stays_postprocess", + "test_wrapper_projection_flattening_aliases_without_changing_grouping", + "test_wrapper_window_metric_filter_stays_postprocess" + ], + "collected_tests": [ + "tests/queries/test_semantic_sql_planner.py::test_explain_direct_semantic_query_is_machine_testable", + "tests/queries/test_semantic_sql_planner.py::test_explain_from_metrics_query_records_metrics_source", + "tests/queries/test_semantic_sql_planner.py::test_explain_lists_deterministic_candidate_plans", + "tests/queries/test_semantic_sql_planner.py::test_safe_outer_filter_pushdown_rewrites_to_direct_semantic", + "tests/queries/test_semantic_sql_planner.py::test_safe_outer_filter_pushdown_from_cte_wrapper", + "tests/queries/test_semantic_sql_planner.py::test_positive_wrapper_rewrites_match_unoptimized_baselines", + "tests/queries/test_semantic_sql_planner.py::test_external_bi_wrapper_corpus_positive_cases", + "tests/queries/test_semantic_sql_planner.py::test_bi_corpus_acceptance_matrix_records_expected_routes", + "tests/queries/test_semantic_sql_planner.py::test_bi_corpus_rejection_matrix_records_expected_reasons[tableau_computed_projection-SELECT status || 'x' AS status_x FROM (SELECT orders.status FROM orders) sq-wrapper_flattening]", + "tests/queries/test_semantic_sql_planner.py::test_bi_corpus_rejection_matrix_records_expected_reasons[power_query_non_foldable_transform-\\n SELECT COALESCE(status, 'unknown') AS status_bucket, SUM(revenue) AS revenue\\n FROM (SELECT orders.status, orders.revenue FROM orders) sq\\n GROUP BY 1\\n -aggregate_boundary_rollup]", + "tests/queries/test_semantic_sql_planner.py::test_bi_corpus_rejection_matrix_records_expected_reasons[power_bi_distinct_count_subtotal-\\n SELECT status, SUM(unique_customers) AS unique_customers\\n FROM (\\n SELECT orders.unique_customers, orders.status, orders.order_date FROM orders\\n ) sq\\n GROUP BY status\\n -aggregate_boundary_rollup]", + "tests/queries/test_semantic_sql_planner.py::test_bi_corpus_rejection_matrix_records_expected_reasons[superset_mixed_or_filter-\\n SELECT *\\n FROM (SELECT orders.revenue, orders.status FROM orders) sq\\n WHERE status = 'completed' OR revenue > 100\\n -safe_filter_pushdown]", + "tests/queries/test_semantic_sql_planner.py::test_external_cte_chain_corpus_flattens_linear_steps", + "tests/queries/test_semantic_sql_planner.py::test_linear_cte_chain_rejects_unsafe_steps[\\n WITH base AS (\\n SELECT orders.revenue, orders.status FROM orders\\n ),\\n filtered AS (\\n SELECT * FROM base\\n )\\n SELECT a.status FROM filtered a JOIN filtered b ON a.status = b.status\\n ]", + "tests/queries/test_semantic_sql_planner.py::test_linear_cte_chain_rejects_unsafe_steps[\\n WITH base AS (\\n SELECT orders.revenue, orders.status FROM orders\\n ),\\n projected AS (\\n SELECT status, revenue * 2 AS doubled FROM base\\n )\\n SELECT * FROM projected\\n ]", + "tests/queries/test_semantic_sql_planner.py::test_linear_cte_chain_rejects_unsafe_steps[\\n WITH base AS (\\n SELECT orders.revenue, orders.status FROM orders\\n ),\\n ranked AS (\\n SELECT status, revenue, ROW_NUMBER() OVER (ORDER BY revenue DESC) AS rn FROM base\\n )\\n SELECT status, revenue FROM ranked\\n ]", + "tests/queries/test_semantic_sql_planner.py::test_linear_cte_chain_rejects_unsafe_steps[\\n WITH base AS (\\n SELECT orders.revenue, orders.status FROM orders\\n ),\\n distinct_statuses AS (\\n SELECT DISTINCT status FROM base\\n )\\n SELECT * FROM distinct_statuses\\n ]", + "tests/queries/test_semantic_sql_planner.py::test_linear_cte_chain_rejects_unsafe_steps[\\n WITH base AS (\\n SELECT orders.revenue, orders.status FROM orders\\n ),\\n rolled AS (\\n SELECT status, SUM(revenue) AS revenue FROM base GROUP BY status\\n )\\n SELECT * FROM rolled\\n ]", + "tests/queries/test_semantic_sql_planner.py::test_outer_dimension_filter_pushdown_predicate_matrix[status IN ('completed', 'pending')]", + "tests/queries/test_semantic_sql_planner.py::test_outer_dimension_filter_pushdown_predicate_matrix[status NOT IN ('pending')]", + "tests/queries/test_semantic_sql_planner.py::test_outer_dimension_filter_pushdown_predicate_matrix[order_date BETWEEN DATE '2024-01-01' AND DATE '2024-01-02']", + "tests/queries/test_semantic_sql_planner.py::test_outer_dimension_filter_pushdown_predicate_matrix[status IS NOT NULL]", + "tests/queries/test_semantic_sql_planner.py::test_outer_dimension_filter_pushdown_predicate_matrix[status LIKE 'comp%']", + "tests/queries/test_semantic_sql_planner.py::test_outer_dimension_filter_pushdown_predicate_matrix[NOT (status = 'pending')]", + "tests/queries/test_semantic_sql_planner.py::test_outer_dimension_filter_pushdown_predicate_matrix[status = 'completed' OR status = 'pending']", + "tests/queries/test_semantic_sql_planner.py::test_outer_dimension_filter_pushdown_predicate_matrix[sq.status = 'completed']", + "tests/queries/test_semantic_sql_planner.py::test_outer_order_limit_pushdown_matrix[status ASC-True]", + "tests/queries/test_semantic_sql_planner.py::test_outer_order_limit_pushdown_matrix[total_revenue DESC-True]", + "tests/queries/test_semantic_sql_planner.py::test_outer_order_limit_pushdown_matrix[sq.status DESC-True]", + "tests/queries/test_semantic_sql_planner.py::test_outer_order_limit_pushdown_matrix[sq.total_revenue DESC-True]", + "tests/queries/test_semantic_sql_planner.py::test_explain_cte_semantic_query_pushes_metric_filter_to_having", + "tests/queries/test_semantic_sql_planner.py::test_wrapper_mixed_and_filter_splits_row_and_metric_stages", + "tests/queries/test_semantic_sql_planner.py::test_wrapper_mixed_or_filter_stays_postprocess", + "tests/queries/test_semantic_sql_planner.py::test_wrapper_metric_filter_over_hidden_metric_stays_postprocess", + "tests/queries/test_semantic_sql_planner.py::test_explain_multiple_semantic_ctes_reports_all_scopes", + "tests/queries/test_semantic_sql_planner.py::test_multiple_semantic_cte_islands_use_preaggregations", + "tests/queries/test_semantic_sql_planner.py::test_one_semantic_cte_island_preserves_plain_cte", + "tests/queries/test_semantic_sql_planner.py::test_derived_table_semantic_island_under_outer_join_uses_preaggregation", + "tests/queries/test_semantic_sql_planner.py::test_semantic_island_with_outer_dependency_is_rejected", + "tests/queries/test_semantic_sql_planner.py::test_explain_root_semantic_query_preserves_user_cte", + "tests/queries/test_semantic_sql_planner.py::test_root_semantic_query_rejects_unsupported_aggregate_clauses[SELECT orders.revenue FROM orders GROUP BY orders.status-GROUP BY]", + "tests/queries/test_semantic_sql_planner.py::test_root_semantic_query_allows_redundant_group_by_dimensions", + "tests/queries/test_semantic_sql_planner.py::test_root_semantic_query_preserves_having_metric_filter", + "tests/queries/test_semantic_sql_planner.py::test_root_unqualified_dimension_filter_is_qualified_for_pushdown", + "tests/queries/test_semantic_sql_planner.py::test_aggregate_boundary_sum_rollup_drops_finer_dimension", + "tests/queries/test_semantic_sql_planner.py::test_same_grain_aggregate_wrapper_flattens_without_changing_grouping", + "tests/queries/test_semantic_sql_planner.py::test_same_grain_aggregate_wrapper_rejects_computed_projection", + "tests/queries/test_semantic_sql_planner.py::test_aggregate_boundary_sum_rollup_uses_preaggregation", + "tests/queries/test_semantic_sql_planner.py::test_aggregate_boundary_count_metric_rollup", + "tests/queries/test_semantic_sql_planner.py::test_aggregate_boundary_min_max_metric_rollup", + "tests/queries/test_semantic_sql_planner.py::test_aggregate_boundary_rejects_mismatched_min_rollup", + "tests/queries/test_semantic_sql_planner.py::test_aggregate_boundary_scalar_sum_rollup", + "tests/queries/test_semantic_sql_planner.py::test_additive_total_union_uses_branch_preaggregations", + "tests/queries/test_semantic_sql_planner.py::test_grouping_sets_subtotal_preserves_outer_shape_and_uses_preaggregation", + "tests/queries/test_semantic_sql_planner.py::test_aggregate_boundary_rejects_non_additive_subtotals", + "tests/queries/test_semantic_sql_planner.py::test_aggregate_boundary_time_grain_rollup_day_to_month", + "tests/queries/test_semantic_sql_planner.py::test_aggregate_boundary_time_grain_rollup_uses_daily_preaggregation", + "tests/queries/test_semantic_sql_planner.py::test_aggregate_boundary_time_grain_rollup_rejects_week_to_month", + "tests/queries/test_semantic_sql_planner.py::test_aggregate_boundary_time_grain_rollup_rejects_unsafe_dimension_expressions[\\n SELECT COALESCE(status, 'unknown') AS status_bucket, SUM(revenue) AS revenue\\n FROM (\\n SELECT orders.status, orders.revenue FROM orders\\n ) sq\\n GROUP BY 1\\n -outer_group_expression_not_supported]", + "tests/queries/test_semantic_sql_planner.py::test_aggregate_boundary_time_grain_rollup_rejects_unsafe_dimension_expressions[\\n SELECT CURRENT_DATE AS today, SUM(revenue) AS revenue\\n FROM (\\n SELECT orders.status, orders.revenue FROM orders\\n ) sq\\n GROUP BY 1\\n -outer_group_expression_not_supported]", + "tests/queries/test_semantic_sql_planner.py::test_conditional_aggregate_pivot_uses_inner_preaggregation", + "tests/queries/test_semantic_sql_planner.py::test_conditional_aggregate_pivot_rejects_count_distinct_metric", + "tests/queries/test_semantic_sql_planner.py::test_conditional_aggregate_pivot_with_outer_row_filter_uses_preaggregation", + "tests/queries/test_semantic_sql_planner.py::test_conditional_aggregate_pivot_rejects_unsafe_shapes[\\n SELECT\\n SUM(CASE WHEN tier = 'premium' THEN revenue ELSE 0 END) AS premium_revenue\\n FROM (\\n SELECT orders.revenue, orders.status FROM orders\\n ) sq\\n -conditional aggregate predicate references a non-dimension]", + "tests/queries/test_semantic_sql_planner.py::test_conditional_aggregate_pivot_rejects_unsafe_shapes[\\n SELECT\\n SUM(CASE WHEN status = 'completed' THEN revenue * 2 ELSE 0 END) AS completed_revenue\\n FROM (\\n SELECT orders.revenue, orders.status FROM orders\\n ) sq\\n -conditional aggregate result is not a metric column]", + "tests/queries/test_semantic_sql_planner.py::test_explain_fanout_preaggregation_candidate", + "tests/queries/test_semantic_sql_planner.py::test_explain_window_metric_candidate", + "tests/queries/test_semantic_sql_planner.py::test_explain_single_model_preaggregation_candidate", + "tests/queries/test_semantic_sql_planner.py::test_explain_preaggregation_negative_eligibility_reasons[preaggregation0-SELECT orders.revenue, orders.order_date FROM orders-dimension_not_in_rollup-dimensions]", + "tests/queries/test_semantic_sql_planner.py::test_explain_preaggregation_negative_eligibility_reasons[preaggregation1-SELECT orders.revenue FROM orders WHERE orders.status = 'completed'-filter_not_compatible-filters]", + "tests/queries/test_semantic_sql_planner.py::test_explain_preaggregation_negative_eligibility_reasons[preaggregation2-SELECT orders.revenue, orders.status FROM orders-metric_not_in_rollup-measures]", + "tests/queries/test_semantic_sql_planner.py::test_explain_preaggregation_negative_eligibility_reasons[preaggregation3-SELECT orders.revenue, orders.order_date__day FROM orders-time_grain_mismatch-granularity]", + "tests/queries/test_semantic_sql_planner.py::test_count_distinct_exact_grain_preaggregation_candidate", + "tests/queries/test_semantic_sql_planner.py::test_count_distinct_exact_grain_preaggregation_executes", + "tests/queries/test_semantic_sql_planner.py::test_count_distinct_rollup_preaggregation_rejected", + "tests/queries/test_semantic_sql_planner.py::test_explain_yardstick_route", + "tests/queries/test_semantic_sql_planner.py::test_explain_rust_rewriter_route", + "tests/queries/test_semantic_sql_planner.py::test_trivial_wrapper_uses_direct_semantic_plan", + "tests/queries/test_semantic_sql_planner.py::test_safe_outer_order_limit_offset_pushdown", + "tests/queries/test_semantic_sql_planner.py::test_wrapper_projection_flattening_aliases_without_changing_grouping", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_preaggregation_route_selection", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_preaggregation_executes_against_materialized_table", + "tests/queries/test_semantic_sql_planner.py::test_root_having_metric_filter_uses_preaggregation", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_metric_filter_uses_preaggregation_having", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_preaggregation_preserves_projection_alias_and_order", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_fanout_strategy_selection", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_fanout_preserves_aliases_and_executes", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_fanout_uses_child_preaggregations", + "tests/queries/test_semantic_sql_planner.py::test_fanout_join_key_preaggregation_rolls_orders_to_customer_region", + "tests/queries/test_semantic_sql_planner.py::test_join_key_preaggregation_reads_local_time_dimension_from_grain_column", + "tests/queries/test_semantic_sql_planner.py::test_join_key_preaggregation_reads_ungrained_local_time_dimension_from_grain_column", + "tests/queries/test_semantic_sql_planner.py::test_join_key_preaggregation_joins_remote_sql_source", + "tests/queries/test_semantic_sql_planner.py::test_fanout_join_key_preaggregation_rejects_missing_join_key_rollup", + "tests/queries/test_semantic_sql_planner.py::test_fanout_join_key_preaggregation_rejects_one_to_many_remote_dimension", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_window_metric_executes_against_baseline", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_window_metric_uses_inner_preaggregation", + "tests/queries/test_semantic_sql_planner.py::test_wrapper_window_metric_filter_stays_postprocess", + "tests/queries/test_semantic_sql_planner.py::test_dimension_only_distinct_wrapper_flattens", + "tests/queries/test_semantic_sql_planner.py::test_dimension_distinct_slicer_preserves_null_filter_order_and_limit", + "tests/queries/test_semantic_sql_planner.py::test_dimension_distinct_slicer_supports_lower_like_search", + "tests/queries/test_semantic_sql_planner.py::test_dimension_distinct_remote_dimension_probe_flattens", + "tests/queries/test_semantic_sql_planner.py::test_dimension_distinct_wrapper_rejects_metrics", + "tests/queries/test_semantic_sql_planner.py::test_dimension_distinct_wrapper_rejects_computed_projection", + "tests/queries/test_semantic_sql_planner.py::test_dimension_distinct_wrapper_rejects_hidden_filter", + "tests/queries/test_semantic_sql_planner.py::test_global_row_number_topn_rewrites_to_order_limit", + "tests/queries/test_semantic_sql_planner.py::test_global_row_number_between_rewrites_to_limit_offset", + "tests/queries/test_semantic_sql_planner.py::test_qualify_row_number_topn_rewrites_to_order_limit", + "tests/queries/test_semantic_sql_planner.py::test_fetch_first_topn_rewrites_through_limit_pushdown", + "tests/queries/test_semantic_sql_planner.py::test_sql_server_top_n_rewrites_through_limit_pushdown", + "tests/queries/test_semantic_sql_planner.py::test_global_topn_rejects_rank_tie_semantics[RANK-only ROW_NUMBER is supported]", + "tests/queries/test_semantic_sql_planner.py::test_global_topn_rejects_rank_tie_semantics[DENSE_RANK-only ROW_NUMBER is supported]", + "tests/queries/test_semantic_sql_planner.py::test_global_topn_rejects_outer_projection_of_rank_column", + "tests/queries/test_semantic_sql_planner.py::test_union_all_semantic_branches_use_preaggregations", + "tests/queries/test_semantic_sql_planner.py::test_hex_style_union_preview_cte_preserves_outer_limit", + "tests/queries/test_semantic_sql_planner.py::test_set_operation_preserves_raw_branch", + "tests/queries/test_semantic_sql_planner.py::test_set_operation_mismatched_branch_projection_is_rejected", + "tests/queries/test_semantic_sql_planner.py::test_set_operation_branch_order_by_is_rejected", + "tests/queries/test_semantic_sql_planner.py::test_global_row_number_topn_rejects_partitioned_rank", + "tests/queries/test_semantic_sql_planner.py::test_projection_width_reduction_omits_unused_primary_key", + "tests/queries/test_semantic_sql_planner.py::test_projection_width_reduction_keeps_join_keys_for_joined_dimensions", + "tests/queries/test_semantic_sql_planner.py::test_projection_width_reduction_keeps_count_distinct_key_state", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_optimizer_negative_cases[SELECT revenue * 2 AS doubled FROM (SELECT orders.revenue, orders.status FROM orders) sq]", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_optimizer_negative_cases[SELECT revenue, ROW_NUMBER() OVER () AS rn FROM (SELECT orders.revenue, orders.status FROM orders) sq]", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_optimizer_negative_cases[SELECT DISTINCT status FROM (SELECT orders.revenue, orders.status FROM orders) sq]", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_optimizer_negative_cases[SELECT revenue FROM (SELECT orders.revenue, orders.status FROM orders) sq]", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_optimizer_negative_cases[SELECT * FROM (SELECT orders.revenue, orders.status FROM orders LIMIT 1) sq WHERE status = 'completed']", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_optimizer_negative_cases[SELECT * FROM (SELECT orders.revenue, orders.status FROM orders) sq ORDER BY 1]", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_optimizer_negative_cases[SELECT * FROM (SELECT orders.revenue, orders.status FROM orders) sq ORDER BY status || '']", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_optimizer_negative_cases[SELECT * FROM (SELECT orders.revenue, orders.status FROM orders) sq ORDER BY status DESC NULLS FIRST]", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_optimizer_negative_cases[SELECT * FROM (SELECT orders.revenue, orders.status FROM orders) sq JOIN other_table ot ON TRUE]", + "tests/queries/test_semantic_sql_planner.py::test_wrapped_optimizer_negative_cases[\\n WITH passthrough AS (\\n SELECT 1 AS marker\\n )\\n SELECT * FROM (SELECT orders.revenue, orders.status FROM orders) sq\\n ]", + "tests/queries/test_semantic_sql_planner.py::test_explain_passthrough_plain_sql_non_strict", + "tests/queries/test_semantic_sql_planner.py::test_rewrite_simple_query_still_generates_same_sql", + "tests/queries/test_semantic_sql_planner.py::test_explanation_can_be_serialized_to_dict" + ] + }, + "scope-141": { + "path": "tests/queries/test_sql_fallback_policy.py", + "declared_tests": [ + "test_non_strict_rewrite_does_not_hide_runtime_bug", + "test_rust_backend_fallback_is_observable", + "test_rust_rewrite_does_not_hide_api_contract_defect" + ], + "collected_tests": [ + "tests/queries/test_sql_fallback_policy.py::test_non_strict_rewrite_does_not_hide_runtime_bug", + "tests/queries/test_sql_fallback_policy.py::test_rust_backend_fallback_is_observable", + "tests/queries/test_sql_fallback_policy.py::test_rust_rewrite_does_not_hide_api_contract_defect[error0]", + "tests/queries/test_sql_fallback_policy.py::test_rust_rewrite_does_not_hide_api_contract_defect[error1]" + ] + }, + "scope-142": { + "path": "tests/queries/test_temporal_sql_projection.py", + "declared_tests": [ + "test_repeated_metric_keeps_each_projection_alias", + "test_temporal_sql_exposes_only_requested_projection" + ], + "collected_tests": [ + "tests/queries/test_temporal_sql_projection.py::test_temporal_sql_exposes_only_requested_projection[False-monthly.sale_date__month, revenue_mom-columns0]", + "tests/queries/test_temporal_sql_projection.py::test_temporal_sql_exposes_only_requested_projection[False-revenue_mom, monthly.sale_date__month-columns1]", + "tests/queries/test_temporal_sql_projection.py::test_temporal_sql_exposes_only_requested_projection[False-monthly.sale_date__month as month, revenue_mom as change-columns2]", + "tests/queries/test_temporal_sql_projection.py::test_temporal_sql_exposes_only_requested_projection[False-monthly.sale_date__month, monthly.revenue, revenue_mom-columns3]", + "tests/queries/test_temporal_sql_projection.py::test_temporal_sql_exposes_only_requested_projection[True-monthly.sale_date__month, revenue_mom-columns0]", + "tests/queries/test_temporal_sql_projection.py::test_temporal_sql_exposes_only_requested_projection[True-revenue_mom, monthly.sale_date__month-columns1]", + "tests/queries/test_temporal_sql_projection.py::test_temporal_sql_exposes_only_requested_projection[True-monthly.sale_date__month as month, revenue_mom as change-columns2]", + "tests/queries/test_temporal_sql_projection.py::test_temporal_sql_exposes_only_requested_projection[True-monthly.sale_date__month, monthly.revenue, revenue_mom-columns3]", + "tests/queries/test_temporal_sql_projection.py::test_repeated_metric_keeps_each_projection_alias[first_total]", + "tests/queries/test_temporal_sql_projection.py::test_repeated_metric_keeps_each_projection_alias[second_total]", + "tests/queries/test_temporal_sql_projection.py::test_repeated_metric_keeps_each_projection_alias[orders.revenue]" + ] + }, + "scope-143": { + "path": "tests/queries/test_yardstick_measures_replay.py", + "declared_tests": [ + "test_upstream_environment_requirements_control_file_eligibility", + "test_yardstick_upstream_create_view_definitions", + "test_yardstick_upstream_sql_replay" + ], + "collected_tests": [ + "tests/queries/test_yardstick_measures_replay.py::test_yardstick_upstream_create_view_definitions", + "tests/queries/test_yardstick_measures_replay.py::test_yardstick_upstream_sql_replay", + "tests/queries/test_yardstick_measures_replay.py::test_upstream_environment_requirements_control_file_eligibility" + ] + }, + "scope-144": { + "path": "tests/queries/test_yardstick_measures_replay.py", + "declared_tests": [ + "test_definition_coverage_is_corpus_wide_without_dropping_plain_sql", + "test_replay_closes_connection_on_success_and_failure", + "test_replay_executes_statement_records_after_last_query", + "test_yardstick_measures_test_replay", + "test_yardstick_upstream_sql_replay" + ], + "collected_tests": [ + "tests/queries/test_yardstick_measures_replay.py::test_yardstick_measures_test_replay", + "tests/queries/test_yardstick_measures_replay.py::test_yardstick_upstream_sql_replay", + "tests/queries/test_yardstick_measures_replay.py::test_replay_executes_statement_records_after_last_query", + "tests/queries/test_yardstick_measures_replay.py::test_replay_closes_connection_on_success_and_failure[False]", + "tests/queries/test_yardstick_measures_replay.py::test_replay_closes_connection_on_success_and_failure[True]", + "tests/queries/test_yardstick_measures_replay.py::test_definition_coverage_is_corpus_wide_without_dropping_plain_sql" + ] + }, + "scope-145": { + "path": "tests/semantic_conformance/test_absent_counts.py", + "declared_tests": [ + "test_absent_count_zero_is_used_by_aggregate_filter_and_order", + "test_absent_counts_are_zero_and_other_aggregates_remain_null", + "test_count_zero_flows_into_derived_and_ratio_before_outer_defaults", + "test_local_calculations_use_absent_source_defaults", + "test_policy_does_not_restore_unauthorized_groups", + "test_source_populations_preserve_orphans_with_zero_customer_count", + "test_three_source_groups_merge_when_the_first_source_has_no_row" + ], + "collected_tests": [ + "tests/semantic_conformance/test_absent_counts.py::test_absent_counts_are_zero_and_other_aggregates_remain_null[python-False]", + "tests/semantic_conformance/test_absent_counts.py::test_absent_counts_are_zero_and_other_aggregates_remain_null[python-True]", + "tests/semantic_conformance/test_absent_counts.py::test_absent_counts_are_zero_and_other_aggregates_remain_null[rust-False]", + "tests/semantic_conformance/test_absent_counts.py::test_absent_counts_are_zero_and_other_aggregates_remain_null[rust-True]", + "tests/semantic_conformance/test_absent_counts.py::test_count_zero_flows_into_derived_and_ratio_before_outer_defaults[python]", + "tests/semantic_conformance/test_absent_counts.py::test_count_zero_flows_into_derived_and_ratio_before_outer_defaults[rust]", + "tests/semantic_conformance/test_absent_counts.py::test_source_populations_preserve_orphans_with_zero_customer_count[python]", + "tests/semantic_conformance/test_absent_counts.py::test_source_populations_preserve_orphans_with_zero_customer_count[rust]", + "tests/semantic_conformance/test_absent_counts.py::test_local_calculations_use_absent_source_defaults[python]", + "tests/semantic_conformance/test_absent_counts.py::test_local_calculations_use_absent_source_defaults[rust]", + "tests/semantic_conformance/test_absent_counts.py::test_policy_does_not_restore_unauthorized_groups[python]", + "tests/semantic_conformance/test_absent_counts.py::test_policy_does_not_restore_unauthorized_groups[rust]", + "tests/semantic_conformance/test_absent_counts.py::test_three_source_groups_merge_when_the_first_source_has_no_row[python]", + "tests/semantic_conformance/test_absent_counts.py::test_three_source_groups_merge_when_the_first_source_has_no_row[rust]", + "tests/semantic_conformance/test_absent_counts.py::test_absent_count_zero_is_used_by_aggregate_filter_and_order[python]", + "tests/semantic_conformance/test_absent_counts.py::test_absent_count_zero_is_used_by_aggregate_filter_and_order[rust]" + ] + }, + "scope-146": { + "path": "tests/semantic_conformance/test_active_consumption_cli.py", + "declared_tests": [ + "test_explore_calculations_follow_selected_paginated_rows", + "test_explore_defaults_and_saved_query_use_real_populations", + "test_explore_rejects_disallowed_selection_and_preserves_security", + "test_structured_selection_filter_order_and_pagination" + ], + "collected_tests": [ + "tests/semantic_conformance/test_active_consumption_cli.py::test_explore_defaults_and_saved_query_use_real_populations[python]", + "tests/semantic_conformance/test_active_consumption_cli.py::test_explore_defaults_and_saved_query_use_real_populations[rust]", + "tests/semantic_conformance/test_active_consumption_cli.py::test_structured_selection_filter_order_and_pagination[python]", + "tests/semantic_conformance/test_active_consumption_cli.py::test_structured_selection_filter_order_and_pagination[rust]", + "tests/semantic_conformance/test_active_consumption_cli.py::test_explore_calculations_follow_selected_paginated_rows[python]", + "tests/semantic_conformance/test_active_consumption_cli.py::test_explore_calculations_follow_selected_paginated_rows[rust]", + "tests/semantic_conformance/test_active_consumption_cli.py::test_explore_rejects_disallowed_selection_and_preserves_security[python]", + "tests/semantic_conformance/test_active_consumption_cli.py::test_explore_rejects_disallowed_selection_and_preserves_security[rust]" + ] + }, + "scope-147": { + "path": "tests/semantic_conformance/test_active_explores.py", + "declared_tests": [ + "test_contract_rejections_precede_dispatch", + "test_dimensions_only_keep_unmatched_base_and_exclude_orphan_children", + "test_independent_aggregate_route_never_discards_explore_population", + "test_intermediate_policy_constrains_related_only_metric", + "test_join_fanout_does_not_repeat_base_measure", + "test_off_base_metrics_keep_authorized_base_population", + "test_order_defaults_and_limit_overrides", + "test_policy_is_required_even_without_selected_anchor_fields", + "test_same_owner_ratio_and_derived_metrics_keep_anchor", + "test_saved_query_cannot_override_resolved_contract", + "test_unjoinable_explore_base_is_rejected" + ], + "collected_tests": [ + "tests/semantic_conformance/test_active_explores.py::test_off_base_metrics_keep_authorized_base_population[python]", + "tests/semantic_conformance/test_active_explores.py::test_off_base_metrics_keep_authorized_base_population[rust]", + "tests/semantic_conformance/test_active_explores.py::test_dimensions_only_keep_unmatched_base_and_exclude_orphan_children[python]", + "tests/semantic_conformance/test_active_explores.py::test_dimensions_only_keep_unmatched_base_and_exclude_orphan_children[rust]", + "tests/semantic_conformance/test_active_explores.py::test_join_fanout_does_not_repeat_base_measure[python]", + "tests/semantic_conformance/test_active_explores.py::test_join_fanout_does_not_repeat_base_measure[rust]", + "tests/semantic_conformance/test_active_explores.py::test_same_owner_ratio_and_derived_metrics_keep_anchor[python]", + "tests/semantic_conformance/test_active_explores.py::test_same_owner_ratio_and_derived_metrics_keep_anchor[rust]", + "tests/semantic_conformance/test_active_explores.py::test_policy_is_required_even_without_selected_anchor_fields[python]", + "tests/semantic_conformance/test_active_explores.py::test_policy_is_required_even_without_selected_anchor_fields[rust]", + "tests/semantic_conformance/test_active_explores.py::test_contract_rejections_precede_dispatch[python-query0-does not allow metric]", + "tests/semantic_conformance/test_active_explores.py::test_contract_rejections_precede_dispatch[python-query1-does not allow dimension]", + "tests/semantic_conformance/test_active_explores.py::test_contract_rejections_precede_dispatch[python-query2-does not allow filter]", + "tests/semantic_conformance/test_active_explores.py::test_contract_rejections_precede_dispatch[python-query3-does not allow ordering]", + "tests/semantic_conformance/test_active_explores.py::test_contract_rejections_precede_dispatch[python-query4-must be selected]", + "tests/semantic_conformance/test_active_explores.py::test_contract_rejections_precede_dispatch[python-query5-exceeds max_limit]", + "tests/semantic_conformance/test_active_explores.py::test_contract_rejections_precede_dispatch[rust-query0-does not allow metric]", + "tests/semantic_conformance/test_active_explores.py::test_contract_rejections_precede_dispatch[rust-query1-does not allow dimension]", + "tests/semantic_conformance/test_active_explores.py::test_contract_rejections_precede_dispatch[rust-query2-does not allow filter]", + "tests/semantic_conformance/test_active_explores.py::test_contract_rejections_precede_dispatch[rust-query3-does not allow ordering]", + "tests/semantic_conformance/test_active_explores.py::test_contract_rejections_precede_dispatch[rust-query4-must be selected]", + "tests/semantic_conformance/test_active_explores.py::test_contract_rejections_precede_dispatch[rust-query5-exceeds max_limit]", + "tests/semantic_conformance/test_active_explores.py::test_order_defaults_and_limit_overrides[python]", + "tests/semantic_conformance/test_active_explores.py::test_order_defaults_and_limit_overrides[rust]", + "tests/semantic_conformance/test_active_explores.py::test_saved_query_cannot_override_resolved_contract[python]", + "tests/semantic_conformance/test_active_explores.py::test_saved_query_cannot_override_resolved_contract[rust]", + "tests/semantic_conformance/test_active_explores.py::test_unjoinable_explore_base_is_rejected[python]", + "tests/semantic_conformance/test_active_explores.py::test_unjoinable_explore_base_is_rejected[rust]", + "tests/semantic_conformance/test_active_explores.py::test_independent_aggregate_route_never_discards_explore_population[python]", + "tests/semantic_conformance/test_active_explores.py::test_independent_aggregate_route_never_discards_explore_population[rust]", + "tests/semantic_conformance/test_active_explores.py::test_intermediate_policy_constrains_related_only_metric[python]", + "tests/semantic_conformance/test_active_explores.py::test_intermediate_policy_constrains_related_only_metric[rust]" + ] + }, + "scope-148": { + "path": "tests/semantic_conformance/test_aggregate_aliases.py", + "declared_tests": [ + "test_dimension_and_metric_names_from_different_owners", + "test_hidden_leaf_collision_does_not_rename_public_dimension", + "test_qualified_metric_filter_and_order_bind_selected_outputs", + "test_same_owner_duplicate_child_output_remains_explicitly_unsupported", + "test_two_grouping_dimensions_share_basename", + "test_unselected_metric_filter_uses_normalized_child_output" + ], + "collected_tests": [ + "tests/semantic_conformance/test_aggregate_aliases.py::test_dimension_and_metric_names_from_different_owners[python]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_dimension_and_metric_names_from_different_owners[rust]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_hidden_leaf_collision_does_not_rename_public_dimension[python]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_hidden_leaf_collision_does_not_rename_public_dimension[rust]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_two_grouping_dimensions_share_basename[python-False-False]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_two_grouping_dimensions_share_basename[python-False-True]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_two_grouping_dimensions_share_basename[python-True-False]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_two_grouping_dimensions_share_basename[python-True-True]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_two_grouping_dimensions_share_basename[rust-False-False]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_two_grouping_dimensions_share_basename[rust-False-True]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_two_grouping_dimensions_share_basename[rust-True-False]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_two_grouping_dimensions_share_basename[rust-True-True]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_qualified_metric_filter_and_order_bind_selected_outputs[python]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_qualified_metric_filter_and_order_bind_selected_outputs[rust]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_unselected_metric_filter_uses_normalized_child_output[python]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_unselected_metric_filter_uses_normalized_child_output[rust]", + "tests/semantic_conformance/test_aggregate_aliases.py::test_same_owner_duplicate_child_output_remains_explicitly_unsupported" + ] + }, + "scope-149": { + "path": "tests/semantic_conformance/test_aggregate_aliases.py", + "declared_tests": [ + "test_same_owner_duplicate_child_output_remains_explicitly_unsupported" + ], + "collected_tests": [ + "tests/semantic_conformance/test_aggregate_aliases.py::test_same_owner_duplicate_child_output_remains_explicitly_unsupported" + ] + }, + "scope-150": { + "path": "tests/semantic_conformance/test_aggregate_breadth_parity.py", + "declared_tests": [ + "test_advanced_aggregates_use_each_entity_once", + "test_approximate_distinct_supports_fanout_and_aggregate_filters", + "test_complete_aggregates_keep_groups_without_source_entities", + "test_complete_and_advanced_totals_deduplicate_overlapping_entity_groups", + "test_complete_default_is_applied_at_selected_output_not_nested_formula", + "test_complete_sql_and_advanced_independent_populations", + "test_complete_sql_and_wrappers_run_after_entity_dedup", + "test_complete_totals_without_fanout_keep_null_and_empty_populations", + "test_distinct_without_expression_uses_entity_identity", + "test_filtered_complete_formulas_keep_python_row_inputs" + ], + "collected_tests": [ + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_advanced_aggregates_use_each_entity_once[python-median]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_advanced_aggregates_use_each_entity_once[python-stddev]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_advanced_aggregates_use_each_entity_once[python-stddev_pop]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_advanced_aggregates_use_each_entity_once[python-variance]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_advanced_aggregates_use_each_entity_once[python-variance_pop]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_advanced_aggregates_use_each_entity_once[rust-median]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_advanced_aggregates_use_each_entity_once[rust-stddev]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_advanced_aggregates_use_each_entity_once[rust-stddev_pop]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_advanced_aggregates_use_each_entity_once[rust-variance]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_advanced_aggregates_use_each_entity_once[rust-variance_pop]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_sql_and_wrappers_run_after_entity_dedup[python]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_sql_and_wrappers_run_after_entity_dedup[rust]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_aggregates_keep_groups_without_source_entities[python]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_aggregates_keep_groups_without_source_entities[rust]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_and_advanced_totals_deduplicate_overlapping_entity_groups[python]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_and_advanced_totals_deduplicate_overlapping_entity_groups[rust]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_totals_without_fanout_keep_null_and_empty_populations[python-False-False]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_totals_without_fanout_keep_null_and_empty_populations[python-False-True]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_totals_without_fanout_keep_null_and_empty_populations[python-True-False]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_totals_without_fanout_keep_null_and_empty_populations[python-True-True]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_totals_without_fanout_keep_null_and_empty_populations[rust-False-False]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_totals_without_fanout_keep_null_and_empty_populations[rust-False-True]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_totals_without_fanout_keep_null_and_empty_populations[rust-True-False]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_totals_without_fanout_keep_null_and_empty_populations[rust-True-True]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_approximate_distinct_supports_fanout_and_aggregate_filters[python]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_approximate_distinct_supports_fanout_and_aggregate_filters[rust]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_sql_and_advanced_independent_populations[python]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_sql_and_advanced_independent_populations[rust]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_distinct_without_expression_uses_entity_identity[python-dimensions0]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_distinct_without_expression_uses_entity_identity[python-dimensions1]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_distinct_without_expression_uses_entity_identity[rust-dimensions0]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_distinct_without_expression_uses_entity_identity[rust-dimensions1]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[python-False-median(amount)-40.0]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[python-False-sum(amount) / count(*)-26.666666666666668]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[python-False-sum(amount) / count(amount)-40.0]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[python-False-count(distinct abs(amount))-2]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[python-False-sum(amount) filter (where amount > 30)-60.0]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[python-True-median(amount)-40.0]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[python-True-sum(amount) / count(*)-26.666666666666668]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[python-True-sum(amount) / count(amount)-40.0]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[python-True-count(distinct abs(amount))-2]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[python-True-sum(amount) filter (where amount > 30)-60.0]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[rust-False-median(amount)-40.0]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[rust-False-sum(amount) / count(*)-26.666666666666668]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[rust-False-sum(amount) / count(amount)-40.0]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[rust-False-count(distinct abs(amount))-2]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[rust-False-sum(amount) filter (where amount > 30)-60.0]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[rust-True-median(amount)-40.0]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[rust-True-sum(amount) / count(*)-26.666666666666668]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[rust-True-sum(amount) / count(amount)-40.0]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[rust-True-count(distinct abs(amount))-2]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_filtered_complete_formulas_keep_python_row_inputs[rust-True-sum(amount) filter (where amount > 30)-60.0]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[python-False-False-False]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[python-False-False-True]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[python-False-True-False]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[python-False-True-True]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[python-True-False-False]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[python-True-False-True]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[python-True-True-False]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[python-True-True-True]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[rust-False-False-False]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[rust-False-False-True]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[rust-False-True-False]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[rust-False-True-True]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[rust-True-False-False]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[rust-True-False-True]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[rust-True-True-False]", + "tests/semantic_conformance/test_aggregate_breadth_parity.py::test_complete_default_is_applied_at_selected_output_not_nested_formula[rust-True-True-True]" + ] + }, + "scope-151": { + "path": "tests/semantic_conformance/test_approximate_distinct.py", + "declared_tests": [ + "test_aggregate_filters_wrappers_and_stored_scalar_fallback", + "test_approximate_dialect_rendering_and_population_results", + "test_cumulative_approximate_counts_use_grouped_outputs", + "test_estimator_and_filtered_populations", + "test_joined_populations", + "test_query_filters_and_empty_populations", + "test_redshift_nested_approximate_expressions_use_independent_parser" + ], + "collected_tests": [ + "tests/semantic_conformance/test_approximate_distinct.py::test_estimator_and_filtered_populations[python]", + "tests/semantic_conformance/test_approximate_distinct.py::test_estimator_and_filtered_populations[rust]", + "tests/semantic_conformance/test_approximate_distinct.py::test_query_filters_and_empty_populations[python-False-filters0]", + "tests/semantic_conformance/test_approximate_distinct.py::test_query_filters_and_empty_populations[python-False-filters1]", + "tests/semantic_conformance/test_approximate_distinct.py::test_query_filters_and_empty_populations[python-True-filters0]", + "tests/semantic_conformance/test_approximate_distinct.py::test_query_filters_and_empty_populations[python-True-filters1]", + "tests/semantic_conformance/test_approximate_distinct.py::test_query_filters_and_empty_populations[rust-False-filters0]", + "tests/semantic_conformance/test_approximate_distinct.py::test_query_filters_and_empty_populations[rust-False-filters1]", + "tests/semantic_conformance/test_approximate_distinct.py::test_query_filters_and_empty_populations[rust-True-filters0]", + "tests/semantic_conformance/test_approximate_distinct.py::test_query_filters_and_empty_populations[rust-True-filters1]", + "tests/semantic_conformance/test_approximate_distinct.py::test_aggregate_filters_wrappers_and_stored_scalar_fallback[python]", + "tests/semantic_conformance/test_approximate_distinct.py::test_aggregate_filters_wrappers_and_stored_scalar_fallback[rust]", + "tests/semantic_conformance/test_approximate_distinct.py::test_joined_populations[python-many_to_one]", + "tests/semantic_conformance/test_approximate_distinct.py::test_joined_populations[python-one_to_many]", + "tests/semantic_conformance/test_approximate_distinct.py::test_joined_populations[rust-many_to_one]", + "tests/semantic_conformance/test_approximate_distinct.py::test_joined_populations[rust-one_to_many]", + "tests/semantic_conformance/test_approximate_distinct.py::test_cumulative_approximate_counts_use_grouped_outputs[python-None]", + "tests/semantic_conformance/test_approximate_distinct.py::test_cumulative_approximate_counts_use_grouped_outputs[python-sum(base.users)]", + "tests/semantic_conformance/test_approximate_distinct.py::test_cumulative_approximate_counts_use_grouped_outputs[rust-None]", + "tests/semantic_conformance/test_approximate_distinct.py::test_cumulative_approximate_counts_use_grouped_outputs[rust-sum(base.users)]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_redshift_nested_approximate_expressions_use_independent_parser[python-ROUND(COALESCE(APPROX_COUNT_DISTINCT(user_id), 0), 0)]", + "tests/semantic_conformance/test_approximate_distinct.py::test_redshift_nested_approximate_expressions_use_independent_parser[python-GREATEST(APPROX_COUNT_DISTINCT(user_id), 0)]", + "tests/semantic_conformance/test_approximate_distinct.py::test_redshift_nested_approximate_expressions_use_independent_parser[python-NULLIF(APPROX_COUNT_DISTINCT(user_id), 0)]", + "tests/semantic_conformance/test_approximate_distinct.py::test_redshift_nested_approximate_expressions_use_independent_parser[rust-ROUND(COALESCE(APPROX_COUNT_DISTINCT(user_id), 0), 0)]", + "tests/semantic_conformance/test_approximate_distinct.py::test_redshift_nested_approximate_expressions_use_independent_parser[rust-GREATEST(APPROX_COUNT_DISTINCT(user_id), 0)]", + "tests/semantic_conformance/test_approximate_distinct.py::test_redshift_nested_approximate_expressions_use_independent_parser[rust-NULLIF(APPROX_COUNT_DISTINCT(user_id), 0)]" + ] + }, + "scope-152": { + "path": "tests/semantic_conformance/test_approximate_distinct.py", + "declared_tests": [ + "test_approximate_dialect_rendering_and_population_results" + ], + "collected_tests": [ + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-simple-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-implicit-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout_implicit-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-filtered-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-wrapper-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-fanout-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-snapshot-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-cumulative-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-complete_filtered-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-nested_complete-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[python-window-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-simple-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-implicit-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout_implicit-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-filtered-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-wrapper-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-fanout-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-snapshot-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-cumulative-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-complete_filtered-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-nested_complete-sqlite-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-duckdb-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-postgres-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-bigquery-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-snowflake-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-trino-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-spark-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-databricks-APPROX_COUNT_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-redshift-APPROXIMATE COUNT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-clickhouse-UNIQ]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-mysql-APPROX_DISTINCT]", + "tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results[rust-window-sqlite-APPROX_DISTINCT]" + ] + }, + "scope-153": { + "path": "tests/semantic_conformance/test_approximate_distinct.py", + "declared_tests": [ + "test_redshift_nested_approximate_expressions_use_independent_parser" + ], + "collected_tests": [ + "tests/semantic_conformance/test_approximate_distinct.py::test_redshift_nested_approximate_expressions_use_independent_parser[python-ROUND(COALESCE(APPROX_COUNT_DISTINCT(user_id), 0), 0)]", + "tests/semantic_conformance/test_approximate_distinct.py::test_redshift_nested_approximate_expressions_use_independent_parser[python-GREATEST(APPROX_COUNT_DISTINCT(user_id), 0)]", + "tests/semantic_conformance/test_approximate_distinct.py::test_redshift_nested_approximate_expressions_use_independent_parser[python-NULLIF(APPROX_COUNT_DISTINCT(user_id), 0)]", + "tests/semantic_conformance/test_approximate_distinct.py::test_redshift_nested_approximate_expressions_use_independent_parser[rust-ROUND(COALESCE(APPROX_COUNT_DISTINCT(user_id), 0), 0)]", + "tests/semantic_conformance/test_approximate_distinct.py::test_redshift_nested_approximate_expressions_use_independent_parser[rust-GREATEST(APPROX_COUNT_DISTINCT(user_id), 0)]", + "tests/semantic_conformance/test_approximate_distinct.py::test_redshift_nested_approximate_expressions_use_independent_parser[rust-NULLIF(APPROX_COUNT_DISTINCT(user_id), 0)]" + ] + }, + "scope-154": { + "path": "tests/semantic_conformance/test_cli.py", + "declared_tests": [ + "test_cli_rewrite_executes_imported_query" + ], + "collected_tests": [ + "tests/semantic_conformance/test_cli.py::test_cli_rewrite_executes_imported_query[python-native/orders-select customers.region, orders.revenue from orders order by customers.region-columns0-rows0]", + "tests/semantic_conformance/test_cli.py::test_cli_rewrite_executes_imported_query[python-cube-select customers.region, orders.revenue from orders order by customers.region-columns1-rows1]", + "tests/semantic_conformance/test_cli.py::test_cli_rewrite_executes_imported_query[python-native/orders-select revenue_per_customer from metrics-columns2-rows2]", + "tests/semantic_conformance/test_cli.py::test_cli_rewrite_executes_imported_query[python-native/orders-select orders.revenue as first_total, orders.revenue as second_total from metrics-columns3-rows3]", + "tests/semantic_conformance/test_cli.py::test_cli_rewrite_executes_imported_query[python-native/monthly-select monthly.sale_date__month as month, revenue_mom as change from metrics order by month-columns4-rows4]", + "tests/semantic_conformance/test_cli.py::test_cli_rewrite_executes_imported_query[python-native/monthly-select monthly.sale_date__month, revenue_mom from metrics order by monthly.sale_date__month-columns5-rows5]", + "tests/semantic_conformance/test_cli.py::test_cli_rewrite_executes_imported_query[python-native/roles-select origin.city as origin_city, destination.city as destination_city, flights.flight_count from metrics order by destination.city-columns6-rows6]", + "tests/semantic_conformance/test_cli.py::test_cli_rewrite_executes_imported_query[rust-native/orders-select customers.region, orders.revenue from orders order by customers.region-columns0-rows0]", + "tests/semantic_conformance/test_cli.py::test_cli_rewrite_executes_imported_query[rust-cube-select customers.region, orders.revenue from orders order by customers.region-columns1-rows1]", + "tests/semantic_conformance/test_cli.py::test_cli_rewrite_executes_imported_query[rust-native/orders-select revenue_per_customer from metrics-columns2-rows2]", + "tests/semantic_conformance/test_cli.py::test_cli_rewrite_executes_imported_query[rust-native/orders-select orders.revenue as first_total, orders.revenue as second_total from metrics-columns3-rows3]", + "tests/semantic_conformance/test_cli.py::test_cli_rewrite_executes_imported_query[rust-native/monthly-select monthly.sale_date__month as month, revenue_mom as change from metrics order by month-columns4-rows4]", + "tests/semantic_conformance/test_cli.py::test_cli_rewrite_executes_imported_query[rust-native/monthly-select monthly.sale_date__month, revenue_mom from metrics order by monthly.sale_date__month-columns5-rows5]", + "tests/semantic_conformance/test_cli.py::test_cli_rewrite_executes_imported_query[rust-native/roles-select origin.city as origin_city, destination.city as destination_city, flights.flight_count from metrics order by destination.city-columns6-rows6]" + ] + }, + "scope-155": { + "path": "tests/semantic_conformance/test_cohort_parity.py", + "declared_tests": [ + "test_cohort_count_zero_is_not_replaced_by_default", + "test_cohort_default_does_not_fill_inner_values_before_having", + "test_cohort_default_fills_outer_empty_aggregate_without_creating_groups", + "test_cohort_order_preserves_explicit_null_placement", + "test_cohort_output_dialects_preserve_qualified_populations", + "test_cohort_policy_requires_caller_context", + "test_compilation_preserves_cohort_source_and_owner", + "test_count_counts_qualified_inner_groups_including_null_entity", + "test_distinct_entity_count_excludes_null_entity", + "test_empty_cohort_outer_sum_is_null", + "test_entity_can_qualify_globally_but_not_within_each_region", + "test_entity_dimensions_are_output_and_grouping_dimensions", + "test_explicit_owner_wins_over_other_entity_and_metric_names", + "test_filter_applies_before_inner_distinct_aggregation", + "test_having_uses_inner_alias_even_when_source_dimension_has_same_name", + "test_inner_source_dimension_arithmetic_preserves_precedence", + "test_inner_source_dimension_root_resolves_physical_expression", + "test_invariants_restrict_inner_population_before_having", + "test_metric_filter_applies_before_inner_distinct_aggregation", + "test_nonexistent_explicit_owner_does_not_fall_back_to_entity_match", + "test_or_predicate_cannot_bypass_metric_filter", + "test_outer_aggregations_read_qualified_inner_values", + "test_outer_expression_reads_cohort_columns_not_source_rows", + "test_outer_sum_binds_inner_measure_alias", + "test_owned_graph_cohort_default_and_ignored_offset_preserve_population", + "test_owned_graph_cohort_unsupported_shapes_remain_gated", + "test_owned_graph_cohort_visibility_is_enforced", + "test_policy_prevents_cross_tenant_entity_qualification", + "test_query_grouping_changes_inner_and_outer_grain", + "test_reserved_output_dimension_is_quoted", + "test_rust_cohort_result_context_requires_scalar_expression", + "test_rust_declared_dimension_cannot_hide_a_subquery", + "test_rust_inner_alias_collisions_ignore_case", + "test_rust_inner_expression_cannot_change_source_scope", + "test_rust_output_alias_collision_ignores_case", + "test_rust_row_filter_cannot_hide_a_subquery", + "test_selected_calculations_preserve_implicit_entity_dimensions", + "test_source_anchored_explore_preserves_cohort_population", + "test_time_bucket_is_carried_through_to_outer_output" + ], + "collected_tests": [ + "tests/semantic_conformance/test_cohort_parity.py::test_source_anchored_explore_preserves_cohort_population[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_source_anchored_explore_preserves_cohort_population[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_source_anchored_explore_preserves_cohort_population[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_source_anchored_explore_preserves_cohort_population[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_count_counts_qualified_inner_groups_including_null_entity[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_count_counts_qualified_inner_groups_including_null_entity[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_count_counts_qualified_inner_groups_including_null_entity[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_count_counts_qualified_inner_groups_including_null_entity[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_distinct_entity_count_excludes_null_entity[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_distinct_entity_count_excludes_null_entity[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_distinct_entity_count_excludes_null_entity[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_distinct_entity_count_excludes_null_entity[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_sum_binds_inner_measure_alias[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_sum_binds_inner_measure_alias[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_sum_binds_inner_measure_alias[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_sum_binds_inner_measure_alias[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_having_uses_inner_alias_even_when_source_dimension_has_same_name[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_having_uses_inner_alias_even_when_source_dimension_has_same_name[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_having_uses_inner_alias_even_when_source_dimension_has_same_name[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_having_uses_inner_alias_even_when_source_dimension_has_same_name[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_query_grouping_changes_inner_and_outer_grain[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_query_grouping_changes_inner_and_outer_grain[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_query_grouping_changes_inner_and_outer_grain[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_query_grouping_changes_inner_and_outer_grain[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_order_preserves_explicit_null_placement[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_order_preserves_explicit_null_placement[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_order_preserves_explicit_null_placement[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_order_preserves_explicit_null_placement[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_time_bucket_is_carried_through_to_outer_output[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_time_bucket_is_carried_through_to_outer_output[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_time_bucket_is_carried_through_to_outer_output[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_time_bucket_is_carried_through_to_outer_output[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_filter_applies_before_inner_distinct_aggregation[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_filter_applies_before_inner_distinct_aggregation[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_filter_applies_before_inner_distinct_aggregation[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_filter_applies_before_inner_distinct_aggregation[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_metric_filter_applies_before_inner_distinct_aggregation[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_metric_filter_applies_before_inner_distinct_aggregation[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_metric_filter_applies_before_inner_distinct_aggregation[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_metric_filter_applies_before_inner_distinct_aggregation[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_policy_prevents_cross_tenant_entity_qualification[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_policy_prevents_cross_tenant_entity_qualification[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_policy_prevents_cross_tenant_entity_qualification[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_policy_prevents_cross_tenant_entity_qualification[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_policy_requires_caller_context[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_policy_requires_caller_context[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_policy_requires_caller_context[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_policy_requires_caller_context[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_entity_dimensions_are_output_and_grouping_dimensions[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_entity_dimensions_are_output_and_grouping_dimensions[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_entity_dimensions_are_output_and_grouping_dimensions[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_entity_dimensions_are_output_and_grouping_dimensions[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_expression_reads_cohort_columns_not_source_rows[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_expression_reads_cohort_columns_not_source_rows[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_expression_reads_cohort_columns_not_source_rows[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_expression_reads_cohort_columns_not_source_rows[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_entity_can_qualify_globally_but_not_within_each_region[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_entity_can_qualify_globally_but_not_within_each_region[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_entity_can_qualify_globally_but_not_within_each_region[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_entity_can_qualify_globally_but_not_within_each_region[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_reserved_output_dimension_is_quoted[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_reserved_output_dimension_is_quoted[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_reserved_output_dimension_is_quoted[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_reserved_output_dimension_is_quoted[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_empty_cohort_outer_sum_is_null[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_empty_cohort_outer_sum_is_null[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_empty_cohort_outer_sum_is_null[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_empty_cohort_outer_sum_is_null[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_or_predicate_cannot_bypass_metric_filter[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_or_predicate_cannot_bypass_metric_filter[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_or_predicate_cannot_bypass_metric_filter[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_or_predicate_cannot_bypass_metric_filter[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_inner_expression_cannot_change_source_scope[(select count(*) from events)-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_inner_expression_cannot_change_source_scope[(select count(*) from events)-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_inner_expression_cannot_change_source_scope[sum(raw_amount) over ()-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_inner_expression_cannot_change_source_scope[sum(raw_amount) over ()-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_inner_expression_cannot_change_source_scope[count(*)-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_inner_expression_cannot_change_source_scope[count(*)-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_inner_expression_cannot_change_source_scope[other.raw_amount-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_inner_expression_cannot_change_source_scope[other.raw_amount-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_declared_dimension_cannot_hide_a_subquery[hidden-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_declared_dimension_cannot_hide_a_subquery[hidden-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_declared_dimension_cannot_hide_a_subquery[hidden + 1-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_declared_dimension_cannot_hide_a_subquery[hidden + 1-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_row_filter_cannot_hide_a_subquery[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_row_filter_cannot_hide_a_subquery[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_arithmetic_preserves_precedence[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_arithmetic_preserves_precedence[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_arithmetic_preserves_precedence[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_arithmetic_preserves_precedence[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_root_resolves_physical_expression[python-amount]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_root_resolves_physical_expression[python-\"amount\"]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_root_resolves_physical_expression[python-events.amount]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_root_resolves_physical_expression[rust-amount]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_root_resolves_physical_expression[rust-\"amount\"]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_root_resolves_physical_expression[rust-events.amount]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_root_resolves_physical_expression[python_owned-amount]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_root_resolves_physical_expression[python_owned-\"amount\"]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_root_resolves_physical_expression[python_owned-events.amount]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_root_resolves_physical_expression[rust_owned-amount]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_root_resolves_physical_expression[rust_owned-\"amount\"]", + "tests/semantic_conformance/test_cohort_parity.py::test_inner_source_dimension_root_resolves_physical_expression[rust_owned-events.amount]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_inner_alias_collisions_ignore_case[AMOUNT-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_inner_alias_collisions_ignore_case[AMOUNT-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_inner_alias_collisions_ignore_case[USER_ID-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_inner_alias_collisions_ignore_case[USER_ID-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_inner_alias_collisions_ignore_case[REGION-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_inner_alias_collisions_ignore_case[REGION-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_output_alias_collision_ignores_case[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_output_alias_collision_ignores_case[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_cohort_result_context_requires_scalar_expression[SUM(amount)-having-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_cohort_result_context_requires_scalar_expression[SUM(amount)-having-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_cohort_result_context_requires_scalar_expression[SUM(amount)-sql-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_cohort_result_context_requires_scalar_expression[SUM(amount)-sql-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_cohort_result_context_requires_scalar_expression[SUM(amount) OVER ()-having-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_cohort_result_context_requires_scalar_expression[SUM(amount) OVER ()-having-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_cohort_result_context_requires_scalar_expression[SUM(amount) OVER ()-sql-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_cohort_result_context_requires_scalar_expression[SUM(amount) OVER ()-sql-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_cohort_result_context_requires_scalar_expression[(SELECT amount)-having-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_cohort_result_context_requires_scalar_expression[(SELECT amount)-having-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_cohort_result_context_requires_scalar_expression[(SELECT amount)-sql-rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_rust_cohort_result_context_requires_scalar_expression[(SELECT amount)-sql-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_invariants_restrict_inner_population_before_having[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_invariants_restrict_inner_population_before_having[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_invariants_restrict_inner_population_before_having[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_invariants_restrict_inner_population_before_having[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_aggregations_read_qualified_inner_values[python-min-3]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_aggregations_read_qualified_inner_values[python-max-70]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_aggregations_read_qualified_inner_values[python-avg-34.333333333333336]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_aggregations_read_qualified_inner_values[rust-min-3]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_aggregations_read_qualified_inner_values[rust-max-70]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_aggregations_read_qualified_inner_values[rust-avg-34.333333333333336]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_aggregations_read_qualified_inner_values[python_owned-min-3]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_aggregations_read_qualified_inner_values[python_owned-max-70]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_aggregations_read_qualified_inner_values[python_owned-avg-34.333333333333336]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_aggregations_read_qualified_inner_values[rust_owned-min-3]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_aggregations_read_qualified_inner_values[rust_owned-max-70]", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_aggregations_read_qualified_inner_values[rust_owned-avg-34.333333333333336]", + "tests/semantic_conformance/test_cohort_parity.py::test_compilation_preserves_cohort_source_and_owner[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_compilation_preserves_cohort_source_and_owner[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_compilation_preserves_cohort_source_and_owner[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_compilation_preserves_cohort_source_and_owner[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_explicit_owner_wins_over_other_entity_and_metric_names[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_explicit_owner_wins_over_other_entity_and_metric_names[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_nonexistent_explicit_owner_does_not_fall_back_to_entity_match[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_nonexistent_explicit_owner_does_not_fall_back_to_entity_match[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_owned_graph_cohort_unsupported_shapes_remain_gated[unknown_metric-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_owned_graph_cohort_unsupported_shapes_remain_gated[wrapper-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_owned_graph_cohort_unsupported_shapes_remain_gated[joined_dimension-rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_owned_graph_cohort_default_and_ignored_offset_preserve_population[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_owned_graph_cohort_default_and_ignored_offset_preserve_population[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_owned_graph_cohort_visibility_is_enforced[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_owned_graph_cohort_visibility_is_enforced[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_default_fills_outer_empty_aggregate_without_creating_groups[python-False]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_default_fills_outer_empty_aggregate_without_creating_groups[python-True]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_default_fills_outer_empty_aggregate_without_creating_groups[rust-False]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_default_fills_outer_empty_aggregate_without_creating_groups[rust-True]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_default_fills_outer_empty_aggregate_without_creating_groups[python_owned-False]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_default_fills_outer_empty_aggregate_without_creating_groups[python_owned-True]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_default_fills_outer_empty_aggregate_without_creating_groups[rust_owned-False]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_default_fills_outer_empty_aggregate_without_creating_groups[rust_owned-True]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_default_does_not_fill_inner_values_before_having[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_default_does_not_fill_inner_values_before_having[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_default_does_not_fill_inner_values_before_having[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_default_does_not_fill_inner_values_before_having[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_count_zero_is_not_replaced_by_default[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_count_zero_is_not_replaced_by_default[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_count_zero_is_not_replaced_by_default[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_count_zero_is_not_replaced_by_default[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_selected_calculations_preserve_implicit_entity_dimensions[python]", + "tests/semantic_conformance/test_cohort_parity.py::test_selected_calculations_preserve_implicit_entity_dimensions[rust]", + "tests/semantic_conformance/test_cohort_parity.py::test_selected_calculations_preserve_implicit_entity_dimensions[python_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_selected_calculations_preserve_implicit_entity_dimensions[rust_owned]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-plain-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-plain-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-plain-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-plain-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-plain-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-plain-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-reserved_dimension-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-reserved_dimension-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-reserved_dimension-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-reserved_dimension-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-reserved_dimension-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-reserved_dimension-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-inner_approximate-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-inner_approximate-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-inner_approximate-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-inner_approximate-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-inner_approximate-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-inner_approximate-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-outer_approximate-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-outer_approximate-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-outer_approximate-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-outer_approximate-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-outer_approximate-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-outer_approximate-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-month-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-month-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-month-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-month-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-month-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python-month-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-plain-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-plain-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-plain-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-plain-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-plain-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-plain-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-reserved_dimension-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-reserved_dimension-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-reserved_dimension-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-reserved_dimension-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-reserved_dimension-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-reserved_dimension-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-inner_approximate-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-inner_approximate-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-inner_approximate-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-inner_approximate-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-inner_approximate-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-inner_approximate-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-outer_approximate-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-outer_approximate-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-outer_approximate-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-outer_approximate-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-outer_approximate-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-outer_approximate-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-month-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-month-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-month-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-month-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-month-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust-month-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-plain-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-plain-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-plain-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-plain-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-plain-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-plain-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-reserved_dimension-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-reserved_dimension-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-reserved_dimension-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-reserved_dimension-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-reserved_dimension-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-reserved_dimension-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-inner_approximate-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-inner_approximate-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-inner_approximate-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-inner_approximate-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-inner_approximate-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-inner_approximate-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-outer_approximate-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-outer_approximate-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-outer_approximate-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-outer_approximate-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-outer_approximate-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-outer_approximate-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-month-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-month-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-month-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-month-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-month-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[python_owned-month-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-plain-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-plain-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-plain-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-plain-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-plain-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-plain-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-reserved_dimension-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-reserved_dimension-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-reserved_dimension-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-reserved_dimension-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-reserved_dimension-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-reserved_dimension-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-inner_approximate-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-inner_approximate-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-inner_approximate-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-inner_approximate-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-inner_approximate-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-inner_approximate-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-outer_approximate-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-outer_approximate-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-outer_approximate-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-outer_approximate-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-outer_approximate-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-outer_approximate-clickhouse]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-month-duckdb]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-month-postgres]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-month-bigquery]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-month-snowflake]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-month-trino]", + "tests/semantic_conformance/test_cohort_parity.py::test_cohort_output_dialects_preserve_qualified_populations[rust_owned-month-clickhouse]" + ] + }, + "scope-156": { + "path": "tests/semantic_conformance/test_complete_filters.py", + "declared_tests": [ + "test_complete_filter_formulas_execute_with_physical_inputs", + "test_complete_filters_use_physical_values_under_semantic_name_collision", + "test_complete_row_count_counts_null_values_and_keeps_groups", + "test_complete_row_count_cross_source_absent_group_restores_zero", + "test_complete_row_count_empty_population_is_zero", + "test_complete_row_count_generator_reuse_observes_graph_changes", + "test_complete_row_count_keyed_fanout_and_missing_source_rows", + "test_complete_row_count_mandatory_policies_and_query_filters", + "test_complete_row_count_physical_filters_preserve_quotes_literals_and_boolean_groups", + "test_complete_row_count_role_queries_preserve_caller_caches", + "test_filter_conjunction_preserves_disjunction_grouping", + "test_filtered_average_and_distinct_filters_use_physical_column_values", + "test_filtered_average_and_distinct_keep_different_denominators", + "test_filtered_average_and_distinct_keep_independent_populations", + "test_filtered_average_and_distinct_obey_source_policies", + "test_filtered_average_and_distinct_preserve_empty_measure_groups", + "test_filtered_average_and_distinct_survive_unequal_join_fanout", + "test_filtered_float_averages_deduplicate_keys_within_each_group", + "test_foreign_filter_population_fails_explicitly", + "test_groups_without_matching_measure_rows_keep_other_measures", + "test_independent_filters_preserve_each_measure_population", + "test_invalid_complete_sql_keeps_database_validation", + "test_invariant_restriction_still_scopes_every_filtered_measure", + "test_qualified_physical_columns_do_not_rewrite_string_literals", + "test_selected_complete_row_count_invalid_filter_is_rejected", + "test_tsql_complete_row_count_retains_existing_path", + "test_unowned_graph_complete_count_remains_explicitly_unsupported", + "test_unproven_complete_filter_shapes_fail_explicitly", + "test_unused_invalid_complete_metric_does_not_break_other_query" + ], + "collected_tests": [ + "tests/semantic_conformance/test_complete_filters.py::test_independent_filters_preserve_each_measure_population[python]", + "tests/semantic_conformance/test_complete_filters.py::test_independent_filters_preserve_each_measure_population[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filters_use_physical_values_under_semantic_name_collision[python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filters_use_physical_values_under_semantic_name_collision[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_groups_without_matching_measure_rows_keep_other_measures[python]", + "tests/semantic_conformance/test_complete_filters.py::test_groups_without_matching_measure_rows_keep_other_measures[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_invariant_restriction_still_scopes_every_filtered_measure[python]", + "tests/semantic_conformance/test_complete_filters.py::test_invariant_restriction_still_scopes_every_filtered_measure[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_qualified_physical_columns_do_not_rewrite_string_literals[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_filter_conjunction_preserves_disjunction_grouping[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(DISTINCT *)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(2)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(DISTINCT 1)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(DISTINCT NULL)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(1 + 0)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(CAST(NULL AS INTEGER))]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT((SELECT 1))]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[SUM(1)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[SUM(COALESCE(other.amount, amount))]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[SUM(CASE WHEN amount > 0 THEN other.amount ELSE 0 END)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[SUM((SELECT amount))]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[SUM(other.amount)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[AVG(other.amount)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(*) OVER ()]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(other.*)]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(CAST(amount AS DOUBLE))-expected0-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(CAST(amount AS DOUBLE))-expected0-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(amount / 2)-expected1-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(amount / 2)-expected1-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(amount) + COUNT(amount)-expected2-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(amount) + COUNT(amount)-expected2-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[COUNT(DISTINCT ABS(amount))-expected3-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[COUNT(DISTINCT ABS(amount))-expected3-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[AVG(DISTINCT amount)-expected4-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[AVG(DISTINCT amount)-expected4-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[COUNT(*) FILTER (WHERE amount > 0)-expected5-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[COUNT(*) FILTER (WHERE amount > 0)-expected5-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[COUNT(CASE WHEN amount > 0 THEN 'prefix{model}.value' ELSE 'other' END)-expected6-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[COUNT(CASE WHEN amount > 0 THEN 'prefix{model}.value' ELSE 'other' END)-expected6-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(amount) OVER ()-expected7-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(amount) OVER ()-expected7-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[AVG(amount) OVER ()-expected8-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[AVG(amount) OVER ()-expected8-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_invalid_complete_sql_keeps_database_validation[SUM(COALESCE(SUM(amount), 0))-aggregate function calls cannot be nested-python]", + "tests/semantic_conformance/test_complete_filters.py::test_invalid_complete_sql_keeps_database_validation[SUM(COALESCE(SUM(amount), 0))-aggregate function calls cannot be nested-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_invalid_complete_sql_keeps_database_validation[COUNT(COALESCE(amount, '{model}'))-Could not convert string-python]", + "tests/semantic_conformance/test_complete_filters.py::test_invalid_complete_sql_keeps_database_validation[COUNT(COALESCE(amount, '{model}'))-Could not convert string-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_foreign_filter_population_fails_explicitly", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_average_and_distinct_keep_different_denominators[python]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_average_and_distinct_keep_different_denominators[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_average_and_distinct_preserve_empty_measure_groups[python]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_average_and_distinct_preserve_empty_measure_groups[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_average_and_distinct_keep_independent_populations[python]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_average_and_distinct_keep_independent_populations[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_average_and_distinct_filters_use_physical_column_values[python]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_average_and_distinct_filters_use_physical_column_values[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_average_and_distinct_obey_source_policies[python]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_average_and_distinct_obey_source_policies[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_average_and_distinct_survive_unequal_join_fanout[python]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_average_and_distinct_survive_unequal_join_fanout[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-none-none-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-none-none-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-none-average-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-none-average-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-none-sum-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-none-sum-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-outputs-none-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-outputs-none-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-outputs-average-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-outputs-average-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-outputs-sum-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-outputs-sum-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-internal-none-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-internal-none-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-internal-average-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-internal-average-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-internal-sum-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[python-internal-sum-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-none-none-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-none-none-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-none-average-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-none-average-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-none-sum-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-none-sum-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-outputs-none-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-outputs-none-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-outputs-average-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-outputs-average-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-outputs-sum-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-outputs-sum-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-internal-none-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-internal-none-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-internal-average-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-internal-average-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-internal-sum-FLOAT]", + "tests/semantic_conformance/test_complete_filters.py::test_filtered_float_averages_deduplicate_keys_within_each_group[rust-internal-sum-DOUBLE]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_counts_null_values_and_keeps_groups[python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_counts_null_values_and_keeps_groups[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_empty_population_is_zero[python-False]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_empty_population_is_zero[python-True]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_empty_population_is_zero[rust-False]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_empty_population_is_zero[rust-True]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_physical_filters_preserve_quotes_literals_and_boolean_groups[python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_physical_filters_preserve_quotes_literals_and_boolean_groups[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_mandatory_policies_and_query_filters[python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_mandatory_policies_and_query_filters[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_keyed_fanout_and_missing_source_rows[python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_keyed_fanout_and_missing_source_rows[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_cross_source_absent_group_restores_zero[python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_cross_source_absent_group_restores_zero[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_generator_reuse_observes_graph_changes[python]", + "tests/semantic_conformance/test_complete_filters.py::test_unused_invalid_complete_metric_does_not_break_other_query[python-COUNT(*)-status = (]", + "tests/semantic_conformance/test_complete_filters.py::test_unused_invalid_complete_metric_does_not_break_other_query[python-SUM(-true]", + "tests/semantic_conformance/test_complete_filters.py::test_unused_invalid_complete_metric_does_not_break_other_query[rust-COUNT(*)-status = (]", + "tests/semantic_conformance/test_complete_filters.py::test_unused_invalid_complete_metric_does_not_break_other_query[rust-SUM(-true]", + "tests/semantic_conformance/test_complete_filters.py::test_selected_complete_row_count_invalid_filter_is_rejected[python]", + "tests/semantic_conformance/test_complete_filters.py::test_selected_complete_row_count_invalid_filter_is_rejected[rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_role_queries_preserve_caller_caches[python]", + "tests/semantic_conformance/test_complete_filters.py::test_unowned_graph_complete_count_remains_explicitly_unsupported[COUNT(*)]", + "tests/semantic_conformance/test_complete_filters.py::test_unowned_graph_complete_count_remains_explicitly_unsupported[COUNT(1)]", + "tests/semantic_conformance/test_complete_filters.py::test_unowned_graph_complete_count_remains_explicitly_unsupported[COUNT(NULL)]", + "tests/semantic_conformance/test_complete_filters.py::test_tsql_complete_row_count_retains_existing_path[COUNT(*)-python]", + "tests/semantic_conformance/test_complete_filters.py::test_tsql_complete_row_count_retains_existing_path[COUNT_BIG(*)-python]" + ] + }, + "scope-157": { + "path": "tests/semantic_conformance/test_complete_filters.py", + "declared_tests": [ + "test_unproven_complete_filter_shapes_fail_explicitly" + ], + "collected_tests": [ + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(DISTINCT *)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(2)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(DISTINCT 1)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(DISTINCT NULL)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(1 + 0)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(CAST(NULL AS INTEGER))]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT((SELECT 1))]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[SUM(1)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[SUM(COALESCE(other.amount, amount))]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[SUM(CASE WHEN amount > 0 THEN other.amount ELSE 0 END)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[SUM((SELECT amount))]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[SUM(other.amount)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[AVG(other.amount)]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(*) OVER ()]", + "tests/semantic_conformance/test_complete_filters.py::test_unproven_complete_filter_shapes_fail_explicitly[COUNT(other.*)]" + ] + }, + "scope-158": { + "path": "tests/semantic_conformance/test_complete_filters.py", + "declared_tests": [ + "test_complete_filter_formulas_execute_with_physical_inputs" + ], + "collected_tests": [ + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(CAST(amount AS DOUBLE))-expected0-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(CAST(amount AS DOUBLE))-expected0-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(amount / 2)-expected1-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(amount / 2)-expected1-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(amount) + COUNT(amount)-expected2-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(amount) + COUNT(amount)-expected2-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[COUNT(DISTINCT ABS(amount))-expected3-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[COUNT(DISTINCT ABS(amount))-expected3-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[AVG(DISTINCT amount)-expected4-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[AVG(DISTINCT amount)-expected4-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[COUNT(*) FILTER (WHERE amount > 0)-expected5-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[COUNT(*) FILTER (WHERE amount > 0)-expected5-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[COUNT(CASE WHEN amount > 0 THEN 'prefix{model}.value' ELSE 'other' END)-expected6-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[COUNT(CASE WHEN amount > 0 THEN 'prefix{model}.value' ELSE 'other' END)-expected6-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(amount) OVER ()-expected7-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[SUM(amount) OVER ()-expected7-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[AVG(amount) OVER ()-expected8-python]", + "tests/semantic_conformance/test_complete_filters.py::test_complete_filter_formulas_execute_with_physical_inputs[AVG(amount) OVER ()-expected8-rust]" + ] + }, + "scope-159": { + "path": "tests/semantic_conformance/test_complete_filters.py", + "declared_tests": [ + "test_invalid_complete_sql_keeps_database_validation" + ], + "collected_tests": [ + "tests/semantic_conformance/test_complete_filters.py::test_invalid_complete_sql_keeps_database_validation[SUM(COALESCE(SUM(amount), 0))-aggregate function calls cannot be nested-python]", + "tests/semantic_conformance/test_complete_filters.py::test_invalid_complete_sql_keeps_database_validation[SUM(COALESCE(SUM(amount), 0))-aggregate function calls cannot be nested-rust]", + "tests/semantic_conformance/test_complete_filters.py::test_invalid_complete_sql_keeps_database_validation[COUNT(COALESCE(amount, '{model}'))-Could not convert string-python]", + "tests/semantic_conformance/test_complete_filters.py::test_invalid_complete_sql_keeps_database_validation[COUNT(COALESCE(amount, '{model}'))-Could not convert string-rust]" + ] + }, + "scope-160": { + "path": "tests/semantic_conformance/test_complete_filters.py", + "declared_tests": [ + "test_foreign_filter_population_fails_explicitly" + ], + "collected_tests": [ + "tests/semantic_conformance/test_complete_filters.py::test_foreign_filter_population_fails_explicitly" + ] + }, + "scope-161": { + "path": "tests/semantic_conformance/test_complete_filters.py", + "declared_tests": [ + "test_complete_row_count_generator_reuse_observes_graph_changes" + ], + "collected_tests": [ + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_generator_reuse_observes_graph_changes[python]" + ] + }, + "scope-162": { + "path": "tests/semantic_conformance/test_complete_filters.py", + "declared_tests": [ + "test_complete_row_count_role_queries_preserve_caller_caches" + ], + "collected_tests": [ + "tests/semantic_conformance/test_complete_filters.py::test_complete_row_count_role_queries_preserve_caller_caches[python]" + ] + }, + "scope-163": { + "path": "tests/semantic_conformance/test_complete_filters.py", + "declared_tests": [ + "test_unowned_graph_complete_count_remains_explicitly_unsupported" + ], + "collected_tests": [ + "tests/semantic_conformance/test_complete_filters.py::test_unowned_graph_complete_count_remains_explicitly_unsupported[COUNT(*)]", + "tests/semantic_conformance/test_complete_filters.py::test_unowned_graph_complete_count_remains_explicitly_unsupported[COUNT(1)]", + "tests/semantic_conformance/test_complete_filters.py::test_unowned_graph_complete_count_remains_explicitly_unsupported[COUNT(NULL)]" + ] + }, + "scope-164": { + "path": "tests/semantic_conformance/test_complete_filters.py", + "declared_tests": [ + "test_tsql_complete_row_count_retains_existing_path" + ], + "collected_tests": [ + "tests/semantic_conformance/test_complete_filters.py::test_tsql_complete_row_count_retains_existing_path[COUNT(*)-python]", + "tests/semantic_conformance/test_complete_filters.py::test_tsql_complete_row_count_retains_existing_path[COUNT_BIG(*)-python]" + ] + }, + "scope-165": { + "path": "tests/semantic_conformance/test_complete_filters_postgres.py", + "declared_tests": [ + "test_complete_filters_preserve_identifier_identity" + ], + "collected_tests": [ + "tests/semantic_conformance/test_complete_filters_postgres.py::test_complete_filters_preserve_identifier_identity[SUM(orders.Amount)-orders.Amount > 0-5]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_complete_filters_preserve_identifier_identity[SUM(orders.\"Amount\")-orders.\"Amount\" > 0-30]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_complete_filters_preserve_identifier_identity[AVG(orders.Amount)-orders.Amount > 0-2.5]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_complete_filters_preserve_identifier_identity[AVG(orders.\"Amount\")-orders.\"Amount\" > 0-15]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_complete_filters_preserve_identifier_identity[COUNT(DISTINCT orders.\"Amount\")-orders.\"Amount\" > 0-2]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_complete_filters_preserve_identifier_identity[COUNT(DISTINCT orders.Amount)-orders.Amount > 0-2]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_complete_filters_preserve_identifier_identity[SUM(orders.Amount)-orders.Amount > 0 AND orders.\"Amount\" = 10 AND orders.label = 'orders.Amount'-2]" + ] + }, + "scope-166": { + "path": "tests/semantic_conformance/test_complete_filters_postgres.py", + "declared_tests": [ + "test_postgres_filtered_float_fanout_average_preserves_values" + ], + "collected_tests": [ + "tests/semantic_conformance/test_complete_filters_postgres.py::test_postgres_filtered_float_fanout_average_preserves_values[none]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_postgres_filtered_float_fanout_average_preserves_values[average]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_postgres_filtered_float_fanout_average_preserves_values[sum]" + ] + }, + "scope-167": { + "path": "tests/semantic_conformance/test_complete_filters_postgres.py", + "declared_tests": [ + "test_postgres_filtered_complete_row_count" + ], + "collected_tests": [ + "tests/semantic_conformance/test_complete_filters_postgres.py::test_postgres_filtered_complete_row_count[grouped]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_postgres_filtered_complete_row_count[no_matches]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_postgres_filtered_complete_row_count[empty]" + ] + }, + "scope-168": { + "path": "tests/semantic_conformance/test_complete_filters_postgres.py", + "declared_tests": [ + "test_postgres_filtered_owned_count_family" + ], + "collected_tests": [ + "tests/semantic_conformance/test_complete_filters_postgres.py::test_postgres_filtered_owned_count_family[grouped-model]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_postgres_filtered_owned_count_family[grouped-graph]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_postgres_filtered_owned_count_family[empty-model]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_postgres_filtered_owned_count_family[empty-graph]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_postgres_filtered_owned_count_family[no_matches-model]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_postgres_filtered_owned_count_family[no_matches-graph]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_postgres_filtered_owned_count_family[fanout-model]", + "tests/semantic_conformance/test_complete_filters_postgres.py::test_postgres_filtered_owned_count_family[fanout-graph]" + ] + }, + "scope-169": { + "path": "tests/semantic_conformance/test_computed_keys.py", + "declared_tests": [ + "test_compound_computed_keys_join_componentwise", + "test_computed_key_predicate_and_raw_self_reference", + "test_cross_role_computed_key_predicate_keeps_role_aliases", + "test_default_distinct_counts_computed_keys_without_join", + "test_disconnected_computed_model_does_not_block_temporal_query", + "test_display_and_both_join_keys_use_semantic_identity", + "test_from_metrics_sql_uses_structured_key_planning", + "test_model_sql_uses_computed_identity", + "test_symmetric_aggregation_uses_computed_identity", + "test_unsafe_key_expressions_are_rejected" + ], + "collected_tests": [ + "tests/semantic_conformance/test_computed_keys.py::test_display_and_both_join_keys_use_semantic_identity", + "tests/semantic_conformance/test_computed_keys.py::test_symmetric_aggregation_uses_computed_identity", + "tests/semantic_conformance/test_computed_keys.py::test_default_distinct_counts_computed_keys_without_join", + "tests/semantic_conformance/test_computed_keys.py::test_computed_key_predicate_and_raw_self_reference", + "tests/semantic_conformance/test_computed_keys.py::test_from_metrics_sql_uses_structured_key_planning", + "tests/semantic_conformance/test_computed_keys.py::test_model_sql_uses_computed_identity", + "tests/semantic_conformance/test_computed_keys.py::test_compound_computed_keys_join_componentwise", + "tests/semantic_conformance/test_computed_keys.py::test_unsafe_key_expressions_are_rejected[random()]", + "tests/semantic_conformance/test_computed_keys.py::test_unsafe_key_expressions_are_rejected[sum(id)]", + "tests/semantic_conformance/test_computed_keys.py::test_unsafe_key_expressions_are_rejected[other.id]", + "tests/semantic_conformance/test_computed_keys.py::test_unsafe_key_expressions_are_rejected[row_number() over ()]", + "tests/semantic_conformance/test_computed_keys.py::test_unsafe_key_expressions_are_rejected[(select id from other)]", + "tests/semantic_conformance/test_computed_keys.py::test_unsafe_key_expressions_are_rejected[1]", + "tests/semantic_conformance/test_computed_keys.py::test_disconnected_computed_model_does_not_block_temporal_query", + "tests/semantic_conformance/test_computed_keys.py::test_cross_role_computed_key_predicate_keeps_role_aliases" + ] + }, + "scope-170": { + "path": "tests/semantic_conformance/test_computed_keys.py", + "declared_tests": [ + "test_omitted_native_relationship_key_does_not_classify_ordinary_id" + ], + "collected_tests": [ + "tests/semantic_conformance/test_computed_keys.py::test_omitted_native_relationship_key_does_not_classify_ordinary_id[False]", + "tests/semantic_conformance/test_computed_keys.py::test_omitted_native_relationship_key_does_not_classify_ordinary_id[True]" + ] + }, + "scope-171": { + "path": "tests/semantic_conformance/test_conversion_parity.py", + "declared_tests": [ + "test_attribution_uses_base_event_dimension", + "test_conversion_policy_requires_caller_context", + "test_empty_base_population_is_null", + "test_filter_literals_are_not_rewritten_as_dimension_expressions", + "test_grouped_pagination_preserves_conversion_output", + "test_invariant_scopes_base_and_target_events", + "test_literal_policy_attribute_cannot_expand_base_population", + "test_metric_filter_scopes_base_and_target_events", + "test_policy_scopes_target_and_denominator", + "test_row_filter_scopes_both_event_populations", + "test_rust_filter_dimension_cannot_hide_a_subquery", + "test_rust_output_alias_collision_ignores_case", + "test_rust_selected_dimension_cannot_change_source_scope", + "test_source_anchored_explore_preserves_conversion_population", + "test_unique_entities_and_inclusive_window" + ], + "collected_tests": [ + "tests/semantic_conformance/test_conversion_parity.py::test_unique_entities_and_inclusive_window[python]", + "tests/semantic_conformance/test_conversion_parity.py::test_unique_entities_and_inclusive_window[rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_attribution_uses_base_event_dimension[python]", + "tests/semantic_conformance/test_conversion_parity.py::test_attribution_uses_base_event_dimension[rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_empty_base_population_is_null[python]", + "tests/semantic_conformance/test_conversion_parity.py::test_empty_base_population_is_null[rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_source_anchored_explore_preserves_conversion_population[python]", + "tests/semantic_conformance/test_conversion_parity.py::test_source_anchored_explore_preserves_conversion_population[rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_row_filter_scopes_both_event_populations[python]", + "tests/semantic_conformance/test_conversion_parity.py::test_row_filter_scopes_both_event_populations[rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_policy_scopes_target_and_denominator[python]", + "tests/semantic_conformance/test_conversion_parity.py::test_policy_scopes_target_and_denominator[rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_conversion_policy_requires_caller_context[python]", + "tests/semantic_conformance/test_conversion_parity.py::test_conversion_policy_requires_caller_context[rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_grouped_pagination_preserves_conversion_output[python]", + "tests/semantic_conformance/test_conversion_parity.py::test_grouped_pagination_preserves_conversion_output[rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_literal_policy_attribute_cannot_expand_base_population[python]", + "tests/semantic_conformance/test_conversion_parity.py::test_literal_policy_attribute_cannot_expand_base_population[rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_invariant_scopes_base_and_target_events[python]", + "tests/semantic_conformance/test_conversion_parity.py::test_invariant_scopes_base_and_target_events[rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_metric_filter_scopes_base_and_target_events[python]", + "tests/semantic_conformance/test_conversion_parity.py::test_metric_filter_scopes_base_and_target_events[rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_rust_selected_dimension_cannot_change_source_scope[(select count(*) from events)-rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_rust_selected_dimension_cannot_change_source_scope[sum(tenant) over ()-rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_rust_selected_dimension_cannot_change_source_scope[other.tenant-rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_rust_filter_dimension_cannot_hide_a_subquery[rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_filter_literals_are_not_rewritten_as_dimension_expressions[python]", + "tests/semantic_conformance/test_conversion_parity.py::test_filter_literals_are_not_rewritten_as_dimension_expressions[rust]", + "tests/semantic_conformance/test_conversion_parity.py::test_rust_output_alias_collision_ignores_case[rust]" + ] + }, + "scope-172": { + "path": "tests/semantic_conformance/test_cross_relationship_parity.py", + "declared_tests": [ + "test_cross_both_measure_populations", + "test_cross_dimensions_need_no_join_keys_and_preserve_nulls", + "test_cross_empty_unfiltered_sibling_preserves_empty_product", + "test_cross_explore_empty_secured_target_removes_anchor_rows", + "test_cross_measure_deduplicates_source_identity" + ], + "collected_tests": [ + "tests/semantic_conformance/test_cross_relationship_parity.py::test_cross_dimensions_need_no_join_keys_and_preserve_nulls[python]", + "tests/semantic_conformance/test_cross_relationship_parity.py::test_cross_dimensions_need_no_join_keys_and_preserve_nulls[rust]", + "tests/semantic_conformance/test_cross_relationship_parity.py::test_cross_measure_deduplicates_source_identity[python]", + "tests/semantic_conformance/test_cross_relationship_parity.py::test_cross_measure_deduplicates_source_identity[rust]", + "tests/semantic_conformance/test_cross_relationship_parity.py::test_cross_explore_empty_secured_target_removes_anchor_rows[python]", + "tests/semantic_conformance/test_cross_relationship_parity.py::test_cross_explore_empty_secured_target_removes_anchor_rows[rust]", + "tests/semantic_conformance/test_cross_relationship_parity.py::test_cross_both_measure_populations[python]", + "tests/semantic_conformance/test_cross_relationship_parity.py::test_cross_both_measure_populations[rust]", + "tests/semantic_conformance/test_cross_relationship_parity.py::test_cross_empty_unfiltered_sibling_preserves_empty_product[python]", + "tests/semantic_conformance/test_cross_relationship_parity.py::test_cross_empty_unfiltered_sibling_preserves_empty_product[rust]" + ] + }, + "scope-173": { + "path": "tests/semantic_conformance/test_cross_source_windows.py", + "declared_tests": [ + "test_native_window_expression_preserves_quoted_input_across_dialects" + ], + "collected_tests": [ + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-order-duckdb]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-order-postgres]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-order-tsql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-order-mysql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-order-bigquery]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-daily amount-duckdb]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-daily amount-postgres]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-daily amount-tsql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-daily amount-mysql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-daily amount-bigquery]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-order-duckdb]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-order-postgres]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-order-tsql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-order-mysql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-order-bigquery]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-daily amount-duckdb]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-daily amount-postgres]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-daily amount-tsql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-daily amount-mysql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-daily amount-bigquery]" + ] + }, + "scope-174": { + "path": "tests/semantic_conformance/test_cross_source_windows.py", + "declared_tests": [ + "test_cross_source_calculation_beside_cumulative_preserves_leaf_grains", + "test_deferred_calculation_keeps_unqueryable_window_owner_validation", + "test_native_window_expression_preserves_quoted_input_across_dialects", + "test_window_inputs_keep_qualified_metric_identity", + "test_window_partitions_bind_both_colliding_sibling_dimensions" + ], + "collected_tests": [ + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-order-duckdb]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-order-postgres]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-order-tsql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-order-mysql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-order-bigquery]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-daily amount-duckdb]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-daily amount-postgres]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-daily amount-tsql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-daily amount-mysql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[day-daily amount-bigquery]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-order-duckdb]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-order-postgres]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-order-tsql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-order-mysql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-order-bigquery]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-daily amount-duckdb]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-daily amount-postgres]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-daily amount-tsql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-daily amount-mysql]", + "tests/semantic_conformance/test_cross_source_windows.py::test_native_window_expression_preserves_quoted_input_across_dialects[order day-daily amount-bigquery]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[python-False-populated]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[python-False-empty_facts]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[python-False-empty_accounts]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[python-False-both_empty]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[python-True-populated]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[python-True-empty_facts]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[python-True-empty_accounts]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[python-True-both_empty]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[rust-False-populated]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[rust-False-empty_facts]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[rust-False-empty_accounts]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[rust-False-both_empty]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[rust-True-populated]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[rust-True-empty_facts]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[rust-True-empty_accounts]", + "tests/semantic_conformance/test_cross_source_windows.py::test_cross_source_calculation_beside_cumulative_preserves_leaf_grains[rust-True-both_empty]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_partitions_bind_both_colliding_sibling_dimensions[python-running]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_partitions_bind_both_colliding_sibling_dimensions[python-expression]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_partitions_bind_both_colliding_sibling_dimensions[python-lag]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_partitions_bind_both_colliding_sibling_dimensions[rust-running]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_partitions_bind_both_colliding_sibling_dimensions[rust-expression]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_partitions_bind_both_colliding_sibling_dimensions[rust-lag]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[python-running-metric]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[python-running-dimension]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[python-expression-metric]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[python-expression-dimension]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[python-lag-metric]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[python-lag-dimension]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[python-ratio-metric]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[python-ratio-dimension]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[rust-running-metric]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[rust-running-dimension]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[rust-expression-metric]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[rust-expression-dimension]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[rust-lag-metric]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[rust-lag-dimension]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[rust-ratio-metric]", + "tests/semantic_conformance/test_cross_source_windows.py::test_window_inputs_keep_qualified_metric_identity[rust-ratio-dimension]", + "tests/semantic_conformance/test_cross_source_windows.py::test_deferred_calculation_keeps_unqueryable_window_owner_validation[False-rust]", + "tests/semantic_conformance/test_cross_source_windows.py::test_deferred_calculation_keeps_unqueryable_window_owner_validation[True-rust]" + ] + }, + "scope-175": { + "path": "tests/semantic_conformance/test_default_time_differential.py", + "declared_tests": [ + "test_skipped_model_defaults_remain_skipped_in_source_children" + ], + "collected_tests": [ + "tests/semantic_conformance/test_default_time_differential.py::test_skipped_model_defaults_remain_skipped_in_source_children[python]", + "tests/semantic_conformance/test_default_time_differential.py::test_skipped_model_defaults_remain_skipped_in_source_children[rust]" + ] + }, + "scope-176": { + "path": "tests/semantic_conformance/test_default_time_differential.py", + "declared_tests": [ + "test_graph_calculation_without_dimensions_is_scalar", + "test_model_default_or_explicit_time_grain_is_projected", + "test_skipped_model_defaults_remain_skipped_in_source_children" + ], + "collected_tests": [ + "tests/semantic_conformance/test_default_time_differential.py::test_graph_calculation_without_dimensions_is_scalar[python]", + "tests/semantic_conformance/test_default_time_differential.py::test_graph_calculation_without_dimensions_is_scalar[rust]", + "tests/semantic_conformance/test_default_time_differential.py::test_skipped_model_defaults_remain_skipped_in_source_children[python]", + "tests/semantic_conformance/test_default_time_differential.py::test_skipped_model_defaults_remain_skipped_in_source_children[rust]", + "tests/semantic_conformance/test_default_time_differential.py::test_model_default_or_explicit_time_grain_is_projected[python-False]", + "tests/semantic_conformance/test_default_time_differential.py::test_model_default_or_explicit_time_grain_is_projected[python-True]", + "tests/semantic_conformance/test_default_time_differential.py::test_model_default_or_explicit_time_grain_is_projected[rust-False]", + "tests/semantic_conformance/test_default_time_differential.py::test_model_default_or_explicit_time_grain_is_projected[rust-True]" + ] + }, + "scope-177": { + "path": "tests/semantic_conformance/test_dialect_boundary.py", + "declared_tests": [ + "test_native_declared_graph_and_query_syntax", + "test_native_fragment_framing_and_source_snapshot", + "test_native_rewrite_syntax_and_policy_context", + "test_source_dialect_preserves_typed_policy_and_parameter_values", + "test_target_dialect_policy_population", + "test_target_policy_literals_survive_alias_wrapping" + ], + "collected_tests": [ + "tests/semantic_conformance/test_dialect_boundary.py::test_target_dialect_policy_population[python-duckdb]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_dialect_policy_population[python-postgres]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_dialect_policy_population[python-bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_dialect_policy_population[python-snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_dialect_policy_population[python-mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_dialect_policy_population[python-spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_dialect_policy_population[python-tsql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_dialect_policy_population[rust-duckdb]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_dialect_policy_population[rust-postgres]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_dialect_policy_population[rust-bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_dialect_policy_population[rust-snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_dialect_policy_population[rust-mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_dialect_policy_population[rust-spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_dialect_policy_population[rust-tsql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[python-bigquery-IFNULL(`amount`, 0)-`orders`.`tenant` = 1-`orders`.`label` DESC NULLS LAST]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[python-mysql-IFNULL(`amount`, 0)-`orders`.`tenant` = 1-`orders`.`label` DESC]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[python-tsql-ISNULL([amount], 0)-[orders].[tenant] = 1-[orders].[label] DESC]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[python-snowflake-COALESCE(\"amount\", 0)-\"orders\".\"tenant\" = 1-\"orders\".\"label\" DESC NULLS LAST]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[python-postgres-COALESCE(\"amount\", 0)-\"orders\".\"tenant\" = 1-\"orders\".\"label\" DESC NULLS LAST]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[rust-bigquery-IFNULL(`amount`, 0)-`orders`.`tenant` = 1-`orders`.`label` DESC NULLS LAST]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[rust-mysql-IFNULL(`amount`, 0)-`orders`.`tenant` = 1-`orders`.`label` DESC]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[rust-tsql-ISNULL([amount], 0)-[orders].[tenant] = 1-[orders].[label] DESC]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[rust-snowflake-COALESCE(\"amount\", 0)-\"orders\".\"tenant\" = 1-\"orders\".\"label\" DESC NULLS LAST]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[rust-postgres-COALESCE(\"amount\", 0)-\"orders\".\"tenant\" = 1-\"orders\".\"label\" DESC NULLS LAST]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_rewrite_syntax_and_policy_context[python-bigquery-`]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_rewrite_syntax_and_policy_context[python-mysql-`]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_rewrite_syntax_and_policy_context[python-postgres-\"]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_rewrite_syntax_and_policy_context[rust-bigquery-`]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_rewrite_syntax_and_policy_context[rust-mysql-`]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_rewrite_syntax_and_policy_context[rust-postgres-\"]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_fragment_framing_and_source_snapshot[python]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_fragment_framing_and_source_snapshot[rust]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\b-mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\b-bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\b-snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\b-spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\' OR 1=1 ---mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\' OR 1=1 ---bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\' OR 1=1 ---snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\' OR 1=1 ---spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-O'Brien-mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-O'Brien-bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-O'Brien-snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-O'Brien-spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\b-mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\b-bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\b-snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\b-spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\' OR 1=1 ---mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\' OR 1=1 ---bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\' OR 1=1 ---snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\' OR 1=1 ---spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-O'Brien-mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-O'Brien-bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-O'Brien-snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-O'Brien-spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[python-a\\\\b-mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[python-a\\\\b-bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[python-a\\\\b-snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[python-a\\\\b-spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[python-a\\\\' OR 1=1 ---mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[python-a\\\\' OR 1=1 ---bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[python-a\\\\' OR 1=1 ---snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[python-a\\\\' OR 1=1 ---spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[python-O'Brien-mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[python-O'Brien-bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[python-O'Brien-snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[python-O'Brien-spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[rust-a\\\\b-mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[rust-a\\\\b-bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[rust-a\\\\b-snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[rust-a\\\\b-spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[rust-a\\\\' OR 1=1 ---mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[rust-a\\\\' OR 1=1 ---bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[rust-a\\\\' OR 1=1 ---snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[rust-a\\\\' OR 1=1 ---spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[rust-O'Brien-mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[rust-O'Brien-bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[rust-O'Brien-snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_target_policy_literals_survive_alias_wrapping[rust-O'Brien-spark]" + ] + }, + "scope-178": { + "path": "tests/semantic_conformance/test_dialect_boundary.py", + "declared_tests": [ + "test_native_declared_graph_and_query_syntax" + ], + "collected_tests": [ + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[python-bigquery-IFNULL(`amount`, 0)-`orders`.`tenant` = 1-`orders`.`label` DESC NULLS LAST]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[python-mysql-IFNULL(`amount`, 0)-`orders`.`tenant` = 1-`orders`.`label` DESC]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[python-tsql-ISNULL([amount], 0)-[orders].[tenant] = 1-[orders].[label] DESC]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[python-snowflake-COALESCE(\"amount\", 0)-\"orders\".\"tenant\" = 1-\"orders\".\"label\" DESC NULLS LAST]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[python-postgres-COALESCE(\"amount\", 0)-\"orders\".\"tenant\" = 1-\"orders\".\"label\" DESC NULLS LAST]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[rust-bigquery-IFNULL(`amount`, 0)-`orders`.`tenant` = 1-`orders`.`label` DESC NULLS LAST]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[rust-mysql-IFNULL(`amount`, 0)-`orders`.`tenant` = 1-`orders`.`label` DESC]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[rust-tsql-ISNULL([amount], 0)-[orders].[tenant] = 1-[orders].[label] DESC]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[rust-snowflake-COALESCE(\"amount\", 0)-\"orders\".\"tenant\" = 1-\"orders\".\"label\" DESC NULLS LAST]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_declared_graph_and_query_syntax[rust-postgres-COALESCE(\"amount\", 0)-\"orders\".\"tenant\" = 1-\"orders\".\"label\" DESC NULLS LAST]" + ] + }, + "scope-179": { + "path": "tests/semantic_conformance/test_dialect_boundary.py", + "declared_tests": [ + "test_native_rewrite_syntax_and_policy_context" + ], + "collected_tests": [ + "tests/semantic_conformance/test_dialect_boundary.py::test_native_rewrite_syntax_and_policy_context[python-bigquery-`]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_rewrite_syntax_and_policy_context[python-mysql-`]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_rewrite_syntax_and_policy_context[python-postgres-\"]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_rewrite_syntax_and_policy_context[rust-bigquery-`]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_rewrite_syntax_and_policy_context[rust-mysql-`]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_rewrite_syntax_and_policy_context[rust-postgres-\"]" + ] + }, + "scope-180": { + "path": "tests/semantic_conformance/test_dialect_boundary.py", + "declared_tests": [ + "test_native_fragment_framing_and_source_snapshot" + ], + "collected_tests": [ + "tests/semantic_conformance/test_dialect_boundary.py::test_native_fragment_framing_and_source_snapshot[python]", + "tests/semantic_conformance/test_dialect_boundary.py::test_native_fragment_framing_and_source_snapshot[rust]" + ] + }, + "scope-181": { + "path": "tests/semantic_conformance/test_dialect_boundary.py", + "declared_tests": [ + "test_source_dialect_preserves_typed_policy_and_parameter_values" + ], + "collected_tests": [ + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\b-mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\b-bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\b-snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\b-spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\' OR 1=1 ---mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\' OR 1=1 ---bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\' OR 1=1 ---snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-a\\\\' OR 1=1 ---spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-O'Brien-mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-O'Brien-bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-O'Brien-snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[python-O'Brien-spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\b-mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\b-bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\b-snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\b-spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\' OR 1=1 ---mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\' OR 1=1 ---bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\' OR 1=1 ---snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-a\\\\' OR 1=1 ---spark]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-O'Brien-mysql]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-O'Brien-bigquery]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-O'Brien-snowflake]", + "tests/semantic_conformance/test_dialect_boundary.py::test_source_dialect_preserves_typed_policy_and_parameter_values[rust-O'Brien-spark]" + ] + }, + "scope-182": { + "path": "tests/semantic_conformance/test_direct_many_relationships.py", + "declared_tests": [ + "test_bridge_keys_override_direct_only_custom_sql", + "test_custom_predicate_remains_physical_with_computed_entity_identity", + "test_direct_alternate_keys_keep_source_grain_and_unmatched_rows", + "test_direct_custom_predicate_overrides_recorded_keys", + "test_direct_role_keeps_custom_predicate_and_source_population", + "test_legacy_remote_foreign_key_joins_source_primary_key" + ], + "collected_tests": [ + "tests/semantic_conformance/test_direct_many_relationships.py::test_direct_alternate_keys_keep_source_grain_and_unmatched_rows[python]", + "tests/semantic_conformance/test_direct_many_relationships.py::test_direct_alternate_keys_keep_source_grain_and_unmatched_rows[rust]", + "tests/semantic_conformance/test_direct_many_relationships.py::test_direct_custom_predicate_overrides_recorded_keys[python]", + "tests/semantic_conformance/test_direct_many_relationships.py::test_direct_custom_predicate_overrides_recorded_keys[rust]", + "tests/semantic_conformance/test_direct_many_relationships.py::test_custom_predicate_remains_physical_with_computed_entity_identity[python]", + "tests/semantic_conformance/test_direct_many_relationships.py::test_custom_predicate_remains_physical_with_computed_entity_identity[rust]", + "tests/semantic_conformance/test_direct_many_relationships.py::test_direct_role_keeps_custom_predicate_and_source_population[python]", + "tests/semantic_conformance/test_direct_many_relationships.py::test_direct_role_keeps_custom_predicate_and_source_population[rust]", + "tests/semantic_conformance/test_direct_many_relationships.py::test_legacy_remote_foreign_key_joins_source_primary_key[python]", + "tests/semantic_conformance/test_direct_many_relationships.py::test_legacy_remote_foreign_key_joins_source_primary_key[rust]", + "tests/semantic_conformance/test_direct_many_relationships.py::test_bridge_keys_override_direct_only_custom_sql[python]", + "tests/semantic_conformance/test_direct_many_relationships.py::test_bridge_keys_override_direct_only_custom_sql[rust]" + ] + }, + "scope-183": { + "path": "tests/semantic_conformance/test_feature_parity.py", + "declared_tests": [ + "test_access_denial_precedes_sql", + "test_access_expression_allows_authorized_user", + "test_empty_context_is_provided_but_missing_context_denies", + "test_explicit_left_join_preserves_purchases_with_filtered_account_details", + "test_inactive_relationship_cannot_be_requested", + "test_joined_policy_scopes_purchases_to_authorized_accounts", + "test_missing_policy_attribute_denies", + "test_named_calendar_comparison_without_declared_granularity", + "test_policy_survives_temporal_child_queries", + "test_policy_values_remain_sql_literals", + "test_rolling_sum_partitions_categories", + "test_sparse_comparison_uses_calendar_month_and_category", + "test_two_roles_preserve_unmatched_rows_and_exclude_inactive_join" + ], + "collected_tests": [ + "tests/semantic_conformance/test_feature_parity.py::test_policy_values_remain_sql_literals[python-alice-10-quoted]", + "tests/semantic_conformance/test_feature_parity.py::test_policy_values_remain_sql_literals[python-alice-10-unquoted]", + "tests/semantic_conformance/test_feature_parity.py::test_policy_values_remain_sql_literals[python-O'Brien-9-quoted]", + "tests/semantic_conformance/test_feature_parity.py::test_policy_values_remain_sql_literals[python-O'Brien-9-unquoted]", + "tests/semantic_conformance/test_feature_parity.py::test_policy_values_remain_sql_literals[python-x' OR '1'='1-7-quoted]", + "tests/semantic_conformance/test_feature_parity.py::test_policy_values_remain_sql_literals[python-x' OR '1'='1-7-unquoted]", + "tests/semantic_conformance/test_feature_parity.py::test_policy_values_remain_sql_literals[rust-alice-10-quoted]", + "tests/semantic_conformance/test_feature_parity.py::test_policy_values_remain_sql_literals[rust-alice-10-unquoted]", + "tests/semantic_conformance/test_feature_parity.py::test_policy_values_remain_sql_literals[rust-O'Brien-9-quoted]", + "tests/semantic_conformance/test_feature_parity.py::test_policy_values_remain_sql_literals[rust-O'Brien-9-unquoted]", + "tests/semantic_conformance/test_feature_parity.py::test_policy_values_remain_sql_literals[rust-x' OR '1'='1-7-quoted]", + "tests/semantic_conformance/test_feature_parity.py::test_policy_values_remain_sql_literals[rust-x' OR '1'='1-7-unquoted]", + "tests/semantic_conformance/test_feature_parity.py::test_missing_policy_attribute_denies[python-None-quoted]", + "tests/semantic_conformance/test_feature_parity.py::test_missing_policy_attribute_denies[python-None-unquoted]", + "tests/semantic_conformance/test_feature_parity.py::test_missing_policy_attribute_denies[python-attributes1-quoted]", + "tests/semantic_conformance/test_feature_parity.py::test_missing_policy_attribute_denies[python-attributes1-unquoted]", + "tests/semantic_conformance/test_feature_parity.py::test_missing_policy_attribute_denies[rust-None-quoted]", + "tests/semantic_conformance/test_feature_parity.py::test_missing_policy_attribute_denies[rust-None-unquoted]", + "tests/semantic_conformance/test_feature_parity.py::test_missing_policy_attribute_denies[rust-attributes1-quoted]", + "tests/semantic_conformance/test_feature_parity.py::test_missing_policy_attribute_denies[rust-attributes1-unquoted]", + "tests/semantic_conformance/test_feature_parity.py::test_empty_context_is_provided_but_missing_context_denies[python]", + "tests/semantic_conformance/test_feature_parity.py::test_empty_context_is_provided_but_missing_context_denies[rust]", + "tests/semantic_conformance/test_feature_parity.py::test_access_denial_precedes_sql[python-denied-attributes0]", + "tests/semantic_conformance/test_feature_parity.py::test_access_denial_precedes_sql[python-admin_only-attributes1]", + "tests/semantic_conformance/test_feature_parity.py::test_access_denial_precedes_sql[rust-denied-attributes0]", + "tests/semantic_conformance/test_feature_parity.py::test_access_denial_precedes_sql[rust-admin_only-attributes1]", + "tests/semantic_conformance/test_feature_parity.py::test_access_expression_allows_authorized_user[python]", + "tests/semantic_conformance/test_feature_parity.py::test_access_expression_allows_authorized_user[rust]", + "tests/semantic_conformance/test_feature_parity.py::test_joined_policy_scopes_purchases_to_authorized_accounts[python]", + "tests/semantic_conformance/test_feature_parity.py::test_joined_policy_scopes_purchases_to_authorized_accounts[rust]", + "tests/semantic_conformance/test_feature_parity.py::test_explicit_left_join_preserves_purchases_with_filtered_account_details[python]", + "tests/semantic_conformance/test_feature_parity.py::test_explicit_left_join_preserves_purchases_with_filtered_account_details[rust]", + "tests/semantic_conformance/test_feature_parity.py::test_two_roles_preserve_unmatched_rows_and_exclude_inactive_join[python]", + "tests/semantic_conformance/test_feature_parity.py::test_two_roles_preserve_unmatched_rows_and_exclude_inactive_join[rust]", + "tests/semantic_conformance/test_feature_parity.py::test_inactive_relationship_cannot_be_requested[python]", + "tests/semantic_conformance/test_feature_parity.py::test_inactive_relationship_cannot_be_requested[rust]", + "tests/semantic_conformance/test_feature_parity.py::test_sparse_comparison_uses_calendar_month_and_category[python]", + "tests/semantic_conformance/test_feature_parity.py::test_sparse_comparison_uses_calendar_month_and_category[rust]", + "tests/semantic_conformance/test_feature_parity.py::test_named_calendar_comparison_without_declared_granularity[python]", + "tests/semantic_conformance/test_feature_parity.py::test_named_calendar_comparison_without_declared_granularity[rust]", + "tests/semantic_conformance/test_feature_parity.py::test_rolling_sum_partitions_categories[python]", + "tests/semantic_conformance/test_feature_parity.py::test_rolling_sum_partitions_categories[rust]", + "tests/semantic_conformance/test_feature_parity.py::test_policy_survives_temporal_child_queries[python]", + "tests/semantic_conformance/test_feature_parity.py::test_policy_survives_temporal_child_queries[rust]" + ] + }, + "scope-184": { + "path": "tests/semantic_conformance/test_filtered_count_family.py", + "declared_tests": [ + "test_count_family_cross_source_counts_restore_absent_zero", + "test_count_family_empty_populations_are_zero", + "test_count_family_grouped_zero_and_null_group", + "test_count_family_independent_predicates_use_physical_values", + "test_count_family_keyed_fanout_and_orphan_group", + "test_count_family_mandatory_policies_apply_to_constant_null", + "test_count_family_null_values_and_public_aliases", + "test_count_family_order_filter_limit_and_public_alias", + "test_owned_count_as_cumulative_base_preserves_public_output", + "test_owned_count_generator_sees_live_graph_changes", + "test_owned_count_private_leaf_names_do_not_shadow_public_fields" + ], + "collected_tests": [ + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_null_values_and_public_aliases[model-python]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_null_values_and_public_aliases[model-rust]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_null_values_and_public_aliases[graph-python]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_null_values_and_public_aliases[graph-rust]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_grouped_zero_and_null_group[model-python]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_grouped_zero_and_null_group[model-rust]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_grouped_zero_and_null_group[graph-python]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_grouped_zero_and_null_group[graph-rust]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_empty_populations_are_zero[model-python-no_matches]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_empty_populations_are_zero[model-python-empty_source]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_empty_populations_are_zero[model-python-query_excluded]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_empty_populations_are_zero[model-rust-no_matches]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_empty_populations_are_zero[model-rust-empty_source]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_empty_populations_are_zero[model-rust-query_excluded]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_empty_populations_are_zero[graph-python-no_matches]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_empty_populations_are_zero[graph-python-empty_source]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_empty_populations_are_zero[graph-python-query_excluded]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_empty_populations_are_zero[graph-rust-no_matches]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_empty_populations_are_zero[graph-rust-empty_source]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_empty_populations_are_zero[graph-rust-query_excluded]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_independent_predicates_use_physical_values[model-python]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_independent_predicates_use_physical_values[model-rust]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_independent_predicates_use_physical_values[graph-python]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_independent_predicates_use_physical_values[graph-rust]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_mandatory_policies_apply_to_constant_null[model-python]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_mandatory_policies_apply_to_constant_null[model-rust]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_mandatory_policies_apply_to_constant_null[graph-python]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_mandatory_policies_apply_to_constant_null[graph-rust]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_keyed_fanout_and_orphan_group[model-python-False]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_keyed_fanout_and_orphan_group[model-python-True]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_keyed_fanout_and_orphan_group[model-rust-False]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_keyed_fanout_and_orphan_group[model-rust-True]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_keyed_fanout_and_orphan_group[graph-python-False]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_keyed_fanout_and_orphan_group[graph-python-True]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_keyed_fanout_and_orphan_group[graph-rust-False]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_keyed_fanout_and_orphan_group[graph-rust-True]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_cross_source_counts_restore_absent_zero[model-python-False]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_cross_source_counts_restore_absent_zero[model-python-True]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_cross_source_counts_restore_absent_zero[model-rust-False]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_cross_source_counts_restore_absent_zero[model-rust-True]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_cross_source_counts_restore_absent_zero[graph-python-False]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_cross_source_counts_restore_absent_zero[graph-python-True]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_cross_source_counts_restore_absent_zero[graph-rust-False]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_cross_source_counts_restore_absent_zero[graph-rust-True]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_order_filter_limit_and_public_alias[model-python]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_order_filter_limit_and_public_alias[model-rust]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_order_filter_limit_and_public_alias[graph-python]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_order_filter_limit_and_public_alias[graph-rust]", + "tests/semantic_conformance/test_filtered_count_family.py::test_owned_count_private_leaf_names_do_not_shadow_public_fields[python-graph]", + "tests/semantic_conformance/test_filtered_count_family.py::test_owned_count_private_leaf_names_do_not_shadow_public_fields[rust-graph]", + "tests/semantic_conformance/test_filtered_count_family.py::test_owned_count_generator_sees_live_graph_changes[python-graph]", + "tests/semantic_conformance/test_filtered_count_family.py::test_owned_count_as_cumulative_base_preserves_public_output[python-star-expected0-graph]", + "tests/semantic_conformance/test_filtered_count_family.py::test_owned_count_as_cumulative_base_preserves_public_output[python-one-expected1-graph]", + "tests/semantic_conformance/test_filtered_count_family.py::test_owned_count_as_cumulative_base_preserves_public_output[python-nulls-expected2-graph]", + "tests/semantic_conformance/test_filtered_count_family.py::test_owned_count_as_cumulative_base_preserves_public_output[rust-star-expected0-graph]", + "tests/semantic_conformance/test_filtered_count_family.py::test_owned_count_as_cumulative_base_preserves_public_output[rust-one-expected1-graph]", + "tests/semantic_conformance/test_filtered_count_family.py::test_owned_count_as_cumulative_base_preserves_public_output[rust-nulls-expected2-graph]" + ] + }, + "scope-185": { + "path": "tests/semantic_conformance/test_filtered_count_family.py", + "declared_tests": [ + "test_owned_count_generator_sees_live_graph_changes" + ], + "collected_tests": [ + "tests/semantic_conformance/test_filtered_count_family.py::test_owned_count_generator_sees_live_graph_changes[python-graph]" + ] + }, + "scope-186": { + "path": "tests/semantic_conformance/test_filtered_count_family.py", + "declared_tests": [ + "test_count_family_does_not_admit_other_filter_scopes" + ], + "collected_tests": [ + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_does_not_admit_other_filter_scopes[other.status = 1-COUNT(*)]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_does_not_admit_other_filter_scopes[other.status = 1-COUNT(1)]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_does_not_admit_other_filter_scopes[other.status = 1-COUNT(NULL)]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_does_not_admit_other_filter_scopes[count(*) > 0-COUNT(*)]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_does_not_admit_other_filter_scopes[count(*) > 0-COUNT(1)]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_does_not_admit_other_filter_scopes[count(*) > 0-COUNT(NULL)]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_does_not_admit_other_filter_scopes[(select count(*) from orders) > 0-COUNT(*)]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_does_not_admit_other_filter_scopes[(select count(*) from orders) > 0-COUNT(1)]", + "tests/semantic_conformance/test_filtered_count_family.py::test_count_family_does_not_admit_other_filter_scopes[(select count(*) from orders) > 0-COUNT(NULL)]" + ] + }, + "scope-187": { + "path": "tests/semantic_conformance/test_filtered_row_expressions.py", + "declared_tests": [ + "test_distinct_case_strings_keep_physical_literal_values", + "test_empty_filtered_row_expression_populations", + "test_excluded_groups_do_not_get_case_or_coalesce_fallback_values", + "test_filter_column_formatting_preserves_expression_precedence", + "test_filtered_expression_cross_source_leaf_keeps_count_zero", + "test_filtered_expressions_survive_unequal_keyed_fanout", + "test_filtered_input_is_evaluated_before_metric_filter", + "test_independent_whole_expression_filters_and_having", + "test_predicates_modulo_and_negation_in_case", + "test_simple_case_and_qualified_columns_preserve_literals" + ], + "collected_tests": [ + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-sum-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-sum-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-sum-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-avg-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-avg-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-avg-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-count-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-count-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-count-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-count_distinct-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-count_distinct-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-count_distinct-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-min-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-min-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-min-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-max-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-max-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-python-max-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-sum-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-sum-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-sum-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-avg-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-avg-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-avg-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-count-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-count-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-count-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-count_distinct-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-count_distinct-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-count_distinct-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-min-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-min-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-min-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-max-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-max-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[model-rust-max-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-sum-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-sum-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-sum-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-avg-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-avg-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-avg-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-count-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-count-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-count-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-count_distinct-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-count_distinct-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-count_distinct-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-min-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-min-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-min-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-max-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-max-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-python-max-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-sum-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-sum-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-sum-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-avg-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-avg-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-avg-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-count-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-count-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-count-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-count_distinct-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-count_distinct-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-count_distinct-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-min-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-min-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-min-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-max-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-max-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_input_is_evaluated_before_metric_filter[graph-rust-max-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expressions_survive_unequal_keyed_fanout[model-python-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expressions_survive_unequal_keyed_fanout[model-python-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expressions_survive_unequal_keyed_fanout[model-python-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expressions_survive_unequal_keyed_fanout[model-rust-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expressions_survive_unequal_keyed_fanout[model-rust-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expressions_survive_unequal_keyed_fanout[model-rust-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expressions_survive_unequal_keyed_fanout[graph-python-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expressions_survive_unequal_keyed_fanout[graph-python-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expressions_survive_unequal_keyed_fanout[graph-python-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expressions_survive_unequal_keyed_fanout[graph-rust-price * qty - COALESCE(rebate, 0)-expected0]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expressions_survive_unequal_keyed_fanout[graph-rust-COALESCE(price * qty, 7)-expected1]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expressions_survive_unequal_keyed_fanout[graph-rust-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_excluded_groups_do_not_get_case_or_coalesce_fallback_values[model-python]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_excluded_groups_do_not_get_case_or_coalesce_fallback_values[model-rust]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_excluded_groups_do_not_get_case_or_coalesce_fallback_values[graph-python]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_excluded_groups_do_not_get_case_or_coalesce_fallback_values[graph-rust]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_simple_case_and_qualified_columns_preserve_literals[model-python]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_simple_case_and_qualified_columns_preserve_literals[model-rust]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_simple_case_and_qualified_columns_preserve_literals[graph-python]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_simple_case_and_qualified_columns_preserve_literals[graph-rust]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_empty_filtered_row_expression_populations[model-python-empty]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_empty_filtered_row_expression_populations[model-python-no_matches]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_empty_filtered_row_expression_populations[model-rust-empty]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_empty_filtered_row_expression_populations[model-rust-no_matches]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_empty_filtered_row_expression_populations[graph-python-empty]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_empty_filtered_row_expression_populations[graph-python-no_matches]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_empty_filtered_row_expression_populations[graph-rust-empty]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_empty_filtered_row_expression_populations[graph-rust-no_matches]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_independent_whole_expression_filters_and_having[model-python]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_independent_whole_expression_filters_and_having[model-rust]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_independent_whole_expression_filters_and_having[graph-python]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_independent_whole_expression_filters_and_having[graph-rust]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_predicates_modulo_and_negation_in_case[model-python]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_predicates_modulo_and_negation_in_case[model-rust]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_predicates_modulo_and_negation_in_case[graph-python]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_predicates_modulo_and_negation_in_case[graph-rust]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_distinct_case_strings_keep_physical_literal_values[model-python]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_distinct_case_strings_keep_physical_literal_values[model-rust]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_distinct_case_strings_keep_physical_literal_values[graph-python]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_distinct_case_strings_keep_physical_literal_values[graph-rust]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expression_cross_source_leaf_keeps_count_zero[model-python]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expression_cross_source_leaf_keeps_count_zero[model-rust]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expression_cross_source_leaf_keeps_count_zero[graph-python]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filtered_expression_cross_source_leaf_keeps_count_zero[graph-rust]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filter_column_formatting_preserves_expression_precedence[python-plain-price-3]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filter_column_formatting_preserves_expression_precedence[python-adjusted-price + 1-5]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filter_column_formatting_preserves_expression_precedence[rust-plain-price-3]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_filter_column_formatting_preserves_expression_precedence[rust-adjusted-price + 1-5]" + ] + }, + "scope-188": { + "path": "tests/semantic_conformance/test_filtered_row_expressions.py", + "declared_tests": [ + "test_postgres_filtered_row_expression_oracles" + ], + "collected_tests": [ + "tests/semantic_conformance/test_filtered_row_expressions.py::test_postgres_filtered_row_expression_oracles[False-price * qty - COALESCE(rebate, 0)-expected0-model]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_postgres_filtered_row_expression_oracles[False-price * qty - COALESCE(rebate, 0)-expected0-graph]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_postgres_filtered_row_expression_oracles[False-COALESCE(price * qty, 7)-expected1-model]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_postgres_filtered_row_expression_oracles[False-COALESCE(price * qty, 7)-expected1-graph]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_postgres_filtered_row_expression_oracles[False-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2-model]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_postgres_filtered_row_expression_oracles[False-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2-graph]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_postgres_filtered_row_expression_oracles[True-price * qty - COALESCE(rebate, 0)-expected0-model]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_postgres_filtered_row_expression_oracles[True-price * qty - COALESCE(rebate, 0)-expected0-graph]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_postgres_filtered_row_expression_oracles[True-COALESCE(price * qty, 7)-expected1-model]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_postgres_filtered_row_expression_oracles[True-COALESCE(price * qty, 7)-expected1-graph]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_postgres_filtered_row_expression_oracles[True-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2-model]", + "tests/semantic_conformance/test_filtered_row_expressions.py::test_postgres_filtered_row_expression_oracles[True-CASE WHEN qty > 0 THEN price * qty ELSE 9 END-expected2-graph]" + ] + }, + "scope-189": { + "path": "tests/semantic_conformance/test_generated_differential.py", + "declared_tests": [ + "test_replay_differential_fixture", + "test_seeded_differential_campaign" + ], + "collected_tests": [ + "tests/semantic_conformance/test_generated_differential.py::test_seeded_differential_campaign", + "tests/semantic_conformance/test_generated_differential.py::test_replay_differential_fixture[absent-local-calculation.case.json]", + "tests/semantic_conformance/test_generated_differential.py::test_replay_differential_fixture[cross-source-cumulative.case.json]", + "tests/semantic_conformance/test_generated_differential.py::test_replay_differential_fixture[cumulative-dimension-collision.case.json]", + "tests/semantic_conformance/test_generated_differential.py::test_replay_differential_fixture[cumulative-null-date.case.json]", + "tests/semantic_conformance/test_generated_differential.py::test_replay_differential_fixture[scalar-default-time.case.json]", + "tests/semantic_conformance/test_generated_differential.py::test_replay_differential_fixture[sibling-fanout.case.json]" + ] + }, + "scope-190": { + "path": "tests/semantic_conformance/test_graph_population_ownership.py", + "declared_tests": [ + "test_dotted_graph_multistep_conversion_preserves_identity_and_policy", + "test_dotted_graph_population_identity_preserves_source_policy", + "test_dotted_graph_population_order_does_not_add_prefix_model_to_policy_population", + "test_graph_cohort_approximate_count_requires_unambiguous_entity_source", + "test_graph_population_metric_infers_unique_entity_and_preserves_policy", + "test_graph_population_metric_rejects_ambiguous_entity_sources", + "test_inferred_graph_cohort_approximate_count_uses_authorized_entities", + "test_local_dependency_precedes_global_name_during_policy_discovery" + ], + "collected_tests": [ + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_infers_unique_entity_and_preserves_policy[python-inferred-cohort]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_infers_unique_entity_and_preserves_policy[python-inferred-conversion]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_infers_unique_entity_and_preserves_policy[python-inferred-retention]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_infers_unique_entity_and_preserves_policy[python-explicit-cohort]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_infers_unique_entity_and_preserves_policy[python-explicit-conversion]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_infers_unique_entity_and_preserves_policy[python-explicit-retention]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_infers_unique_entity_and_preserves_policy[rust-inferred-cohort]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_infers_unique_entity_and_preserves_policy[rust-inferred-conversion]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_infers_unique_entity_and_preserves_policy[rust-inferred-retention]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_infers_unique_entity_and_preserves_policy[rust-explicit-cohort]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_infers_unique_entity_and_preserves_policy[rust-explicit-conversion]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_infers_unique_entity_and_preserves_policy[rust-explicit-retention]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_rejects_ambiguous_entity_sources[python-cohort]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_rejects_ambiguous_entity_sources[python-conversion]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_rejects_ambiguous_entity_sources[python-retention]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_rejects_ambiguous_entity_sources[rust-cohort]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_rejects_ambiguous_entity_sources[rust-conversion]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_population_metric_rejects_ambiguous_entity_sources[rust-retention]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_identity_preserves_source_policy[python-analytics-cohort]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_identity_preserves_source_policy[python-analytics-conversion]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_identity_preserves_source_policy[python-analytics-retention]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_identity_preserves_source_policy[python-events-cohort]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_identity_preserves_source_policy[python-events-conversion]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_identity_preserves_source_policy[python-events-retention]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_identity_preserves_source_policy[rust-analytics-cohort]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_identity_preserves_source_policy[rust-analytics-conversion]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_identity_preserves_source_policy[rust-analytics-retention]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_identity_preserves_source_policy[rust-events-cohort]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_identity_preserves_source_policy[rust-events-conversion]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_identity_preserves_source_policy[rust-events-retention]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_local_dependency_precedes_global_name_during_policy_discovery[python]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_local_dependency_precedes_global_name_during_policy_discovery[rust]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_order_does_not_add_prefix_model_to_policy_population[python-cohort]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_order_does_not_add_prefix_model_to_policy_population[python-conversion]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_order_does_not_add_prefix_model_to_policy_population[rust-cohort]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_population_order_does_not_add_prefix_model_to_policy_population[rust-conversion]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_multistep_conversion_preserves_identity_and_policy[python]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_dotted_graph_multistep_conversion_preserves_identity_and_policy[rust]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_inferred_graph_cohort_approximate_count_uses_authorized_entities[python]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_inferred_graph_cohort_approximate_count_uses_authorized_entities[rust]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_cohort_approximate_count_requires_unambiguous_entity_source[python-missing]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_cohort_approximate_count_requires_unambiguous_entity_source[python-ambiguous]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_cohort_approximate_count_requires_unambiguous_entity_source[rust-missing]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_graph_cohort_approximate_count_requires_unambiguous_entity_source[rust-ambiguous]" + ] + }, + "scope-191": { + "path": "tests/semantic_conformance/test_graph_population_ownership.py", + "declared_tests": [ + "test_native_dotted_graph_population_visibility" + ], + "collected_tests": [ + "tests/semantic_conformance/test_graph_population_ownership.py::test_native_dotted_graph_population_visibility[select-analytics-compile]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_native_dotted_graph_population_visibility[select-analytics-rewrite]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_native_dotted_graph_population_visibility[select-events-compile]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_native_dotted_graph_population_visibility[select-events-rewrite]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_native_dotted_graph_population_visibility[filter-analytics-compile]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_native_dotted_graph_population_visibility[filter-analytics-rewrite]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_native_dotted_graph_population_visibility[filter-events-compile]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_native_dotted_graph_population_visibility[filter-events-rewrite]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_native_dotted_graph_population_visibility[order-analytics-compile]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_native_dotted_graph_population_visibility[order-analytics-rewrite]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_native_dotted_graph_population_visibility[order-events-compile]", + "tests/semantic_conformance/test_graph_population_ownership.py::test_native_dotted_graph_population_visibility[order-events-rewrite]" + ] + }, + "scope-192": { + "path": "tests/semantic_conformance/test_many_role_results.py", + "declared_tests": [ + "test_access_denial_on_every_population", + "test_alternate_roles_do_not_share_junction_keys", + "test_bridge_join_retains_bridge_keys_when_custom_sql_is_present", + "test_bridge_policies_bind_each_role", + "test_composite_junction_keys_do_not_cross_tenants", + "test_duplicate_role_identity_is_rejected", + "test_inactive_role_is_excluded", + "test_incomplete_junction_contract_is_rejected", + "test_role_fanout_deduplicates_at_order_key", + "test_role_filter_preserves_source_grain", + "test_target_measures_retain_target_key_grain" + ], + "collected_tests": [ + "tests/semantic_conformance/test_many_role_results.py::test_role_fanout_deduplicates_at_order_key", + "tests/semantic_conformance/test_many_role_results.py::test_bridge_policies_bind_each_role[primary_tags-expected0]", + "tests/semantic_conformance/test_many_role_results.py::test_bridge_policies_bind_each_role[secondary_tags-expected1]", + "tests/semantic_conformance/test_many_role_results.py::test_alternate_roles_do_not_share_junction_keys", + "tests/semantic_conformance/test_many_role_results.py::test_role_filter_preserves_source_grain", + "tests/semantic_conformance/test_many_role_results.py::test_access_denial_on_every_population[0]", + "tests/semantic_conformance/test_many_role_results.py::test_access_denial_on_every_population[1]", + "tests/semantic_conformance/test_many_role_results.py::test_access_denial_on_every_population[2]", + "tests/semantic_conformance/test_many_role_results.py::test_inactive_role_is_excluded", + "tests/semantic_conformance/test_many_role_results.py::test_duplicate_role_identity_is_rejected", + "tests/semantic_conformance/test_many_role_results.py::test_incomplete_junction_contract_is_rejected[missing_bridge-unknown bridge]", + "tests/semantic_conformance/test_many_role_results.py::test_incomplete_junction_contract_is_rejected[missing_key-explicit through_foreign_key]", + "tests/semantic_conformance/test_many_role_results.py::test_incomplete_junction_contract_is_rejected[arity-junction key arity]", + "tests/semantic_conformance/test_many_role_results.py::test_incomplete_junction_contract_is_rejected[no_through-without_through]", + "tests/semantic_conformance/test_many_role_results.py::test_bridge_join_retains_bridge_keys_when_custom_sql_is_present", + "tests/semantic_conformance/test_many_role_results.py::test_target_measures_retain_target_key_grain", + "tests/semantic_conformance/test_many_role_results.py::test_composite_junction_keys_do_not_cross_tenants" + ] + }, + "scope-193": { + "path": "tests/semantic_conformance/test_multistep_conversion_parity.py", + "declared_tests": [ + "test_dimension_and_metric_ordering_with_limit", + "test_empty_population_has_zero_counts", + "test_entrants_chronology_repeated_actions_ties_and_nulls", + "test_fixed_output_alias_collisions_are_explicit", + "test_funnel_order_preserves_explicit_null_placement", + "test_invariant_excludes_later_step_before_chronology", + "test_later_steps_keep_first_step_dimension_attribution", + "test_mapped_entity_time_and_qualified_physical_steps", + "test_mapped_time_cannot_change_source_scope", + "test_metric_filter_scopes_every_step_and_parenthesizes_or", + "test_output_aliases_can_share_names_with_scoped_internal_columns", + "test_policy_context_is_required", + "test_policy_scopes_every_step_independently", + "test_query_filter_scopes_every_step", + "test_repeated_entrant_has_independent_chronology_in_each_first_step_group", + "test_step_cannot_change_source_scope", + "test_step_literal_is_not_rewritten_as_model_reference", + "test_time_bucket_belongs_to_first_step", + "test_two_step_list_has_its_existing_count_outputs" + ], + "collected_tests": [ + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_entrants_chronology_repeated_actions_ties_and_nulls[python]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_entrants_chronology_repeated_actions_ties_and_nulls[rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_later_steps_keep_first_step_dimension_attribution[python]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_later_steps_keep_first_step_dimension_attribution[rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_repeated_entrant_has_independent_chronology_in_each_first_step_group[python]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_repeated_entrant_has_independent_chronology_in_each_first_step_group[rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_query_filter_scopes_every_step[python]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_query_filter_scopes_every_step[rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_metric_filter_scopes_every_step_and_parenthesizes_or[python]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_metric_filter_scopes_every_step_and_parenthesizes_or[rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_policy_scopes_every_step_independently[python]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_policy_scopes_every_step_independently[rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_policy_context_is_required[python]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_policy_context_is_required[rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_invariant_excludes_later_step_before_chronology[python]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_invariant_excludes_later_step_before_chronology[rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_two_step_list_has_its_existing_count_outputs[python]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_two_step_list_has_its_existing_count_outputs[rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_empty_population_has_zero_counts[python]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_empty_population_has_zero_counts[rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_dimension_and_metric_ordering_with_limit[python]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_dimension_and_metric_ordering_with_limit[rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_mapped_entity_time_and_qualified_physical_steps[python]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_mapped_entity_time_and_qualified_physical_steps[rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_step_literal_is_not_rewritten_as_model_reference[python]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_step_literal_is_not_rewritten_as_model_reference[rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_time_bucket_belongs_to_first_step[python]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_time_bucket_belongs_to_first_step[rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_funnel_order_preserves_explicit_null_placement[python-FIRST]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_funnel_order_preserves_explicit_null_placement[python-LAST]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_funnel_order_preserves_explicit_null_placement[rust-FIRST]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_funnel_order_preserves_explicit_null_placement[rust-LAST]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_step_cannot_change_source_scope[count(*) > 0-rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_step_cannot_change_source_scope[sum(tenant) over () > 0-rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_step_cannot_change_source_scope[(select count(*) from funnel_events) > 0-rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_step_cannot_change_source_scope[other.kind = 'signup'-rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_fixed_output_alias_collisions_are_explicit[TOTAL_ENTITIES-rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_fixed_output_alias_collisions_are_explicit[STEP_2_COUNT-rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_fixed_output_alias_collisions_are_explicit[FUNNEL-rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_output_aliases_can_share_names_with_scoped_internal_columns[ENTITY-rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_output_aliases_can_share_names_with_scoped_internal_columns[STEP_1_TS-rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_output_aliases_can_share_names_with_scoped_internal_columns[step_2_ts-rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_output_aliases_can_share_names_with_scoped_internal_columns[STEP_3_TS-rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_mapped_time_cannot_change_source_scope[sum(tenant) over ()-rust]", + "tests/semantic_conformance/test_multistep_conversion_parity.py::test_mapped_time_cannot_change_source_scope[(select max(occurred) from funnel_events)-rust]" + ] + }, + "scope-194": { + "path": "tests/semantic_conformance/test_nested_policy_sql.py", + "declared_tests": [ + "test_chained_ctes_and_column_aliases_preserve_outer_aggregation", + "test_cte_binding_takes_precedence_over_semantic_names", + "test_cte_named_like_physical_source_cannot_capture_compiler_read", + "test_each_caller_gets_only_its_authorized_nested_population", + "test_every_semantic_leaf_checks_model_access_including_unused_ctes", + "test_hidden_fields_remain_denied_in_nested_leaves", + "test_internal_cte_names_do_not_collide_with_trusted_sql_sources", + "test_native_context_boundary_rejects_unsecured_or_unqualified_shapes", + "test_native_nested_shapes_compile_every_policy_leaf", + "test_nested_cte_shadowing_is_scoped", + "test_outer_filter_projection_order_and_pagination_follow_policies", + "test_user_cte_cannot_capture_private_policy_entitlement_source" + ], + "collected_tests": [ + "tests/semantic_conformance/test_nested_policy_sql.py::test_outer_filter_projection_order_and_pagination_follow_policies", + "tests/semantic_conformance/test_nested_policy_sql.py::test_each_caller_gets_only_its_authorized_nested_population[1-expected0]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_each_caller_gets_only_its_authorized_nested_population[2-expected1]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_each_caller_gets_only_its_authorized_nested_population[3-expected2]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_chained_ctes_and_column_aliases_preserve_outer_aggregation", + "tests/semantic_conformance/test_nested_policy_sql.py::test_nested_cte_shadowing_is_scoped[visible-expected0]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_nested_cte_shadowing_is_scoped[nested-expected1]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_cte_binding_takes_precedence_over_semantic_names[metrics]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_cte_binding_takes_precedence_over_semantic_names[\"MeTrIcS\"]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_cte_binding_takes_precedence_over_semantic_names[purchases]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_cte_binding_takes_precedence_over_semantic_names[accounts_cte]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_cte_binding_takes_precedence_over_semantic_names[\"Visible Values\"]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_cte_named_like_physical_source_cannot_capture_compiler_read", + "tests/semantic_conformance/test_nested_policy_sql.py::test_internal_cte_names_do_not_collide_with_trusted_sql_sources", + "tests/semantic_conformance/test_nested_policy_sql.py::test_user_cte_cannot_capture_private_policy_entitlement_source[security]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_user_cte_cannot_capture_private_policy_entitlement_source[invariant]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_hidden_fields_remain_denied_in_nested_leaves[select purchases.secret_cost from metrics]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_hidden_fields_remain_denied_in_nested_leaves[select round(purchases.secret_cost, 2) from metrics]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_hidden_fields_remain_denied_in_nested_leaves[select sum(purchases.cost) from purchases]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_hidden_fields_remain_denied_in_nested_leaves[select purchases.revenue from metrics where purchases.cost > 0]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_hidden_fields_remain_denied_in_nested_leaves[select purchases.revenue from metrics order by purchases.secret_cost]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_hidden_fields_remain_denied_in_nested_leaves[select purchases.revenue as total from metrics order by purchases.cost]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_every_semantic_leaf_checks_model_access_including_unused_ctes[False]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_every_semantic_leaf_checks_model_access_including_unused_ctes[True]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select * from aggregate_purchases]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select purchases.revenue from main.metrics]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select * from (select * from aggregate_purchases) q]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[with visible as (select * from aggregate_purchases) select * from visible]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select purchases.revenue, (select max(amount) from aggregate_purchases) from metrics]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select * from (select purchases.revenue from metrics) q where exists (select 1 from aggregate_purchases)]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select sum((select max(amount) from aggregate_purchases)) from (select purchases.revenue from metrics) q]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select coalesce((select max(amount) from aggregate_purchases), 0) from (select purchases.revenue from metrics) q]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select case when q.revenue > 0 then (select max(amount) from aggregate_purchases) else 0 end from (select purchases.revenue from metrics) q]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select * from (select purchases.revenue from metrics) q where coalesce((select max(amount) from aggregate_purchases), 0) > 0]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select * from (select purchases.revenue from metrics) q where case when q.revenue > 0 then (select max(amount) from aggregate_purchases) else 0 end > 0]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select sum(q.revenue) from (select purchases.revenue from metrics) q having sum((select max(amount) from aggregate_purchases)) > 0]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select * from (select purchases.revenue from metrics) q order by coalesce((select max(amount) from aggregate_purchases), q.revenue)]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select * from read_parquet('private.parquet')]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[delete from aggregate_purchases]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[create table leaked as select purchases.revenue from metrics]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select purchases.revenue into leaked from metrics]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_context_boundary_rejects_unsecured_or_unqualified_shapes[select purchases.revenue from metrics; select purchases.revenue from metrics]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_nested_shapes_compile_every_policy_leaf[select purchases.revenue from purchases-expected0]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_nested_shapes_compile_every_policy_leaf[select round(purchases.revenue / 3, 2) from purchases-expected1]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_nested_shapes_compile_every_policy_leaf[with recursive q as (select purchases.revenue from metrics) select * from q-expected2]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_nested_shapes_compile_every_policy_leaf[select purchases.revenue from metrics union all select purchases.revenue from metrics-expected3]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_nested_shapes_compile_every_policy_leaf[select * from (select purchases.revenue from metrics) a join (select accounts.quota from metrics) b on true-expected4]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_nested_shapes_compile_every_policy_leaf[select purchases.revenue + (select accounts.quota from metrics) as adjusted from metrics-expected5]", + "tests/semantic_conformance/test_nested_policy_sql.py::test_native_nested_shapes_compile_every_policy_leaf[select coalesce((select accounts.quota from metrics), 0) as quota from (select purchases.revenue from metrics) q-expected6]" + ] + }, + "scope-195": { + "path": "tests/semantic_conformance/test_null_fill.py", + "declared_tests": [ + "test_filled_leaf_participates_in_cross_source_calculation", + "test_metric_result_and_dependency_defaults", + "test_policy_excluded_groups_are_not_created_by_fill" + ], + "collected_tests": [ + "tests/semantic_conformance/test_null_fill.py::test_metric_result_and_dependency_defaults[python-metrics0-filters0-expected0]", + "tests/semantic_conformance/test_null_fill.py::test_metric_result_and_dependency_defaults[python-metrics1-filters1-expected1]", + "tests/semantic_conformance/test_null_fill.py::test_metric_result_and_dependency_defaults[python-metrics2-filters2-expected2]", + "tests/semantic_conformance/test_null_fill.py::test_metric_result_and_dependency_defaults[python-metrics3-filters3-expected3]", + "tests/semantic_conformance/test_null_fill.py::test_metric_result_and_dependency_defaults[python-metrics4-filters4-expected4]", + "tests/semantic_conformance/test_null_fill.py::test_metric_result_and_dependency_defaults[python-metrics5-filters5-expected5]", + "tests/semantic_conformance/test_null_fill.py::test_metric_result_and_dependency_defaults[rust-metrics0-filters0-expected0]", + "tests/semantic_conformance/test_null_fill.py::test_metric_result_and_dependency_defaults[rust-metrics1-filters1-expected1]", + "tests/semantic_conformance/test_null_fill.py::test_metric_result_and_dependency_defaults[rust-metrics2-filters2-expected2]", + "tests/semantic_conformance/test_null_fill.py::test_metric_result_and_dependency_defaults[rust-metrics3-filters3-expected3]", + "tests/semantic_conformance/test_null_fill.py::test_metric_result_and_dependency_defaults[rust-metrics4-filters4-expected4]", + "tests/semantic_conformance/test_null_fill.py::test_metric_result_and_dependency_defaults[rust-metrics5-filters5-expected5]", + "tests/semantic_conformance/test_null_fill.py::test_filled_leaf_participates_in_cross_source_calculation[python-filled-expected0]", + "tests/semantic_conformance/test_null_fill.py::test_filled_leaf_participates_in_cross_source_calculation[python-fractional-expected1]", + "tests/semantic_conformance/test_null_fill.py::test_filled_leaf_participates_in_cross_source_calculation[python-raw-expected2]", + "tests/semantic_conformance/test_null_fill.py::test_filled_leaf_participates_in_cross_source_calculation[rust-filled-expected0]", + "tests/semantic_conformance/test_null_fill.py::test_filled_leaf_participates_in_cross_source_calculation[rust-fractional-expected1]", + "tests/semantic_conformance/test_null_fill.py::test_filled_leaf_participates_in_cross_source_calculation[rust-raw-expected2]", + "tests/semantic_conformance/test_null_fill.py::test_policy_excluded_groups_are_not_created_by_fill[python]", + "tests/semantic_conformance/test_null_fill.py::test_policy_excluded_groups_are_not_created_by_fill[rust]" + ] + }, + "scope-196": { + "path": "tests/semantic_conformance/test_ossie_aggregate_inputs.py", + "declared_tests": [ + "test_column_free_aggregate_uses_sole_dataset_population", + "test_computed_input_cannot_be_shadowed_by_physical_column", + "test_imported_window_field_is_materialized_before_grouping_and_filtering", + "test_joined_aggregate_preserves_compound_computed_relationship_keys", + "test_joined_row_aggregate_and_independent_aggregates_keep_separate_grains", + "test_joined_row_aggregate_does_not_require_unused_entity_keys", + "test_joined_row_aggregate_groups_and_rewrites", + "test_joined_rows_preserve_unmatched_facts_and_equal_value_entities", + "test_joined_tuple_grain_survives_an_additional_fanout", + "test_native_complete_sql_keeps_physical_input_semantics" + ], + "collected_tests": [ + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_computed_input_cannot_be_shadowed_by_physical_column[query-amount-amount]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_computed_input_cannot_be_shadowed_by_physical_column[query-Amount-amount]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_computed_input_cannot_be_shadowed_by_physical_column[query-gross-gross]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_computed_input_cannot_be_shadowed_by_physical_column[rewrite-amount-amount]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_computed_input_cannot_be_shadowed_by_physical_column[rewrite-Amount-amount]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_computed_input_cannot_be_shadowed_by_physical_column[rewrite-gross-gross]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_column_free_aggregate_uses_sole_dataset_population[dimensions0]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_column_free_aggregate_uses_sole_dataset_population[dimensions1]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_imported_window_field_is_materialized_before_grouping_and_filtering", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_joined_row_aggregate_and_independent_aggregates_keep_separate_grains", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_joined_row_aggregate_groups_and_rewrites", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_joined_rows_preserve_unmatched_facts_and_equal_value_entities", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_joined_row_aggregate_does_not_require_unused_entity_keys", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_joined_tuple_grain_survives_an_additional_fanout", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_native_complete_sql_keeps_physical_input_semantics", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_joined_aggregate_preserves_compound_computed_relationship_keys" + ] + }, + "scope-197": { + "path": "tests/semantic_conformance/test_ossie_aggregate_inputs.py", + "declared_tests": [ + "test_graph_measures_preserve_input_scope" + ], + "collected_tests": [ + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[False-amount-False-ordinary]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[False-amount-False-independent]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[False-amount-False-fanout]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[False-amount-True-ordinary]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[False-amount-True-independent]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[False-amount-True-fanout]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[False-gross-False-ordinary]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[False-gross-False-independent]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[False-gross-False-fanout]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[False-gross-True-ordinary]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[False-gross-True-independent]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[False-gross-True-fanout]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[True-amount-False-ordinary]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[True-amount-False-independent]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[True-amount-False-fanout]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[True-amount-True-ordinary]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[True-amount-True-independent]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[True-amount-True-fanout]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[True-gross-False-ordinary]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[True-gross-False-independent]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[True-gross-False-fanout]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[True-gross-True-ordinary]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[True-gross-True-independent]", + "tests/semantic_conformance/test_ossie_aggregate_inputs.py::test_graph_measures_preserve_input_scope[True-gross-True-fanout]" + ] + }, + "scope-198": { + "path": "tests/semantic_conformance/test_parameterized_segments.py", + "declared_tests": [ + "test_control_values_remain_raw_while_outputs_are_typed", + "test_segment_subqueries_keep_physical_scope", + "test_simple_segment_parameters_preserve_defaults_and_values", + "test_template_value_contexts_match_python" + ], + "collected_tests": [ + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[python-None-10-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[python-None-10-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[python-parameters1-20-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[python-parameters1-20-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[python-parameters2-30-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[python-parameters2-30-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[python-parameters3-50-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[python-parameters3-50-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[rust-None-10-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[rust-None-10-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[rust-parameters1-20-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[rust-parameters1-20-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[rust-parameters2-30-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[rust-parameters2-30-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[rust-parameters3-50-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_simple_segment_parameters_preserve_defaults_and_values[rust-parameters3-50-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[python-None-140-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[python-None-140-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[python-None-140-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[python-None-140-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[python-parameters1-10-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[python-parameters1-10-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[python-parameters1-10-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[python-parameters1-10-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[python-parameters2-120-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[python-parameters2-120-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[python-parameters2-120-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[python-parameters2-120-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[rust-None-140-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[rust-None-140-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[rust-None-140-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[rust-None-140-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[rust-parameters1-10-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[rust-parameters1-10-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[rust-parameters1-10-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[rust-parameters1-10-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[rust-parameters2-120-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[rust-parameters2-120-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[rust-parameters2-120-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_control_values_remain_raw_while_outputs_are_typed[rust-parameters2-120-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = {{ label }}-parameters0-20-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = {{ label }}-parameters0-20-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = {{ label }}-parameters0-20-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = {{ label }}-parameters0-20-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = '{{ label }}'-parameters1-30-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = '{{ label }}'-parameters1-30-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = '{{ label }}'-parameters1-30-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = '{{ label }}'-parameters1-30-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = '\\xe9 prefix {{ label }} suffix'-parameters2-40-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = '\\xe9 prefix {{ label }} suffix'-parameters2-40-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = '\\xe9 prefix {{ label }} suffix'-parameters2-40-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = '\\xe9 prefix {{ label }} suffix'-parameters2-40-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{% if label == 'plain' %}orders.label = {{ label }}{% else %}FALSE{% endif %}-None-10-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{% if label == 'plain' %}orders.label = {{ label }}{% else %}FALSE{% endif %}-None-10-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{% if label == 'plain' %}orders.label = {{ label }}{% else %}FALSE{% endif %}-None-10-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{% if label == 'plain' %}orders.label = {{ label }}{% else %}FALSE{% endif %}-None-10-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}LOWER(orders.label) = {{ label|lower }}-parameters4-10-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}LOWER(orders.label) = {{ label|lower }}-parameters4-10-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}LOWER(orders.label) = {{ label|lower }}-parameters4-10-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}LOWER(orders.label) = {{ label|lower }}-parameters4-10-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = {{ label }}-parameters5-50-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = {{ label }}-parameters5-50-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = {{ label }}-parameters5-50-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}orders.label = {{ label }}-parameters5-50-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}{{ field }} >= {{ minimum }}-parameters6-90-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}{{ field }} >= {{ minimum }}-parameters6-90-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}{{ field }} >= {{ minimum }}-parameters6-90-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[python-{# values #}{{ field }} >= {{ minimum }}-parameters6-90-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = {{ label }}-parameters0-20-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = {{ label }}-parameters0-20-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = {{ label }}-parameters0-20-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = {{ label }}-parameters0-20-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = '{{ label }}'-parameters1-30-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = '{{ label }}'-parameters1-30-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = '{{ label }}'-parameters1-30-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = '{{ label }}'-parameters1-30-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = '\\xe9 prefix {{ label }} suffix'-parameters2-40-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = '\\xe9 prefix {{ label }} suffix'-parameters2-40-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = '\\xe9 prefix {{ label }} suffix'-parameters2-40-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = '\\xe9 prefix {{ label }} suffix'-parameters2-40-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{% if label == 'plain' %}orders.label = {{ label }}{% else %}FALSE{% endif %}-None-10-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{% if label == 'plain' %}orders.label = {{ label }}{% else %}FALSE{% endif %}-None-10-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{% if label == 'plain' %}orders.label = {{ label }}{% else %}FALSE{% endif %}-None-10-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{% if label == 'plain' %}orders.label = {{ label }}{% else %}FALSE{% endif %}-None-10-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}LOWER(orders.label) = {{ label|lower }}-parameters4-10-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}LOWER(orders.label) = {{ label|lower }}-parameters4-10-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}LOWER(orders.label) = {{ label|lower }}-parameters4-10-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}LOWER(orders.label) = {{ label|lower }}-parameters4-10-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = {{ label }}-parameters5-50-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = {{ label }}-parameters5-50-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = {{ label }}-parameters5-50-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}orders.label = {{ label }}-parameters5-50-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}{{ field }} >= {{ minimum }}-parameters6-90-False-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}{{ field }} >= {{ minimum }}-parameters6-90-False-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}{{ field }} >= {{ minimum }}-parameters6-90-True-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_template_value_contexts_match_python[rust-{# values #}{{ field }} >= {{ minimum }}-parameters6-90-True-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_segment_subqueries_keep_physical_scope[python-None-60-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_segment_subqueries_keep_physical_scope[python-None-60-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_segment_subqueries_keep_physical_scope[python-parameters1-10-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_segment_subqueries_keep_physical_scope[python-parameters1-10-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_segment_subqueries_keep_physical_scope[rust-None-60-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_segment_subqueries_keep_physical_scope[rust-None-60-snowflake]", + "tests/semantic_conformance/test_parameterized_segments.py::test_segment_subqueries_keep_physical_scope[rust-parameters1-10-duckdb]", + "tests/semantic_conformance/test_parameterized_segments.py::test_segment_subqueries_keep_physical_scope[rust-parameters1-10-snowflake]" + ] + }, + "scope-199": { + "path": "tests/semantic_conformance/test_policy_aggregate_parity.py", + "declared_tests": [ + "test_account_invariant_excludes_inactive_denominator_rows", + "test_derived_dependencies_require_policy_context", + "test_grouped_policy_aggregate_keeps_each_tier_population", + "test_joined_invariant_and_policy_scope_purchase_revenue", + "test_policy_and_invariants_constrain_both_metric_populations", + "test_visibility_denies_hidden_fields_in_every_query_position" + ], + "collected_tests": [ + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_policy_and_invariants_constrain_both_metric_populations[python-1-30.0-174]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_policy_and_invariants_constrain_both_metric_populations[python-2-100.0-990]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_policy_and_invariants_constrain_both_metric_populations[rust-1-30.0-174]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_policy_and_invariants_constrain_both_metric_populations[rust-2-100.0-990]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_grouped_policy_aggregate_keeps_each_tier_population[python]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_grouped_policy_aggregate_keeps_each_tier_population[rust]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_joined_invariant_and_policy_scope_purchase_revenue[python]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_joined_invariant_and_policy_scope_purchase_revenue[rust]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_account_invariant_excludes_inactive_denominator_rows[python]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_account_invariant_excludes_inactive_denominator_rows[rust]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_derived_dependencies_require_policy_context[python-None]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_derived_dependencies_require_policy_context[python-attributes1]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_derived_dependencies_require_policy_context[rust-None]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_derived_dependencies_require_policy_context[rust-attributes1]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_visibility_denies_hidden_fields_in_every_query_position[python-metric]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_visibility_denies_hidden_fields_in_every_query_position[python-dimension]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_visibility_denies_hidden_fields_in_every_query_position[python-filter]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_visibility_denies_hidden_fields_in_every_query_position[python-order]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_visibility_denies_hidden_fields_in_every_query_position[rust-metric]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_visibility_denies_hidden_fields_in_every_query_position[rust-dimension]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_visibility_denies_hidden_fields_in_every_query_position[rust-filter]", + "tests/semantic_conformance/test_policy_aggregate_parity.py::test_visibility_denies_hidden_fields_in_every_query_position[rust-order]" + ] + }, + "scope-200": { + "path": "tests/semantic_conformance/test_policy_cli.py", + "declared_tests": [ + "test_cli_authorized_context_reaches_rust", + "test_cli_policy_denial_emits_no_sql_or_results", + "test_cli_rejects_non_object_attribute_files", + "test_declared_left_join_preserves_base_rows_with_secured_details", + "test_model_from_policy_sql_selects_rust_without_fallback", + "test_policy_applies_independently_to_both_relationship_roles", + "test_scoped_filters_and_alias_pagination_keep_authorized_rows", + "test_secured_rollup_request_uses_authorized_source_rows", + "test_security_failures_never_enter_python_fallback", + "test_sql_join_policy_excludes_orphans_and_other_tenants", + "test_sql_physical_sources_cannot_bypass_policy", + "test_sql_policy_attributes_are_literals", + "test_undeclared_filter_columns_are_validation_errors_without_fallback" + ], + "collected_tests": [ + "tests/semantic_conformance/test_policy_cli.py::test_cli_authorized_context_reaches_rust[query]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_authorized_context_reaches_rust[dry-run]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_authorized_context_reaches_rust[rewrite]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_policy_denial_emits_no_sql_or_results[policy_literals-select denied.total from metrics-attributes0-rust]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_policy_denial_emits_no_sql_or_results[policy_literals-select denied.total from metrics-attributes0-auto]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_policy_denial_emits_no_sql_or_results[policy_literals-select quoted.total from metrics-None-rust]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_policy_denial_emits_no_sql_or_results[policy_literals-select quoted.total from metrics-None-auto]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_policy_denial_emits_no_sql_or_results[policy_aggregate-select purchases.secret_cost from metrics-attributes2-rust]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_policy_denial_emits_no_sql_or_results[policy_aggregate-select purchases.secret_cost from metrics-attributes2-auto]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select denied.total from metrics-attributes0-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select denied.total from metrics-attributes0-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select denied.total from metrics-attributes0-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select admin_only.total from metrics-attributes1-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select admin_only.total from metrics-attributes1-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select admin_only.total from metrics-attributes1-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select admin_only.total from metrics-attributes2-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select admin_only.total from metrics-attributes2-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select admin_only.total from metrics-attributes2-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select quoted.total from metrics-None-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select quoted.total from metrics-None-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select quoted.total from metrics-None-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select quoted.total from metrics-attributes4-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select quoted.total from metrics-attributes4-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_literals-select quoted.total from metrics-attributes4-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_aggregate-select purchases.secret_cost from metrics-attributes5-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_aggregate-select purchases.secret_cost from metrics-attributes5-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_aggregate-select purchases.secret_cost from metrics-attributes5-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_aggregate-select purchases.cost, purchases.revenue from metrics-attributes6-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_aggregate-select purchases.cost, purchases.revenue from metrics-attributes6-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_aggregate-select purchases.cost, purchases.revenue from metrics-attributes6-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_aggregate-select purchases.revenue from metrics where purchases.cost > 0-attributes7-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_aggregate-select purchases.revenue from metrics where purchases.cost > 0-attributes7-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_aggregate-select purchases.revenue from metrics where purchases.cost > 0-attributes7-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_aggregate-select purchases.revenue from metrics order by purchases.secret_cost-attributes8-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_aggregate-select purchases.revenue from metrics order by purchases.secret_cost-attributes8-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_security_failures_never_enter_python_fallback[policy_aggregate-select purchases.revenue from metrics order by purchases.secret_cost-attributes8-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[purchases.amount-where-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[purchases.amount-where-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[purchases.amount-where-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[purchases.amount-having-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[purchases.amount-having-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[purchases.amount-having-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[amount-where-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[amount-where-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[amount-where-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[amount-having-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[amount-having-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[amount-having-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[unknown_owner.amount-where-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[unknown_owner.amount-where-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[unknown_owner.amount-where-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[unknown_owner.amount-having-rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[unknown_owner.amount-having-rust-True]", + "tests/semantic_conformance/test_policy_cli.py::test_undeclared_filter_columns_are_validation_errors_without_fallback[unknown_owner.amount-having-auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_sql_policy_attributes_are_literals[O'Brien-9-quoted]", + "tests/semantic_conformance/test_policy_cli.py::test_sql_policy_attributes_are_literals[O'Brien-9-unquoted]", + "tests/semantic_conformance/test_policy_cli.py::test_sql_policy_attributes_are_literals[x' OR '1'='1-7-quoted]", + "tests/semantic_conformance/test_policy_cli.py::test_sql_policy_attributes_are_literals[x' OR '1'='1-7-unquoted]", + "tests/semantic_conformance/test_policy_cli.py::test_sql_policy_attributes_are_literals[missing'; ---None-quoted]", + "tests/semantic_conformance/test_policy_cli.py::test_sql_policy_attributes_are_literals[missing'; ---None-unquoted]", + "tests/semantic_conformance/test_policy_cli.py::test_sql_join_policy_excludes_orphans_and_other_tenants", + "tests/semantic_conformance/test_policy_cli.py::test_declared_left_join_preserves_base_rows_with_secured_details", + "tests/semantic_conformance/test_policy_cli.py::test_policy_applies_independently_to_both_relationship_roles", + "tests/semantic_conformance/test_policy_cli.py::test_secured_rollup_request_uses_authorized_source_rows", + "tests/semantic_conformance/test_policy_cli.py::test_sql_physical_sources_cannot_bypass_policy[select * from policy_values]", + "tests/semantic_conformance/test_policy_cli.py::test_sql_physical_sources_cannot_bypass_policy[select allowed.total from metrics left join policy_values on true]", + "tests/semantic_conformance/test_policy_cli.py::test_sql_physical_sources_cannot_bypass_policy[select allowed.total, (select max(amount) from policy_values) from metrics]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_rejects_non_object_attribute_files[[]-query]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_rejects_non_object_attribute_files[[]-rewrite]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_rejects_non_object_attribute_files[null-query]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_rejects_non_object_attribute_files[null-rewrite]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_rejects_non_object_attribute_files[\"tenant\"-query]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_rejects_non_object_attribute_files[\"tenant\"-rewrite]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_rejects_non_object_attribute_files[{broken-query]", + "tests/semantic_conformance/test_policy_cli.py::test_cli_rejects_non_object_attribute_files[{broken-rewrite]", + "tests/semantic_conformance/test_policy_cli.py::test_model_from_policy_sql_selects_rust_without_fallback[rust-False]", + "tests/semantic_conformance/test_policy_cli.py::test_model_from_policy_sql_selects_rust_without_fallback[auto-True]", + "tests/semantic_conformance/test_policy_cli.py::test_scoped_filters_and_alias_pagination_keep_authorized_rows" + ] + }, + "scope-201": { + "path": "tests/semantic_conformance/test_postgres_policies.py", + "declared_tests": [ + "test_explicit_postgres_graph_input_preserves_policy_results", + "test_other_policy_output_dialects_preserve_population", + "test_postgres_date_diff_policy_is_not_claimed_equivalent", + "test_postgres_policy_denial_produces_no_sql", + "test_postgres_preserves_typed_policy_literals_and_exact_population", + "test_postgres_public_denial_does_not_fall_back", + "test_postgres_public_null_ordering_matches_adapter", + "test_postgres_public_paths_reach_rust_with_transport_syntax", + "test_postgres_translates_year_in_policy_and_invariant", + "test_postgres_transport_normalizes_declared_graph_dialect", + "test_postgres_visibility_is_enforced_only_when_requested" + ], + "collected_tests": [ + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_preserves_typed_policy_literals_and_exact_population[alice-True-10-compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_preserves_typed_policy_literals_and_exact_population[alice-True-10-rewrite]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_preserves_typed_policy_literals_and_exact_population[O'Brien-True-7-compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_preserves_typed_policy_literals_and_exact_population[O'Brien-True-7-rewrite]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_preserves_typed_policy_literals_and_exact_population[x' OR '1'='1-True-11-compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_preserves_typed_policy_literals_and_exact_population[x' OR '1'='1-True-11-rewrite]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_preserves_typed_policy_literals_and_exact_population[back\\\\slash' OR TRUE ---True-13-compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_preserves_typed_policy_literals_and_exact_population[back\\\\slash' OR TRUE ---True-13-rewrite]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_preserves_typed_policy_literals_and_exact_population[None-False-17-compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_preserves_typed_policy_literals_and_exact_population[None-False-17-rewrite]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_policy_denial_produces_no_sql[None-compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_policy_denial_produces_no_sql[None-rewrite]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_policy_denial_produces_no_sql[attributes1-compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_policy_denial_produces_no_sql[attributes1-rewrite]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_policy_denial_produces_no_sql[attributes2-compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_policy_denial_produces_no_sql[attributes2-rewrite]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_policy_denial_produces_no_sql[attributes3-compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_policy_denial_produces_no_sql[attributes3-rewrite]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_visibility_is_enforced_only_when_requested[compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_visibility_is_enforced_only_when_requested[rewrite]", + "tests/semantic_conformance/test_postgres_policies.py::test_other_policy_output_dialects_preserve_population[compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_other_policy_output_dialects_preserve_population[rewrite]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_translates_year_in_policy_and_invariant[compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_translates_year_in_policy_and_invariant[rewrite]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_date_diff_policy_is_not_claimed_equivalent[compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_date_diff_policy_is_not_claimed_equivalent[rewrite]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_public_paths_reach_rust_with_transport_syntax[compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_public_paths_reach_rust_with_transport_syntax[query]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_public_paths_reach_rust_with_transport_syntax[sql]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_public_paths_reach_rust_with_transport_syntax[rewriter]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_public_denial_does_not_fall_back[compile]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_public_denial_does_not_fall_back[sql]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_transport_normalizes_declared_graph_dialect", + "tests/semantic_conformance/test_postgres_policies.py::test_explicit_postgres_graph_input_preserves_policy_results", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_public_null_ordering_matches_adapter[query]", + "tests/semantic_conformance/test_postgres_policies.py::test_postgres_public_null_ordering_matches_adapter[sql]" + ] + }, + "scope-202": { + "path": "tests/semantic_conformance/test_query_catalogs.py", + "declared_tests": [ + "test_active_explore_is_enforced", + "test_catalogs_do_not_disable_mandatory_policy", + "test_invalid_active_saved_query_is_not_treated_as_unused", + "test_invalid_catalog_identity_is_rejected", + "test_raw_active_catalog_requests_are_never_ignored", + "test_resolved_saved_query_keeps_filters_and_immutability", + "test_rewrite_preserves_policies_with_unused_catalogs", + "test_saved_query_visibility_is_checked_before_dispatch", + "test_unused_catalogs_do_not_block_strict_query_or_mutate_source" + ], + "collected_tests": [ + "tests/semantic_conformance/test_query_catalogs.py::test_unused_catalogs_do_not_block_strict_query_or_mutate_source[python]", + "tests/semantic_conformance/test_query_catalogs.py::test_unused_catalogs_do_not_block_strict_query_or_mutate_source[rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_resolved_saved_query_keeps_filters_and_immutability[python]", + "tests/semantic_conformance/test_query_catalogs.py::test_resolved_saved_query_keeps_filters_and_immutability[rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_catalogs_do_not_disable_mandatory_policy[python]", + "tests/semantic_conformance/test_query_catalogs.py::test_catalogs_do_not_disable_mandatory_policy[rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_saved_query_visibility_is_checked_before_dispatch[python]", + "tests/semantic_conformance/test_query_catalogs.py::test_saved_query_visibility_is_checked_before_dispatch[rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_invalid_active_saved_query_is_not_treated_as_unused[python]", + "tests/semantic_conformance/test_query_catalogs.py::test_invalid_active_saved_query_is_not_treated_as_unused[rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_active_explore_is_enforced[python-query0]", + "tests/semantic_conformance/test_query_catalogs.py::test_active_explore_is_enforced[python-query1]", + "tests/semantic_conformance/test_query_catalogs.py::test_active_explore_is_enforced[rust-query0]", + "tests/semantic_conformance/test_query_catalogs.py::test_active_explore_is_enforced[rust-query1]", + "tests/semantic_conformance/test_query_catalogs.py::test_rewrite_preserves_policies_with_unused_catalogs[rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_raw_active_catalog_requests_are_never_ignored[explore-large_orders-rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_raw_active_catalog_requests_are_never_ignored[saved_query-paid-rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_raw_active_catalog_requests_are_never_ignored[table_calculations-value2-rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_invalid_catalog_identity_is_rejected[definitions0-rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_invalid_catalog_identity_is_rejected[definitions1-rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_invalid_catalog_identity_is_rejected[definitions2-rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_invalid_catalog_identity_is_rejected[definitions3-rust]" + ] + }, + "scope-203": { + "path": "tests/semantic_conformance/test_query_catalogs.py", + "declared_tests": [ + "test_raw_active_catalog_requests_are_never_ignored" + ], + "collected_tests": [ + "tests/semantic_conformance/test_query_catalogs.py::test_raw_active_catalog_requests_are_never_ignored[explore-large_orders-rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_raw_active_catalog_requests_are_never_ignored[saved_query-paid-rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_raw_active_catalog_requests_are_never_ignored[table_calculations-value2-rust]" + ] + }, + "scope-204": { + "path": "tests/semantic_conformance/test_query_catalogs.py", + "declared_tests": [ + "test_invalid_catalog_identity_is_rejected" + ], + "collected_tests": [ + "tests/semantic_conformance/test_query_catalogs.py::test_invalid_catalog_identity_is_rejected[definitions0-rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_invalid_catalog_identity_is_rejected[definitions1-rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_invalid_catalog_identity_is_rejected[definitions2-rust]", + "tests/semantic_conformance/test_query_catalogs.py::test_invalid_catalog_identity_is_rejected[definitions3-rust]" + ] + }, + "scope-205": { + "path": "tests/semantic_conformance/test_query_options_parity.py", + "declared_tests": [ + "test_aliases_bind_selected_calculation_order", + "test_aliases_keep_ordering_and_pagination", + "test_calculation_pagination_preserves_ordinary_null_order", + "test_quoted_aliases_are_identifiers", + "test_snapshot_totals_retain_latest_per_entity_selection", + "test_spaced_output_alias_ordering_keeps_full_names", + "test_totals_aliases_filters_and_multiple_dimensions", + "test_totals_deduplicate_fanned_out_keys_across_detail_groups", + "test_totals_empty_population_keeps_the_grand_total", + "test_totals_invalid_combinations", + "test_totals_one_to_one_sources_keep_null_detail_separate_from_total", + "test_totals_preaggregation_is_unsupported", + "test_totals_recompute_nonadditive_aggregates_and_keep_real_null_group", + "test_totals_with_dimension_only_and_without_dimensions", + "test_ungrouped_aliases" + ], + "collected_tests": [ + "tests/semantic_conformance/test_query_options_parity.py::test_aliases_keep_ordering_and_pagination[python-orders.revenue desc]", + "tests/semantic_conformance/test_query_options_parity.py::test_aliases_keep_ordering_and_pagination[python-revenue desc]", + "tests/semantic_conformance/test_query_options_parity.py::test_aliases_keep_ordering_and_pagination[python-total desc]", + "tests/semantic_conformance/test_query_options_parity.py::test_aliases_keep_ordering_and_pagination[rust-orders.revenue desc]", + "tests/semantic_conformance/test_query_options_parity.py::test_aliases_keep_ordering_and_pagination[rust-revenue desc]", + "tests/semantic_conformance/test_query_options_parity.py::test_aliases_keep_ordering_and_pagination[rust-total desc]", + "tests/semantic_conformance/test_query_options_parity.py::test_quoted_aliases_are_identifiers[python-sum\"; drop table orders; --]", + "tests/semantic_conformance/test_query_options_parity.py::test_quoted_aliases_are_identifiers[python-select]", + "tests/semantic_conformance/test_query_options_parity.py::test_quoted_aliases_are_identifiers[python-MixedCase]", + "tests/semantic_conformance/test_query_options_parity.py::test_quoted_aliases_are_identifiers[rust-sum\"; drop table orders; --]", + "tests/semantic_conformance/test_query_options_parity.py::test_quoted_aliases_are_identifiers[rust-select]", + "tests/semantic_conformance/test_query_options_parity.py::test_quoted_aliases_are_identifiers[rust-MixedCase]", + "tests/semantic_conformance/test_query_options_parity.py::test_aliases_bind_selected_calculation_order[python-orders.revenue desc]", + "tests/semantic_conformance/test_query_options_parity.py::test_aliases_bind_selected_calculation_order[python-revenue desc]", + "tests/semantic_conformance/test_query_options_parity.py::test_aliases_bind_selected_calculation_order[python-total desc]", + "tests/semantic_conformance/test_query_options_parity.py::test_aliases_bind_selected_calculation_order[rust-orders.revenue desc]", + "tests/semantic_conformance/test_query_options_parity.py::test_aliases_bind_selected_calculation_order[rust-revenue desc]", + "tests/semantic_conformance/test_query_options_parity.py::test_aliases_bind_selected_calculation_order[rust-total desc]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_recompute_nonadditive_aggregates_and_keep_real_null_group[python]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_recompute_nonadditive_aggregates_and_keep_real_null_group[rust]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_aliases_filters_and_multiple_dimensions[python]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_aliases_filters_and_multiple_dimensions[rust]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_with_dimension_only_and_without_dimensions[python]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_with_dimension_only_and_without_dimensions[rust]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_invalid_combinations[python-options0]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_invalid_combinations[python-options1]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_invalid_combinations[python-options2]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_invalid_combinations[rust-options0]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_invalid_combinations[rust-options1]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_invalid_combinations[rust-options2]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_preaggregation_is_unsupported[python]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_preaggregation_is_unsupported[rust]", + "tests/semantic_conformance/test_query_options_parity.py::test_ungrouped_aliases[python]", + "tests/semantic_conformance/test_query_options_parity.py::test_ungrouped_aliases[rust]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_one_to_one_sources_keep_null_detail_separate_from_total[python]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_one_to_one_sources_keep_null_detail_separate_from_total[rust]", + "tests/semantic_conformance/test_query_options_parity.py::test_snapshot_totals_retain_latest_per_entity_selection[python-False]", + "tests/semantic_conformance/test_query_options_parity.py::test_snapshot_totals_retain_latest_per_entity_selection[python-True]", + "tests/semantic_conformance/test_query_options_parity.py::test_snapshot_totals_retain_latest_per_entity_selection[rust-False]", + "tests/semantic_conformance/test_query_options_parity.py::test_snapshot_totals_retain_latest_per_entity_selection[rust-True]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_deduplicate_fanned_out_keys_across_detail_groups[python-all-False]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_deduplicate_fanned_out_keys_across_detail_groups[python-all-True]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_deduplicate_fanned_out_keys_across_detail_groups[python-filtered-False]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_deduplicate_fanned_out_keys_across_detail_groups[python-filtered-True]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_deduplicate_fanned_out_keys_across_detail_groups[python-empty-False]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_deduplicate_fanned_out_keys_across_detail_groups[python-empty-True]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_deduplicate_fanned_out_keys_across_detail_groups[rust-all-False]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_deduplicate_fanned_out_keys_across_detail_groups[rust-all-True]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_deduplicate_fanned_out_keys_across_detail_groups[rust-filtered-False]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_deduplicate_fanned_out_keys_across_detail_groups[rust-filtered-True]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_deduplicate_fanned_out_keys_across_detail_groups[rust-empty-False]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_deduplicate_fanned_out_keys_across_detail_groups[rust-empty-True]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_empty_population_keeps_the_grand_total[python]", + "tests/semantic_conformance/test_query_options_parity.py::test_totals_empty_population_keeps_the_grand_total[rust]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-False--expected0-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-False--expected0-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-False--expected0-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-False- desc-expected1-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-False- desc-expected1-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-False- desc-expected1-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-False- asc nulls first-expected2-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-False- asc nulls first-expected2-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-False- asc nulls first-expected2-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-False-\\tDESC\\tNULLS\\tLAST-expected3-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-False-\\tDESC\\tNULLS\\tLAST-expected3-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-False-\\tDESC\\tNULLS\\tLAST-expected3-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-True--expected0-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-True--expected0-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-True--expected0-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-True- desc-expected1-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-True- desc-expected1-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-True- desc-expected1-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-True- asc nulls first-expected2-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-True- asc nulls first-expected2-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-True- asc nulls first-expected2-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-True-\\tDESC\\tNULLS\\tLAST-expected3-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-True-\\tDESC\\tNULLS\\tLAST-expected3-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[python-True-\\tDESC\\tNULLS\\tLAST-expected3-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-False--expected0-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-False--expected0-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-False--expected0-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-False- desc-expected1-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-False- desc-expected1-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-False- desc-expected1-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-False- asc nulls first-expected2-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-False- asc nulls first-expected2-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-False- asc nulls first-expected2-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-False-\\tDESC\\tNULLS\\tLAST-expected3-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-False-\\tDESC\\tNULLS\\tLAST-expected3-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-False-\\tDESC\\tNULLS\\tLAST-expected3-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-True--expected0-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-True--expected0-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-True--expected0-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-True- desc-expected1-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-True- desc-expected1-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-True- desc-expected1-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-True- asc nulls first-expected2-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-True- asc nulls first-expected2-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-True- asc nulls first-expected2-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-True-\\tDESC\\tNULLS\\tLAST-expected3-Category label]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-True-\\tDESC\\tNULLS\\tLAST-expected3-Category DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_spaced_output_alias_ordering_keeps_full_names[rust-True-\\tDESC\\tNULLS\\tLAST-expected3-Category NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-0-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-0- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-0- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-0- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-0- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-0- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-0- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-0- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-0- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-1-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-1- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-1- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-1- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-1- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-1- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-1- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-1- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-False-1- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-0-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-0- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-0- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-0- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-0- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-0- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-0- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-0- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-0- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-1-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-1- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-1- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-1- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-1- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-1- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-1- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-1- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-duckdb-True-1- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-0-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-0- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-0- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-0- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-0- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-0- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-0- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-0- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-0- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-1-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-1- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-1- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-1- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-1- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-1- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-1- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-1- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-False-1- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-0-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-0- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-0- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-0- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-0- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-0- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-0- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-0- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-0- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-1-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-1- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-1- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-1- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-1- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-1- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-1- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-1- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[python-postgres-True-1- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-0-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-0- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-0- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-0- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-0- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-0- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-0- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-0- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-0- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-1-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-1- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-1- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-1- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-1- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-1- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-1- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-1- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-False-1- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-0-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-0- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-0- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-0- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-0- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-0- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-0- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-0- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-0- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-1-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-1- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-1- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-1- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-1- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-1- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-1- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-1- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-duckdb-True-1- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-0-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-0- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-0- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-0- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-0- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-0- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-0- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-0- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-0- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-1-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-1- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-1- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-1- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-1- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-1- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-1- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-1- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-False-1- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-0-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-0- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-0- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-0- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-0- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-0- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-0- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-0- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-0- DESC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-1-]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-1- ASC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-1- DESC]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-1- NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-1- NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-1- ASC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-1- ASC NULLS LAST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-1- DESC NULLS FIRST]", + "tests/semantic_conformance/test_query_options_parity.py::test_calculation_pagination_preserves_ordinary_null_order[rust-postgres-True-1- DESC NULLS LAST]" + ] + }, + "scope-206": { + "path": "tests/semantic_conformance/test_query_timezone_parity.py", + "declared_tests": [ + "test_absent_timezone_keeps_utc_buckets", + "test_local_time_buckets_and_dst", + "test_supported_dialect_localization", + "test_timezone_bypasses_utc_rollup", + "test_timezone_rejects_invalid_characters", + "test_unsupported_dialect_is_explicit" + ], + "collected_tests": [ + "tests/semantic_conformance/test_query_timezone_parity.py::test_local_time_buckets_and_dst[python-ts-hour]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_local_time_buckets_and_dst[python-ts-day]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_local_time_buckets_and_dst[python-ts-month]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_local_time_buckets_and_dst[python-computed_ts-hour]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_local_time_buckets_and_dst[python-computed_ts-day]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_local_time_buckets_and_dst[python-computed_ts-month]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_local_time_buckets_and_dst[rust-ts-hour]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_local_time_buckets_and_dst[rust-ts-day]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_local_time_buckets_and_dst[rust-ts-month]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_local_time_buckets_and_dst[rust-computed_ts-hour]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_local_time_buckets_and_dst[rust-computed_ts-day]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_local_time_buckets_and_dst[rust-computed_ts-month]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_supported_dialect_localization[python-duckdb-AT TIME ZONE]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_supported_dialect_localization[python-postgres-AT TIME ZONE]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_supported_dialect_localization[python-snowflake-CONVERT_TIMEZONE]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_supported_dialect_localization[python-bigquery-DATETIME]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_supported_dialect_localization[python-spark-FROM_UTC_TIMESTAMP]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_supported_dialect_localization[python-databricks-FROM_UTC_TIMESTAMP]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_supported_dialect_localization[python-clickhouse-TOTIMEZONE]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_supported_dialect_localization[rust-duckdb-AT TIME ZONE]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_supported_dialect_localization[rust-postgres-AT TIME ZONE]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_supported_dialect_localization[rust-snowflake-CONVERT_TIMEZONE]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_supported_dialect_localization[rust-bigquery-DATETIME]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_supported_dialect_localization[rust-spark-FROM_UTC_TIMESTAMP]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_supported_dialect_localization[rust-databricks-FROM_UTC_TIMESTAMP]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_supported_dialect_localization[rust-clickhouse-TOTIMEZONE]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_timezone_rejects_invalid_characters[python-UTC'; --]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_timezone_rejects_invalid_characters[python-America/New York]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_timezone_rejects_invalid_characters[python-UTC\\\\]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_timezone_rejects_invalid_characters[python-UTC\\n]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_timezone_rejects_invalid_characters[rust-UTC'; --]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_timezone_rejects_invalid_characters[rust-America/New York]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_timezone_rejects_invalid_characters[rust-UTC\\\\]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_timezone_rejects_invalid_characters[rust-UTC\\n]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_absent_timezone_keeps_utc_buckets[python-None]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_absent_timezone_keeps_utc_buckets[python-]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_absent_timezone_keeps_utc_buckets[rust-None]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_absent_timezone_keeps_utc_buckets[rust-]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_unsupported_dialect_is_explicit[python]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_unsupported_dialect_is_explicit[rust]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_timezone_bypasses_utc_rollup[python]", + "tests/semantic_conformance/test_query_timezone_parity.py::test_timezone_bypasses_utc_rollup[rust]" + ] + }, + "scope-207": { + "path": "tests/semantic_conformance/test_reference.py", + "declared_tests": [ + "test_compiler_results" + ], + "collected_tests": [ + "tests/semantic_conformance/test_reference.py::test_compiler_results[keyless_aggregate-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[keyless_aggregate-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[unknown_key_fanout-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[unknown_key_fanout-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[cross_model_ratio-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[cross_model_ratio-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[local_customer_proxy_uses_customer_grain-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[local_customer_proxy_uses_customer_grain-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[graph_customer_proxy_uses_customer_grain-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[graph_customer_proxy_uses_customer_grain-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[grouped_customer_proxy_uses_customer_grain-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[grouped_customer_proxy_uses_customer_grain-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[restricted_rollup-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[restricted_rollup-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[restricted_rollup_requested-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[restricted_rollup_requested-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[missing_security_context-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[missing_security_context-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[composite_null_foreign_key-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[composite_null_foreign_key-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[sparse_month_comparison-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[sparse_month_comparison-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[computed_physical_collision-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[computed_physical_collision-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[relationship_roles-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[relationship_roles-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[cube_join-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[cube_join-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[cube_filtered_measure-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[cube_filtered_measure-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[ossie_complete_aggregate-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[ossie_complete_aggregate-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[empty_aggregate_null_fill-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[empty_aggregate_null_fill-rust]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[complete_aggregate_physical_filter-python]", + "tests/semantic_conformance/test_reference.py::test_compiler_results[complete_aggregate_physical_filter-rust]" + ] + }, + "scope-208": { + "path": "tests/semantic_conformance/test_relationship_role_parity.py", + "declared_tests": [ + "test_equally_short_undeclared_join_choice_is_rejected", + "test_nested_country_paths_keep_parent_role_identity", + "test_repeated_aliases_are_scoped_by_owning_model" + ], + "collected_tests": [ + "tests/semantic_conformance/test_relationship_role_parity.py::test_nested_country_paths_keep_parent_role_identity[python]", + "tests/semantic_conformance/test_relationship_role_parity.py::test_nested_country_paths_keep_parent_role_identity[rust]", + "tests/semantic_conformance/test_relationship_role_parity.py::test_repeated_aliases_are_scoped_by_owning_model[python]", + "tests/semantic_conformance/test_relationship_role_parity.py::test_repeated_aliases_are_scoped_by_owning_model[rust]", + "tests/semantic_conformance/test_relationship_role_parity.py::test_equally_short_undeclared_join_choice_is_rejected[python]", + "tests/semantic_conformance/test_relationship_role_parity.py::test_equally_short_undeclared_join_choice_is_rejected[rust]" + ] + }, + "scope-209": { + "path": "tests/semantic_conformance/test_relative_date_operators.py", + "declared_tests": [ + "test_relative_date_operator_result_matches_period_contract" + ], + "collected_tests": [ + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-today-=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-today-=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-today-!=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-today-!=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-today-<>-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-today-<>-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-today-<-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-today-<-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-today-<=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-today-<=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-today->-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-today->-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-today->=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-today->=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-this month-=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-this month-=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-this month-!=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-this month-!=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-this month-<>-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-this month-<>-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-this month-<-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-this month-<-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-this month-<=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-this month-<=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-this month->-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-this month->-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-this month->=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[python-this month->=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-today-=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-today-=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-today-!=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-today-!=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-today-<>-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-today-<>-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-today-<-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-today-<-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-today-<=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-today-<=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-today->-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-today->-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-today->=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-today->=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-this month-=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-this month-=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-this month-!=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-this month-!=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-this month-<>-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-this month-<>-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-this month-<-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-this month-<-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-this month-<=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-this month-<=-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-this month->-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-this month->-sql]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-this month->=-query]", + "tests/semantic_conformance/test_relative_date_operators.py::test_relative_date_operator_result_matches_period_contract[rust-this month->=-sql]" + ] + }, + "scope-210": { + "path": "tests/semantic_conformance/test_retention_parity.py", + "declared_tests": [ + "test_aliased_dimension_filter_can_empty_cohort_population", + "test_calendar_periods_have_fixed_output_labels", + "test_default_activity_includes_signup_and_preserves_inactive_denominator", + "test_first_cohort_sparse_periods_nulls_and_inactive_denominator", + "test_metric_filter_scopes_both_populations", + "test_missing_policy_context_denies_retention", + "test_or_filter_cannot_bypass_cohort_predicate_or_mandatory_policies", + "test_order_and_pagination_apply_to_retention_outputs", + "test_policy_scopes_cohort_and_activity_for_each_tenant", + "test_retention_accepts_fill_metadata_without_changing_its_fixed_output_schema", + "test_retention_cannot_combine_with_additive_metric", + "test_retention_filter_literals_are_not_metric_references", + "test_retention_output_dialects_preserve_calendar_periods", + "test_retention_rejects_aggregate_source_filters_before_execution", + "test_retention_rejects_unsupported_shapes_before_execution", + "test_row_filter_scopes_denominator_as_well_as_activity", + "test_selected_calculations_preserve_retention_fixed_projection", + "test_source_anchored_explore_preserves_retention_population", + "test_sql_source_and_model_placeholders_preserve_population", + "test_time_filter_recomputes_first_qualifying_cohort" + ], + "collected_tests": [ + "tests/semantic_conformance/test_retention_parity.py::test_first_cohort_sparse_periods_nulls_and_inactive_denominator[python]", + "tests/semantic_conformance/test_retention_parity.py::test_first_cohort_sparse_periods_nulls_and_inactive_denominator[rust]", + "tests/semantic_conformance/test_retention_parity.py::test_source_anchored_explore_preserves_retention_population[python]", + "tests/semantic_conformance/test_retention_parity.py::test_source_anchored_explore_preserves_retention_population[rust]", + "tests/semantic_conformance/test_retention_parity.py::test_policy_scopes_cohort_and_activity_for_each_tenant[python]", + "tests/semantic_conformance/test_retention_parity.py::test_policy_scopes_cohort_and_activity_for_each_tenant[rust]", + "tests/semantic_conformance/test_retention_parity.py::test_row_filter_scopes_denominator_as_well_as_activity[python]", + "tests/semantic_conformance/test_retention_parity.py::test_row_filter_scopes_denominator_as_well_as_activity[rust]", + "tests/semantic_conformance/test_retention_parity.py::test_or_filter_cannot_bypass_cohort_predicate_or_mandatory_policies[python]", + "tests/semantic_conformance/test_retention_parity.py::test_or_filter_cannot_bypass_cohort_predicate_or_mandatory_policies[rust]", + "tests/semantic_conformance/test_retention_parity.py::test_metric_filter_scopes_both_populations[python]", + "tests/semantic_conformance/test_retention_parity.py::test_metric_filter_scopes_both_populations[rust]", + "tests/semantic_conformance/test_retention_parity.py::test_time_filter_recomputes_first_qualifying_cohort[python]", + "tests/semantic_conformance/test_retention_parity.py::test_time_filter_recomputes_first_qualifying_cohort[rust]", + "tests/semantic_conformance/test_retention_parity.py::test_aliased_dimension_filter_can_empty_cohort_population[python]", + "tests/semantic_conformance/test_retention_parity.py::test_aliased_dimension_filter_can_empty_cohort_population[rust]", + "tests/semantic_conformance/test_retention_parity.py::test_default_activity_includes_signup_and_preserves_inactive_denominator[python]", + "tests/semantic_conformance/test_retention_parity.py::test_default_activity_includes_signup_and_preserves_inactive_denominator[rust]", + "tests/semantic_conformance/test_retention_parity.py::test_calendar_periods_have_fixed_output_labels[python-week-weeks_since-rows0]", + "tests/semantic_conformance/test_retention_parity.py::test_calendar_periods_have_fixed_output_labels[python-month-months_since-rows1]", + "tests/semantic_conformance/test_retention_parity.py::test_calendar_periods_have_fixed_output_labels[rust-week-weeks_since-rows0]", + "tests/semantic_conformance/test_retention_parity.py::test_calendar_periods_have_fixed_output_labels[rust-month-months_since-rows1]", + "tests/semantic_conformance/test_retention_parity.py::test_order_and_pagination_apply_to_retention_outputs[python]", + "tests/semantic_conformance/test_retention_parity.py::test_order_and_pagination_apply_to_retention_outputs[rust]", + "tests/semantic_conformance/test_retention_parity.py::test_sql_source_and_model_placeholders_preserve_population[python]", + "tests/semantic_conformance/test_retention_parity.py::test_sql_source_and_model_placeholders_preserve_population[rust]", + "tests/semantic_conformance/test_retention_parity.py::test_missing_policy_context_denies_retention[python-None]", + "tests/semantic_conformance/test_retention_parity.py::test_missing_policy_context_denies_retention[python-attributes1]", + "tests/semantic_conformance/test_retention_parity.py::test_missing_policy_context_denies_retention[rust-None]", + "tests/semantic_conformance/test_retention_parity.py::test_missing_policy_context_denies_retention[rust-attributes1]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_cannot_combine_with_additive_metric[python]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_cannot_combine_with_additive_metric[rust]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_unsupported_shapes_before_execution[python-dimension-metric.retention_query_shape]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_unsupported_shapes_before_execution[python-aggregate_filter-metric.retention_aggregate_filter]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_unsupported_shapes_before_execution[python-wrapper-metric.retention_wrapped_metric]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_unsupported_shapes_before_execution[rust-dimension-metric.retention_query_shape]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_unsupported_shapes_before_execution[rust-aggregate_filter-metric.retention_aggregate_filter]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_unsupported_shapes_before_execution[rust-wrapper-metric.retention_wrapped_metric]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_aggregate_source_filters_before_execution[python-query-event_count > 0]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_aggregate_source_filters_before_execution[python-query-events.event_count > 0]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_aggregate_source_filters_before_execution[python-query-COUNT(*) > 0]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_aggregate_source_filters_before_execution[python-metric-event_count > 0]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_aggregate_source_filters_before_execution[python-metric-events.event_count > 0]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_aggregate_source_filters_before_execution[python-metric-COUNT(*) > 0]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_aggregate_source_filters_before_execution[rust-query-event_count > 0]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_aggregate_source_filters_before_execution[rust-query-events.event_count > 0]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_aggregate_source_filters_before_execution[rust-query-COUNT(*) > 0]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_aggregate_source_filters_before_execution[rust-metric-event_count > 0]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_aggregate_source_filters_before_execution[rust-metric-events.event_count > 0]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_rejects_aggregate_source_filters_before_execution[rust-metric-COUNT(*) > 0]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_filter_literals_are_not_metric_references[python]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_filter_literals_are_not_metric_references[rust]", + "tests/semantic_conformance/test_retention_parity.py::test_selected_calculations_preserve_retention_fixed_projection[python]", + "tests/semantic_conformance/test_retention_parity.py::test_selected_calculations_preserve_retention_fixed_projection[rust]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_accepts_fill_metadata_without_changing_its_fixed_output_schema[python-0]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_accepts_fill_metadata_without_changing_its_fixed_output_schema[python--99]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_accepts_fill_metadata_without_changing_its_fixed_output_schema[python-missing]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_accepts_fill_metadata_without_changing_its_fixed_output_schema[rust-0]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_accepts_fill_metadata_without_changing_its_fixed_output_schema[rust--99]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_accepts_fill_metadata_without_changing_its_fixed_output_schema[rust-missing]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[python-day-days_since-rows0-duckdb]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[python-day-days_since-rows0-postgres]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[python-day-days_since-rows0-bigquery]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[python-day-days_since-rows0-snowflake]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[python-week-weeks_since-rows1-duckdb]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[python-week-weeks_since-rows1-postgres]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[python-week-weeks_since-rows1-bigquery]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[python-week-weeks_since-rows1-snowflake]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[python-month-months_since-rows2-duckdb]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[python-month-months_since-rows2-postgres]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[python-month-months_since-rows2-bigquery]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[python-month-months_since-rows2-snowflake]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[rust-day-days_since-rows0-duckdb]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[rust-day-days_since-rows0-postgres]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[rust-day-days_since-rows0-bigquery]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[rust-day-days_since-rows0-snowflake]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[rust-week-weeks_since-rows1-duckdb]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[rust-week-weeks_since-rows1-postgres]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[rust-week-weeks_since-rows1-bigquery]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[rust-week-weeks_since-rows1-snowflake]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[rust-month-months_since-rows2-duckdb]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[rust-month-months_since-rows2-postgres]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[rust-month-months_since-rows2-bigquery]", + "tests/semantic_conformance/test_retention_parity.py::test_retention_output_dialects_preserve_calendar_periods[rust-month-months_since-rows2-snowflake]" + ] + }, + "scope-211": { + "path": "tests/semantic_conformance/test_rewriter_ci_regressions.py", + "declared_tests": [ + "test_correlated_semantic_sources_fail_before_execution", + "test_dimension_only_grouping_preserves_explicit_ungrouped_mode", + "test_group_by_accepts_exact_selected_dimensions_and_aliases", + "test_group_by_cannot_silently_change_selected_grain", + "test_rewritten_result_contract", + "test_subquery_local_alias_can_shadow_outer_semantic_source" + ], + "collected_tests": [ + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_rewritten_result_contract[python-select count(*) as n from orders-expected0]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_rewritten_result_contract[python-select sum(amount) + count(*) as total from orders-expected1]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_rewritten_result_contract[python-select status, sum(amount) as total from orders group by status order by status-expected2]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_rewritten_result_contract[python-select status from orders order by status-expected3]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_rewritten_result_contract[rust-select count(*) as n from orders-expected0]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_rewritten_result_contract[rust-select sum(amount) + count(*) as total from orders-expected1]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_rewritten_result_contract[rust-select status, sum(amount) as total from orders group by status order by status-expected2]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_rewritten_result_contract[rust-select status from orders order by status-expected3]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_dimension_only_grouping_preserves_explicit_ungrouped_mode[python-False-expected0]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_dimension_only_grouping_preserves_explicit_ungrouped_mode[python-True-expected1]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_dimension_only_grouping_preserves_explicit_ungrouped_mode[rust-False-expected0]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_dimension_only_grouping_preserves_explicit_ungrouped_mode[rust-True-expected1]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_group_by_cannot_silently_change_selected_grain[python-select orders.sd_adhoc_metric_0 from orders group by orders.status]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_group_by_cannot_silently_change_selected_grain[python-select orders.status, orders.amount from orders group by orders.status]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_group_by_cannot_silently_change_selected_grain[python-select orders.status from orders group by 1]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_group_by_cannot_silently_change_selected_grain[python-select orders.status from orders group by lower(orders.status)]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_group_by_cannot_silently_change_selected_grain[rust-select orders.sd_adhoc_metric_0 from orders group by orders.status]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_group_by_cannot_silently_change_selected_grain[rust-select orders.status, orders.amount from orders group by orders.status]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_group_by_cannot_silently_change_selected_grain[rust-select orders.status from orders group by 1]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_group_by_cannot_silently_change_selected_grain[rust-select orders.status from orders group by lower(orders.status)]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_group_by_accepts_exact_selected_dimensions_and_aliases[python-orders.status]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_group_by_accepts_exact_selected_dimensions_and_aliases[python-status]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_group_by_accepts_exact_selected_dimensions_and_aliases[python-state]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_group_by_accepts_exact_selected_dimensions_and_aliases[rust-orders.status]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_group_by_accepts_exact_selected_dimensions_and_aliases[rust-status]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_group_by_accepts_exact_selected_dimensions_and_aliases[rust-state]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_correlated_semantic_sources_fail_before_execution[python-select orders.status, (select count(*) from labels l where l.status = orders.status) as n from orders-KeyError-Model l not found]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_correlated_semantic_sources_fail_before_execution[python-select o.status, (select count(*) from labels l where l.status = o.status) as n from orders o-KeyError-Model l not found]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_correlated_semantic_sources_fail_before_execution[python-select orders.status from orders where exists (select 1 from labels l where l.status = orders.status)-ValueError-Query expressions cannot introduce physical data sources]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_correlated_semantic_sources_fail_before_execution[python-select orders.status, (select (select count(*) from labels l where l.status = orders.status)) as n from orders-KeyError-Model l not found]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_correlated_semantic_sources_fail_before_execution[rust-select orders.status, (select count(*) from labels l where l.status = orders.status) as n from orders-KeyError-Model l not found]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_correlated_semantic_sources_fail_before_execution[rust-select o.status, (select count(*) from labels l where l.status = o.status) as n from orders o-KeyError-Model l not found]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_correlated_semantic_sources_fail_before_execution[rust-select orders.status from orders where exists (select 1 from labels l where l.status = orders.status)-ValueError-Query expressions cannot introduce physical data sources]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_correlated_semantic_sources_fail_before_execution[rust-select orders.status, (select (select count(*) from labels l where l.status = orders.status)) as n from orders-KeyError-Model l not found]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_subquery_local_alias_can_shadow_outer_semantic_source[python]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_subquery_local_alias_can_shadow_outer_semantic_source[rust]" + ] + }, + "scope-212": { + "path": "tests/semantic_conformance/test_rewriter_ci_regressions.py", + "declared_tests": [ + "test_subquery_local_alias_can_shadow_outer_semantic_source" + ], + "collected_tests": [ + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_subquery_local_alias_can_shadow_outer_semantic_source[python]", + "tests/semantic_conformance/test_rewriter_ci_regressions.py::test_subquery_local_alias_can_shadow_outer_semantic_source[rust]" + ] + }, + "scope-213": { + "path": "tests/semantic_conformance/test_rewriter_count_keys.py", + "declared_tests": [ + "test_composite_primary_keys_preserve_selected_aggregate_grain", + "test_composite_relationship_rewrite_uses_both_key_components", + "test_count_without_sql_counts_rows_including_null_payloads" + ], + "collected_tests": [ + "tests/semantic_conformance/test_rewriter_count_keys.py::test_count_without_sql_counts_rows_including_null_payloads[python--3]", + "tests/semantic_conformance/test_rewriter_count_keys.py::test_count_without_sql_counts_rows_including_null_payloads[python- where orders.status = 'done'-2]", + "tests/semantic_conformance/test_rewriter_count_keys.py::test_count_without_sql_counts_rows_including_null_payloads[python- where orders.status = 'missing'-0]", + "tests/semantic_conformance/test_rewriter_count_keys.py::test_count_without_sql_counts_rows_including_null_payloads[rust--3]", + "tests/semantic_conformance/test_rewriter_count_keys.py::test_count_without_sql_counts_rows_including_null_payloads[rust- where orders.status = 'done'-2]", + "tests/semantic_conformance/test_rewriter_count_keys.py::test_count_without_sql_counts_rows_including_null_payloads[rust- where orders.status = 'missing'-0]", + "tests/semantic_conformance/test_rewriter_count_keys.py::test_composite_primary_keys_preserve_selected_aggregate_grain[python]", + "tests/semantic_conformance/test_rewriter_count_keys.py::test_composite_primary_keys_preserve_selected_aggregate_grain[rust]", + "tests/semantic_conformance/test_rewriter_count_keys.py::test_composite_relationship_rewrite_uses_both_key_components[python]", + "tests/semantic_conformance/test_rewriter_count_keys.py::test_composite_relationship_rewrite_uses_both_key_components[rust]" + ] + }, + "scope-214": { + "path": "tests/semantic_conformance/test_rollup_reconstruction.py", + "declared_tests": [ + "test_average_and_derived_having_reconstruct_unselected_dependencies", + "test_average_chooses_compatible_count_by_definition_not_name", + "test_colliding_join_dimension_outputs_keep_raw_contract", + "test_composite_join_rollup_uses_every_key_and_preserves_literals", + "test_derived_ratio_and_nullable_average_reconstruct_from_states", + "test_distinct_rollup_preserves_exact_grain_only", + "test_empty_remote_dimension_domain_stays_empty", + "test_empty_rollup_count_is_zero_and_average_is_null", + "test_explicit_inner_join_declines_remote_domain_rollup", + "test_global_filtered_distinct_rollup_count_population", + "test_incompatible_average_denominator_falls_back_to_raw", + "test_join_key_rollup_alias_order_limit_and_local_dimension", + "test_join_key_rollup_preserves_remote_domain_and_metric_states", + "test_join_key_rollup_with_empty_source_retains_remote_members", + "test_join_rollup_preserves_local_and_role_source_population", + "test_lambda_daily_states_roll_up_to_months", + "test_lambda_rebuilds_entire_boundary_bucket_from_fresh_source", + "test_lambda_without_boundary_reads_only_materialized_state", + "test_mandatory_policy_bypasses_join_rollup", + "test_missing_rollup_table_query_retries_raw_source", + "test_missing_stored_join_key_uses_raw_source", + "test_nonnull_average_can_use_row_count", + "test_sum_having_filters_reaggregated_rollup_total" + ], + "collected_tests": [ + "tests/semantic_conformance/test_rollup_reconstruction.py::test_derived_ratio_and_nullable_average_reconstruct_from_states[python-python-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_derived_ratio_and_nullable_average_reconstruct_from_states[python-rust-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_derived_ratio_and_nullable_average_reconstruct_from_states[rust-python-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_derived_ratio_and_nullable_average_reconstruct_from_states[rust-rust-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_average_and_derived_having_reconstruct_unselected_dependencies[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_average_and_derived_having_reconstruct_unselected_dependencies[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_sum_having_filters_reaggregated_rollup_total[python-100-expected0]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_sum_having_filters_reaggregated_rollup_total[python-250-expected1]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_sum_having_filters_reaggregated_rollup_total[rust-100-expected0]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_sum_having_filters_reaggregated_rollup_total[rust-250-expected1]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_empty_rollup_count_is_zero_and_average_is_null[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_empty_rollup_count_is_zero_and_average_is_null[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_incompatible_average_denominator_falls_back_to_raw[python-None-count_filters0]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_incompatible_average_denominator_falls_back_to_raw[python-discount-count_filters1]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_incompatible_average_denominator_falls_back_to_raw[python-amount-count_filters2]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_incompatible_average_denominator_falls_back_to_raw[rust-None-count_filters0]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_incompatible_average_denominator_falls_back_to_raw[rust-discount-count_filters1]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_incompatible_average_denominator_falls_back_to_raw[rust-amount-count_filters2]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_nonnull_average_can_use_row_count[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_nonnull_average_can_use_row_count[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_key_rollup_preserves_remote_domain_and_metric_states[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_key_rollup_preserves_remote_domain_and_metric_states[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_key_rollup_with_empty_source_retains_remote_members[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_key_rollup_with_empty_source_retains_remote_members[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_key_rollup_alias_order_limit_and_local_dimension[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_key_rollup_alias_order_limit_and_local_dimension[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_mandatory_policy_bypasses_join_rollup[python-policy]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_mandatory_policy_bypasses_join_rollup[python-invariant]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_mandatory_policy_bypasses_join_rollup[rust-policy]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_mandatory_policy_bypasses_join_rollup[rust-invariant]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_rebuilds_entire_boundary_bucket_from_fresh_source[python-python-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_rebuilds_entire_boundary_bucket_from_fresh_source[python-rust-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_rebuilds_entire_boundary_bucket_from_fresh_source[rust-python-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_rebuilds_entire_boundary_bucket_from_fresh_source[rust-rust-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_without_boundary_reads_only_materialized_state[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_without_boundary_reads_only_materialized_state[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_missing_rollup_table_query_retries_raw_source[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_missing_rollup_table_query_retries_raw_source[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_composite_join_rollup_uses_every_key_and_preserves_literals[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_composite_join_rollup_uses_every_key_and_preserves_literals[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_missing_stored_join_key_uses_raw_source[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_missing_stored_join_key_uses_raw_source[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_empty_remote_dimension_domain_stays_empty[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_empty_remote_dimension_domain_stays_empty[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_daily_states_roll_up_to_months[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_daily_states_roll_up_to_months[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_average_chooses_compatible_count_by_definition_not_name[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_average_chooses_compatible_count_by_definition_not_name[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_explicit_inner_join_declines_remote_domain_rollup[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_explicit_inner_join_declines_remote_domain_rollup[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_colliding_join_dimension_outputs_keep_raw_contract[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_colliding_join_dimension_outputs_keep_raw_contract[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_rollup_preserves_local_and_role_source_population[python-local-first]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_rollup_preserves_local_and_role_source_population[python-role-owner]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_rollup_preserves_local_and_role_source_population[rust-local-first]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_rollup_preserves_local_and_role_source_population[rust-role-owner]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-python-build-exact]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-python-build-coarser-time]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-python-build-omitted-dimension]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-python-build-lambda]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-rust-build-exact]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-rust-build-coarser-time]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-rust-build-omitted-dimension]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-rust-build-lambda]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-python-build-exact]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-python-build-coarser-time]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-python-build-omitted-dimension]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-python-build-lambda]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-rust-build-exact]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-rust-build-coarser-time]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-rust-build-omitted-dimension]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-rust-build-lambda]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_global_filtered_distinct_rollup_count_population[python-False]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_global_filtered_distinct_rollup_count_population[python-True]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_global_filtered_distinct_rollup_count_population[rust-False]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_global_filtered_distinct_rollup_count_population[rust-True]" + ] + }, + "scope-215": { + "path": "tests/semantic_conformance/test_rollup_reconstruction.py", + "declared_tests": [ + "test_average_and_derived_having_reconstruct_unselected_dependencies", + "test_average_chooses_compatible_count_by_definition_not_name", + "test_colliding_join_dimension_outputs_keep_raw_contract", + "test_composite_join_rollup_uses_every_key_and_preserves_literals", + "test_derived_ratio_and_nullable_average_reconstruct_from_states", + "test_distinct_rollup_preserves_exact_grain_only", + "test_empty_remote_dimension_domain_stays_empty", + "test_empty_rollup_count_is_zero_and_average_is_null", + "test_explicit_inner_join_declines_remote_domain_rollup", + "test_global_filtered_distinct_rollup_count_population", + "test_incompatible_average_denominator_falls_back_to_raw", + "test_join_key_rollup_alias_order_limit_and_local_dimension", + "test_join_key_rollup_preserves_remote_domain_and_metric_states", + "test_join_key_rollup_with_empty_source_retains_remote_members", + "test_join_rollup_preserves_local_and_role_source_population", + "test_lambda_daily_states_roll_up_to_months", + "test_lambda_rebuilds_entire_boundary_bucket_from_fresh_source", + "test_lambda_without_boundary_reads_only_materialized_state", + "test_mandatory_policy_bypasses_join_rollup", + "test_missing_stored_join_key_uses_raw_source", + "test_nonnull_average_can_use_row_count", + "test_sum_having_filters_reaggregated_rollup_total" + ], + "collected_tests": [ + "tests/semantic_conformance/test_rollup_reconstruction.py::test_derived_ratio_and_nullable_average_reconstruct_from_states[python-python-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_derived_ratio_and_nullable_average_reconstruct_from_states[python-rust-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_derived_ratio_and_nullable_average_reconstruct_from_states[rust-python-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_derived_ratio_and_nullable_average_reconstruct_from_states[rust-rust-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_average_and_derived_having_reconstruct_unselected_dependencies[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_average_and_derived_having_reconstruct_unselected_dependencies[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_sum_having_filters_reaggregated_rollup_total[python-100-expected0]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_sum_having_filters_reaggregated_rollup_total[python-250-expected1]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_sum_having_filters_reaggregated_rollup_total[rust-100-expected0]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_sum_having_filters_reaggregated_rollup_total[rust-250-expected1]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_empty_rollup_count_is_zero_and_average_is_null[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_empty_rollup_count_is_zero_and_average_is_null[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_incompatible_average_denominator_falls_back_to_raw[python-None-count_filters0]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_incompatible_average_denominator_falls_back_to_raw[python-discount-count_filters1]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_incompatible_average_denominator_falls_back_to_raw[python-amount-count_filters2]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_incompatible_average_denominator_falls_back_to_raw[rust-None-count_filters0]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_incompatible_average_denominator_falls_back_to_raw[rust-discount-count_filters1]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_incompatible_average_denominator_falls_back_to_raw[rust-amount-count_filters2]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_nonnull_average_can_use_row_count[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_nonnull_average_can_use_row_count[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_key_rollup_preserves_remote_domain_and_metric_states[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_key_rollup_preserves_remote_domain_and_metric_states[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_key_rollup_with_empty_source_retains_remote_members[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_key_rollup_with_empty_source_retains_remote_members[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_key_rollup_alias_order_limit_and_local_dimension[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_key_rollup_alias_order_limit_and_local_dimension[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_mandatory_policy_bypasses_join_rollup[python-policy]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_mandatory_policy_bypasses_join_rollup[python-invariant]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_mandatory_policy_bypasses_join_rollup[rust-policy]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_mandatory_policy_bypasses_join_rollup[rust-invariant]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_rebuilds_entire_boundary_bucket_from_fresh_source[python-python-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_rebuilds_entire_boundary_bucket_from_fresh_source[python-rust-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_rebuilds_entire_boundary_bucket_from_fresh_source[rust-python-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_rebuilds_entire_boundary_bucket_from_fresh_source[rust-rust-build]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_without_boundary_reads_only_materialized_state[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_without_boundary_reads_only_materialized_state[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_composite_join_rollup_uses_every_key_and_preserves_literals[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_composite_join_rollup_uses_every_key_and_preserves_literals[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_missing_stored_join_key_uses_raw_source[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_missing_stored_join_key_uses_raw_source[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_empty_remote_dimension_domain_stays_empty[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_empty_remote_dimension_domain_stays_empty[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_daily_states_roll_up_to_months[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_lambda_daily_states_roll_up_to_months[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_average_chooses_compatible_count_by_definition_not_name[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_average_chooses_compatible_count_by_definition_not_name[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_explicit_inner_join_declines_remote_domain_rollup[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_explicit_inner_join_declines_remote_domain_rollup[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_colliding_join_dimension_outputs_keep_raw_contract[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_colliding_join_dimension_outputs_keep_raw_contract[rust]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_rollup_preserves_local_and_role_source_population[python-local-first]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_rollup_preserves_local_and_role_source_population[python-role-owner]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_rollup_preserves_local_and_role_source_population[rust-local-first]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_rollup_preserves_local_and_role_source_population[rust-role-owner]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-python-build-exact]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-python-build-coarser-time]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-python-build-omitted-dimension]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-python-build-lambda]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-rust-build-exact]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-rust-build-coarser-time]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-rust-build-omitted-dimension]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[python-rust-build-lambda]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-python-build-exact]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-python-build-coarser-time]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-python-build-omitted-dimension]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-python-build-lambda]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-rust-build-exact]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-rust-build-coarser-time]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-rust-build-omitted-dimension]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_distinct_rollup_preserves_exact_grain_only[rust-rust-build-lambda]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_global_filtered_distinct_rollup_count_population[python-False]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_global_filtered_distinct_rollup_count_population[python-True]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_global_filtered_distinct_rollup_count_population[rust-False]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_global_filtered_distinct_rollup_count_population[rust-True]" + ] + }, + "scope-216": { + "path": "tests/semantic_conformance/test_rollup_reconstruction.py", + "declared_tests": [ + "test_postgres_rollup_reconstruction_executes" + ], + "collected_tests": [ + "tests/semantic_conformance/test_rollup_reconstruction.py::test_postgres_rollup_reconstruction_executes[direct]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_postgres_rollup_reconstruction_executes[join]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_postgres_rollup_reconstruction_executes[lambda]" + ] + }, + "scope-217": { + "path": "tests/semantic_conformance/test_rollup_reconstruction.py", + "declared_tests": [ + "test_colliding_join_dimension_outputs_keep_raw_contract" + ], + "collected_tests": [ + "tests/semantic_conformance/test_rollup_reconstruction.py::test_colliding_join_dimension_outputs_keep_raw_contract[python]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_colliding_join_dimension_outputs_keep_raw_contract[rust]" + ] + }, + "scope-218": { + "path": "tests/semantic_conformance/test_rollup_reconstruction.py", + "declared_tests": [ + "test_join_rollup_preserves_local_and_role_source_population" + ], + "collected_tests": [ + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_rollup_preserves_local_and_role_source_population[python-local-first]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_rollup_preserves_local_and_role_source_population[python-role-owner]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_rollup_preserves_local_and_role_source_population[rust-local-first]", + "tests/semantic_conformance/test_rollup_reconstruction.py::test_join_rollup_preserves_local_and_role_source_population[rust-role-owner]" + ] + }, + "scope-219": { + "path": "tests/semantic_conformance/test_rollup_routing.py", + "declared_tests": [ + "test_access_denied_before_rollup_access", + "test_bucket_rollup_cannot_restore_finer_timestamps", + "test_colliding_state_and_dimension_aliases_cannot_materialize_or_route", + "test_compatible_rollup_executes", + "test_declared_grain_applies_to_rollup_raw_time_dimension", + "test_empty_rollup_retains_zero_count", + "test_filtered_materialization_preserves_null_and_count_populations", + "test_incompatible_rollup_uses_raw_source", + "test_invariant_materialization_keeps_restricted_population", + "test_mandatory_restrictions_bypass_unscoped_rollup", + "test_relationship_foreign_key_dimension_declines_unrelated_rollup", + "test_week_rollup_cannot_serve_calendar_month" + ], + "collected_tests": [ + "tests/semantic_conformance/test_rollup_routing.py::test_compatible_rollup_executes[query0-rows0-python-build]", + "tests/semantic_conformance/test_rollup_routing.py::test_compatible_rollup_executes[query0-rows0-rust-build]", + "tests/semantic_conformance/test_rollup_routing.py::test_compatible_rollup_executes[query1-rows1-python-build]", + "tests/semantic_conformance/test_rollup_routing.py::test_compatible_rollup_executes[query1-rows1-rust-build]", + "tests/semantic_conformance/test_rollup_routing.py::test_compatible_rollup_executes[query2-rows2-python-build]", + "tests/semantic_conformance/test_rollup_routing.py::test_compatible_rollup_executes[query2-rows2-rust-build]", + "tests/semantic_conformance/test_rollup_routing.py::test_compatible_rollup_executes[query3-rows3-python-build]", + "tests/semantic_conformance/test_rollup_routing.py::test_compatible_rollup_executes[query3-rows3-rust-build]", + "tests/semantic_conformance/test_rollup_routing.py::test_incompatible_rollup_uses_raw_source[query0-rows0]", + "tests/semantic_conformance/test_rollup_routing.py::test_incompatible_rollup_uses_raw_source[query1-rows1]", + "tests/semantic_conformance/test_rollup_routing.py::test_incompatible_rollup_uses_raw_source[query2-rows2]", + "tests/semantic_conformance/test_rollup_routing.py::test_incompatible_rollup_uses_raw_source[query3-rows3]", + "tests/semantic_conformance/test_rollup_routing.py::test_incompatible_rollup_uses_raw_source[query4-rows4]", + "tests/semantic_conformance/test_rollup_routing.py::test_incompatible_rollup_uses_raw_source[query5-rows5]", + "tests/semantic_conformance/test_rollup_routing.py::test_incompatible_rollup_uses_raw_source[query6-rows6]", + "tests/semantic_conformance/test_rollup_routing.py::test_incompatible_rollup_uses_raw_source[query7-rows7]", + "tests/semantic_conformance/test_rollup_routing.py::test_relationship_foreign_key_dimension_declines_unrelated_rollup", + "tests/semantic_conformance/test_rollup_routing.py::test_mandatory_restrictions_bypass_unscoped_rollup[invariant]", + "tests/semantic_conformance/test_rollup_routing.py::test_mandatory_restrictions_bypass_unscoped_rollup[policy]", + "tests/semantic_conformance/test_rollup_routing.py::test_mandatory_restrictions_bypass_unscoped_rollup[both]", + "tests/semantic_conformance/test_rollup_routing.py::test_invariant_materialization_keeps_restricted_population", + "tests/semantic_conformance/test_rollup_routing.py::test_access_denied_before_rollup_access[policy0-attributes0]", + "tests/semantic_conformance/test_rollup_routing.py::test_access_denied_before_rollup_access[policy1-None]", + "tests/semantic_conformance/test_rollup_routing.py::test_filtered_materialization_preserves_null_and_count_populations", + "tests/semantic_conformance/test_rollup_routing.py::test_bucket_rollup_cannot_restore_finer_timestamps[orders.created]", + "tests/semantic_conformance/test_rollup_routing.py::test_bucket_rollup_cannot_restore_finer_timestamps[orders.created__hour]", + "tests/semantic_conformance/test_rollup_routing.py::test_week_rollup_cannot_serve_calendar_month", + "tests/semantic_conformance/test_rollup_routing.py::test_empty_rollup_retains_zero_count", + "tests/semantic_conformance/test_rollup_routing.py::test_declared_grain_applies_to_rollup_raw_time_dimension", + "tests/semantic_conformance/test_rollup_routing.py::test_colliding_state_and_dimension_aliases_cannot_materialize_or_route[False]", + "tests/semantic_conformance/test_rollup_routing.py::test_colliding_state_and_dimension_aliases_cannot_materialize_or_route[True]" + ] + }, + "scope-220": { + "path": "tests/semantic_conformance/test_selected_table_calculations.py", + "declared_tests": [ + "test_all_calculations_match_independent_processor", + "test_bounded_formula_contract", + "test_calculations_use_only_authorized_population", + "test_helper_names_do_not_shadow_physical_tables", + "test_invalid_selections_fail_before_execution", + "test_postgres_calculation_results_match_processor", + "test_postprocess_keeps_paginated_calculations", + "test_sequential_calculations_order_by_custom_output_aliases" + ], + "collected_tests": [ + "tests/semantic_conformance/test_selected_table_calculations.py::test_all_calculations_match_independent_processor[python-population0]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_all_calculations_match_independent_processor[python-population1]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_all_calculations_match_independent_processor[python-population2]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_all_calculations_match_independent_processor[python-population3]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_all_calculations_match_independent_processor[python-population4]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_all_calculations_match_independent_processor[rust-population0]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_all_calculations_match_independent_processor[rust-population1]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_all_calculations_match_independent_processor[rust-population2]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_all_calculations_match_independent_processor[rust-population3]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_all_calculations_match_independent_processor[rust-population4]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postprocess_keeps_paginated_calculations[python]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postprocess_keeps_paginated_calculations[rust]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_sequential_calculations_order_by_custom_output_aliases[python-True-gross]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_sequential_calculations_order_by_custom_output_aliases[python-True-Gross Revenue]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_sequential_calculations_order_by_custom_output_aliases[python-False-gross]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_sequential_calculations_order_by_custom_output_aliases[python-False-Gross Revenue]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_sequential_calculations_order_by_custom_output_aliases[rust-True-gross]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_sequential_calculations_order_by_custom_output_aliases[rust-True-Gross Revenue]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_sequential_calculations_order_by_custom_output_aliases[rust-False-gross]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_sequential_calculations_order_by_custom_output_aliases[rust-False-Gross Revenue]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[python-missing]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[python-later]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[python-duplicate]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[python-collision]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[python-no_order]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[python-partition]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[python-order]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[python-window]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[python-percentile]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[python-formula]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[python-synthetic_ref]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[python-infinite]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[rust-missing]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[rust-later]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[rust-duplicate]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[rust-collision]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[rust-no_order]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[rust-partition]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[rust-order]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[rust-window]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[rust-percentile]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[rust-formula]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[rust-synthetic_ref]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_invalid_selections_fail_before_execution[rust-infinite]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_helper_names_do_not_shadow_physical_tables[python]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_helper_names_do_not_shadow_physical_tables[rust]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[python-population0]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[python-population1]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[python-population2]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[python-population3]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[rust-population0]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[rust-population1]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[rust-population2]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[rust-population3]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_bounded_formula_contract[python-((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((1))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_bounded_formula_contract[python-----------------------------------------------------------------1]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_bounded_formula_contract[python-1e309]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_bounded_formula_contract[python-01]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_bounded_formula_contract[python-${value} % 2]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_bounded_formula_contract[rust-((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((1))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_bounded_formula_contract[rust-----------------------------------------------------------------1]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_bounded_formula_contract[rust-1e309]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_bounded_formula_contract[rust-01]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_bounded_formula_contract[rust-${value} % 2]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_calculations_use_only_authorized_population[python]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_calculations_use_only_authorized_population[rust]" + ] + }, + "scope-221": { + "path": "tests/semantic_conformance/test_selected_table_calculations.py", + "declared_tests": [ + "test_canonical_validation_checks_active_calculations" + ], + "collected_tests": [ + "tests/semantic_conformance/test_selected_table_calculations.py::test_canonical_validation_checks_active_calculations[None]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_canonical_validation_checks_active_calculations[unknown]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_canonical_validation_checks_active_calculations[dependency]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_canonical_validation_checks_active_calculations[formula]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_canonical_validation_checks_active_calculations[unknown_option]" + ] + }, + "scope-222": { + "path": "tests/semantic_conformance/test_selected_table_calculations.py", + "declared_tests": [ + "test_postgres_calculation_results_match_processor" + ], + "collected_tests": [ + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[python-population0]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[python-population1]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[python-population2]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[python-population3]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[rust-population0]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[rust-population1]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[rust-population2]", + "tests/semantic_conformance/test_selected_table_calculations.py::test_postgres_calculation_results_match_processor[rust-population3]" + ] + }, + "scope-223": { + "path": "tests/semantic_conformance/test_semantic_sql_binding.py", + "declared_tests": [ + "test_ad_hoc_aggregate_inputs_are_physical_and_do_not_mutate_model", + "test_explicit_relationship_join_retains_row_existence", + "test_expression_dependencies_do_not_escape_requested_projection", + "test_filter_cte_scope_preserves_nested_qualifiers_and_literal_text", + "test_joined_scalar_measures_keep_independent_populations", + "test_scalar_functions_bind_measure_outputs_before_arithmetic", + "test_scalar_graph_metric_keeps_independent_populations", + "test_semantic_query_in_join_source_is_compiled_without_binding_outer_columns", + "test_set_operations_compile_both_semantic_operands" + ], + "collected_tests": [ + "tests/semantic_conformance/test_semantic_sql_binding.py::test_scalar_functions_bind_measure_outputs_before_arithmetic[python]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_scalar_functions_bind_measure_outputs_before_arithmetic[rust]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_ad_hoc_aggregate_inputs_are_physical_and_do_not_mutate_model[python]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_ad_hoc_aggregate_inputs_are_physical_and_do_not_mutate_model[rust]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_scalar_graph_metric_keeps_independent_populations[python]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_scalar_graph_metric_keeps_independent_populations[rust]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_joined_scalar_measures_keep_independent_populations[python]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_joined_scalar_measures_keep_independent_populations[rust]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_explicit_relationship_join_retains_row_existence[python-join-450]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_explicit_relationship_join_retains_row_existence[python-left join-500]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_explicit_relationship_join_retains_row_existence[rust-join-450]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_explicit_relationship_join_retains_row_existence[rust-left join-500]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_filter_cte_scope_preserves_nested_qualifiers_and_literal_text[python]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_filter_cte_scope_preserves_nested_qualifiers_and_literal_text[rust]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_set_operations_compile_both_semantic_operands[python-union all-expected0]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_set_operations_compile_both_semantic_operands[python-intersect-expected1]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_set_operations_compile_both_semantic_operands[python-except-expected2]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_set_operations_compile_both_semantic_operands[rust-union all-expected0]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_set_operations_compile_both_semantic_operands[rust-intersect-expected1]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_set_operations_compile_both_semantic_operands[rust-except-expected2]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_semantic_query_in_join_source_is_compiled_without_binding_outer_columns[python]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_semantic_query_in_join_source_is_compiled_without_binding_outer_columns[rust]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_expression_dependencies_do_not_escape_requested_projection[python]", + "tests/semantic_conformance/test_semantic_sql_binding.py::test_expression_dependencies_do_not_escape_requested_projection[rust]" + ] + }, + "scope-224": { + "path": "tests/semantic_conformance/test_sibling_fanout_parity.py", + "declared_tests": [ + "test_empty_sibling_population_has_no_groups", + "test_minimized_generated_sibling_fanout", + "test_sibling_groups_preserve_each_item_and_null_population", + "test_source_identity_survives_three_edge_fanout_path" + ], + "collected_tests": [ + "tests/semantic_conformance/test_sibling_fanout_parity.py::test_minimized_generated_sibling_fanout[python]", + "tests/semantic_conformance/test_sibling_fanout_parity.py::test_minimized_generated_sibling_fanout[rust]", + "tests/semantic_conformance/test_sibling_fanout_parity.py::test_sibling_groups_preserve_each_item_and_null_population[python-False]", + "tests/semantic_conformance/test_sibling_fanout_parity.py::test_sibling_groups_preserve_each_item_and_null_population[python-True]", + "tests/semantic_conformance/test_sibling_fanout_parity.py::test_sibling_groups_preserve_each_item_and_null_population[rust-False]", + "tests/semantic_conformance/test_sibling_fanout_parity.py::test_sibling_groups_preserve_each_item_and_null_population[rust-True]", + "tests/semantic_conformance/test_sibling_fanout_parity.py::test_empty_sibling_population_has_no_groups[python]", + "tests/semantic_conformance/test_sibling_fanout_parity.py::test_empty_sibling_population_has_no_groups[rust]", + "tests/semantic_conformance/test_sibling_fanout_parity.py::test_source_identity_survives_three_edge_fanout_path[python]", + "tests/semantic_conformance/test_sibling_fanout_parity.py::test_source_identity_survives_three_edge_fanout_path[rust]" + ] + }, + "scope-225": { + "path": "tests/semantic_conformance/test_snapshot_parity.py", + "declared_tests": [ + "test_coarse_time_uses_snapshot_within_each_month", + "test_declared_grouping_keeps_latest_account_when_region_changes", + "test_declared_groups_roll_up_into_selected_region", + "test_declared_snapshot_groups_do_not_become_global_latest_date", + "test_equal_latest_dates_keep_all_tied_rows", + "test_explicit_unsafe_snapshot_option_preserves_all_authorized_rows", + "test_filled_snapshot_calculated_wrapper_uses_final_aggregate_default", + "test_intraday_snapshot_uses_declared_dimension_grain", + "test_metric_filter_does_not_pick_an_earlier_eligible_snapshot", + "test_null_grouping_key_is_one_snapshot_partition", + "test_opening_closing_and_additive_sibling_keep_separate_populations", + "test_policy_changes_snapshot_candidates_before_window", + "test_raw_time_grouping_bypasses_snapshot_mask_including_null_time", + "test_row_filter_changes_snapshot_candidates_before_window", + "test_simple_model_snapshot_is_not_silently_summed", + "test_snapshot_and_additive_sibling_keep_distinct_final_defaults", + "test_snapshot_count_and_distinct_count_mask_rows_not_entities", + "test_snapshot_default_fills_final_aggregate_not_selected_null_inputs", + "test_snapshot_default_handles_empty_totals_without_creating_groups", + "test_snapshot_groups_preserve_all_null_time_and_latest_null_value", + "test_snapshot_order_preserves_explicit_null_placement", + "test_snapshot_policy_requires_context", + "test_snapshot_source_coalesce_is_distinct_from_final_count_default" + ], + "collected_tests": [ + "tests/semantic_conformance/test_snapshot_parity.py::test_opening_closing_and_additive_sibling_keep_separate_populations[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_opening_closing_and_additive_sibling_keep_separate_populations[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_simple_model_snapshot_is_not_silently_summed[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_simple_model_snapshot_is_not_silently_summed[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_explicit_unsafe_snapshot_option_preserves_all_authorized_rows[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_explicit_unsafe_snapshot_option_preserves_all_authorized_rows[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_declared_snapshot_groups_do_not_become_global_latest_date[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_declared_snapshot_groups_do_not_become_global_latest_date[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_groups_preserve_all_null_time_and_latest_null_value[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_groups_preserve_all_null_time_and_latest_null_value[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_order_preserves_explicit_null_placement[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_order_preserves_explicit_null_placement[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_declared_groups_roll_up_into_selected_region[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_declared_groups_roll_up_into_selected_region[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_declared_grouping_keeps_latest_account_when_region_changes[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_declared_grouping_keeps_latest_account_when_region_changes[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_equal_latest_dates_keep_all_tied_rows[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_equal_latest_dates_keep_all_tied_rows[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_null_grouping_key_is_one_snapshot_partition[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_null_grouping_key_is_one_snapshot_partition[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_coarse_time_uses_snapshot_within_each_month[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_coarse_time_uses_snapshot_within_each_month[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_raw_time_grouping_bypasses_snapshot_mask_including_null_time[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_raw_time_grouping_bypasses_snapshot_mask_including_null_time[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_row_filter_changes_snapshot_candidates_before_window[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_row_filter_changes_snapshot_candidates_before_window[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_metric_filter_does_not_pick_an_earlier_eligible_snapshot[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_metric_filter_does_not_pick_an_earlier_eligible_snapshot[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_policy_changes_snapshot_candidates_before_window[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_policy_changes_snapshot_candidates_before_window[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_policy_requires_context[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_policy_requires_context[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_intraday_snapshot_uses_declared_dimension_grain[python-day-430]", + "tests/semantic_conformance/test_snapshot_parity.py::test_intraday_snapshot_uses_declared_dimension_grain[python-None-260]", + "tests/semantic_conformance/test_snapshot_parity.py::test_intraday_snapshot_uses_declared_dimension_grain[rust-day-430]", + "tests/semantic_conformance/test_snapshot_parity.py::test_intraday_snapshot_uses_declared_dimension_grain[rust-None-260]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_count_and_distinct_count_mask_rows_not_entities[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_count_and_distinct_count_mask_rows_not_entities[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_default_fills_final_aggregate_not_selected_null_inputs[python-sum-expected0]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_default_fills_final_aggregate_not_selected_null_inputs[python-avg-expected1]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_default_fills_final_aggregate_not_selected_null_inputs[python-count-expected2]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_default_fills_final_aggregate_not_selected_null_inputs[rust-sum-expected0]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_default_fills_final_aggregate_not_selected_null_inputs[rust-avg-expected1]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_default_fills_final_aggregate_not_selected_null_inputs[rust-count-expected2]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_default_handles_empty_totals_without_creating_groups[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_default_handles_empty_totals_without_creating_groups[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_filled_snapshot_calculated_wrapper_uses_final_aggregate_default[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_filled_snapshot_calculated_wrapper_uses_final_aggregate_default[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_and_additive_sibling_keep_distinct_final_defaults[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_and_additive_sibling_keep_distinct_final_defaults[rust]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_source_coalesce_is_distinct_from_final_count_default[python]", + "tests/semantic_conformance/test_snapshot_parity.py::test_snapshot_source_coalesce_is_distinct_from_final_count_default[rust]" + ] + }, + "scope-226": { + "path": "tests/semantic_conformance/test_snowflake_dates.py", + "declared_tests": [ + "test_snowflake_date_differences" + ], + "collected_tests": [ + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[rewrite-DATEDIFF(day, DATE '2024-02-28', DATE '2024-03-01')-2]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[rewrite-DATEDIFF('DD', DATE '2024-03-01', DATE '2024-02-28')--2]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[rewrite-DATEDIFF(day, TIMESTAMP '2024-01-01 23:59:59', TIMESTAMP '2024-01-02 00:00:00')-1]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[rewrite-DATEDIFF(day, TIMESTAMP '2024-01-02 00:00:00', TIMESTAMP '2024-01-01 23:59:59')--1]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[rewrite-DATEDIFF(month, DATE '2024-01-31', DATE '2024-02-01')-1]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[rewrite-DATEDIFF('MM', DATE '2024-02-01', DATE '2024-01-31')--1]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[rewrite-DATEDIFF(month, DATE '2024-01-01', DATE '2024-01-31')-0]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[rewrite-DATEDIFF(week, DATE '2024-01-07', DATE '2024-01-08')-1]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[rewrite-DATEDIFF('WK', DATE '2024-01-08', DATE '2024-01-07')--1]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[rewrite-DATEDIFF(week, DATE '2024-01-01', DATE '2024-01-07')-0]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[rewrite-DATEDIFF(week, DATE '2023-12-31', DATE '2024-01-01')-1]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[rewrite-COALESCE(DATEDIFF(day, NULL, DATE '2024-01-01'), 42)-42]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[compile-DATEDIFF(day, DATE '2024-02-28', DATE '2024-03-01')-2]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[compile-DATEDIFF('DD', DATE '2024-03-01', DATE '2024-02-28')--2]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[compile-DATEDIFF(day, TIMESTAMP '2024-01-01 23:59:59', TIMESTAMP '2024-01-02 00:00:00')-1]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[compile-DATEDIFF(day, TIMESTAMP '2024-01-02 00:00:00', TIMESTAMP '2024-01-01 23:59:59')--1]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[compile-DATEDIFF(month, DATE '2024-01-31', DATE '2024-02-01')-1]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[compile-DATEDIFF('MM', DATE '2024-02-01', DATE '2024-01-31')--1]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[compile-DATEDIFF(month, DATE '2024-01-01', DATE '2024-01-31')-0]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[compile-DATEDIFF(week, DATE '2024-01-07', DATE '2024-01-08')-1]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[compile-DATEDIFF('WK', DATE '2024-01-08', DATE '2024-01-07')--1]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[compile-DATEDIFF(week, DATE '2024-01-01', DATE '2024-01-07')-0]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[compile-DATEDIFF(week, DATE '2023-12-31', DATE '2024-01-01')-1]", + "tests/semantic_conformance/test_snowflake_dates.py::test_snowflake_date_differences[compile-COALESCE(DATEDIFF(day, NULL, DATE '2024-01-01'), 42)-42]" + ] + }, + "scope-227": { + "path": "tests/semantic_conformance/test_source_null_ordering.py", + "declared_tests": [ + "test_multi_source_ordering_renders_target_dialect", + "test_source_ordering_matches_independent_rows" + ], + "collected_tests": [ + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False--dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False--dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False--dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False--metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False--metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False--metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- ASC-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- ASC-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- ASC-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- ASC-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- ASC-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- ASC-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- DESC-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- DESC-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- DESC-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- DESC-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- DESC-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- DESC-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- ASC NULLS LAST-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- ASC NULLS LAST-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- ASC NULLS LAST-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- ASC NULLS LAST-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- ASC NULLS LAST-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- ASC NULLS LAST-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- DESC NULLS FIRST-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- DESC NULLS FIRST-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- DESC NULLS FIRST-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- DESC NULLS FIRST-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- DESC NULLS FIRST-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-False- DESC NULLS FIRST-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True--dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True--dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True--dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True--metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True--metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True--metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- ASC-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- ASC-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- ASC-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- ASC-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- ASC-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- ASC-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- DESC-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- DESC-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- DESC-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- DESC-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- DESC-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- DESC-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- ASC NULLS LAST-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- ASC NULLS LAST-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- ASC NULLS LAST-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- ASC NULLS LAST-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- ASC NULLS LAST-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- ASC NULLS LAST-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- DESC NULLS FIRST-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- DESC NULLS FIRST-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- DESC NULLS FIRST-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- DESC NULLS FIRST-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- DESC NULLS FIRST-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[python-True- DESC NULLS FIRST-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False--dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False--dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False--dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False--metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False--metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False--metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- ASC-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- ASC-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- ASC-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- ASC-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- ASC-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- ASC-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- DESC-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- DESC-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- DESC-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- DESC-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- DESC-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- DESC-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- ASC NULLS LAST-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- ASC NULLS LAST-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- ASC NULLS LAST-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- ASC NULLS LAST-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- ASC NULLS LAST-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- ASC NULLS LAST-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- DESC NULLS FIRST-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- DESC NULLS FIRST-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- DESC NULLS FIRST-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- DESC NULLS FIRST-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- DESC NULLS FIRST-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-False- DESC NULLS FIRST-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True--dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True--dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True--dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True--metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True--metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True--metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- ASC-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- ASC-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- ASC-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- ASC-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- ASC-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- ASC-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- DESC-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- DESC-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- DESC-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- DESC-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- DESC-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- DESC-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- ASC NULLS LAST-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- ASC NULLS LAST-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- ASC NULLS LAST-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- ASC NULLS LAST-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- ASC NULLS LAST-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- ASC NULLS LAST-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- DESC NULLS FIRST-dimension-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- DESC NULLS FIRST-dimension-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- DESC NULLS FIRST-dimension-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- DESC NULLS FIRST-metric-ordinary]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- DESC NULLS FIRST-metric-fanout]", + "tests/semantic_conformance/test_source_null_ordering.py::test_source_ordering_matches_independent_rows[rust-True- DESC NULLS FIRST-metric-multi_source]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[python- ASC-tsql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[python- ASC-mysql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[python- DESC-tsql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[python- DESC-mysql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[python- ASC NULLS LAST-tsql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[python- ASC NULLS LAST-mysql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[python- DESC NULLS FIRST-tsql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[python- DESC NULLS FIRST-mysql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[rust- ASC-tsql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[rust- ASC-mysql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[rust- DESC-tsql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[rust- DESC-mysql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[rust- ASC NULLS LAST-tsql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[rust- ASC NULLS LAST-mysql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[rust- DESC NULLS FIRST-tsql]", + "tests/semantic_conformance/test_source_null_ordering.py::test_multi_source_ordering_renders_target_dialect[rust- DESC NULLS FIRST-mysql]" + ] + }, + "scope-228": { + "path": "tests/semantic_conformance/test_source_null_ordering.py", + "declared_tests": [ + "test_minimized_nullable_fanout_case" + ], + "collected_tests": [ + "tests/semantic_conformance/test_source_null_ordering.py::test_minimized_nullable_fanout_case" + ] + }, + "scope-229": { + "path": "tests/semantic_conformance/test_special_population.py", + "declared_tests": [ + "test_cumulative_computed_population_excludes_orphans_and_hidden_rows", + "test_independent_computed_populations_include_empty_anchor", + "test_query_row_filter_restricts_every_independent_leaf", + "test_snapshot_computed_population_and_null_unmatched_group", + "test_special_routes_evaluate_computed_keys_instead_of_shadow_columns" + ], + "collected_tests": [ + "tests/semantic_conformance/test_special_population.py::test_independent_computed_populations_include_empty_anchor[python]", + "tests/semantic_conformance/test_special_population.py::test_independent_computed_populations_include_empty_anchor[rust]", + "tests/semantic_conformance/test_special_population.py::test_query_row_filter_restricts_every_independent_leaf[python]", + "tests/semantic_conformance/test_special_population.py::test_query_row_filter_restricts_every_independent_leaf[rust]", + "tests/semantic_conformance/test_special_population.py::test_cumulative_computed_population_excludes_orphans_and_hidden_rows[python]", + "tests/semantic_conformance/test_special_population.py::test_cumulative_computed_population_excludes_orphans_and_hidden_rows[rust]", + "tests/semantic_conformance/test_special_population.py::test_snapshot_computed_population_and_null_unmatched_group[python]", + "tests/semantic_conformance/test_special_population.py::test_snapshot_computed_population_and_null_unmatched_group[rust]", + "tests/semantic_conformance/test_special_population.py::test_special_routes_evaluate_computed_keys_instead_of_shadow_columns[rust]" + ] + }, + "scope-230": { + "path": "tests/semantic_conformance/test_temporal_dialect_fallback.py", + "declared_tests": [ + "test_calendar_capable_dialects_preserve_exact_period_lookup", + "test_comparison_falls_back_to_named_period_row_count", + "test_ratio_lag_scales_offset_to_result_grain", + "test_ungranulated_ratio_uses_row_fallback" + ], + "collected_tests": [ + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-month-2 months-2-bigquery]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-month-2 months-2-snowflake]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-month-2 months-2-trino]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-month-75 days-2-bigquery]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-month-75 days-2-snowflake]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-month-75 days-2-trino]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-month-105 days-4-bigquery]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-month-105 days-4-snowflake]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-month-105 days-4-trino]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-None-2 months-2-bigquery]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-None-2 months-2-snowflake]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-None-2 months-2-trino]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-quarter-1 year-4-bigquery]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-quarter-1 year-4-snowflake]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[python-quarter-1 year-4-trino]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-month-2 months-2-bigquery]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-month-2 months-2-snowflake]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-month-2 months-2-trino]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-month-75 days-2-bigquery]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-month-75 days-2-snowflake]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-month-75 days-2-trino]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-month-105 days-4-bigquery]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-month-105 days-4-snowflake]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-month-105 days-4-trino]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-None-2 months-2-bigquery]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-None-2 months-2-snowflake]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-None-2 months-2-trino]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-quarter-1 year-4-bigquery]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-quarter-1 year-4-snowflake]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ratio_lag_scales_offset_to_result_grain[rust-quarter-1 year-4-trino]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ungranulated_ratio_uses_row_fallback[python-duckdb]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ungranulated_ratio_uses_row_fallback[python-postgres]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ungranulated_ratio_uses_row_fallback[rust-duckdb]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_ungranulated_ratio_uses_row_fallback[rust-postgres]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_comparison_falls_back_to_named_period_row_count[python-bigquery]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_comparison_falls_back_to_named_period_row_count[python-snowflake]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_comparison_falls_back_to_named_period_row_count[python-trino]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_comparison_falls_back_to_named_period_row_count[rust-bigquery]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_comparison_falls_back_to_named_period_row_count[rust-snowflake]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_comparison_falls_back_to_named_period_row_count[rust-trino]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_calendar_capable_dialects_preserve_exact_period_lookup[python-duckdb]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_calendar_capable_dialects_preserve_exact_period_lookup[python-postgres]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_calendar_capable_dialects_preserve_exact_period_lookup[rust-duckdb]", + "tests/semantic_conformance/test_temporal_dialect_fallback.py::test_calendar_capable_dialects_preserve_exact_period_lookup[rust-postgres]" + ] + }, + "scope-231": { + "path": "tests/semantic_conformance/test_temporal_null_fill.py", + "declared_tests": [ + "test_base_fill_and_temporal_fill_are_separate", + "test_comparison_fill_keeps_python_precedence_for_cumulative_controls", + "test_cumulative_explicit_order_and_post_window_pagination", + "test_cumulative_fill_keeps_python_precedence_for_unused_offsets", + "test_cumulative_final_default_keeps_null_base_and_partitions", + "test_cumulative_string_default_is_a_literal", + "test_explicit_comparison_offset_keeps_sparse_calendar_lookup", + "test_filters_and_policy_do_not_create_empty_period_groups", + "test_missing_prior_and_zero_denominator_fill_after_calculation", + "test_mixed_temporal_outputs_retain_filled_cumulative_in_lag_cte", + "test_offset_ratio_default_applies_after_sparse_prior_division" + ], + "collected_tests": [ + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_final_default_keeps_null_base_and_partitions[python-controls0-expected0]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_final_default_keeps_null_base_and_partitions[python-controls1-expected1]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_final_default_keeps_null_base_and_partitions[python-controls2-expected2]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_final_default_keeps_null_base_and_partitions[python-controls3-expected3]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_final_default_keeps_null_base_and_partitions[python-controls4-expected4]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_final_default_keeps_null_base_and_partitions[rust-controls0-expected0]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_final_default_keeps_null_base_and_partitions[rust-controls1-expected1]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_final_default_keeps_null_base_and_partitions[rust-controls2-expected2]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_final_default_keeps_null_base_and_partitions[rust-controls3-expected3]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_final_default_keeps_null_base_and_partitions[rust-controls4-expected4]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_missing_prior_and_zero_denominator_fill_after_calculation[python-difference-expected0]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_missing_prior_and_zero_denominator_fill_after_calculation[python-ratio-expected1]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_missing_prior_and_zero_denominator_fill_after_calculation[python-percent_change-expected2]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_missing_prior_and_zero_denominator_fill_after_calculation[rust-difference-expected0]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_missing_prior_and_zero_denominator_fill_after_calculation[rust-ratio-expected1]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_missing_prior_and_zero_denominator_fill_after_calculation[rust-percent_change-expected2]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_base_fill_and_temporal_fill_are_separate[python]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_base_fill_and_temporal_fill_are_separate[rust]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_filters_and_policy_do_not_create_empty_period_groups[python-cumulative]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_filters_and_policy_do_not_create_empty_period_groups[python-time_comparison]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_filters_and_policy_do_not_create_empty_period_groups[rust-cumulative]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_filters_and_policy_do_not_create_empty_period_groups[rust-time_comparison]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_explicit_order_and_post_window_pagination[python]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_explicit_order_and_post_window_pagination[rust]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_string_default_is_a_literal[python]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_string_default_is_a_literal[rust]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_explicit_comparison_offset_keeps_sparse_calendar_lookup[python]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_explicit_comparison_offset_keeps_sparse_calendar_lookup[rust]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_mixed_temporal_outputs_retain_filled_cumulative_in_lag_cte[python]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_mixed_temporal_outputs_retain_filled_cumulative_in_lag_cte[rust]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_offset_ratio_default_applies_after_sparse_prior_division[python-1 day-expected0]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_offset_ratio_default_applies_after_sparse_prior_division[python-2 days-expected1]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_offset_ratio_default_applies_after_sparse_prior_division[rust-1 day-expected0]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_offset_ratio_default_applies_after_sparse_prior_division[rust-2 days-expected1]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_fill_keeps_python_precedence_for_unused_offsets[python-controls0]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_fill_keeps_python_precedence_for_unused_offsets[python-controls1]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_fill_keeps_python_precedence_for_unused_offsets[rust-controls0]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_fill_keeps_python_precedence_for_unused_offsets[rust-controls1]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_comparison_fill_keeps_python_precedence_for_cumulative_controls[python-controls0]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_comparison_fill_keeps_python_precedence_for_cumulative_controls[python-controls1]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_comparison_fill_keeps_python_precedence_for_cumulative_controls[rust-controls0]", + "tests/semantic_conformance/test_temporal_null_fill.py::test_comparison_fill_keeps_python_precedence_for_cumulative_controls[rust-controls1]" + ] + }, + "scope-232": { + "path": "tests/semantic_conformance/test_time_key_projection.py", + "declared_tests": [ + "test_numeric_computed_identity_keeps_unbucketed_projection", + "test_time_identity_projection_uses_requested_or_default_grain", + "test_time_identity_stays_unbucketed_for_join_and_fanout" + ], + "collected_tests": [ + "tests/semantic_conformance/test_time_key_projection.py::test_time_identity_projection_uses_requested_or_default_grain[python-None-events.event_time]", + "tests/semantic_conformance/test_time_key_projection.py::test_time_identity_projection_uses_requested_or_default_grain[python-None-events.event_time__day]", + "tests/semantic_conformance/test_time_key_projection.py::test_time_identity_projection_uses_requested_or_default_grain[python-America/Los_Angeles-events.event_time]", + "tests/semantic_conformance/test_time_key_projection.py::test_time_identity_projection_uses_requested_or_default_grain[python-America/Los_Angeles-events.event_time__day]", + "tests/semantic_conformance/test_time_key_projection.py::test_time_identity_projection_uses_requested_or_default_grain[rust-None-events.event_time]", + "tests/semantic_conformance/test_time_key_projection.py::test_time_identity_projection_uses_requested_or_default_grain[rust-None-events.event_time__day]", + "tests/semantic_conformance/test_time_key_projection.py::test_time_identity_projection_uses_requested_or_default_grain[rust-America/Los_Angeles-events.event_time]", + "tests/semantic_conformance/test_time_key_projection.py::test_time_identity_projection_uses_requested_or_default_grain[rust-America/Los_Angeles-events.event_time__day]", + "tests/semantic_conformance/test_time_key_projection.py::test_numeric_computed_identity_keeps_unbucketed_projection[python]", + "tests/semantic_conformance/test_time_key_projection.py::test_numeric_computed_identity_keeps_unbucketed_projection[rust]", + "tests/semantic_conformance/test_time_key_projection.py::test_time_identity_stays_unbucketed_for_join_and_fanout[python]", + "tests/semantic_conformance/test_time_key_projection.py::test_time_identity_stays_unbucketed_for_join_and_fanout[rust]" + ] + }, + "scope-233": { + "path": "tests/semantic_conformance/test_time_key_projection.py", + "declared_tests": [ + "test_time_identity_stays_unbucketed_for_join_and_fanout" + ], + "collected_tests": [ + "tests/semantic_conformance/test_time_key_projection.py::test_time_identity_stays_unbucketed_for_join_and_fanout[python]", + "tests/semantic_conformance/test_time_key_projection.py::test_time_identity_stays_unbucketed_for_join_and_fanout[rust]" + ] + }, + "scope-234": { + "path": "tests/semantic_conformance/test_window_output_parity.py", + "declared_tests": [ + "test_aggregate_reference_honors_explicit_range_frame", + "test_aggregate_reference_rejects_conflicting_frame_controls", + "test_aggregate_reference_rejects_invalid_frame", + "test_cumulative_count_counts_nonnull_period_values", + "test_distinct_period_counts_are_summed_not_combined_row_distincts", + "test_explicit_metric_output_order_overrides_chronological_order", + "test_expression_alias_is_a_period_metric_and_not_a_physical_column", + "test_following_and_excluded_window_frames", + "test_graph_calculation_keeps_its_identity_beside_cumulative_metric", + "test_graph_window_infers_unique_period_metric_owner", + "test_graph_window_rejects_missing_or_ambiguous_period_metric", + "test_invalid_window_frame_rejected_before_execution", + "test_invalid_window_order_rejected_before_execution", + "test_period_frames_preserve_sparse_boundaries_null_values_and_partitions", + "test_promoted_functions_consume_period_values", + "test_query_filter_and_policy_apply_before_window", + "test_quoted_output_expression_is_generated_for_bigquery", + "test_scalar_window_expression_is_typed_unsupported", + "test_window_dependency_cycles_return_validation_errors", + "test_window_dimension_replaces_same_named_source_for_grouping_and_filters", + "test_window_expression_arithmetic_filter_and_null_arguments", + "test_window_expression_binds_multiple_grouped_dependencies", + "test_window_expression_preserves_python_precedence", + "test_window_order_rejects_multiple_selected_grains", + "test_window_order_resolves_the_selected_dimension_grain" + ], + "collected_tests": [ + "tests/semantic_conformance/test_window_output_parity.py::test_window_dimension_replaces_same_named_source_for_grouping_and_filters[python]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_dimension_replaces_same_named_source_for_grouping_and_filters[rust]", + "tests/semantic_conformance/test_window_output_parity.py::test_graph_calculation_keeps_its_identity_beside_cumulative_metric[python]", + "tests/semantic_conformance/test_window_output_parity.py::test_graph_calculation_keeps_its_identity_beside_cumulative_metric[rust]", + "tests/semantic_conformance/test_window_output_parity.py::test_period_frames_preserve_sparse_boundaries_null_values_and_partitions[python-None-expected0]", + "tests/semantic_conformance/test_window_output_parity.py::test_period_frames_preserve_sparse_boundaries_null_values_and_partitions[python-ROWS BETWEEN 1 PRECEDING AND CURRENT ROW-expected1]", + "tests/semantic_conformance/test_window_output_parity.py::test_period_frames_preserve_sparse_boundaries_null_values_and_partitions[python-RANGE BETWEEN INTERVAL 1 DAY PRECEDING AND CURRENT ROW-expected2]", + "tests/semantic_conformance/test_window_output_parity.py::test_period_frames_preserve_sparse_boundaries_null_values_and_partitions[python-RANGE BETWEEN INTERVAL '2 day' PRECEDING AND CURRENT ROW-expected3]", + "tests/semantic_conformance/test_window_output_parity.py::test_period_frames_preserve_sparse_boundaries_null_values_and_partitions[rust-None-expected0]", + "tests/semantic_conformance/test_window_output_parity.py::test_period_frames_preserve_sparse_boundaries_null_values_and_partitions[rust-ROWS BETWEEN 1 PRECEDING AND CURRENT ROW-expected1]", + "tests/semantic_conformance/test_window_output_parity.py::test_period_frames_preserve_sparse_boundaries_null_values_and_partitions[rust-RANGE BETWEEN INTERVAL 1 DAY PRECEDING AND CURRENT ROW-expected2]", + "tests/semantic_conformance/test_window_output_parity.py::test_period_frames_preserve_sparse_boundaries_null_values_and_partitions[rust-RANGE BETWEEN INTERVAL '2 day' PRECEDING AND CURRENT ROW-expected3]", + "tests/semantic_conformance/test_window_output_parity.py::test_expression_alias_is_a_period_metric_and_not_a_physical_column[python]", + "tests/semantic_conformance/test_window_output_parity.py::test_expression_alias_is_a_period_metric_and_not_a_physical_column[rust]", + "tests/semantic_conformance/test_window_output_parity.py::test_explicit_metric_output_order_overrides_chronological_order[python]", + "tests/semantic_conformance/test_window_output_parity.py::test_explicit_metric_output_order_overrides_chronological_order[rust]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_order_resolves_the_selected_dimension_grain[python-None-day]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_order_resolves_the_selected_dimension_grain[python-None-events.day]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_order_resolves_the_selected_dimension_grain[python-None-day__month]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_order_resolves_the_selected_dimension_grain[python-avg-day]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_order_resolves_the_selected_dimension_grain[python-avg-events.day]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_order_resolves_the_selected_dimension_grain[python-avg-day__month]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_order_resolves_the_selected_dimension_grain[rust-None-day]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_order_resolves_the_selected_dimension_grain[rust-None-events.day]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_order_resolves_the_selected_dimension_grain[rust-None-day__month]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_order_resolves_the_selected_dimension_grain[rust-avg-day]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_order_resolves_the_selected_dimension_grain[rust-avg-events.day]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_order_resolves_the_selected_dimension_grain[rust-avg-day__month]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_order_rejects_multiple_selected_grains[python]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_order_rejects_multiple_selected_grains[rust]", + "tests/semantic_conformance/test_window_output_parity.py::test_aggregate_reference_honors_explicit_range_frame[python]", + "tests/semantic_conformance/test_window_output_parity.py::test_aggregate_reference_honors_explicit_range_frame[rust]", + "tests/semantic_conformance/test_window_output_parity.py::test_aggregate_reference_rejects_invalid_frame[python-garbage]", + "tests/semantic_conformance/test_window_output_parity.py::test_aggregate_reference_rejects_invalid_frame[python-ROWS BETWEEN 1 PRECEDING AND CURRENT ROW); SELECT 1; --]", + "tests/semantic_conformance/test_window_output_parity.py::test_aggregate_reference_rejects_invalid_frame[rust-garbage]", + "tests/semantic_conformance/test_window_output_parity.py::test_aggregate_reference_rejects_invalid_frame[rust-ROWS BETWEEN 1 PRECEDING AND CURRENT ROW); SELECT 1; --]", + "tests/semantic_conformance/test_window_output_parity.py::test_aggregate_reference_rejects_conflicting_frame_controls[python-controls0]", + "tests/semantic_conformance/test_window_output_parity.py::test_aggregate_reference_rejects_conflicting_frame_controls[python-controls1]", + "tests/semantic_conformance/test_window_output_parity.py::test_aggregate_reference_rejects_conflicting_frame_controls[rust-controls0]", + "tests/semantic_conformance/test_window_output_parity.py::test_aggregate_reference_rejects_conflicting_frame_controls[rust-controls1]", + "tests/semantic_conformance/test_window_output_parity.py::test_distinct_period_counts_are_summed_not_combined_row_distincts[python]", + "tests/semantic_conformance/test_window_output_parity.py::test_distinct_period_counts_are_summed_not_combined_row_distincts[rust]", + "tests/semantic_conformance/test_window_output_parity.py::test_promoted_functions_consume_period_values[python-MIN-expected0]", + "tests/semantic_conformance/test_window_output_parity.py::test_promoted_functions_consume_period_values[python-MAX-expected1]", + "tests/semantic_conformance/test_window_output_parity.py::test_promoted_functions_consume_period_values[python-COUNT-expected2]", + "tests/semantic_conformance/test_window_output_parity.py::test_promoted_functions_consume_period_values[rust-MIN-expected0]", + "tests/semantic_conformance/test_window_output_parity.py::test_promoted_functions_consume_period_values[rust-MAX-expected1]", + "tests/semantic_conformance/test_window_output_parity.py::test_promoted_functions_consume_period_values[rust-COUNT-expected2]", + "tests/semantic_conformance/test_window_output_parity.py::test_query_filter_and_policy_apply_before_window[python]", + "tests/semantic_conformance/test_window_output_parity.py::test_query_filter_and_policy_apply_before_window[rust]", + "tests/semantic_conformance/test_window_output_parity.py::test_invalid_window_order_rejected_before_execution[python-amount]", + "tests/semantic_conformance/test_window_output_parity.py::test_invalid_window_order_rejected_before_execution[python-missing]", + "tests/semantic_conformance/test_window_output_parity.py::test_invalid_window_order_rejected_before_execution[python-day DESC]", + "tests/semantic_conformance/test_window_output_parity.py::test_invalid_window_order_rejected_before_execution[python-day) FROM events; --]", + "tests/semantic_conformance/test_window_output_parity.py::test_invalid_window_order_rejected_before_execution[rust-amount]", + "tests/semantic_conformance/test_window_output_parity.py::test_invalid_window_order_rejected_before_execution[rust-missing]", + "tests/semantic_conformance/test_window_output_parity.py::test_invalid_window_order_rejected_before_execution[rust-day DESC]", + "tests/semantic_conformance/test_window_output_parity.py::test_invalid_window_order_rejected_before_execution[rust-day) FROM events; --]", + "tests/semantic_conformance/test_window_output_parity.py::test_invalid_window_frame_rejected_before_execution[python-garbage]", + "tests/semantic_conformance/test_window_output_parity.py::test_invalid_window_frame_rejected_before_execution[python-ROWS BETWEEN 1 PRECEDING AND CURRENT ROW); SELECT 1; --]", + "tests/semantic_conformance/test_window_output_parity.py::test_invalid_window_frame_rejected_before_execution[rust-garbage]", + "tests/semantic_conformance/test_window_output_parity.py::test_invalid_window_frame_rejected_before_execution[rust-ROWS BETWEEN 1 PRECEDING AND CURRENT ROW); SELECT 1; --]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_dependency_cycles_return_validation_errors[python-references0]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_dependency_cycles_return_validation_errors[python-references1]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_dependency_cycles_return_validation_errors[rust-references0]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_dependency_cycles_return_validation_errors[rust-references1]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_expression_preserves_python_precedence[python-controls0]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_expression_preserves_python_precedence[python-controls1]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_expression_preserves_python_precedence[rust-controls0]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_expression_preserves_python_precedence[rust-controls1]", + "tests/semantic_conformance/test_window_output_parity.py::test_graph_window_infers_unique_period_metric_owner[python]", + "tests/semantic_conformance/test_window_output_parity.py::test_graph_window_infers_unique_period_metric_owner[rust]", + "tests/semantic_conformance/test_window_output_parity.py::test_quoted_output_expression_is_generated_for_bigquery[python]", + "tests/semantic_conformance/test_window_output_parity.py::test_quoted_output_expression_is_generated_for_bigquery[rust]", + "tests/semantic_conformance/test_window_output_parity.py::test_graph_window_rejects_missing_or_ambiguous_period_metric[python-missing]", + "tests/semantic_conformance/test_window_output_parity.py::test_graph_window_rejects_missing_or_ambiguous_period_metric[python-daily_amount]", + "tests/semantic_conformance/test_window_output_parity.py::test_graph_window_rejects_missing_or_ambiguous_period_metric[rust-missing]", + "tests/semantic_conformance/test_window_output_parity.py::test_graph_window_rejects_missing_or_ambiguous_period_metric[rust-daily_amount]", + "tests/semantic_conformance/test_window_output_parity.py::test_cumulative_count_counts_nonnull_period_values[python-count]", + "tests/semantic_conformance/test_window_output_parity.py::test_cumulative_count_counts_nonnull_period_values[python-count_distinct]", + "tests/semantic_conformance/test_window_output_parity.py::test_cumulative_count_counts_nonnull_period_values[rust-count]", + "tests/semantic_conformance/test_window_output_parity.py::test_cumulative_count_counts_nonnull_period_values[rust-count_distinct]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_expression_arithmetic_filter_and_null_arguments[python-SUM(base.daily_amount * 2) FILTER (WHERE base.daily_amount >= 7)-expected0]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_expression_arithmetic_filter_and_null_arguments[python-COUNT(DISTINCT base.daily_amount)-expected1]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_expression_arithmetic_filter_and_null_arguments[python-SUM(COALESCE(base.daily_amount, 1))-expected2]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_expression_arithmetic_filter_and_null_arguments[rust-SUM(base.daily_amount * 2) FILTER (WHERE base.daily_amount >= 7)-expected0]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_expression_arithmetic_filter_and_null_arguments[rust-COUNT(DISTINCT base.daily_amount)-expected1]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_expression_arithmetic_filter_and_null_arguments[rust-SUM(COALESCE(base.daily_amount, 1))-expected2]", + "tests/semantic_conformance/test_window_output_parity.py::test_following_and_excluded_window_frames[python-ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING-expected0]", + "tests/semantic_conformance/test_window_output_parity.py::test_following_and_excluded_window_frames[python-ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING EXCLUDE CURRENT ROW-expected1]", + "tests/semantic_conformance/test_window_output_parity.py::test_following_and_excluded_window_frames[rust-ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING-expected0]", + "tests/semantic_conformance/test_window_output_parity.py::test_following_and_excluded_window_frames[rust-ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING EXCLUDE CURRENT ROW-expected1]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_expression_binds_multiple_grouped_dependencies[python]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_expression_binds_multiple_grouped_dependencies[rust]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[python-base.daily_amount]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[python-base.daily_amount + 1]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[python-SUM(base.daily_amount) + 1]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[python-ABS(base.daily_amount)]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[rust-base.daily_amount]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[rust-base.daily_amount + 1]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[rust-SUM(base.daily_amount) + 1]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[rust-ABS(base.daily_amount)]" + ] + }, + "scope-235": { + "path": "tests/semantic_conformance/test_window_output_parity.py", + "declared_tests": [ + "test_graph_window_rejects_missing_or_ambiguous_period_metric", + "test_quoted_output_expression_is_generated_for_bigquery", + "test_scalar_window_expression_is_typed_unsupported", + "test_window_dependency_cycles_return_validation_errors" + ], + "collected_tests": [ + "tests/semantic_conformance/test_window_output_parity.py::test_window_dependency_cycles_return_validation_errors[python-references0]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_dependency_cycles_return_validation_errors[python-references1]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_dependency_cycles_return_validation_errors[rust-references0]", + "tests/semantic_conformance/test_window_output_parity.py::test_window_dependency_cycles_return_validation_errors[rust-references1]", + "tests/semantic_conformance/test_window_output_parity.py::test_quoted_output_expression_is_generated_for_bigquery[python]", + "tests/semantic_conformance/test_window_output_parity.py::test_quoted_output_expression_is_generated_for_bigquery[rust]", + "tests/semantic_conformance/test_window_output_parity.py::test_graph_window_rejects_missing_or_ambiguous_period_metric[python-missing]", + "tests/semantic_conformance/test_window_output_parity.py::test_graph_window_rejects_missing_or_ambiguous_period_metric[python-daily_amount]", + "tests/semantic_conformance/test_window_output_parity.py::test_graph_window_rejects_missing_or_ambiguous_period_metric[rust-missing]", + "tests/semantic_conformance/test_window_output_parity.py::test_graph_window_rejects_missing_or_ambiguous_period_metric[rust-daily_amount]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[python-base.daily_amount]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[python-base.daily_amount + 1]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[python-SUM(base.daily_amount) + 1]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[python-ABS(base.daily_amount)]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[rust-base.daily_amount]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[rust-base.daily_amount + 1]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[rust-SUM(base.daily_amount) + 1]", + "tests/semantic_conformance/test_window_output_parity.py::test_scalar_window_expression_is_typed_unsupported[rust-ABS(base.daily_amount)]" + ] + }, + "scope-236": { + "path": "tests/semantic_conformance/test_yardstick_source_dialects.py", + "declared_tests": [ + "test_native_ordinary_statement_batches_retain_both_results", + "test_public_rewriter_preserves_multi_statement_strictness", + "test_source_current_modifier_uses_canonical_group_context", + "test_source_date_functions_inside_where_modifier", + "test_source_functions_and_quoted_all_dimensions", + "test_source_modifier_literals_and_unicode_offsets", + "test_table_function_inner_sql_keeps_authored_dialect" + ], + "collected_tests": [ + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_functions_and_quoted_all_dimensions[python-bigquery-`-IF]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_functions_and_quoted_all_dimensions[python-snowflake-\"-IFF]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_functions_and_quoted_all_dimensions[rust-bigquery-`-IF]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_functions_and_quoted_all_dimensions[rust-snowflake-\"-IFF]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_current_modifier_uses_canonical_group_context[python-False-bigquery-`]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_current_modifier_uses_canonical_group_context[python-False-snowflake-\"]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_current_modifier_uses_canonical_group_context[python-True-bigquery-`]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_current_modifier_uses_canonical_group_context[python-True-snowflake-\"]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_current_modifier_uses_canonical_group_context[rust-False-bigquery-`]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_current_modifier_uses_canonical_group_context[rust-False-snowflake-\"]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_current_modifier_uses_canonical_group_context[rust-True-bigquery-`]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_current_modifier_uses_canonical_group_context[rust-True-snowflake-\"]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_date_functions_inside_where_modifier[python-bigquery-DATE_DIFF(DATE '2023-01-02', DATE '2023-01-01', DAY) = 1 AND `year` = 2023]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_date_functions_inside_where_modifier[python-snowflake-DATEDIFF(day, DATE '2023-01-01', DATE '2023-01-02') = 1 AND \"year\" = 2023]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_date_functions_inside_where_modifier[rust-bigquery-DATE_DIFF(DATE '2023-01-02', DATE '2023-01-01', DAY) = 1 AND `year` = 2023]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_date_functions_inside_where_modifier[rust-snowflake-DATEDIFF(day, DATE '2023-01-01', DATE '2023-01-02') = 1 AND \"year\" = 2023]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_modifier_literals_and_unicode_offsets[python-bigquery-r'C:\\\\user'-C:\\\\user]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_modifier_literals_and_unicode_offsets[python-snowflake-'C:\\\\\\\\user'-C:\\\\user]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_modifier_literals_and_unicode_offsets[python-snowflake-'can\\\\'t'-can't]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_modifier_literals_and_unicode_offsets[rust-bigquery-r'C:\\\\user'-C:\\\\user]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_modifier_literals_and_unicode_offsets[rust-snowflake-'C:\\\\\\\\user'-C:\\\\user]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_source_modifier_literals_and_unicode_offsets[rust-snowflake-'can\\\\'t'-can't]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_table_function_inner_sql_keeps_authored_dialect[python-bigquery-`]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_table_function_inner_sql_keeps_authored_dialect[python-snowflake-\"]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_table_function_inner_sql_keeps_authored_dialect[rust-bigquery-`]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_table_function_inner_sql_keeps_authored_dialect[rust-snowflake-\"]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_public_rewriter_preserves_multi_statement_strictness[python-bigquery]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_public_rewriter_preserves_multi_statement_strictness[python-snowflake]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_public_rewriter_preserves_multi_statement_strictness[rust-bigquery]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_public_rewriter_preserves_multi_statement_strictness[rust-snowflake]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_native_ordinary_statement_batches_retain_both_results[python-bigquery-`]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_native_ordinary_statement_batches_retain_both_results[python-snowflake-\"]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_native_ordinary_statement_batches_retain_both_results[rust-bigquery-`]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_native_ordinary_statement_batches_retain_both_results[rust-snowflake-\"]" + ] + }, + "scope-237": { + "path": "tests/semantic_conformance/test_yardstick_source_dialects.py", + "declared_tests": [ + "test_native_ordinary_statement_batches_retain_both_results" + ], + "collected_tests": [ + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_native_ordinary_statement_batches_retain_both_results[python-bigquery-`]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_native_ordinary_statement_batches_retain_both_results[python-snowflake-\"]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_native_ordinary_statement_batches_retain_both_results[rust-bigquery-`]", + "tests/semantic_conformance/test_yardstick_source_dialects.py::test_native_ordinary_statement_batches_retain_both_results[rust-snowflake-\"]" + ] + }, + "scope-238": { + "path": "tests/server/test_api_security.py", + "declared_tests": [ + "test_custom_user_header_name", + "test_direct_client_cannot_choose_tenant", + "test_enforce_visibility_rejects_non_public_field", + "test_malformed_json_header_returns_400", + "test_models_catalog_hides_non_public_fields_when_enforcing", + "test_models_catalog_shows_all_fields_without_enforcement", + "test_mounted_mcp_auth_and_request_identity", + "test_mounted_mcp_identity_does_not_persist_between_requests", + "test_non_object_json_header_returns_400", + "test_proxy_mode_requires_authentication", + "test_raw_endpoint_denied_when_model_secured", + "test_require_user_attrs_missing_header_returns_400", + "test_result_cache_key_differs_across_users", + "test_result_cache_no_cross_user_leak_end_to_end", + "test_secured_model_without_attrs_returns_403", + "test_sql_and_raw_deny_hidden_fields_when_visibility_enforced", + "test_sql_compile_endpoint_enforces_row_filter_when_model_secured", + "test_sql_endpoint_allowed_without_security", + "test_sql_endpoint_enforces_row_filter_when_model_secured", + "test_sql_passthrough_denied_when_security_active", + "test_user_header_scopes_rows", + "test_verified_resolver_ignores_forged_header" + ], + "collected_tests": [ + "tests/server/test_api_security.py::test_user_header_scopes_rows", + "tests/server/test_api_security.py::test_require_user_attrs_missing_header_returns_400", + "tests/server/test_api_security.py::test_malformed_json_header_returns_400", + "tests/server/test_api_security.py::test_non_object_json_header_returns_400", + "tests/server/test_api_security.py::test_secured_model_without_attrs_returns_403", + "tests/server/test_api_security.py::test_enforce_visibility_rejects_non_public_field", + "tests/server/test_api_security.py::test_custom_user_header_name", + "tests/server/test_api_security.py::test_result_cache_key_differs_across_users", + "tests/server/test_api_security.py::test_result_cache_no_cross_user_leak_end_to_end", + "tests/server/test_api_security.py::test_sql_endpoint_enforces_row_filter_when_model_secured", + "tests/server/test_api_security.py::test_sql_compile_endpoint_enforces_row_filter_when_model_secured", + "tests/server/test_api_security.py::test_raw_endpoint_denied_when_model_secured", + "tests/server/test_api_security.py::test_sql_passthrough_denied_when_security_active", + "tests/server/test_api_security.py::test_sql_and_raw_deny_hidden_fields_when_visibility_enforced", + "tests/server/test_api_security.py::test_sql_endpoint_allowed_without_security", + "tests/server/test_api_security.py::test_models_catalog_hides_non_public_fields_when_enforcing", + "tests/server/test_api_security.py::test_models_catalog_shows_all_fields_without_enforcement", + "tests/server/test_api_security.py::test_direct_client_cannot_choose_tenant", + "tests/server/test_api_security.py::test_verified_resolver_ignores_forged_header", + "tests/server/test_api_security.py::test_proxy_mode_requires_authentication", + "tests/server/test_api_security.py::test_mounted_mcp_auth_and_request_identity[False-/mcp]", + "tests/server/test_api_security.py::test_mounted_mcp_auth_and_request_identity[False-/mcp/]", + "tests/server/test_api_security.py::test_mounted_mcp_auth_and_request_identity[True-/mcp]", + "tests/server/test_api_security.py::test_mounted_mcp_auth_and_request_identity[True-/mcp/]", + "tests/server/test_api_security.py::test_mounted_mcp_identity_does_not_persist_between_requests" + ] + }, + "scope-239": { + "path": "tests/server/test_api_server.py", + "declared_tests": [ + "test_bearer_exchange_issues_short_lived_header_session", + "test_bearer_exchange_issues_short_lived_httponly_session", + "test_bearer_exchange_rejects_invalid_token", + "test_compile_accepts_timezone", + "test_compile_and_query_json_endpoints", + "test_dashboard_endpoint_is_optional_and_authenticated", + "test_describe_endpoint", + "test_health_and_models_endpoints", + "test_health_requires_auth", + "test_invalid_filter_returns_400", + "test_json_responses_use_arrow_reader_for_generic_adapters", + "test_query_arrow_endpoint", + "test_query_arrow_respects_accept_header", + "test_query_falls_back_to_raw_when_rollup_missing", + "test_query_strict_mode_returns_409_when_rollup_missing", + "test_query_strict_override_via_payload", + "test_raw_allows_set_operations", + "test_raw_rejects_dml_in_cte", + "test_raw_rejects_non_select", + "test_raw_select_returns_results", + "test_readyz_is_public", + "test_request_size_limit_returns_413", + "test_result_cache_disabled_by_default", + "test_result_cache_serves_repeated_query", + "test_serve_ui_serves_spa_and_keeps_api_gated", + "test_sql_compile_and_sql_query_endpoints", + "test_sql_endpoint_falls_back_to_raw_when_rollup_missing", + "test_sql_endpoint_strict_mode_returns_409_when_rollup_missing", + "test_sql_multi_statement_rejected", + "test_sql_with_semicolon_in_string_literal" + ], + "collected_tests": [ + "tests/server/test_api_server.py::test_health_requires_auth", + "tests/server/test_api_server.py::test_bearer_exchange_issues_short_lived_httponly_session", + "tests/server/test_api_server.py::test_bearer_exchange_rejects_invalid_token", + "tests/server/test_api_server.py::test_bearer_exchange_issues_short_lived_header_session", + "tests/server/test_api_server.py::test_readyz_is_public", + "tests/server/test_api_server.py::test_health_and_models_endpoints", + "tests/server/test_api_server.py::test_dashboard_endpoint_is_optional_and_authenticated", + "tests/server/test_api_server.py::test_describe_endpoint", + "tests/server/test_api_server.py::test_result_cache_serves_repeated_query", + "tests/server/test_api_server.py::test_result_cache_disabled_by_default", + "tests/server/test_api_server.py::test_serve_ui_serves_spa_and_keeps_api_gated", + "tests/server/test_api_server.py::test_compile_and_query_json_endpoints", + "tests/server/test_api_server.py::test_compile_accepts_timezone", + "tests/server/test_api_server.py::test_query_arrow_endpoint", + "tests/server/test_api_server.py::test_query_arrow_respects_accept_header", + "tests/server/test_api_server.py::test_sql_compile_and_sql_query_endpoints", + "tests/server/test_api_server.py::test_invalid_filter_returns_400", + "tests/server/test_api_server.py::test_request_size_limit_returns_413", + "tests/server/test_api_server.py::test_sql_with_semicolon_in_string_literal", + "tests/server/test_api_server.py::test_sql_multi_statement_rejected", + "tests/server/test_api_server.py::test_raw_select_returns_results", + "tests/server/test_api_server.py::test_raw_allows_set_operations[SELECT 1 AS n UNION SELECT 2 AS n]", + "tests/server/test_api_server.py::test_raw_allows_set_operations[SELECT 1 AS n UNION ALL SELECT 2 AS n]", + "tests/server/test_api_server.py::test_raw_allows_set_operations[SELECT 1 AS n INTERSECT SELECT 1 AS n]", + "tests/server/test_api_server.py::test_raw_allows_set_operations[SELECT 1 AS n EXCEPT SELECT 2 AS n]", + "tests/server/test_api_server.py::test_raw_allows_set_operations[(SELECT 1 AS n)]", + "tests/server/test_api_server.py::test_raw_rejects_non_select[INSERT INTO orders VALUES (99, 'x', 1.0, '2024-01-01')]", + "tests/server/test_api_server.py::test_raw_rejects_non_select[UPDATE orders SET status = 'x']", + "tests/server/test_api_server.py::test_raw_rejects_non_select[DELETE FROM orders]", + "tests/server/test_api_server.py::test_raw_rejects_non_select[DROP TABLE orders]", + "tests/server/test_api_server.py::test_raw_rejects_non_select[CREATE TABLE hack (id INT)]", + "tests/server/test_api_server.py::test_raw_rejects_dml_in_cte", + "tests/server/test_api_server.py::test_json_responses_use_arrow_reader_for_generic_adapters", + "tests/server/test_api_server.py::test_query_falls_back_to_raw_when_rollup_missing", + "tests/server/test_api_server.py::test_query_strict_mode_returns_409_when_rollup_missing", + "tests/server/test_api_server.py::test_query_strict_override_via_payload", + "tests/server/test_api_server.py::test_sql_endpoint_falls_back_to_raw_when_rollup_missing", + "tests/server/test_api_server.py::test_sql_endpoint_strict_mode_returns_409_when_rollup_missing" + ] + }, + "scope-240": { + "path": "tests/server/test_api_server.py", + "declared_tests": [ + "test_serve_ui_serves_spa_and_keeps_api_gated" + ], + "collected_tests": [ + "tests/server/test_api_server.py::test_serve_ui_serves_spa_and_keeps_api_gated" + ] + }, + "scope-241": { + "path": "tests/server/test_concurrency.py", + "declared_tests": [ + "test_concurrent_reads_do_not_serialize", + "test_mutation_style_endpoint_works_while_queries_run" + ], + "collected_tests": [ + "tests/server/test_concurrency.py::test_concurrent_reads_do_not_serialize", + "tests/server/test_concurrency.py::test_mutation_style_endpoint_works_while_queries_run" + ] + }, + "scope-242": { + "path": "tests/server/test_connection.py", + "declared_tests": [ + "test_handle_auth" + ], + "collected_tests": [ + "tests/server/test_connection.py::test_handle_auth" + ] + }, + "scope-243": { + "path": "tests/server/test_connection.py", + "declared_tests": [ + "test_handle_auth_partial_config_fails_closed" + ], + "collected_tests": [ + "tests/server/test_connection.py::test_handle_auth_partial_config_fails_closed" + ] + }, + "scope-244": { + "path": "tests/server/test_connection.py", + "declared_tests": [ + "test_handle_system_queries" + ], + "collected_tests": [ + "tests/server/test_connection.py::test_handle_system_queries" + ] + }, + "scope-245": { + "path": "tests/server/test_connection.py", + "declared_tests": [ + "test_dml_passthrough" + ], + "collected_tests": [ + "tests/server/test_connection.py::test_dml_passthrough" + ] + }, + "scope-246": { + "path": "tests/server/test_connection.py", + "declared_tests": [ + "test_query_error_raises_exception" + ], + "collected_tests": [ + "tests/server/test_connection.py::test_query_error_raises_exception" + ] + }, + "scope-247": { + "path": "tests/server/test_connection.py", + "declared_tests": [ + "test_user_attributes_lookup_by_session_user" + ], + "collected_tests": [ + "tests/server/test_connection.py::test_user_attributes_lookup_by_session_user" + ] + }, + "scope-248": { + "path": "tests/server/test_connection.py", + "declared_tests": [ + "test_enforce_pg_access_denies_secured_model_without_attrs" + ], + "collected_tests": [ + "tests/server/test_connection.py::test_enforce_pg_access_denies_secured_model_without_attrs" + ] + }, + "scope-249": { + "path": "tests/server/test_connection.py", + "declared_tests": [ + "test_pg_catalog_filters_session_models_and_physical_sources", + "test_pg_description_probe_is_compatible", + "test_pg_namespace_omits_physical_schemas_under_controls", + "test_pg_qualified_model_names_still_enforce_policy", + "test_pg_rejects_physical_source_bypasses", + "test_pg_semantic_query_applies_row_filters", + "test_pg_session_setting_remains_safe_with_controls" + ], + "collected_tests": [ + "tests/server/test_connection.py::test_pg_rejects_physical_source_bypasses[select * from private_orders -- obj_description]", + "tests/server/test_connection.py::test_pg_rejects_physical_source_bypasses[select * from private_orders where 'obj_description' = 'obj_description']", + "tests/server/test_connection.py::test_pg_rejects_physical_source_bypasses[select * from \"main\" . \"private_orders\"]", + "tests/server/test_connection.py::test_pg_rejects_physical_source_bypasses[select obj_description(oid, 'pg_namespace') from private_orders]", + "tests/server/test_connection.py::test_pg_rejects_physical_source_bypasses[with source as (select * from private_orders) select * from source]", + "tests/server/test_connection.py::test_pg_rejects_physical_source_bypasses[select 1; select * from private_orders]", + "tests/server/test_connection.py::test_pg_rejects_physical_source_bypasses[table orders]", + "tests/server/test_connection.py::test_pg_rejects_physical_source_bypasses[show tables]", + "tests/server/test_connection.py::test_pg_rejects_physical_source_bypasses[pragma show_tables]", + "tests/server/test_connection.py::test_pg_rejects_physical_source_bypasses[table private_orders]", + "tests/server/test_connection.py::test_pg_rejects_physical_source_bypasses[pragma table_info('private_orders')]", + "tests/server/test_connection.py::test_pg_rejects_physical_source_bypasses[show all tables]", + "tests/server/test_connection.py::test_pg_rejects_physical_source_bypasses[pragma database_list]", + "tests/server/test_connection.py::test_pg_catalog_filters_session_models_and_physical_sources[information_schema.tables-None]", + "tests/server/test_connection.py::test_pg_catalog_filters_session_models_and_physical_sources[information_schema.tables-bob]", + "tests/server/test_connection.py::test_pg_catalog_filters_session_models_and_physical_sources[information_schema.tables-alice]", + "tests/server/test_connection.py::test_pg_catalog_filters_session_models_and_physical_sources[\"information_schema\".\"tables\"-None]", + "tests/server/test_connection.py::test_pg_catalog_filters_session_models_and_physical_sources[\"information_schema\".\"tables\"-bob]", + "tests/server/test_connection.py::test_pg_catalog_filters_session_models_and_physical_sources[\"information_schema\".\"tables\"-alice]", + "tests/server/test_connection.py::test_pg_catalog_filters_session_models_and_physical_sources[information_schema.tables;-None]", + "tests/server/test_connection.py::test_pg_catalog_filters_session_models_and_physical_sources[information_schema.tables;-bob]", + "tests/server/test_connection.py::test_pg_catalog_filters_session_models_and_physical_sources[information_schema.tables;-alice]", + "tests/server/test_connection.py::test_pg_catalog_filters_session_models_and_physical_sources[pg_catalog.pg_class-None]", + "tests/server/test_connection.py::test_pg_catalog_filters_session_models_and_physical_sources[pg_catalog.pg_class-bob]", + "tests/server/test_connection.py::test_pg_catalog_filters_session_models_and_physical_sources[pg_catalog.pg_class-alice]", + "tests/server/test_connection.py::test_pg_namespace_omits_physical_schemas_under_controls", + "tests/server/test_connection.py::test_pg_semantic_query_applies_row_filters", + "tests/server/test_connection.py::test_pg_description_probe_is_compatible", + "tests/server/test_connection.py::test_pg_qualified_model_names_still_enforce_policy[\"main\".\"orders\"]", + "tests/server/test_connection.py::test_pg_qualified_model_names_still_enforce_policy[main.orders]", + "tests/server/test_connection.py::test_pg_qualified_model_names_still_enforce_policy[semantic_layer.orders]", + "tests/server/test_connection.py::test_pg_session_setting_remains_safe_with_controls" + ] + }, + "scope-250": { + "path": "tests/server/test_connection.py", + "declared_tests": [ + "test_empty_pg_catalog_is_valid" + ], + "collected_tests": [ + "tests/server/test_connection.py::test_empty_pg_catalog_is_valid" + ] + }, + "scope-251": { + "path": "tests/server/test_transport_security_parity.py", + "declared_tests": [ + "test_allowed_identity_gets_identical_rows_across_http_and_mcp", + "test_hidden_column_is_rejected_and_omitted_across_http_and_mcp", + "test_nonquery_forms_fail_closed_across_transports", + "test_projection_queries_remain_available_with_controls", + "test_raw_and_unproven_sql_fail_closed_across_http_and_mcp", + "test_sql_rewrite_cache_isolated_by_visibility_state", + "test_unproven_nested_sql_fails_closed_across_http_and_mcp", + "test_unsupported_rust_shape_preserves_secured_transport_fallback", + "test_yardstick_sql_fails_closed_across_http_and_mcp" + ], + "collected_tests": [ + "tests/server/test_transport_security_parity.py::test_allowed_identity_gets_identical_rows_across_http_and_mcp", + "tests/server/test_transport_security_parity.py::test_raw_and_unproven_sql_fail_closed_across_http_and_mcp", + "tests/server/test_transport_security_parity.py::test_unproven_nested_sql_fails_closed_across_http_and_mcp[SELECT * FROM (SELECT amount FROM orders) AS scoped-semantic subquery]", + "tests/server/test_transport_security_parity.py::test_unproven_nested_sql_fails_closed_across_http_and_mcp[SELECT total_amount FROM orders WHERE EXISTS (SELECT 1 FROM orders WHERE secret_note = 'secret')-predicate subquery]", + "tests/server/test_transport_security_parity.py::test_unproven_nested_sql_fails_closed_across_http_and_mcp[SELECT (SELECT 1 FROM orders LIMIT 1) AS leaked, total_amount FROM orders-projection subquery]", + "tests/server/test_transport_security_parity.py::test_unsupported_rust_shape_preserves_secured_transport_fallback", + "tests/server/test_transport_security_parity.py::test_sql_rewrite_cache_isolated_by_visibility_state", + "tests/server/test_transport_security_parity.py::test_yardstick_sql_fails_closed_across_http_and_mcp", + "tests/server/test_transport_security_parity.py::test_hidden_column_is_rejected_and_omitted_across_http_and_mcp", + "tests/server/test_transport_security_parity.py::test_nonquery_forms_fail_closed_across_transports[table orders]", + "tests/server/test_transport_security_parity.py::test_nonquery_forms_fail_closed_across_transports[show tables]", + "tests/server/test_transport_security_parity.py::test_nonquery_forms_fail_closed_across_transports[pragma show_tables]", + "tests/server/test_transport_security_parity.py::test_nonquery_forms_fail_closed_across_transports[table private_orders]", + "tests/server/test_transport_security_parity.py::test_nonquery_forms_fail_closed_across_transports[pragma table_info('private_orders')]", + "tests/server/test_transport_security_parity.py::test_nonquery_forms_fail_closed_across_transports[show all tables]", + "tests/server/test_transport_security_parity.py::test_nonquery_forms_fail_closed_across_transports[pragma database_list]", + "tests/server/test_transport_security_parity.py::test_nonquery_forms_fail_closed_across_transports[select 1; table orders]", + "tests/server/test_transport_security_parity.py::test_nonquery_forms_fail_closed_across_transports[delete from orders]", + "tests/server/test_transport_security_parity.py::test_nonquery_forms_fail_closed_across_transports[with removed as (delete from orders returning *) select * from removed]", + "tests/server/test_transport_security_parity.py::test_nonquery_forms_fail_closed_across_transports[select 1 into orders]", + "tests/server/test_transport_security_parity.py::test_projection_queries_remain_available_with_controls[select 1 as ok]", + "tests/server/test_transport_security_parity.py::test_projection_queries_remain_available_with_controls[select 1 as ok;]", + "tests/server/test_transport_security_parity.py::test_projection_queries_remain_available_with_controls[select 1 as ok union all select 2 as ok]" + ] + }, + "scope-252": { + "path": "tests/templates/test_parameters.py", + "declared_tests": [ + "test_parameters_with_actual_data", + "test_sql_generator_with_default_parameter", + "test_sql_generator_with_multiple_parameters", + "test_sql_generator_with_parameters" + ], + "collected_tests": [ + "tests/templates/test_parameters.py::test_sql_generator_with_parameters", + "tests/templates/test_parameters.py::test_sql_generator_with_default_parameter", + "tests/templates/test_parameters.py::test_sql_generator_with_multiple_parameters", + "tests/templates/test_parameters.py::test_parameters_with_actual_data" + ] + }, + "scope-253": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestSemanticLayerAdapterInterface::test_layer_adapter_fetch_record_batch" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestSemanticLayerAdapterInterface::test_layer_adapter_fetch_record_batch" + ] + }, + "scope-254": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestServerConnectionAdapterIntegration::test_connection_handler_uses_adapter_for_dml" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestServerConnectionAdapterIntegration::test_connection_handler_uses_adapter_for_dml" + ] + }, + "scope-255": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestServerConnectionAdapterIntegration::test_connection_handler_uses_adapter_for_system_queries" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestServerConnectionAdapterIntegration::test_connection_handler_uses_adapter_for_system_queries" + ] + }, + "scope-256": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestServerConnectionAdapterIntegration::test_connection_handler_uses_adapter_for_pg_namespace" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestServerConnectionAdapterIntegration::test_connection_handler_uses_adapter_for_pg_namespace" + ] + }, + "scope-257": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestServerCatalogAdapterIntegration::test_start_server_uses_adapter_for_catalog_queries" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestServerCatalogAdapterIntegration::test_start_server_uses_adapter_for_catalog_queries" + ] + }, + "scope-258": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestMCPServerAdapterIntegration::test_mcp_run_query_uses_adapter" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestMCPServerAdapterIntegration::test_mcp_run_query_uses_adapter" + ] + }, + "scope-259": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestWorkbenchAdapterIntegration::test_workbench_command_wiring" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestWorkbenchAdapterIntegration::test_workbench_command_wiring" + ] + }, + "scope-260": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestWidgetAdapterIntegration::test_widget_generator_uses_layer_dialect" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestWidgetAdapterIntegration::test_widget_generator_uses_layer_dialect" + ] + }, + "scope-261": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestWidgetAdapterIntegration::test_widget_date_range_query_handles_qualified_table" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestWidgetAdapterIntegration::test_widget_date_range_query_handles_qualified_table" + ] + }, + "scope-262": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestWidgetAdapterIntegration::test_widget_sets_time_series_column_in_config" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestWidgetAdapterIntegration::test_widget_sets_time_series_column_in_config" + ] + }, + "scope-263": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestWidgetAdapterIntegration::test_widget_binary_transport_populates_binary_traits" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestWidgetAdapterIntegration::test_widget_binary_transport_populates_binary_traits" + ] + }, + "scope-264": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestWidgetAdapterIntegration::test_widget_uses_adapter_in_layer_mode" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestWidgetAdapterIntegration::test_widget_uses_adapter_in_layer_mode" + ] + }, + "scope-265": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestWidgetAdapterIntegration::test_widget_execute_routes_through_adapter" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestWidgetAdapterIntegration::test_widget_execute_routes_through_adapter" + ] + }, + "scope-266": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestWidgetAdapterIntegration::test_widget_dataframe_mode_uses_raw_connection" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestWidgetAdapterIntegration::test_widget_dataframe_mode_uses_raw_connection" + ] + }, + "scope-267": { + "path": "tests/test_adapter_integration.py", + "declared_tests": [ + "TestWidgetAdapterIntegration::test_widget_execute_arrow_uses_fetch_record_batch" + ], + "collected_tests": [ + "tests/test_adapter_integration.py::TestWidgetAdapterIntegration::test_widget_execute_arrow_uses_fetch_record_batch" + ] + }, + "scope-268": { + "path": "tests/test_bugfix_batch.py", + "declared_tests": [ + "TestConversionMetricDimensions::test_conversion_dimension_join_prevents_cross_group_leaking", + "TestConversionMetricDimensions::test_conversion_with_derived_dimension_sql", + "TestConversionMetricDimensions::test_conversion_with_dimension", + "TestConversionMetricDimensions::test_conversion_with_time_granularity", + "TestConversionMetricDimensions::test_conversion_without_dimensions_still_works", + "TestDuplicateSegmentResolution::test_segment_not_double_applied", + "TestFanoutAllHops::test_multi_hop_fanout_detected", + "TestNullSafeJoin::test_join_condition_not_coalesce_equality", + "TestNullSafeJoin::test_null_dimension_in_full_outer_join", + "TestSharedFiltersOnOuterQuery::test_classify_filters_preserves_or_group_parens", + "TestSharedFiltersOnOuterQuery::test_compound_and_filter_decomposed_into_pushdowns", + "TestSharedFiltersOnOuterQuery::test_filter_rewrite_uses_ast", + "TestSharedFiltersOnOuterQuery::test_model_specific_filter_pushdown", + "TestSharedFiltersOnOuterQuery::test_or_group_parens_preserved_in_pushdown" + ], + "collected_tests": [ + "tests/test_bugfix_batch.py::TestNullSafeJoin::test_null_dimension_in_full_outer_join", + "tests/test_bugfix_batch.py::TestNullSafeJoin::test_join_condition_not_coalesce_equality", + "tests/test_bugfix_batch.py::TestFanoutAllHops::test_multi_hop_fanout_detected", + "tests/test_bugfix_batch.py::TestSharedFiltersOnOuterQuery::test_model_specific_filter_pushdown", + "tests/test_bugfix_batch.py::TestSharedFiltersOnOuterQuery::test_filter_rewrite_uses_ast", + "tests/test_bugfix_batch.py::TestSharedFiltersOnOuterQuery::test_compound_and_filter_decomposed_into_pushdowns", + "tests/test_bugfix_batch.py::TestSharedFiltersOnOuterQuery::test_or_group_parens_preserved_in_pushdown", + "tests/test_bugfix_batch.py::TestSharedFiltersOnOuterQuery::test_classify_filters_preserves_or_group_parens", + "tests/test_bugfix_batch.py::TestDuplicateSegmentResolution::test_segment_not_double_applied", + "tests/test_bugfix_batch.py::TestConversionMetricDimensions::test_conversion_with_dimension", + "tests/test_bugfix_batch.py::TestConversionMetricDimensions::test_conversion_without_dimensions_still_works", + "tests/test_bugfix_batch.py::TestConversionMetricDimensions::test_conversion_dimension_join_prevents_cross_group_leaking", + "tests/test_bugfix_batch.py::TestConversionMetricDimensions::test_conversion_with_time_granularity", + "tests/test_bugfix_batch.py::TestConversionMetricDimensions::test_conversion_with_derived_dimension_sql" + ] + }, + "scope-269": { + "path": "tests/test_charts.py", + "declared_tests": [ + "test_chart_generation_available" + ], + "collected_tests": [ + "tests/test_charts.py::test_chart_generation_available" + ] + }, + "scope-270": { + "path": "tests/test_charts.py", + "declared_tests": [ + "test_format_label" + ], + "collected_tests": [ + "tests/test_charts.py::test_format_label" + ] + }, + "scope-271": { + "path": "tests/test_charts.py", + "declared_tests": [ + "test_color_palette" + ], + "collected_tests": [ + "tests/test_charts.py::test_color_palette" + ] + }, + "scope-272": { + "path": "tests/test_cli_commands.py", + "declared_tests": [ + "test_workbench_calls_runner" + ], + "collected_tests": [ + "tests/test_cli_commands.py::test_workbench_calls_runner" + ] + }, + "scope-273": { + "path": "tests/test_cli_commands.py", + "declared_tests": [ + "test_api_serve_calls_start_server" + ], + "collected_tests": [ + "tests/test_cli_commands.py::test_api_serve_calls_start_server" + ] + }, + "scope-274": { + "path": "tests/test_cli_commands.py", + "declared_tests": [ + "test_api_serve_legacy_warning_precedes_start_server" + ], + "collected_tests": [ + "tests/test_cli_commands.py::test_api_serve_legacy_warning_precedes_start_server" + ] + }, + "scope-275": { + "path": "tests/test_cli_commands.py", + "declared_tests": [ + "test_http_entrypoints_forward_trusted_identity" + ], + "collected_tests": [ + "tests/test_cli_commands.py::test_http_entrypoints_forward_trusted_identity[command0-False]", + "tests/test_cli_commands.py::test_http_entrypoints_forward_trusted_identity[command0-True]", + "tests/test_cli_commands.py::test_http_entrypoints_forward_trusted_identity[command1-False]", + "tests/test_cli_commands.py::test_http_entrypoints_forward_trusted_identity[command1-True]", + "tests/test_cli_commands.py::test_http_entrypoints_forward_trusted_identity[command2-False]", + "tests/test_cli_commands.py::test_http_entrypoints_forward_trusted_identity[command2-True]" + ] + }, + "scope-276": { + "path": "tests/test_cli_contract.py", + "declared_tests": [ + "test_api_auth_token_can_be_read_from_stdin" + ], + "collected_tests": [ + "tests/test_cli_contract.py::test_api_auth_token_can_be_read_from_stdin" + ] + }, + "scope-277": { + "path": "tests/test_cli_project_contract.py", + "declared_tests": [ + "test_dashboard_serve_discovers_default_spec_and_project" + ], + "collected_tests": [ + "tests/test_cli_project_contract.py::test_dashboard_serve_discovers_default_spec_and_project" + ] + }, + "scope-278": { + "path": "tests/test_cli_t2_contract.py", + "declared_tests": [ + "test_format_default_does_not_suppress_unstructured_server_status" + ], + "collected_tests": [ + "tests/test_cli_t2_contract.py::test_format_default_does_not_suppress_unstructured_server_status" + ] + }, + "scope-279": { + "path": "tests/test_dashboard.py", + "declared_tests": [ + "test_crossfilter_dashboard_asgi_app_routes_requests_without_eager_preagg" + ], + "collected_tests": [ + "tests/test_dashboard.py::test_crossfilter_dashboard_asgi_app_routes_requests_without_eager_preagg" + ] + }, + "scope-280": { + "path": "tests/test_dashboard.py", + "declared_tests": [ + "test_crossfilter_dashboard_asgi_app_loads_non_initial_tab_specs_lazily" + ], + "collected_tests": [ + "tests/test_dashboard.py::test_crossfilter_dashboard_asgi_app_loads_non_initial_tab_specs_lazily" + ] + }, + "scope-281": { + "path": "tests/test_mcp_apps.py", + "declared_tests": [ + "test_build_chart_html", + "test_build_chart_html_escapes_json", + "test_build_chart_html_prevents_script_injection", + "test_create_chart_resource", + "test_create_chart_with_apps_enabled", + "test_create_chart_without_apps_returns_dict", + "test_protocol_widget_lifecycle_cleans_up_stale_renders", + "test_protocol_widget_loader_reports_missing_build", + "test_protocol_widget_resource_uses_lazy_built_asset", + "test_protocol_widget_source_is_self_contained_and_csp_safe" + ], + "collected_tests": [ + "tests/test_mcp_apps.py::test_build_chart_html", + "tests/test_mcp_apps.py::test_protocol_widget_source_is_self_contained_and_csp_safe", + "tests/test_mcp_apps.py::test_protocol_widget_lifecycle_cleans_up_stale_renders", + "tests/test_mcp_apps.py::test_protocol_widget_resource_uses_lazy_built_asset", + "tests/test_mcp_apps.py::test_protocol_widget_loader_reports_missing_build", + "tests/test_mcp_apps.py::test_build_chart_html_escapes_json", + "tests/test_mcp_apps.py::test_build_chart_html_prevents_script_injection", + "tests/test_mcp_apps.py::test_create_chart_resource", + "tests/test_mcp_apps.py::test_create_chart_with_apps_enabled", + "tests/test_mcp_apps.py::test_create_chart_without_apps_returns_dict" + ] + }, + "scope-282": { + "path": "tests/test_native_build_cache.py", + "declared_tests": [ + "test_native_source_changes_invalidate_uv_wheels" + ], + "collected_tests": [ + "tests/test_native_build_cache.py::test_native_source_changes_invalidate_uv_wheels[sidemantic-rs-src/lib.rs]", + "tests/test_native_build_cache.py::test_native_source_changes_invalidate_uv_wheels[sidemantic-rs-build.rs]", + "tests/test_native_build_cache.py::test_native_source_changes_invalidate_uv_wheels[sidemantic-rs-../Cargo.lock]", + "tests/test_native_build_cache.py::test_native_source_changes_invalidate_uv_wheels[crates/dax-pyo3-src/lib.rs]", + "tests/test_native_build_cache.py::test_native_source_changes_invalidate_uv_wheels[crates/dax-pyo3-../dax-parser/src/functions.rs]", + "tests/test_native_build_cache.py::test_native_source_changes_invalidate_uv_wheels[crates/dax-pyo3-python/sidemantic_dax/__init__.py]" + ] + }, + "scope-283": { + "path": "tests/test_performance.py", + "declared_tests": [ + "test_simple_rewrite_performance" + ], + "collected_tests": [ + "tests/test_performance.py::test_simple_rewrite_performance" + ] + }, + "scope-284": { + "path": "tests/test_performance.py", + "declared_tests": [ + "test_complex_rewrite_performance" + ], + "collected_tests": [ + "tests/test_performance.py::test_complex_rewrite_performance" + ] + }, + "scope-285": { + "path": "tests/test_performance.py", + "declared_tests": [ + "test_sql_generation_performance" + ], + "collected_tests": [ + "tests/test_performance.py::test_sql_generation_performance" + ] + }, + "scope-286": { + "path": "tests/test_performance.py", + "declared_tests": [ + "test_multi_join_generation_performance" + ], + "collected_tests": [ + "tests/test_performance.py::test_multi_join_generation_performance" + ] + }, + "scope-287": { + "path": "tests/test_performance.py", + "declared_tests": [ + "test_filter_parsing_performance" + ], + "collected_tests": [ + "tests/test_performance.py::test_filter_parsing_performance" + ] + }, + "scope-288": { + "path": "tests/test_performance.py", + "declared_tests": [ + "test_query_rewriter_warm_vs_cold" + ], + "collected_tests": [ + "tests/test_performance.py::test_query_rewriter_warm_vs_cold" + ] + }, + "scope-289": { + "path": "tests/test_performance.py", + "declared_tests": [ + "test_parameter_substitution_performance" + ], + "collected_tests": [ + "tests/test_performance.py::test_parameter_substitution_performance" + ] + }, + "scope-290": { + "path": "tests/test_query_fragment_boundary.py", + "declared_tests": [ + "test_rewriter_cte_scope_does_not_authorize_structured_or_later_calls" + ], + "collected_tests": [ + "tests/test_query_fragment_boundary.py::test_rewriter_cte_scope_does_not_authorize_structured_or_later_calls" + ] + }, + "scope-291": { + "path": "tests/test_query_fragment_boundary.py", + "declared_tests": [ + "test_cte_scope_allows_expression_plan_and_identifier_folding" + ], + "collected_tests": [ + "tests/test_query_fragment_boundary.py::test_cte_scope_allows_expression_plan_and_identifier_folding" + ] + }, + "scope-292": { + "path": "tests/test_sql_generation_security.py", + "declared_tests": [ + "test_conversion_invalid_entity_rejected" + ], + "collected_tests": [ + "tests/test_sql_generation_security.py::test_conversion_invalid_entity_rejected" + ] + }, + "scope-293": { + "path": "tests/test_sql_generation_security.py", + "declared_tests": [ + "test_conversion_invalid_window_rejected" + ], + "collected_tests": [ + "tests/test_sql_generation_security.py::test_conversion_invalid_window_rejected" + ] + }, + "scope-294": { + "path": "tests/test_sql_generation_security.py", + "declared_tests": [ + "test_conversion_event_name_quotes_escaped" + ], + "collected_tests": [ + "tests/test_sql_generation_security.py::test_conversion_event_name_quotes_escaped" + ] + }, + "scope-295": { + "path": "tests/test_sql_generation_security.py", + "declared_tests": [ + "test_build_interval_duckdb" + ], + "collected_tests": [ + "tests/test_sql_generation_security.py::test_build_interval_duckdb" + ] + }, + "scope-296": { + "path": "tests/test_sql_generation_security.py", + "declared_tests": [ + "test_build_interval_bigquery" + ], + "collected_tests": [ + "tests/test_sql_generation_security.py::test_build_interval_bigquery" + ] + }, + "scope-297": { + "path": "tests/test_sql_generation_security.py", + "declared_tests": [ + "test_build_interval_postgres" + ], + "collected_tests": [ + "tests/test_sql_generation_security.py::test_build_interval_postgres" + ] + }, + "scope-298": { + "path": "tests/test_workbench_demo.py", + "declared_tests": [ + "test_workbench_demo_starter_queries_execute" + ], + "collected_tests": [ + "tests/test_workbench_demo.py::test_workbench_demo_starter_queries_execute" + ] + }, + "scope-299": { + "path": "tests/widget/test_widget_examples.py", + "declared_tests": [ + "test_build_auto_model_sets_simple_aggs" + ], + "collected_tests": [ + "tests/widget/test_widget_examples.py::test_build_auto_model_sets_simple_aggs" + ] + } + }, + "helper_test_assessments": { + "tests/adapters/bsl/test_parsing.py": { + "TestBSLCurrentSyntaxSupport::test_deferred_calculated_measure_compiles": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestBSLCurrentSyntaxSupport::test_all_calculated_measure_compiles_to_window_total": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestBSLCurrentSyntaxSupport::test_qualified_calculated_measure_compiles_joined_measure": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestBSLCurrentSyntaxSupport::test_join_aliases_self_join_and_how_roundtrip": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestBSLCurrentSyntaxSupport::test_reused_join_aliases_scope_to_source_model": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestBSLCurrentSyntaxSupport::test_cross_join_compiles": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/adapters/cube/test_fixtures.py": { + "TestTesseractFeatures::test_aggregate_complete_measures_queryable": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestTesseractFeatures::test_plain_non_numeric_measures_queryable": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestTesseractFeatures::test_complete_measure_preserves_raw_timestamp": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestTesseractFeatures::test_complete_measure_applies_filters": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestTesseractFeatures::test_plain_complete_measure_grouped_by_other_dimension": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/adapters/metricflow/test_parsing.py": { + "test_metricflow_adapter_join_discovery": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_metricflow_derived_non_offset_aliases_queryable": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_metricflow_disabled_model_skips_inline_metrics": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_metricflow_inline_constant_count_anchored_to_model": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_metricflow_inline_exprless_non_count_uses_metric_column": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_metricflow_keyless_inline_count_planner_contract": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_metricflow_latest_spec_inline_metric_queryable_alone": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/adapters/sidemantic_adapter/test_parsing.py": { + "test_dimension_window_in_sql_generation": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/adapters/tableau/test_real_world.py": { + "test_sf_trial_joined_metric_uses_collection_sql": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_shapes_joined_dimension_uses_collection_sql": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/adapters/test_added_fixture_coverage.py": { + "test_added_fixtures_execute_sql_for_execution_candidates": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_added_fixtures_generate_sql_for_compile_candidates": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/adapters/test_fixture_functionality_contracts.py": { + "test_fixture_adapter_exact_execution_semantics": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_fixture_query_compilation_coverage": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_fixture_query_execution_coverage": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_fixture_representative_execution_semantics": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/adapters/tmdl/test_parsing.py": { + "test_tmdl_dax_only_calculated_table_is_not_compiled_as_sql": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_tmdl_untranslated_dax_dimension_is_not_compiled_as_sql": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/core/test_invariant_filters.py": { + "test_inheritance_conjoins_invariants_and_rust_rewriter_falls_back": { + "category": null, + "evidence": "reason-7" + } + }, + "tests/core/test_relationship_role_aliases.py": { + "test_many_to_many_through_column_check_uses_scoped_target_instance": { + "category": "intentional-Python-only", + "evidence": "reason-9" + }, + "test_nested_role_alias_is_scoped_to_parent_instance": { + "category": null, + "evidence": "reason-10" + }, + "test_role_alias_one_to_many_keeps_base_measure_fanout_safe": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_two_roles_to_same_target_use_distinct_join_instances": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/core/test_security_advisor_regressions.py": { + "test_rewriter_threads_user_attributes": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/dates/test_query_timezone.py": { + "test_generator_timezone_bypasses_preagg_routing": { + "category": null, + "evidence": "reason-11" + }, + "test_timezone_dialect_specific_sql": { + "category": "intentional-Python-only", + "evidence": "reason-12" + }, + "test_timezone_value_is_validated_against_injection": { + "category": null, + "evidence": "reason-11" + } + }, + "tests/dates/test_time_comparison.py": { + "test_model_level_conversion_metric": { + "category": null, + "evidence": "reason-13" + }, + "test_model_level_time_comparison_metric": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_named_calendar_comparison_without_declared_granularity": { + "category": null, + "evidence": "reason-14" + } + }, + "tests/metrics/test_advanced.py": { + "test_conversion_metric": { + "category": "real-gap", + "evidence": "reason-19" + }, + "test_conversion_metric_backwards_compatible": { + "category": "real-gap", + "evidence": "reason-20" + }, + "test_conversion_metric_steps_and_base_event": { + "category": "real-gap", + "evidence": "reason-21" + }, + "test_cumulative_fill_nulls_applies_after_window": { + "category": null, + "evidence": "reason-22" + }, + "test_dotted_metric_name_alias": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_fill_nulls_with_string": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_fill_nulls_with_zero": { + "category": null, + "evidence": "reason-23" + }, + "test_filter_dimension_with_model_qualified_sql_expr": { + "category": "real-gap", + "evidence": "reason-24" + }, + "test_model_measure_null_fill_applies_to_direct_and_dependent_metrics": { + "category": null, + "evidence": "reason-23" + }, + "test_mom_difference": { + "category": null, + "evidence": "reason-25" + }, + "test_month_comparison_does_not_use_previous_available_sparse_row": { + "category": null, + "evidence": "reason-25" + }, + "test_month_to_date_metric": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_multistep_conversion_2_steps_via_steps_list": { + "category": "real-gap", + "evidence": "reason-26" + }, + "test_multistep_conversion_funnel": { + "category": "real-gap", + "evidence": "reason-27" + }, + "test_multistep_funnel_chronological_order_enforced": { + "category": "real-gap", + "evidence": "reason-28" + }, + "test_multistep_funnel_expression_timestamp": { + "category": "real-gap", + "evidence": "reason-29" + }, + "test_multistep_funnel_model_name_prefix_step_predicates": { + "category": "real-gap", + "evidence": "reason-30" + }, + "test_multistep_funnel_model_placeholder_filter": { + "category": "real-gap", + "evidence": "reason-31" + }, + "test_multistep_funnel_model_placeholder_step_predicates": { + "category": "real-gap", + "evidence": "reason-32" + }, + "test_multistep_funnel_model_placeholder_timestamp": { + "category": "real-gap", + "evidence": "reason-33" + }, + "test_multistep_funnel_monotonic_counts": { + "category": "real-gap", + "evidence": "reason-34" + }, + "test_multistep_funnel_only_prior_step2_not_counted": { + "category": "real-gap", + "evidence": "reason-35" + }, + "test_multistep_funnel_or_step_with_filter": { + "category": "real-gap", + "evidence": "reason-36" + }, + "test_multistep_funnel_order_by_metric_name": { + "category": "real-gap", + "evidence": "reason-37" + }, + "test_multistep_funnel_qualified_filters": { + "category": "real-gap", + "evidence": "reason-38" + }, + "test_multistep_funnel_repeated_actions_valid_path": { + "category": "real-gap", + "evidence": "reason-39" + }, + "test_multistep_funnel_total_excludes_non_entrants": { + "category": "real-gap", + "evidence": "reason-40" + }, + "test_offset_ratio_fill_nulls_applies_to_missing_prior_period": { + "category": null, + "evidence": "reason-22" + }, + "test_offset_ratio_metric": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_offset_ratio_metric_multi_period": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_offset_ratio_metric_uses_base_granularity": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_offset_ratio_metric_year_offset": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_time_comparison_fill_nulls_applies_to_missing_prior_period": { + "category": null, + "evidence": "reason-22" + }, + "test_wow_percent_change_partitions_by_dimension": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_wow_ratio": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_year_to_date_metric": { + "category": null, + "evidence": "reason-41" + }, + "test_yoy_percent_change": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/metrics/test_cohort.py": { + "test_cohort_ambiguous_unqualified_raises": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_cohort_basic": { + "category": null, + "evidence": "reason-42" + }, + "test_cohort_graph_level_metric": { + "category": "real-gap", + "evidence": "reason-43" + }, + "test_cohort_mixed_with_conversion_raises": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_cohort_model_scoped_unqualified": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_cohort_outer_agg_without_sql_raises": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_cohort_outer_sql_references_subquery": { + "category": null, + "evidence": "reason-42" + }, + "test_cohort_reserved_word_dimension": { + "category": null, + "evidence": "reason-42" + }, + "test_cohort_unknown_dimension_raises": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_cohort_with_dimension": { + "category": null, + "evidence": "reason-42" + }, + "test_cohort_with_time_grain_uses_grained_output_alias": { + "category": null, + "evidence": "reason-42" + } + }, + "tests/metrics/test_conversion_source_parity.py": { + "test_conversion_fill_is_accepted_without_changing_empty_result": { + "category": null, + "evidence": "reason-44" + }, + "test_conversion_sql_source_expressions": { + "category": null, + "evidence": "reason-44" + }, + "test_two_event_conversion_uses_last_time_dimension_instead_of_default": { + "category": null, + "evidence": "reason-44" + } + }, + "tests/metrics/test_cumulative.py": { + "test_cumulative_with_time_comparison": { + "category": null, + "evidence": "reason-45" + }, + "test_time_comparison_over_derived_cumulative_chain": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_time_comparison_over_ratio_cumulative_chain": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_time_comparison_with_dependency_free_expression_metric": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/metrics/test_filters.py": { + "test_filter_classification_and_rewrite_respect_nested_select_alias_scope": { + "category": "intentional-Python-only", + "evidence": "reason-46" + }, + "test_filter_classification_ignores_metric_names_in_non_column_tokens": { + "category": "intentional-Python-only", + "evidence": "reason-47" + }, + "test_where_filter_rewrite_only_changes_semantic_columns": { + "category": "intentional-Python-only", + "evidence": "reason-48" + } + }, + "tests/metrics/test_non_additive_guard.py": { + "test_semi_additive_compiles_without_qualify_on_postgres": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/metrics/test_retention.py": { + "test_retention_aliased_entity_dimension": { + "category": "real-gap", + "evidence": "reason-49" + }, + "test_retention_ambiguous_model_raises": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_retention_day_granularity_results": { + "category": "real-gap", + "evidence": "reason-50" + }, + "test_retention_default_activity_event": { + "category": "real-gap", + "evidence": "reason-51" + }, + "test_retention_filter_with_model_qualified_sql_expr": { + "category": "real-gap", + "evidence": "reason-52" + }, + "test_retention_graph_metric_does_not_bind_to_same_name_model_metric": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_retention_metric_level_filters": { + "category": "real-gap", + "evidence": "reason-53" + }, + "test_retention_mixed_with_regular_metric_raises": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_retention_model_level_metric": { + "category": null, + "evidence": "reason-54" + }, + "test_retention_model_placeholder_expansion_sql_model": { + "category": "real-gap", + "evidence": "reason-55" + }, + "test_retention_model_placeholder_expansion_table_model": { + "category": "real-gap", + "evidence": "reason-56" + }, + "test_retention_model_placeholder_in_time_dimension": { + "category": "real-gap", + "evidence": "reason-57" + }, + "test_retention_multiple_retention_metrics_raises": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_retention_offset_in_sql": { + "category": "real-gap", + "evidence": "reason-58" + }, + "test_retention_periods_zero_raises_validation_error": { + "category": null, + "evidence": "reason-59" + }, + "test_retention_sql_generation": { + "category": "real-gap", + "evidence": "reason-60" + }, + "test_retention_week_granularity": { + "category": "real-gap", + "evidence": "reason-61" + } + }, + "tests/metrics/test_symmetric_aggs.py": { + "test_derived_and_ratio_metrics_reuse_fanout_safe_leaf_aggregates": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_fanout_evaluates_complete_sql_over_deduplicated_entity_rows": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_fanout_isolates_typed_entity_rows_for_double_sum_avg_and_nulls": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_fanout_join_detection_multiple_joins": { + "category": "intentional-Python-only", + "evidence": "reason-62" + }, + "test_fanout_join_detection_single_join": { + "category": "intentional-Python-only", + "evidence": "reason-62" + }, + "test_fanout_rejects_filtered_unqualified_constant_complete_sql": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_fanout_typed_composite_keys_do_not_collide_on_delimiters": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_filter_only_sibling_fanout_is_deduplicated_for_non_base_metric": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_filtered_count_under_fanout": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_model_measure_null_fill_under_fanout": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_preagg_grain_preserved_with_filters": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_symmetric_aggregates_in_sql_generation": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_symmetric_aggregates_with_data": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/native_compat/test_basic_model_fixture.py": { + "test_native_fixture_rewrites_semantic_sql": { + "category": null, + "evidence": "reason-63" + } + }, + "tests/queries/test_cross_model_calculated_grain.py": { + "test_calculated_metrics_preserve_each_source_grain": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_cross_model_calculation_output_name_collisions": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_filtered_ratio_rejects_unknown_customer_grain": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_mixed_row_and_calculation_or_rejected": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/queries/test_deterministic_join_anchor.py": { + "test_graph_metric_sql_reference_order_determines_one_to_one_join_anchor": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/queries/test_rust_query_rewriter_route.py": { + "test_caller_context_reaches_rust_without_fallback": { + "category": null, + "evidence": "reason-7" + }, + "test_cte_collision_binding_belongs_to_contextual_rust": { + "category": null, + "evidence": "reason-7" + }, + "test_explicit_python_overrides_legacy_environment": { + "category": "intentional-Python-only", + "evidence": "reason-64" + }, + "test_nonstrict_yardstick_validation_returns_original_sql": { + "category": null, + "evidence": "reason-7" + }, + "test_only_typed_failures_allow_fallback": { + "category": null, + "evidence": "reason-7" + }, + "test_plain_query_explanation_does_not_claim_rust_compilation": { + "category": null, + "evidence": "reason-7" + }, + "test_query_rewriter_passes_unexpanded_graph_metric_to_rust": { + "category": null, + "evidence": "reason-7" + }, + "test_rust_route_validates_empty_projection_and_source": { + "category": null, + "evidence": "reason-7" + }, + "test_security_errors_never_fall_back": { + "category": null, + "evidence": "reason-7" + }, + "test_set_operations_reach_rust_before_python_rewrite": { + "category": null, + "evidence": "reason-7" + }, + "test_strict_rust_passes_yardstick_sql_to_rust": { + "category": null, + "evidence": "reason-7" + }, + "test_strict_rust_preserves_query_only_validation": { + "category": null, + "evidence": "reason-7" + }, + "test_unexpected_compiler_errors_propagate": { + "category": null, + "evidence": "reason-7" + } + }, + "tests/queries/test_rust_rewrite_preaggregation_options.py": { + "test_rollup_preference_reaches_native_compiler": { + "category": null, + "evidence": "reason-7" + } + }, + "tests/queries/test_semantic_sql_planner.py": { + "test_additive_total_union_uses_branch_preaggregations": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_aggregate_boundary_count_metric_rollup": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_aggregate_boundary_min_max_metric_rollup": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_aggregate_boundary_rejects_mismatched_min_rollup": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_aggregate_boundary_rejects_non_additive_subtotals": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_aggregate_boundary_scalar_sum_rollup": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_aggregate_boundary_sum_rollup_drops_finer_dimension": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_aggregate_boundary_sum_rollup_uses_preaggregation": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_aggregate_boundary_time_grain_rollup_day_to_month": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_aggregate_boundary_time_grain_rollup_rejects_unsafe_dimension_expressions": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_aggregate_boundary_time_grain_rollup_rejects_week_to_month": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_aggregate_boundary_time_grain_rollup_uses_daily_preaggregation": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_bi_corpus_acceptance_matrix_records_expected_routes": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_bi_corpus_rejection_matrix_records_expected_reasons": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_conditional_aggregate_pivot_rejects_count_distinct_metric": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_conditional_aggregate_pivot_rejects_unsafe_shapes": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_conditional_aggregate_pivot_uses_inner_preaggregation": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_conditional_aggregate_pivot_with_outer_row_filter_uses_preaggregation": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_count_distinct_exact_grain_preaggregation_candidate": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_count_distinct_exact_grain_preaggregation_executes": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_count_distinct_rollup_preaggregation_rejected": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_derived_table_semantic_island_under_outer_join_uses_preaggregation": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_dimension_distinct_remote_dimension_probe_flattens": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_dimension_distinct_slicer_preserves_null_filter_order_and_limit": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_dimension_distinct_slicer_supports_lower_like_search": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_dimension_distinct_wrapper_rejects_computed_projection": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_dimension_distinct_wrapper_rejects_hidden_filter": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_dimension_distinct_wrapper_rejects_metrics": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_dimension_only_distinct_wrapper_flattens": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_explain_cte_semantic_query_pushes_metric_filter_to_having": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_explain_direct_semantic_query_is_machine_testable": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_explain_fanout_preaggregation_candidate": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_explain_from_metrics_query_records_metrics_source": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_explain_lists_deterministic_candidate_plans": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_explain_multiple_semantic_ctes_reports_all_scopes": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_explain_passthrough_plain_sql_non_strict": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_explain_preaggregation_negative_eligibility_reasons": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_explain_root_semantic_query_preserves_user_cte": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_explain_rust_rewriter_route": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_explain_single_model_preaggregation_candidate": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_explain_window_metric_candidate": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_explain_yardstick_route": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_explanation_can_be_serialized_to_dict": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_external_bi_wrapper_corpus_positive_cases": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_external_cte_chain_corpus_flattens_linear_steps": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_fanout_join_key_preaggregation_rejects_missing_join_key_rollup": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_fanout_join_key_preaggregation_rejects_one_to_many_remote_dimension": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_fanout_join_key_preaggregation_rolls_orders_to_customer_region": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_fetch_first_topn_rewrites_through_limit_pushdown": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_global_row_number_between_rewrites_to_limit_offset": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_global_row_number_topn_rejects_partitioned_rank": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_global_row_number_topn_rewrites_to_order_limit": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_global_topn_rejects_outer_projection_of_rank_column": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_global_topn_rejects_rank_tie_semantics": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_grouping_sets_subtotal_preserves_outer_shape_and_uses_preaggregation": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_hex_style_union_preview_cte_preserves_outer_limit": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_join_key_preaggregation_joins_remote_sql_source": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_join_key_preaggregation_reads_local_time_dimension_from_grain_column": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_join_key_preaggregation_reads_ungrained_local_time_dimension_from_grain_column": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_linear_cte_chain_rejects_unsafe_steps": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_multiple_semantic_cte_islands_use_preaggregations": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_one_semantic_cte_island_preserves_plain_cte": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_outer_dimension_filter_pushdown_predicate_matrix": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_outer_order_limit_pushdown_matrix": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_positive_wrapper_rewrites_match_unoptimized_baselines": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_projection_width_reduction_keeps_count_distinct_key_state": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_projection_width_reduction_keeps_join_keys_for_joined_dimensions": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_projection_width_reduction_omits_unused_primary_key": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_qualify_row_number_topn_rewrites_to_order_limit": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_rewrite_simple_query_still_generates_same_sql": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_root_having_metric_filter_uses_preaggregation": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_root_semantic_query_allows_redundant_group_by_dimensions": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_root_semantic_query_preserves_having_metric_filter": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_root_semantic_query_rejects_unsupported_aggregate_clauses": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_root_unqualified_dimension_filter_is_qualified_for_pushdown": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_safe_outer_filter_pushdown_from_cte_wrapper": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_safe_outer_filter_pushdown_rewrites_to_direct_semantic": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_safe_outer_order_limit_offset_pushdown": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_same_grain_aggregate_wrapper_flattens_without_changing_grouping": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_same_grain_aggregate_wrapper_rejects_computed_projection": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_semantic_island_with_outer_dependency_is_rejected": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_set_operation_branch_order_by_is_rejected": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_set_operation_mismatched_branch_projection_is_rejected": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_set_operation_preserves_raw_branch": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_sql_server_top_n_rewrites_through_limit_pushdown": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_trivial_wrapper_uses_direct_semantic_plan": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_union_all_semantic_branches_use_preaggregations": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapped_fanout_preserves_aliases_and_executes": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapped_fanout_strategy_selection": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapped_fanout_uses_child_preaggregations": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapped_metric_filter_uses_preaggregation_having": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapped_optimizer_negative_cases": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapped_preaggregation_executes_against_materialized_table": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapped_preaggregation_preserves_projection_alias_and_order": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapped_preaggregation_route_selection": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapped_window_metric_executes_against_baseline": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapped_window_metric_uses_inner_preaggregation": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapper_metric_filter_over_hidden_metric_stays_postprocess": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapper_mixed_and_filter_splits_row_and_metric_stages": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapper_mixed_or_filter_stays_postprocess": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapper_projection_flattening_aliases_without_changing_grouping": { + "category": "intentional-Python-only", + "evidence": "reason-65" + }, + "test_wrapper_window_metric_filter_stays_postprocess": { + "category": "intentional-Python-only", + "evidence": "reason-65" + } + }, + "tests/queries/test_sql_fallback_policy.py": { + "test_non_strict_rewrite_does_not_hide_runtime_bug": { + "category": "intentional-Python-only", + "evidence": "reason-64" + }, + "test_rust_backend_fallback_is_observable": { + "category": null, + "evidence": "reason-7" + }, + "test_rust_rewrite_does_not_hide_api_contract_defect": { + "category": null, + "evidence": "reason-7" + } + }, + "tests/queries/test_sql_rewriter.py": { + "test_dry_run_with_postprocess_subquery": { + "category": null, + "evidence": "reason-66" + }, + "test_explicit_join_requires_complete_composite_relationship": { + "category": null, + "evidence": "reason-67" + }, + "test_postprocess_zero_limit_and_offset_in_outer": { + "category": null, + "evidence": "reason-68" + }, + "test_query_without_metrics_or_dimensions": { + "category": null, + "evidence": "reason-69" + }, + "test_rewrite_less_than_relative_date": { + "category": null, + "evidence": "reason-70" + }, + "test_rewrite_not_equal_relative_date": { + "category": null, + "evidence": "reason-71" + }, + "test_rewriter_directly": { + "category": null, + "evidence": "reason-72" + }, + "test_rewriter_invalid_sql": { + "category": null, + "evidence": "reason-73" + }, + "test_rewriter_non_select_query": { + "category": null, + "evidence": "reason-74" + }, + "test_rewriter_non_strict_mode": { + "category": null, + "evidence": "reason-75" + }, + "test_select_star_without_from": { + "category": null, + "evidence": "reason-76" + }, + "test_zero_limit_and_offset_are_preserved": { + "category": null, + "evidence": "reason-77" + } + }, + "tests/queries/test_temporal_sql_projection.py": { + "test_repeated_metric_keeps_each_projection_alias": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_temporal_sql_exposes_only_requested_projection": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/queries/test_view_generation.py": { + "test_generate_view_creates_valid_sql": { + "category": null, + "evidence": "reason-78" + }, + "test_join_view_against_other_tables": { + "category": null, + "evidence": "reason-79" + }, + "test_view_can_be_queried": { + "category": null, + "evidence": "reason-80" + }, + "test_view_name_sql_injection_rejected": { + "category": null, + "evidence": "reason-81" + }, + "test_view_name_with_spaces_rejected": { + "category": null, + "evidence": "reason-82" + } + }, + "tests/queries/test_yardstick_query_rewriter.py": { + "test_yardstick_default_alias_not_applied_with_non_semantic_join": { + "category": null, + "evidence": "reason-83" + }, + "test_yardstick_expression_dimension_rewrite_uses_projection_alias": { + "category": null, + "evidence": "reason-84" + }, + "test_yardstick_generate_series_rewrite_uses_subquery_source": { + "category": null, + "evidence": "reason-85" + } + }, + "tests/queries/test_yardstick_warnings.py": { + "test_lost_filter_warns_and_can_be_an_error": { + "category": null, + "evidence": "reason-86" + }, + "test_unknown_or_ambiguous_measure_is_a_binding_error": { + "category": null, + "evidence": "reason-87" + }, + "test_wrapper_explanation_matches_rewrite_and_emits_warning": { + "category": null, + "evidence": "reason-88" + }, + "test_yardstick_table_function_requires_single_literal_read": { + "category": null, + "evidence": "reason-89" + }, + "test_yardstick_wrapper_cannot_bypass_semantic_security": { + "category": null, + "evidence": "reason-90" + } + }, + "tests/semantic_conformance/test_complete_filters.py": { + "test_complete_row_count_generator_reuse_observes_graph_changes": { + "category": "intentional-Python-only", + "evidence": "reason-91" + }, + "test_complete_row_count_role_queries_preserve_caller_caches": { + "category": "intentional-Python-only", + "evidence": "reason-92" + }, + "test_tsql_complete_row_count_retains_existing_path": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/semantic_conformance/test_default_time_differential.py": { + "test_skipped_model_defaults_remain_skipped_in_source_children": { + "category": "real-gap", + "evidence": "reason-94" + } + }, + "tests/semantic_conformance/test_filtered_count_family.py": { + "test_owned_count_generator_sees_live_graph_changes": { + "category": "intentional-Python-only", + "evidence": "reason-91" + } + }, + "tests/semantic_conformance/test_parameterized_segments.py": { + "test_control_values_remain_raw_while_outputs_are_typed": { + "category": null, + "evidence": "reason-96" + }, + "test_segment_subqueries_keep_physical_scope": { + "category": null, + "evidence": "reason-96" + }, + "test_simple_segment_parameters_preserve_defaults_and_values": { + "category": null, + "evidence": "reason-96" + }, + "test_template_value_contexts_match_python": { + "category": null, + "evidence": "reason-96" + } + }, + "tests/semantic_conformance/test_policy_cli.py": { + "test_security_failures_never_enter_python_fallback": { + "category": null, + "evidence": "reason-44" + }, + "test_undeclared_filter_columns_are_validation_errors_without_fallback": { + "category": null, + "evidence": "reason-44" + } + }, + "tests/semantic_conformance/test_postgres_policies.py": { + "test_postgres_public_paths_reach_rust_with_transport_syntax": { + "category": null, + "evidence": "reason-7" + } + }, + "tests/semantic_conformance/test_yardstick_source_dialects.py": { + "test_public_rewriter_preserves_multi_statement_strictness": { + "category": null, + "evidence": "reason-96" + }, + "test_source_current_modifier_uses_canonical_group_context": { + "category": null, + "evidence": "reason-96" + }, + "test_source_date_functions_inside_where_modifier": { + "category": null, + "evidence": "reason-96" + }, + "test_source_functions_and_quoted_all_dimensions": { + "category": null, + "evidence": "reason-96" + }, + "test_source_modifier_literals_and_unicode_offsets": { + "category": null, + "evidence": "reason-96" + }, + "test_table_function_inner_sql_keeps_authored_dialect": { + "category": null, + "evidence": "reason-96" + } + }, + "tests/templates/test_parameters.py": { + "test_parameters_with_actual_data": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_sql_generator_with_default_parameter": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_sql_generator_with_multiple_parameters": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_sql_generator_with_parameters": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/test_bugfix_batch.py": { + "TestConversionMetricDimensions::test_conversion_dimension_join_prevents_cross_group_leaking": { + "category": "real-gap", + "evidence": "reason-97" + }, + "TestConversionMetricDimensions::test_conversion_with_derived_dimension_sql": { + "category": "real-gap", + "evidence": "reason-98" + }, + "TestConversionMetricDimensions::test_conversion_with_dimension": { + "category": "real-gap", + "evidence": "reason-99" + }, + "TestConversionMetricDimensions::test_conversion_with_time_granularity": { + "category": "real-gap", + "evidence": "reason-100" + }, + "TestConversionMetricDimensions::test_conversion_without_dimensions_still_works": { + "category": "real-gap", + "evidence": "reason-101" + }, + "TestDuplicateSegmentResolution::test_segment_not_double_applied": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestFanoutAllHops::test_multi_hop_fanout_detected": { + "category": "intentional-Python-only", + "evidence": "reason-102" + }, + "TestNullSafeJoin::test_join_condition_not_coalesce_equality": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestNullSafeJoin::test_null_dimension_in_full_outer_join": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestSharedFiltersOnOuterQuery::test_classify_filters_preserves_or_group_parens": { + "category": "intentional-Python-only", + "evidence": "reason-103" + }, + "TestSharedFiltersOnOuterQuery::test_compound_and_filter_decomposed_into_pushdowns": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestSharedFiltersOnOuterQuery::test_filter_rewrite_uses_ast": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestSharedFiltersOnOuterQuery::test_model_specific_filter_pushdown": { + "category": "real-gap", + "evidence": "reason-1" + }, + "TestSharedFiltersOnOuterQuery::test_or_group_parens_preserved_in_pushdown": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/test_foreign_key_dimensions.py": { + "test_foreign_key_as_dimension_no_join": { + "category": null, + "evidence": "reason-104" + }, + "test_foreign_key_dimension_with_join": { + "category": null, + "evidence": "reason-105" + } + }, + "tests/test_performance.py": { + "test_simple_rewrite_performance": { + "category": "intentional-Python-only", + "evidence": "reason-106" + }, + "test_complex_rewrite_performance": { + "category": "intentional-Python-only", + "evidence": "reason-106" + }, + "test_sql_generation_performance": { + "category": "intentional-Python-only", + "evidence": "reason-106" + }, + "test_multi_join_generation_performance": { + "category": "intentional-Python-only", + "evidence": "reason-106" + }, + "test_filter_parsing_performance": { + "category": "intentional-Python-only", + "evidence": "reason-106" + }, + "test_query_rewriter_warm_vs_cold": { + "category": "intentional-Python-only", + "evidence": "reason-106" + }, + "test_parameter_substitution_performance": { + "category": "intentional-Python-only", + "evidence": "reason-106" + } + }, + "tests/test_query_fragment_boundary.py": { + "test_rewriter_cte_scope_does_not_authorize_structured_or_later_calls": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_cte_scope_allows_expression_plan_and_identifier_folding": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/test_sql_generation_security.py": { + "test_conversion_invalid_entity_rejected": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_conversion_invalid_window_rejected": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_conversion_event_name_quotes_escaped": { + "category": "real-gap", + "evidence": "reason-1" + }, + "test_count_fanout_uses_column_reference": { + "category": null, + "evidence": "reason-107" + }, + "test_build_interval_duckdb": { + "category": "intentional-Python-only", + "evidence": "reason-108" + }, + "test_build_interval_bigquery": { + "category": "intentional-Python-only", + "evidence": "reason-108" + }, + "test_build_interval_postgres": { + "category": "intentional-Python-only", + "evidence": "reason-108" + } + }, + "tests/test_workbench_demo.py": { + "test_workbench_demo_starter_queries_execute": { + "category": "real-gap", + "evidence": "reason-1" + } + }, + "tests/widget/test_widget_examples.py": { + "test_auto_model_metrics_generate_without_dependency_errors": { + "category": null, + "evidence": "reason-109" + }, + "test_notebook_metric_sql_generates": { + "category": null, + "evidence": "reason-110" + } + } + }, + "explanations": { + "reason-1": "docs/rust-parity-helper-evidence.json#unresolved-public-helper-contracts: These direct Python helper assertions have no assertion-level native counterpart established by this audit. This is a coverage gap, not a claim that native behavior is defective. Limitation: Do not count shared Rust-selected success for these helpers as native execution evidence. Public engine replay or an independently asserted native contract is required to close each item.", + "reason-2": "Per-test adjudication below distinguishes replay coverage, private units, and unresolved behavioral coverage.", + "reason-3": "OSI legacy adapter shim defaults to Python independently of --test-engine; separate backend override required.", + "reason-4": "Dependency availability gate; native Rust must be installed for acceptance.", + "reason-5": "Explicit LegacyOSIAdapter alias bypasses canonical native OSI adapter; legacy compatibility coverage needs separate Rust evidence.", + "reason-6": "Optional local dependency, artifact, fixture, or emulator compatibility gate.", + "reason-7": "Explicit use_rust_rewriter=True route in this test.", + "reason-8": "Explicit engine selection, legacy fallback, or routing contract.", + "reason-9": "Direct private implementation-unit calls: generator._model_needs_keyed_join_columns", + "reason-10": "docs/rust-parity-helper-evidence.json#nested-role-identity: origin$countries and destination$countries remain separately scoped join instances; native fixture asserts US/Canada and Canada/France independently. Counterparts: tests/semantic_conformance/test_relationship_role_parity.py::test_nested_country_paths_keep_parent_role_identity", + "reason-11": "docs/rust-parity-helper-evidence.json#timezone-routing: Timezone queries bypass UTC rollups; quote/space/backslash/newline injection attempts are rejected before SQL. Counterparts: tests/semantic_conformance/test_query_timezone_parity.py::test_timezone_bypasses_utc_rollup; tests/semantic_conformance/test_query_timezone_parity.py::test_timezone_rejects_invalid_characters", + "reason-12": "Direct private implementation-unit calls: SQLGenerator(g, dialect='bigquery', timezone='America/New_York')._date_trunc, SQLGenerator(g, dialect='mysql', timezone='UTC')._date_trunc, SQLGenerator(g, dialect='snowflake', timezone='America/New_York')._date_trunc, SQLGenerator(g, dialect='spark', timezone='America/New_York')._date_trunc", + "reason-13": "docs/rust-parity-helper-evidence.json#model-conversion-window: Model-local conversion metric selects distinct signup entities and counts purchases within an inclusive seven-day window; late purchases do not convert. Counterparts: tests/semantic_conformance/test_conversion_parity.py::test_unique_entities_and_inclusive_window Limitation: Python graph auto-registration bookkeeping remains Python-owned; the public native fixture tests model-local resolution and results.", + "reason-14": "docs/rust-parity-helper-evidence.json#timezone-period-lookup: Named dod/wow/mom/qoq/yoy map to calendar intervals without a declared grain; month result regression independently verifies sparse periods and category partitions. Counterparts: sidemantic-rs/src/sql/generator/temporal.rs::named_comparisons_have_calendar_intervals_without_declared_granularity; tests/semantic_conformance/test_feature_parity.py::test_named_calendar_comparison_without_declared_granularity Limitation: All five intervals have native unit assertions; the dual-engine result counterpart executes month specifically.", + "reason-15": "Explicit external database, network oracle, or integration environment gate.", + "reason-16": "Deselected by default addopts; may additionally have dependency or behavioral skips.", + "reason-17": "Behavioral or emulator limitation; do not count the omitted contract as parity.", + "reason-18": "Connection contract delegated to the integration suite.", + "reason-19": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_conversion_metric: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-20": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_conversion_metric_backwards_compatible: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-21": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_conversion_metric_steps_and_base_event: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-22": "docs/rust-parity-helper-evidence.json#temporal-null-fill: Fill applies to final cumulative/comparison/offset-ratio result; empty/prior-missing periods use the declared default instead of feeding a filled base value into the temporal operation. Counterparts: tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_final_default_keeps_null_base_and_partitions; tests/semantic_conformance/test_temporal_null_fill.py::test_missing_prior_and_zero_denominator_fill_after_calculation; tests/semantic_conformance/test_temporal_null_fill.py::test_offset_ratio_default_applies_after_sparse_prior_division", + "reason-23": "docs/rust-parity-helper-evidence.json#null-default-dependencies: Model leaf defaults are used by direct, derived and ratio dependencies; null groups/empty aggregates retain explicit defaults. Counterparts: tests/semantic_conformance/test_null_fill.py::test_metric_result_and_dependency_defaults; tests/semantic_conformance/test_null_fill.py::test_filled_leaf_participates_in_cross_source_calculation", + "reason-24": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_filter_dimension_with_model_qualified_sql_expr: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-25": "docs/rust-parity-helper-evidence.json#sparse-month-comparison: Month comparison subtracts the matching prior calendar month within each category and yields null across a missing month. Counterparts: tests/semantic_conformance/test_feature_parity.py::test_sparse_comparison_uses_calendar_month_and_category", + "reason-26": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_conversion_2_steps_via_steps_list: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-27": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_conversion_funnel: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-28": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_funnel_chronological_order_enforced: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-29": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_funnel_expression_timestamp: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-30": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_funnel_model_name_prefix_step_predicates: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-31": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_funnel_model_placeholder_filter: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-32": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_funnel_model_placeholder_step_predicates: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-33": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_funnel_model_placeholder_timestamp: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-34": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_funnel_monotonic_counts: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-35": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_funnel_only_prior_step2_not_counted: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-36": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_funnel_or_step_with_filter: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-37": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_funnel_order_by_metric_name: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-38": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_funnel_qualified_filters: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-39": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_funnel_repeated_actions_valid_path: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-40": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_advanced.py-test_multistep_funnel_total_excludes_non_entrants: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-41": "docs/rust-parity-helper-evidence.json#cumulative-year-reset: Year-to-date window partitions on calendar year rather than retaining prior-year rows. Counterparts: sidemantic-rs/src/sql/generator/temporal.rs::cumulative_frames_preserve_groups_and_calendar_reset Limitation: Native counterpart asserts emitted calendar-year partition/frame; it is not a result-level duplicate of the original fixture.", + "reason-42": "docs/rust-parity-helper-evidence.json#cohort-group-results: Model-local inner count-distinct/HAVING cohort qualification preserves outer dimension/time-grain names; outer average reads qualified inner aggregate values, and reserved output dimensions are quoted. Counterparts: tests/semantic_conformance/test_cohort_parity.py::test_count_counts_qualified_inner_groups_including_null_entity; tests/semantic_conformance/test_cohort_parity.py::test_query_grouping_changes_inner_and_outer_grain; tests/semantic_conformance/test_cohort_parity.py::test_time_bucket_is_carried_through_to_outer_output; tests/semantic_conformance/test_cohort_parity.py::test_outer_aggregations_read_qualified_inner_values; tests/semantic_conformance/test_cohort_parity.py::test_reserved_output_dimension_is_quoted Limitation: Counterparts cover the same operations with independent synthetic populations; graph-owner inference is explicitly excluded from this mapping.", + "reason-43": "docs/rust-parity-helper-evidence.json#unowned-graph-cohort: Python infers the unique source model from the graph-level cohort entity without metric_owners. Rust strict graph scope requires an explicit cohort owner and rejects this valid Python shape. Counterparts: tests/semantic_conformance/test_cohort_parity.py::test_owned_graph_cohort_unsupported_shapes_remain_gated; sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Counterpart is negative evidence: mutation=unowned is intentionally rejected. SemanticLayer.add_metric does not supply an owner, and graph_to_semantic_input preserves that absence. Source-confirmed; live repro remains lead-owned.", + "reason-44": "Co-located engine-parametrized native/reference oracle; inspect test and Rust import.", + "reason-45": "tests/core/test_pure_rust_python_test_parity.py::test_existing_python_layer_contract_matches_pure_rust[tests.metrics.test_cumulative::test_cumulative_with_time_comparison]", + "reason-46": "Direct private implementation-unit calls: generator._add_where_filters_to_query, generator._split_where_having_filters, snowflake_generator._split_where_having_filters", + "reason-47": "Direct private implementation-unit calls: generator._split_where_having_filters", + "reason-48": "Direct private implementation-unit calls: generator._add_where_filters_to_query", + "reason-49": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_retention.py-test_retention_aliased_entity_dimension: This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-50": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_retention.py-test_retention_day_granularity_results: This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-51": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_retention.py-test_retention_default_activity_event: This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-52": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_retention.py-test_retention_filter_with_model_qualified_sql_expr: This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-53": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_retention.py-test_retention_metric_level_filters: This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-54": "docs/rust-parity-helper-evidence.json#model-retention: Model-local retention executes with a fixed cohort/period/active_users/cohort_size/percentage schema. Counterparts: tests/semantic_conformance/test_retention_parity.py::test_first_cohort_sparse_periods_nulls_and_inactive_denominator", + "reason-55": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_retention.py-test_retention_model_placeholder_expansion_sql_model: This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-56": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_retention.py-test_retention_model_placeholder_expansion_table_model: This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-57": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_retention.py-test_retention_model_placeholder_in_time_dimension: This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-58": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_retention.py-test_retention_offset_in_sql: This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-59": "docs/rust-parity-helper-evidence.json#retention-period-validation: Zero retention periods are rejected instead of silently defaulting to 28. Counterparts: sidemantic-rs/src/sql/generator/retention.rs::retention_requires_valid_period_and_granularity", + "reason-60": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_retention.py-test_retention_sql_generation: This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-61": "docs/rust-parity-helper-evidence.json#unowned-tests-metrics-test_retention.py-test_retention_week_granularity: This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-62": "Direct private implementation-unit calls: generator._has_fanout_joins", + "reason-63": "docs/rust-parity-helper-evidence.json#shared-native-manifest-rewrite: Both harnesses load tests/native-fixtures/manifest.yml rewrite_queries and assert each sql_contains token after semantic rewrite. Counterparts: sidemantic-rs/tests/native_fixtures.rs::native_fixtures_load_and_compile Limitation: Compilation/token assertions only; this source test does not execute rewritten SQL.", + "reason-64": "docs/rust-parity-helper-evidence.json#legacy-rewriter-route: Explicit Python route override and monkeypatched Python _rewrite_python RuntimeError propagation test the legacy implementation contract, not a missing native semantic query feature.", + "reason-65": "Python optimizer plan/rule contract (module docstring); engine-selected SemanticLayer execution assertions remain active.", + "reason-66": "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_dry_run_with_postprocess_subquery]", + "reason-67": "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_explicit_join_requires_complete_composite_relationship]", + "reason-68": "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_postprocess_zero_limit_and_offset_in_outer]", + "reason-69": "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_query_without_metrics_or_dimensions]", + "reason-70": "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewrite_less_than_relative_date]", + "reason-71": "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewrite_not_equal_relative_date]", + "reason-72": "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewriter_directly]", + "reason-73": "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewriter_invalid_sql]", + "reason-74": "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewriter_non_select_query]", + "reason-75": "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_rewriter_non_strict_mode]", + "reason-76": "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_select_star_without_from]", + "reason-77": "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract[test_zero_limit_and_offset_are_preserved]", + "reason-78": "tests/core/test_pure_rust_python_test_parity.py::test_existing_python_layer_contract_matches_pure_rust[tests.queries.test_view_generation::test_generate_view_creates_valid_sql]", + "reason-79": "tests/core/test_pure_rust_python_test_parity.py::test_existing_python_layer_contract_matches_pure_rust[tests.queries.test_view_generation::test_join_view_against_other_tables]", + "reason-80": "tests/core/test_pure_rust_python_test_parity.py::test_existing_python_layer_contract_matches_pure_rust[tests.queries.test_view_generation::test_view_can_be_queried]", + "reason-81": "tests/core/test_pure_rust_python_test_parity.py::test_existing_python_layer_contract_matches_pure_rust[tests.queries.test_view_generation::test_view_name_sql_injection_rejected]", + "reason-82": "tests/core/test_pure_rust_python_test_parity.py::test_existing_python_layer_contract_matches_pure_rust[tests.queries.test_view_generation::test_view_name_with_spaces_rejected]", + "reason-83": "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_default_alias_not_applied_with_non_semantic_join]", + "reason-84": "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_expression_dimension_rewrite_uses_projection_alias]", + "reason-85": "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_generate_series_rewrite_uses_subquery_source]", + "reason-86": "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_lost_filter_warns_and_can_be_an_error]", + "reason-87": "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_unknown_or_ambiguous_measure_is_a_binding_error]", + "reason-88": "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_wrapper_explanation_matches_rewrite_and_emits_warning]", + "reason-89": "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_table_function_requires_single_literal_read]", + "reason-90": "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract[test_yardstick_wrapper_cannot_bypass_semantic_security]", + "reason-91": "Python SQLGenerator object reuse and graph identity contract.", + "reason-92": "Python graph private cache identity and SQLGenerator non-mutation contract.", + "reason-93": "Python-only parameter selection: adjudicate behavioral coverage separately from private implementation contracts.", + "reason-94": "Direct helper behavioral coverage has no established replay counterpart; requires native coverage adjudication, not a confirmed Rust defect.", + "reason-95": "Engine-asymmetric contract: skips the Python parameter; Rust still runs. Not a Rust-default blocker by itself.", + "reason-96": "Engine-parametrized layer fixture and result/rows helper branch between Rust bridge and Python helper in this module.", + "reason-97": "docs/rust-parity-helper-evidence.json#unowned-tests-test_bugfix_batch.py-test_conversion_dimension_join_prevents_cross_group_leaking: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-98": "docs/rust-parity-helper-evidence.json#unowned-tests-test_bugfix_batch.py-test_conversion_with_derived_dimension_sql: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-99": "docs/rust-parity-helper-evidence.json#unowned-tests-test_bugfix_batch.py-test_conversion_with_dimension: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-100": "docs/rust-parity-helper-evidence.json#unowned-tests-test_bugfix_batch.py-test_conversion_with_time_granularity: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-101": "docs/rust-parity-helper-evidence.json#unowned-tests-test_bugfix_batch.py-test_conversion_without_dimensions_still_works: This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract. Counterparts: sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners Limitation: Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported.", + "reason-102": "Direct private implementation-unit calls: gen._has_fanout_joins", + "reason-103": "Direct private implementation-unit calls: gen._classify_filters_for_pushdown, self._build_graph", + "reason-104": "tests/core/test_pure_rust_python_test_parity.py::test_existing_python_layer_contract_matches_pure_rust[tests.test_foreign_key_dimensions::test_foreign_key_as_dimension_no_join]", + "reason-105": "tests/core/test_pure_rust_python_test_parity.py::test_existing_python_layer_contract_matches_pure_rust[tests.test_foreign_key_dimensions::test_foreign_key_dimension_with_join]", + "reason-106": "docs/rust-parity-helper-evidence.json#python-helper-timings: Timing thresholds and warm-cache comparisons directly benchmark Python SQLGenerator/QueryRewriter objects; these are not correctness exclusions or proof of native performance.", + "reason-107": "tests/core/test_pure_rust_python_test_parity.py::test_existing_python_layer_contract_matches_pure_rust[tests.test_sql_generation_security::test_count_fanout_uses_column_reference]", + "reason-108": "Direct private implementation-unit calls: gen._build_interval", + "reason-109": "tests/core/test_pure_rust_python_test_parity.py::test_existing_python_layer_contract_matches_pure_rust[tests.widget.test_widget_examples::test_auto_model_metrics_generate_without_dependency_errors]", + "reason-110": "tests/core/test_pure_rust_python_test_parity.py::test_existing_python_layer_contract_matches_pure_rust[tests.widget.test_widget_examples::test_notebook_metric_sql_generates]" + } +} diff --git a/docs/rust-parity-exceptions.md b/docs/rust-parity-exceptions.md new file mode 100644 index 000000000..8233d77a9 --- /dev/null +++ b/docs/rust-parity-exceptions.md @@ -0,0 +1,165 @@ +# Rust parity exception inventory + +Generated by `uv run --no-project scripts/audit_engine_exceptions.py`. + +This is an auditable source inventory, not a passing-test claim. The JSON contains every matched source expression, enclosing condition, qualified scope, and statically affected test function. + +## Counts + +```json +{ + "source_records": 740, + "by_kind": { + "engine-control": 244, + "engine-matrix": 94, + "implementation-import": 83, + "importorskip": 202, + "integration-marker": 13, + "legacy-adapter-import": 6, + "public-layer-import": 20, + "skip": 65, + "skipif": 13 + }, + "exception_records": 366, + "observation_records": 374, + "exceptions_by_category": { + "external-service": 42, + "intentional-Python-only": 35, + "optional-host": 235, + "real-gap": 54 + }, + "exceptions_by_direction": { + "both-engines": 279, + "python-only-exclusion": 14, + "rust-coverage-exclusion": 73 + }, + "declared_test_functions": 6511, + "collected_nodeids": 11876, + "direct_helper_tests": { + "native_counterpart_or_route": 84, + "intentional_python_implementation": 126, + "unresolved_native_coverage": 129 + } +} +``` + +## Interpretation + +- Static source inventory, not execution results or proof of product defects. +- Declared scope expansion follows local fixture/helper references conservatively; dynamic imports, cross-module fixtures, and generated parity cases require collection/runtime evidence. +- Engine-aware imports and explicit Rust/differential routing are observations with is_exception=false and category=null. +- real-gap includes Python-only omissions and unproven Rust coverage, not only confirmed Rust failures. +- Module dependency gates and integration deselection can overlap behavioral omissions; records are not additive test counts. +- Only actual exclusions appear in exceptions. affected_scope=self means the source test; module means its module; subtree means the conftest directory (conservative); other values reference affected_scopes. rationale references explanations. Routing observations contribute counts only. Empty conditions are omitted. Helper assessments retain native counterpart evidence. + +- Missing native Rust is an `optional-host` gate operationally, but unacceptable for a Rust-readiness run. +- `--test-engine rust` selects the public layer. Importing that layer from its implementation module does not pin Python. Direct `SQLGenerator` and `QueryRewriter` use must be assessed separately. +- CI runs Python 3.11–3.14 for Python and 3.12 for Rust. Both shared lanes exclude `integration`; integration.yml supplies separate engine runs. Inspect `selection_rules` for all commands and environment controls. +- Zero executable xfail records means the prose mention of xfail in LookML fixtures is not an active exemption. + +## Behavioral omissions and Python pins + +| Source scope | Kind | Reason | +| --- | --- | --- | +| `tests/adapters/osi/conftest.py::_backend_is_rust` | engine-control | OSI legacy adapter shim defaults to Python independently of --test-engine; separate backend override required. | +| `tests/adapters/osi/test_parsing.py::` | legacy-adapter-import | Explicit LegacyOSIAdapter alias bypasses canonical native OSI adapter; legacy compatibility coverage needs separate Rust evidence. | +| `tests/adapters/osi/test_query_execution.py::` | legacy-adapter-import | Explicit LegacyOSIAdapter alias bypasses canonical native OSI adapter; legacy compatibility coverage needs separate Rust evidence. | +| `tests/adapters/test_added_fixture_coverage.py::` | legacy-adapter-import | Explicit LegacyOSIAdapter alias bypasses canonical native OSI adapter; legacy compatibility coverage needs separate Rust evidence. | +| `tests/adapters/test_fixture_functionality_contracts.py::` | legacy-adapter-import | Explicit LegacyOSIAdapter alias bypasses canonical native OSI adapter; legacy compatibility coverage needs separate Rust evidence. | +| `tests/db/test_bigquery_integration.py::test_semantic_layer_date_functions` | skip | Behavioral or emulator limitation; do not count the omitted contract as parity. | +| `tests/db/test_clickhouse_integration.py::test_semantic_layer_date_functions` | skip | Behavioral or emulator limitation; do not count the omitted contract as parity. | +| `tests/db/test_snowflake_integration.py::test_semantic_layer_date_functions` | skip | Behavioral or emulator limitation; do not count the omitted contract as parity. | +| `tests/db/test_spark_integration.py::test_semantic_layer_date_functions` | skip | Behavioral or emulator limitation; do not count the omitted contract as parity. | +| `tests/semantic_conformance/test_approximate_distinct.py::test_approximate_dialect_rendering_and_population_results` | skip | Behavioral or emulator limitation; do not count the omitted contract as parity. | +| `tests/semantic_conformance/test_approximate_distinct.py::test_redshift_nested_approximate_expressions_use_independent_parser` | skip | Behavioral or emulator limitation; do not count the omitted contract as parity. | +| `tests/semantic_conformance/test_complete_filters.py::test_tsql_complete_row_count_retains_existing_path` | engine-matrix | Python-only parameter selection: adjudicate behavioral coverage separately from private implementation contracts. | +| `tests/semantic_conformance/test_time_key_projection.py::test_time_identity_stays_unbucketed_for_join_and_fanout` | skip | Behavioral or emulator limitation; do not count the omitted contract as parity. | + +## Direct implementation coverage + +The JSON enumerates direct helper imports and their scopes. These are coverage warnings, not assertions that every helper test should be rewritten: implementation-unit contracts can remain Python-specific when their public behavior has independent native coverage. The parity replay in `tests/core/test_pure_rust_python_test_parity.py` selects modules, signatures, and explicit node IDs; it does not replay every Python test. Its monkeypatches and `tests/rust_layer_adapter.py` routing are included in the inventory. + +To expand to parametrized IDs, save the output of an authorized collect-only run to a file, then pass `--collected-nodeids FILE`. The report does not import tests, install packages, or compile extensions. + +Each count below is a unique declared function, not parametrized cases. Native counterparts are identified by exact replay selection or a co-located explicit native route; unresolved means the static audit has not established coverage. + +| Helper consumer | Native counterpart / route | Private Python contract | Unresolved native coverage | +| --- | ---: | ---: | ---: | +| `tests/adapters/bsl/test_parsing.py` | 0 | 0 | 6 | +| `tests/adapters/cube/test_fixtures.py` | 0 | 0 | 5 | +| `tests/adapters/metricflow/test_parsing.py` | 0 | 0 | 7 | +| `tests/adapters/sidemantic_adapter/test_parsing.py` | 0 | 0 | 1 | +| `tests/adapters/tableau/test_real_world.py` | 0 | 0 | 2 | +| `tests/adapters/test_added_fixture_coverage.py` | 0 | 0 | 2 | +| `tests/adapters/test_fixture_functionality_contracts.py` | 0 | 0 | 4 | +| `tests/adapters/tmdl/test_parsing.py` | 0 | 0 | 2 | +| `tests/core/test_invariant_filters.py` | 1 | 0 | 0 | +| `tests/core/test_relationship_role_aliases.py` | 1 | 1 | 2 | +| `tests/core/test_security_advisor_regressions.py` | 0 | 0 | 1 | +| `tests/dates/test_query_timezone.py` | 2 | 1 | 0 | +| `tests/dates/test_time_comparison.py` | 2 | 0 | 1 | +| `tests/metrics/test_advanced.py` | 8 | 0 | 29 | +| `tests/metrics/test_cohort.py` | 5 | 0 | 6 | +| `tests/metrics/test_conversion_source_parity.py` | 3 | 0 | 0 | +| `tests/metrics/test_cumulative.py` | 1 | 0 | 3 | +| `tests/metrics/test_filters.py` | 0 | 3 | 0 | +| `tests/metrics/test_non_additive_guard.py` | 0 | 0 | 1 | +| `tests/metrics/test_retention.py` | 2 | 0 | 15 | +| `tests/metrics/test_symmetric_aggs.py` | 0 | 2 | 11 | +| `tests/native_compat/test_basic_model_fixture.py` | 1 | 0 | 0 | +| `tests/queries/test_cross_model_calculated_grain.py` | 0 | 0 | 4 | +| `tests/queries/test_deterministic_join_anchor.py` | 0 | 0 | 1 | +| `tests/queries/test_rust_query_rewriter_route.py` | 12 | 1 | 0 | +| `tests/queries/test_rust_rewrite_preaggregation_options.py` | 1 | 0 | 0 | +| `tests/queries/test_semantic_sql_planner.py` | 0 | 102 | 0 | +| `tests/queries/test_sql_fallback_policy.py` | 2 | 1 | 0 | +| `tests/queries/test_sql_rewriter.py` | 12 | 0 | 0 | +| `tests/queries/test_temporal_sql_projection.py` | 0 | 0 | 2 | +| `tests/queries/test_view_generation.py` | 5 | 0 | 0 | +| `tests/queries/test_yardstick_query_rewriter.py` | 3 | 0 | 0 | +| `tests/queries/test_yardstick_warnings.py` | 5 | 0 | 0 | +| `tests/semantic_conformance/test_complete_filters.py` | 0 | 2 | 1 | +| `tests/semantic_conformance/test_default_time_differential.py` | 0 | 0 | 1 | +| `tests/semantic_conformance/test_filtered_count_family.py` | 0 | 1 | 0 | +| `tests/semantic_conformance/test_parameterized_segments.py` | 4 | 0 | 0 | +| `tests/semantic_conformance/test_policy_cli.py` | 2 | 0 | 0 | +| `tests/semantic_conformance/test_postgres_policies.py` | 1 | 0 | 0 | +| `tests/semantic_conformance/test_yardstick_source_dialects.py` | 6 | 0 | 0 | +| `tests/templates/test_parameters.py` | 0 | 0 | 4 | +| `tests/test_bugfix_batch.py` | 0 | 2 | 12 | +| `tests/test_foreign_key_dimensions.py` | 2 | 0 | 0 | +| `tests/test_performance.py` | 0 | 7 | 0 | +| `tests/test_query_fragment_boundary.py` | 0 | 0 | 2 | +| `tests/test_sql_generation_security.py` | 1 | 3 | 3 | +| `tests/test_workbench_demo.py` | 0 | 0 | 1 | +| `tests/widget/test_widget_examples.py` | 2 | 0 | 0 | + +## Execution evidence + +PR 409 review working tree based on 5ca50124, Python 3.13 / DuckDB 1.5.6 / rebuilt native engine. Full Rust shared lane before the final Python local-calculation and funnel DATE-expectation fixes: 11724 passed, 147 skipped, 2 failed. Both failures were the funnel DATE expectation; after repair its full module passed 45 tests. Final calculation follow-ups: 2913 conformance passes plus those two repaired assertions, 958 metric/query passes, and 520/520 generated inputs agreed. + +JUnit: 11873 cases, 147 skipped, 2 failures, 0 errors. + +JUnit does not enumerate deselected tests. Historical results do not validate current edits. + +| Skip reason | Cases | +| --- | ---: | +| Existing native direct-call batch contract; public Python rejects strict batches | 2 | +| Native boundary syntax contract; target-dialect result oracle is shared above | 5 | +| Native effective-anchor routing regression | 2 | +| Native input validation contract | 1 | +| Native output-name collision contract | 1 | +| Native rewrite boundary contract | 3 | +| Native source-dialect literal contract | 12 | +| Native subquery scope regression | 1 | +| PostgreSQL adapter available, tested in integration tests | 1 | +| PostgreSQL execution requires SIDEMANTIC_TEST_POSTGRES_DSN | 44 | +| PostgreSQL policy execution requires SIDEMANTIC_TEST_POSTGRES_DSN | 36 | +| Python joins physical keys; native computed-key identity has its own independent oracle | 1 | +| Python reparses completed Redshift aggregates with its generic SQL parser | 3 | +| Rust target emission; Python reparses Redshift using its generic parser | 3 | +| Set SIDEMANTIC_YARDSTICK_UPSTREAM_TESTS=1 to fetch and replay live upstream Yardstick tests | 2 | +| Strict Rust compiler validation contract | 9 | +| could not import 'anywidget': No module named 'anywidget' | 8 | +| could not import 'textual': No module named 'textual' | 2 | +| set SIDEMANTIC_DAX_ONLINE_CONFORMANCE=1 to probe DAX Formatter | 11 | diff --git a/docs/rust-parity-helper-evidence.json b/docs/rust-parity-helper-evidence.json new file mode 100644 index 000000000..467fa933a --- /dev/null +++ b/docs/rust-parity-helper-evidence.json @@ -0,0 +1,778 @@ +{ + "schema_version": 1, + "basis": "Source-level assertion review only; no execution is claimed. Native tests under src are included alongside integration tests.", + "groups": [ + { + "id": "timezone-routing", + "category": null, + "status": "native-contract", + "source_tests": [ + "tests/dates/test_query_timezone.py::test_generator_timezone_bypasses_preagg_routing", + "tests/dates/test_query_timezone.py::test_timezone_value_is_validated_against_injection" + ], + "behavior": "Timezone queries bypass UTC rollups; quote/space/backslash/newline injection attempts are rejected before SQL.", + "counterparts": [ + "tests/semantic_conformance/test_query_timezone_parity.py::test_timezone_bypasses_utc_rollup", + "tests/semantic_conformance/test_query_timezone_parity.py::test_timezone_rejects_invalid_characters" + ] + }, + { + "id": "shared-native-manifest-rewrite", + "category": null, + "status": "native-contract", + "source_tests": [ + "tests/native_compat/test_basic_model_fixture.py::test_native_fixture_rewrites_semantic_sql" + ], + "behavior": "Both harnesses load tests/native-fixtures/manifest.yml rewrite_queries and assert each sql_contains token after semantic rewrite.", + "counterparts": [ + "sidemantic-rs/tests/native_fixtures.rs::native_fixtures_load_and_compile" + ], + "limitation": "Compilation/token assertions only; this source test does not execute rewritten SQL." + }, + { + "id": "nested-role-identity", + "category": null, + "status": "native-contract", + "source_tests": [ + "tests/core/test_relationship_role_aliases.py::test_nested_role_alias_is_scoped_to_parent_instance" + ], + "behavior": "origin$countries and destination$countries remain separately scoped join instances; native fixture asserts US/Canada and Canada/France independently.", + "counterparts": [ + "tests/semantic_conformance/test_relationship_role_parity.py::test_nested_country_paths_keep_parent_role_identity" + ] + }, + { + "id": "timezone-period-lookup", + "category": null, + "status": "native-contract", + "source_tests": [ + "tests/dates/test_time_comparison.py::test_named_calendar_comparison_without_declared_granularity" + ], + "behavior": "Named dod/wow/mom/qoq/yoy map to calendar intervals without a declared grain; month result regression independently verifies sparse periods and category partitions.", + "counterparts": [ + "sidemantic-rs/src/sql/generator/temporal.rs::named_comparisons_have_calendar_intervals_without_declared_granularity", + "tests/semantic_conformance/test_feature_parity.py::test_named_calendar_comparison_without_declared_granularity" + ], + "limitation": "All five intervals have native unit assertions; the dual-engine result counterpart executes month specifically." + }, + { + "id": "cumulative-year-reset", + "category": null, + "status": "native-contract", + "source_tests": [ + "tests/metrics/test_advanced.py::test_year_to_date_metric" + ], + "behavior": "Year-to-date window partitions on calendar year rather than retaining prior-year rows.", + "counterparts": [ + "sidemantic-rs/src/sql/generator/temporal.rs::cumulative_frames_preserve_groups_and_calendar_reset" + ], + "limitation": "Native counterpart asserts emitted calendar-year partition/frame; it is not a result-level duplicate of the original fixture." + }, + { + "id": "temporal-null-fill", + "category": null, + "status": "native-contract", + "source_tests": [ + "tests/metrics/test_advanced.py::test_cumulative_fill_nulls_applies_after_window", + "tests/metrics/test_advanced.py::test_time_comparison_fill_nulls_applies_to_missing_prior_period", + "tests/metrics/test_advanced.py::test_offset_ratio_fill_nulls_applies_to_missing_prior_period" + ], + "behavior": "Fill applies to final cumulative/comparison/offset-ratio result; empty/prior-missing periods use the declared default instead of feeding a filled base value into the temporal operation.", + "counterparts": [ + "tests/semantic_conformance/test_temporal_null_fill.py::test_cumulative_final_default_keeps_null_base_and_partitions", + "tests/semantic_conformance/test_temporal_null_fill.py::test_missing_prior_and_zero_denominator_fill_after_calculation", + "tests/semantic_conformance/test_temporal_null_fill.py::test_offset_ratio_default_applies_after_sparse_prior_division" + ] + }, + { + "id": "null-default-dependencies", + "category": null, + "status": "native-contract", + "source_tests": [ + "tests/metrics/test_advanced.py::test_fill_nulls_with_zero", + "tests/metrics/test_advanced.py::test_model_measure_null_fill_applies_to_direct_and_dependent_metrics" + ], + "behavior": "Model leaf defaults are used by direct, derived and ratio dependencies; null groups/empty aggregates retain explicit defaults.", + "counterparts": [ + "tests/semantic_conformance/test_null_fill.py::test_metric_result_and_dependency_defaults", + "tests/semantic_conformance/test_null_fill.py::test_filled_leaf_participates_in_cross_source_calculation" + ] + }, + { + "id": "sparse-month-comparison", + "category": null, + "status": "native-contract", + "source_tests": [ + "tests/metrics/test_advanced.py::test_mom_difference", + "tests/metrics/test_advanced.py::test_month_comparison_does_not_use_previous_available_sparse_row" + ], + "behavior": "Month comparison subtracts the matching prior calendar month within each category and yields null across a missing month.", + "counterparts": [ + "tests/semantic_conformance/test_feature_parity.py::test_sparse_comparison_uses_calendar_month_and_category" + ] + }, + { + "id": "model-conversion-window", + "category": null, + "status": "native-contract", + "source_tests": [ + "tests/dates/test_time_comparison.py::test_model_level_conversion_metric" + ], + "behavior": "Model-local conversion metric selects distinct signup entities and counts purchases within an inclusive seven-day window; late purchases do not convert.", + "counterparts": [ + "tests/semantic_conformance/test_conversion_parity.py::test_unique_entities_and_inclusive_window" + ], + "limitation": "Python graph auto-registration bookkeeping remains Python-owned; the public native fixture tests model-local resolution and results." + }, + { + "id": "model-retention", + "category": null, + "status": "native-contract", + "source_tests": [ + "tests/metrics/test_retention.py::test_retention_model_level_metric" + ], + "behavior": "Model-local retention executes with a fixed cohort/period/active_users/cohort_size/percentage schema.", + "counterparts": [ + "tests/semantic_conformance/test_retention_parity.py::test_first_cohort_sparse_periods_nulls_and_inactive_denominator" + ] + }, + { + "id": "retention-period-validation", + "category": null, + "status": "native-contract", + "source_tests": [ + "tests/metrics/test_retention.py::test_retention_periods_zero_raises_validation_error" + ], + "behavior": "Zero retention periods are rejected instead of silently defaulting to 28.", + "counterparts": [ + "sidemantic-rs/src/sql/generator/retention.rs::retention_requires_valid_period_and_granularity" + ] + }, + { + "id": "cohort-group-results", + "category": null, + "status": "native-contract", + "source_tests": [ + "tests/metrics/test_cohort.py::test_cohort_basic", + "tests/metrics/test_cohort.py::test_cohort_with_dimension", + "tests/metrics/test_cohort.py::test_cohort_with_time_grain_uses_grained_output_alias", + "tests/metrics/test_cohort.py::test_cohort_outer_sql_references_subquery", + "tests/metrics/test_cohort.py::test_cohort_reserved_word_dimension" + ], + "behavior": "Model-local inner count-distinct/HAVING cohort qualification preserves outer dimension/time-grain names; outer average reads qualified inner aggregate values, and reserved output dimensions are quoted.", + "counterparts": [ + "tests/semantic_conformance/test_cohort_parity.py::test_count_counts_qualified_inner_groups_including_null_entity", + "tests/semantic_conformance/test_cohort_parity.py::test_query_grouping_changes_inner_and_outer_grain", + "tests/semantic_conformance/test_cohort_parity.py::test_time_bucket_is_carried_through_to_outer_output", + "tests/semantic_conformance/test_cohort_parity.py::test_outer_aggregations_read_qualified_inner_values", + "tests/semantic_conformance/test_cohort_parity.py::test_reserved_output_dimension_is_quoted" + ], + "limitation": "Counterparts cover the same operations with independent synthetic populations; graph-owner inference is explicitly excluded from this mapping." + }, + { + "id": "legacy-rewriter-route", + "category": "intentional-Python-only", + "status": "implementation-contract", + "source_tests": [ + "tests/queries/test_rust_query_rewriter_route.py::test_explicit_python_overrides_legacy_environment", + "tests/queries/test_sql_fallback_policy.py::test_non_strict_rewrite_does_not_hide_runtime_bug" + ], + "behavior": "Explicit Python route override and monkeypatched Python _rewrite_python RuntimeError propagation test the legacy implementation contract, not a missing native semantic query feature.", + "counterparts": [] + }, + { + "id": "python-helper-timings", + "category": "intentional-Python-only", + "status": "implementation-contract", + "source_tests": [ + "tests/test_performance.py::test_simple_rewrite_performance", + "tests/test_performance.py::test_complex_rewrite_performance", + "tests/test_performance.py::test_sql_generation_performance", + "tests/test_performance.py::test_multi_join_generation_performance", + "tests/test_performance.py::test_filter_parsing_performance", + "tests/test_performance.py::test_query_rewriter_warm_vs_cold", + "tests/test_performance.py::test_parameter_substitution_performance" + ], + "behavior": "Timing thresholds and warm-cache comparisons directly benchmark Python SQLGenerator/QueryRewriter objects; these are not correctness exclusions or proof of native performance.", + "counterparts": [] + }, + { + "id": "unowned-graph-cohort", + "category": "real-gap", + "status": "unsupported-valid-shape", + "source_tests": [ + "tests/metrics/test_cohort.py::test_cohort_graph_level_metric" + ], + "behavior": "Python infers the unique source model from the graph-level cohort entity without metric_owners. Rust strict graph scope requires an explicit cohort owner and rejects this valid Python shape.", + "counterparts": [ + "tests/semantic_conformance/test_cohort_parity.py::test_owned_graph_cohort_unsupported_shapes_remain_gated", + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Counterpart is negative evidence: mutation=unowned is intentionally rejected. SemanticLayer.add_metric does not supply an owner, and graph_to_semantic_input preserves that absence. Source-confirmed; live repro remains lead-owned." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_conversion_metric", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_conversion_metric" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_conversion_funnel", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_conversion_funnel" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_conversion_2_steps_via_steps_list", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_conversion_2_steps_via_steps_list" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_conversion_metric_backwards_compatible", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_conversion_metric_backwards_compatible" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_conversion_metric_steps_and_base_event", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_conversion_metric_steps_and_base_event" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_funnel_monotonic_counts", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_funnel_monotonic_counts" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_funnel_total_excludes_non_entrants", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_funnel_total_excludes_non_entrants" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_funnel_chronological_order_enforced", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_funnel_chronological_order_enforced" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_funnel_qualified_filters", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_funnel_qualified_filters" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_filter_dimension_with_model_qualified_sql_expr", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_filter_dimension_with_model_qualified_sql_expr" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_funnel_repeated_actions_valid_path", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_funnel_repeated_actions_valid_path" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_funnel_only_prior_step2_not_counted", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_funnel_only_prior_step2_not_counted" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_funnel_expression_timestamp", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_funnel_expression_timestamp" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_funnel_or_step_with_filter", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_funnel_or_step_with_filter" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_funnel_model_placeholder_timestamp", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_funnel_model_placeholder_timestamp" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_funnel_model_placeholder_step_predicates", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_funnel_model_placeholder_step_predicates" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_funnel_model_name_prefix_step_predicates", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_funnel_model_name_prefix_step_predicates" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_funnel_model_placeholder_filter", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_funnel_model_placeholder_filter" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_advanced.py-test_multistep_funnel_order_by_metric_name", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_advanced.py::test_multistep_funnel_order_by_metric_name" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_retention.py-test_retention_sql_generation", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_retention.py::test_retention_sql_generation" + ], + "behavior": "This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_retention.py-test_retention_day_granularity_results", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_retention.py::test_retention_day_granularity_results" + ], + "behavior": "This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_retention.py-test_retention_default_activity_event", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_retention.py::test_retention_default_activity_event" + ], + "behavior": "This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_retention.py-test_retention_week_granularity", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_retention.py::test_retention_week_granularity" + ], + "behavior": "This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_retention.py-test_retention_model_placeholder_expansion_sql_model", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_retention.py::test_retention_model_placeholder_expansion_sql_model" + ], + "behavior": "This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_retention.py-test_retention_model_placeholder_expansion_table_model", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_retention.py::test_retention_model_placeholder_expansion_table_model" + ], + "behavior": "This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_retention.py-test_retention_model_placeholder_in_time_dimension", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_retention.py::test_retention_model_placeholder_in_time_dimension" + ], + "behavior": "This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_retention.py-test_retention_aliased_entity_dimension", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_retention.py::test_retention_aliased_entity_dimension" + ], + "behavior": "This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_retention.py-test_retention_metric_level_filters", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_retention.py::test_retention_metric_level_filters" + ], + "behavior": "This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_retention.py-test_retention_filter_with_model_qualified_sql_expr", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_retention.py::test_retention_filter_with_model_qualified_sql_expr" + ], + "behavior": "This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-metrics-test_retention.py-test_retention_offset_in_sql", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/metrics/test_retention.py::test_retention_offset_in_sql" + ], + "behavior": "This positive test adds a retention metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-test_bugfix_batch.py-test_conversion_with_dimension", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/test_bugfix_batch.py::TestConversionMetricDimensions::test_conversion_with_dimension" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-test_bugfix_batch.py-test_conversion_without_dimensions_still_works", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/test_bugfix_batch.py::TestConversionMetricDimensions::test_conversion_without_dimensions_still_works" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-test_bugfix_batch.py-test_conversion_dimension_join_prevents_cross_group_leaking", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/test_bugfix_batch.py::TestConversionMetricDimensions::test_conversion_dimension_join_prevents_cross_group_leaking" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-test_bugfix_batch.py-test_conversion_with_time_granularity", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/test_bugfix_batch.py::TestConversionMetricDimensions::test_conversion_with_time_granularity" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unowned-tests-test_bugfix_batch.py-test_conversion_with_derived_dimension_sql", + "category": "real-gap", + "status": "graph-scope-coverage-gap", + "source_tests": [ + "tests/test_bugfix_batch.py::TestConversionMetricDimensions::test_conversion_with_derived_dimension_sql" + ], + "behavior": "This positive test adds a conversion metric with graph.add_metric and no owner. The positive public counterparts reviewed use model-local metrics; they do not prove the graph-scoped contract.", + "counterparts": [ + "sidemantic-rs/src/sql/generator.rs::strict_graph_metric_owners" + ], + "limitation": "Strict owner discovery does not inspect entity/event fields; live native rejection and any source inference from qualified filters must be checked before calling every variant unsupported." + }, + { + "id": "unresolved-public-helper-contracts", + "category": "real-gap", + "status": "unresolved-coverage", + "source_tests": [ + "tests/adapters/bsl/test_parsing.py::TestBSLCurrentSyntaxSupport::test_all_calculated_measure_compiles_to_window_total", + "tests/adapters/bsl/test_parsing.py::TestBSLCurrentSyntaxSupport::test_cross_join_compiles", + "tests/adapters/bsl/test_parsing.py::TestBSLCurrentSyntaxSupport::test_deferred_calculated_measure_compiles", + "tests/adapters/bsl/test_parsing.py::TestBSLCurrentSyntaxSupport::test_join_aliases_self_join_and_how_roundtrip", + "tests/adapters/bsl/test_parsing.py::TestBSLCurrentSyntaxSupport::test_qualified_calculated_measure_compiles_joined_measure", + "tests/adapters/bsl/test_parsing.py::TestBSLCurrentSyntaxSupport::test_reused_join_aliases_scope_to_source_model", + "tests/adapters/cube/test_fixtures.py::TestTesseractFeatures::test_aggregate_complete_measures_queryable", + "tests/adapters/cube/test_fixtures.py::TestTesseractFeatures::test_complete_measure_applies_filters", + "tests/adapters/cube/test_fixtures.py::TestTesseractFeatures::test_complete_measure_preserves_raw_timestamp", + "tests/adapters/cube/test_fixtures.py::TestTesseractFeatures::test_plain_complete_measure_grouped_by_other_dimension", + "tests/adapters/cube/test_fixtures.py::TestTesseractFeatures::test_plain_non_numeric_measures_queryable", + "tests/adapters/metricflow/test_parsing.py::test_metricflow_adapter_join_discovery", + "tests/adapters/metricflow/test_parsing.py::test_metricflow_derived_non_offset_aliases_queryable", + "tests/adapters/metricflow/test_parsing.py::test_metricflow_disabled_model_skips_inline_metrics", + "tests/adapters/metricflow/test_parsing.py::test_metricflow_inline_constant_count_anchored_to_model", + "tests/adapters/metricflow/test_parsing.py::test_metricflow_inline_exprless_non_count_uses_metric_column", + "tests/adapters/metricflow/test_parsing.py::test_metricflow_keyless_inline_count_planner_contract", + "tests/adapters/metricflow/test_parsing.py::test_metricflow_latest_spec_inline_metric_queryable_alone", + "tests/adapters/sidemantic_adapter/test_parsing.py::test_dimension_window_in_sql_generation", + "tests/adapters/tableau/test_real_world.py::test_sf_trial_joined_metric_uses_collection_sql", + "tests/adapters/tableau/test_real_world.py::test_shapes_joined_dimension_uses_collection_sql", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_execute_sql_for_execution_candidates", + "tests/adapters/test_added_fixture_coverage.py::test_added_fixtures_generate_sql_for_compile_candidates", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_adapter_exact_execution_semantics", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_query_compilation_coverage", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_query_execution_coverage", + "tests/adapters/test_fixture_functionality_contracts.py::test_fixture_representative_execution_semantics", + "tests/adapters/tmdl/test_parsing.py::test_tmdl_dax_only_calculated_table_is_not_compiled_as_sql", + "tests/adapters/tmdl/test_parsing.py::test_tmdl_untranslated_dax_dimension_is_not_compiled_as_sql", + "tests/core/test_relationship_role_aliases.py::test_role_alias_one_to_many_keeps_base_measure_fanout_safe", + "tests/core/test_relationship_role_aliases.py::test_two_roles_to_same_target_use_distinct_join_instances", + "tests/core/test_security_advisor_regressions.py::test_rewriter_threads_user_attributes", + "tests/dates/test_time_comparison.py::test_model_level_time_comparison_metric", + "tests/metrics/test_advanced.py::test_dotted_metric_name_alias", + "tests/metrics/test_advanced.py::test_fill_nulls_with_string", + "tests/metrics/test_advanced.py::test_month_to_date_metric", + "tests/metrics/test_advanced.py::test_offset_ratio_metric", + "tests/metrics/test_advanced.py::test_offset_ratio_metric_multi_period", + "tests/metrics/test_advanced.py::test_offset_ratio_metric_uses_base_granularity", + "tests/metrics/test_advanced.py::test_offset_ratio_metric_year_offset", + "tests/metrics/test_advanced.py::test_wow_percent_change_partitions_by_dimension", + "tests/metrics/test_advanced.py::test_wow_ratio", + "tests/metrics/test_advanced.py::test_yoy_percent_change", + "tests/metrics/test_cohort.py::test_cohort_ambiguous_unqualified_raises", + "tests/metrics/test_cohort.py::test_cohort_mixed_with_conversion_raises", + "tests/metrics/test_cohort.py::test_cohort_model_scoped_unqualified", + "tests/metrics/test_cohort.py::test_cohort_outer_agg_without_sql_raises", + "tests/metrics/test_cohort.py::test_cohort_unknown_dimension_raises", + "tests/metrics/test_cumulative.py::test_time_comparison_over_derived_cumulative_chain", + "tests/metrics/test_cumulative.py::test_time_comparison_over_ratio_cumulative_chain", + "tests/metrics/test_cumulative.py::test_time_comparison_with_dependency_free_expression_metric", + "tests/metrics/test_non_additive_guard.py::test_semi_additive_compiles_without_qualify_on_postgres", + "tests/metrics/test_retention.py::test_retention_ambiguous_model_raises", + "tests/metrics/test_retention.py::test_retention_graph_metric_does_not_bind_to_same_name_model_metric", + "tests/metrics/test_retention.py::test_retention_mixed_with_regular_metric_raises", + "tests/metrics/test_retention.py::test_retention_multiple_retention_metrics_raises", + "tests/metrics/test_symmetric_aggs.py::test_derived_and_ratio_metrics_reuse_fanout_safe_leaf_aggregates", + "tests/metrics/test_symmetric_aggs.py::test_fanout_evaluates_complete_sql_over_deduplicated_entity_rows", + "tests/metrics/test_symmetric_aggs.py::test_fanout_isolates_typed_entity_rows_for_double_sum_avg_and_nulls", + "tests/metrics/test_symmetric_aggs.py::test_fanout_rejects_filtered_unqualified_constant_complete_sql", + "tests/metrics/test_symmetric_aggs.py::test_fanout_typed_composite_keys_do_not_collide_on_delimiters", + "tests/metrics/test_symmetric_aggs.py::test_filter_only_sibling_fanout_is_deduplicated_for_non_base_metric", + "tests/metrics/test_symmetric_aggs.py::test_filtered_count_under_fanout", + "tests/metrics/test_symmetric_aggs.py::test_model_measure_null_fill_under_fanout", + "tests/metrics/test_symmetric_aggs.py::test_preagg_grain_preserved_with_filters", + "tests/metrics/test_symmetric_aggs.py::test_symmetric_aggregates_in_sql_generation", + "tests/metrics/test_symmetric_aggs.py::test_symmetric_aggregates_with_data", + "tests/queries/test_cross_model_calculated_grain.py::test_calculated_metrics_preserve_each_source_grain", + "tests/queries/test_cross_model_calculated_grain.py::test_cross_model_calculation_output_name_collisions", + "tests/queries/test_cross_model_calculated_grain.py::test_filtered_ratio_rejects_unknown_customer_grain", + "tests/queries/test_cross_model_calculated_grain.py::test_mixed_row_and_calculation_or_rejected", + "tests/queries/test_deterministic_join_anchor.py::test_graph_metric_sql_reference_order_determines_one_to_one_join_anchor", + "tests/queries/test_temporal_sql_projection.py::test_repeated_metric_keeps_each_projection_alias", + "tests/queries/test_temporal_sql_projection.py::test_temporal_sql_exposes_only_requested_projection", + "tests/semantic_conformance/test_complete_filters.py::test_tsql_complete_row_count_retains_existing_path", + "tests/templates/test_parameters.py::test_parameters_with_actual_data", + "tests/templates/test_parameters.py::test_sql_generator_with_default_parameter", + "tests/templates/test_parameters.py::test_sql_generator_with_multiple_parameters", + "tests/templates/test_parameters.py::test_sql_generator_with_parameters", + "tests/test_bugfix_batch.py::TestDuplicateSegmentResolution::test_segment_not_double_applied", + "tests/test_bugfix_batch.py::TestNullSafeJoin::test_join_condition_not_coalesce_equality", + "tests/test_bugfix_batch.py::TestNullSafeJoin::test_null_dimension_in_full_outer_join", + "tests/test_bugfix_batch.py::TestSharedFiltersOnOuterQuery::test_compound_and_filter_decomposed_into_pushdowns", + "tests/test_bugfix_batch.py::TestSharedFiltersOnOuterQuery::test_filter_rewrite_uses_ast", + "tests/test_bugfix_batch.py::TestSharedFiltersOnOuterQuery::test_model_specific_filter_pushdown", + "tests/test_bugfix_batch.py::TestSharedFiltersOnOuterQuery::test_or_group_parens_preserved_in_pushdown", + "tests/test_query_fragment_boundary.py::test_cte_scope_allows_expression_plan_and_identifier_folding", + "tests/test_query_fragment_boundary.py::test_rewriter_cte_scope_does_not_authorize_structured_or_later_calls", + "tests/test_sql_generation_security.py::test_conversion_event_name_quotes_escaped", + "tests/test_sql_generation_security.py::test_conversion_invalid_entity_rejected", + "tests/test_sql_generation_security.py::test_conversion_invalid_window_rejected", + "tests/test_workbench_demo.py::test_workbench_demo_starter_queries_execute" + ], + "behavior": "These direct Python helper assertions have no assertion-level native counterpart established by this audit. This is a coverage gap, not a claim that native behavior is defective.", + "counterparts": [], + "limitation": "Do not count shared Rust-selected success for these helpers as native execution evidence. Public engine replay or an independently asserted native contract is required to close each item." + } + ], + "scope": { + "baseline_unresolved_helper_tests": 158, + "all_baseline_tests_assessed": 158, + "native_contract_tests": 21, + "intentional_python_tests": 9, + "remaining_coverage_gap_tests": 128 + } +} diff --git a/pyproject.toml b/pyproject.toml index 528de6ca4..0ee2e43d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ dependencies = [ "pyyaml>=6.0", "pydantic>=2.0.0", "jinja2>=3.1.0", - "duckdb>=1.0.0", + "duckdb>=1.4.4", "click>=8.0.0", "typer>=0.18.0", ] diff --git a/scripts/audit_engine_exceptions.py b/scripts/audit_engine_exceptions.py new file mode 100644 index 000000000..52d3fd182 --- /dev/null +++ b/scripts/audit_engine_exceptions.py @@ -0,0 +1,745 @@ +"""Inventory pytest exceptions and engine routing without importing or running tests. + +Run with ``uv run --no-project scripts/audit_engine_exceptions.py``. Optionally +supply ``--collected-nodeids FILE`` containing one pytest node ID per line to +expand static scopes to actual parametrized cases. Classification is deliberately +conservative: a pinned behavioral contract is a coverage gap until demonstrated +otherwise, not evidence that the Rust implementation itself is defective. +""" + +from __future__ import annotations + +import argparse +import ast +import json +import re +import tomllib +import xml.etree.ElementTree as ET +from collections import Counter +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +ENGINE_ENV = re.compile(r"SIDEMANTIC_(?:ENGINE|RS_|OSI_BACKEND)") +HELPERS = { + "SQLGenerator", + "QueryRewriter", + "RustRuntimeSemanticLayer", + "RustSemanticLayerAdapter", + "RustSQLGeneratorAdapter", + "RustQueryRewriterAdapter", + "RustSemanticGraphDirectAdapter", + "LegacyOSIAdapter", +} +CONTRACT_FILES = { + "tests/core/test_runtime_defaults.py", + "tests/core/test_rust_engine_mode.py", + "tests/core/test_rust_strict_sql_generator.py", + "tests/core/test_rust_query_validation.py", + "tests/test_cli_engine_routing.py", + "tests/core/test_rust_adapter_forwarding.py", +} +PRIVATE_CONTRACTS = { + "test_complete_row_count_generator_reuse_observes_graph_changes": "Python SQLGenerator object reuse and graph identity contract.", + "test_complete_row_count_role_queries_preserve_caller_caches": "Python graph private cache identity and SQLGenerator non-mutation contract.", + "test_owned_count_generator_sees_live_graph_changes": "Python SQLGenerator object reuse and graph identity contract.", +} + + +def classify(path, scope, kind, source, context): + text = (source + " " + context).lower() + if kind == "importorskip": + return "optional-host", "Dependency availability gate; native Rust must be installed for acceptance." + if kind in {"skip", "skipif", "xfail"}: + if any( + s in text + for s in ("date functions test", "format_date", "cross-model segments", "reparses", "physical keys") + ): + return "real-gap", "Behavioral or emulator limitation; do not count the omitted contract as parity." + if ( + any( + s in text + for s in ( + "postgres_dsn", + "_test", + "databricks_url", + "dax_online", + "dax_engine_conformance", + "yardstick_upstream", + "adbc_db", + "postgres_url", + "power bi", + "dax formatter", + ) + ) + and "sqlite" not in text + ): + return "external-service", "Explicit external database, network oracle, or integration environment gate." + if any( + s in text + for s in ( + "not installed", + "not available", + "not present", + "not built", + "sqlite_tests", + "no working adbc", + "fakesnow not compatible", + "uv is required", + "file not found", + "could not import", + ) + ): + return "optional-host", "Optional local dependency, artifact, fixture, or emulator compatibility gate." + if "native" in text or "strict rust" in text: + return ( + "intentional-Python-only", + "Engine-asymmetric contract: skips the Python parameter; Rust still runs. Not a Rust-default blocker by itself.", + ) + if "postgresql adapter available" in text: + return "external-service", "Connection contract delegated to the integration suite." + return "real-gap", "Unconditional or conditional behavioral omission requiring explicit review." + if kind == "integration-marker": + return ( + "external-service", + "Deselected by default addopts; may additionally have dependency or behavioral skips.", + ) + if kind == "engine-matrix": + if "'python'" in source or '"python"' in source: + if "'rust'" not in source and '"rust"' not in source: + if scope.split("::")[-1] in PRIVATE_CONTRACTS: + return "intentional-Python-only", PRIVATE_CONTRACTS[scope.split("::")[-1]] + return ( + "real-gap", + "Python-only parameter selection: adjudicate behavioral coverage separately from private implementation contracts.", + ) + return None, "Explicit engine matrix, including Rust; not a Python-only exclusion." + if kind == "implementation-import": + if "rust" in source.lower(): + return ( + None, + "Explicit Rust helper/adapter route, recorded for completeness; this is not a Python exclusion.", + ) + return ( + "real-gap", + "Direct implementation helper bypasses SemanticLayer engine selection; shared-suite success alone is not Rust coverage.", + ) + if kind == "public-layer-import": + return None, "Public SemanticLayer import alias is engine-aware; not a Python pin." + if kind == "legacy-adapter-import": + if path.endswith(("conftest.py", "test_rust_parity.py")): + return None, "Legacy adapter constants or explicit Python side of OSI differential oracle." + return ( + "real-gap", + "Explicit LegacyOSIAdapter alias bypasses canonical native OSI adapter; legacy compatibility coverage needs separate Rust evidence.", + ) + if kind == "engine-control": + if "SIDEMANTIC_OSI_BACKEND" in source and '"python"' in source: + return ( + "real-gap", + "OSI legacy adapter shim defaults to Python independently of --test-engine; separate backend override required.", + ) + python_pin = bool(re.search(r"engine\s*=\s*['\"]python['\"]", source)) or bool( + re.search(r"setenv\(['\"]SIDEMANTIC_ENGINE['\"],\s*['\"]python['\"]", source) + ) + if not python_pin: + return None, "Engine route control or default/reset observation; not a Python exclusion." + if path in CONTRACT_FILES or any( + s in scope for s in ("legacy_python", "rust_modes", "python_engine", "python_mode") + ): + return "intentional-Python-only", "Explicit engine selection, legacy fallback, or routing contract." + if python_pin: + if "ossie_engine_conformance" in path: + return None, "Python side of explicit Python/Rust differential oracle." + return ( + "real-gap", + "Behavioral test explicitly pins Python; remove pin or establish equivalent Rust coverage.", + ) + return ( + None, + "Engine route control (Rust, dynamic matrix, environment reset, or test double); inspect source and conditions.", + ) + return "external-service", "Selection rule or CI boundary; see exact source." + + +def replay_contracts(): + """Reconstruct the replay selector from AST, without importing native modules.""" + path = ROOT / "tests/core/test_pure_rust_python_test_parity.py" + tree = ast.parse(path.read_text()) + imports = { + n.asname: n.name for statement in tree.body if isinstance(statement, ast.Import) for n in statement.names + } + values = {} + for statement in tree.body: + if isinstance(statement, ast.Assign) and isinstance(statement.targets[0], ast.Name): + try: + values[statement.targets[0].id] = ast.literal_eval(statement.value) + except (ValueError, TypeError): + if statement.targets[0].id == "PYTHON_TEST_PARITY_MODULES": + values["modules"] = {imports[n.id] for n in statement.value.elts} + return values + + +def scan_file(path, replay): + relative = path.relative_to(ROOT).as_posix() + source = path.read_text() + source_lines = source.splitlines(keepends=True) + tree = ast.parse(source) + parents = {child: parent for parent in ast.walk(tree) for child in ast.iter_child_nodes(parent)} + functions = [n for n in ast.walk(tree) if isinstance(n, (ast.FunctionDef, ast.AsyncFunctionDef))] + + def ancestors(node): + result = [] + while node in parents: + node = parents[node] + result.append(node) + return result + + def scope_of(node): + owners = [ + n.name + for n in reversed(ancestors(node)) + if isinstance(n, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)) + ] + return "::".join(owners) or "" + + def function_id(node): + prefix = scope_of(node) + return node.name if prefix == "" else prefix + "::" + node.name + + tests = {function_id(n): n for n in functions if n.name.startswith("test_")} + dependencies = {} + for function in functions: + dependencies[function.name] = {n.id for n in ast.walk(function) if isinstance(n, ast.Name)} | { + a.arg for a in function.args.args + } + autouse = { + f.name + for f in functions + for d in f.decorator_list + if isinstance(d, ast.Call) + and any(k.arg == "autouse" and isinstance(k.value, ast.Constant) and k.value.value is True for k in d.keywords) + } + + def affected(scope, symbols=None): + if symbols is None and (scope == "" or scope.split("::")[-1] in autouse): + return sorted(tests) + if scope in tests: + return [scope] + target = scope.split("::")[-1] + result = [] + for name, node in tests.items(): + pending = [node.name] + seen = set() + while pending: + current = pending.pop() + if current in seen: + continue + seen.add(current) + pending.extend(dependencies.get(current, set()) - seen) + if (symbols is not None and symbols & seen) or ( + symbols is None and (target in seen or name.startswith(scope + "::")) + ): + result.append(name) + return sorted(result) + + def assess_helper(test): + function = tests[test] + reviewed = replay.get("helper_evidence", {}).get(relative + "::" + test) + if reviewed is not None: + detail = reviewed["behavior"] + if reviewed.get("counterparts"): + detail += " Counterparts: " + "; ".join(reviewed["counterparts"]) + if reviewed.get("limitation"): + detail += " Limitation: " + reviewed["limitation"] + return { + "test": relative + "::" + test, + "category": reviewed["category"], + "evidence": "docs/rust-parity-helper-evidence.json#" + reviewed["id"] + ": " + detail, + } + module = relative.removesuffix(".py").replace("/", ".") + nodeid = module + "::" + test + signature = tuple(a.arg for a in function.args.args if a.arg != "self") + if function.name in PRIVATE_CONTRACTS: + return { + "test": relative + "::" + test, + "category": "intentional-Python-only", + "evidence": PRIVATE_CONTRACTS[function.name], + } + full_replays = { + "tests/queries/test_sql_rewriter.py": "tests/queries/test_rust_sql_rewriter_parity.py::test_semantic_sql_contract", + "tests/queries/test_yardstick_query_rewriter.py": "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract", + "tests/queries/test_yardstick_warnings.py": "tests/queries/test_rust_yardstick_parity.py::test_yardstick_result_contract", + } + if relative in full_replays and "::" not in test: + return { + "test": relative + "::" + test, + "category": None, + "evidence": full_replays[relative] + "[" + test + "]", + } + if relative == "tests/queries/test_semantic_sql_planner.py": + return { + "test": relative + "::" + test, + "category": "intentional-Python-only", + "evidence": "Python optimizer plan/rule contract (module docstring); engine-selected SemanticLayer execution assertions remain active.", + } + if relative in { + "tests/semantic_conformance/test_parameterized_segments.py", + "tests/semantic_conformance/test_yardstick_source_dialects.py", + }: + return { + "test": relative + "::" + test, + "category": None, + "evidence": "Engine-parametrized layer fixture and result/rows helper branch between Rust bridge and Python helper in this module.", + } + replayed = module in replay["modules"] and ( + signature in replay["SUPPORTED_SIGNATURES"] + or not signature + and nodeid + in replay["DIRECT_RUST_GRAPH_PARITY_NODEIDS"] | replay["DIRECT_RUST_SQL_GENERATOR_PARITY_NODEIDS"] + or module in replay["DIRECT_RUST_FUNCTION_PARITY_MODULES"] + and signature in {(), ("conn",)} + ) + if replayed: + return { + "test": relative + "::" + test, + "category": None, + "evidence": "tests/core/test_pure_rust_python_test_parity.py::test_existing_python_layer_contract_matches_pure_rust[" + + nodeid + + "]", + } + calls = [n for n in ast.walk(function) if isinstance(n, ast.Call)] + private = [ + ast.unparse(n.func) for n in calls if isinstance(n.func, ast.Attribute) and n.func.attr.startswith("_") + ] + public = [ + n + for n in calls + if isinstance(n.func, ast.Attribute) + and n.func.attr in {"generate", "rewrite", "compile", "query", "explain"} + ] + if private and not public: + return { + "test": relative + "::" + test, + "category": "intentional-Python-only", + "evidence": "Direct private implementation-unit calls: " + ", ".join(sorted(set(private))), + } + if "engine" in signature and "sidemantic_rs" in source: + return { + "test": relative + "::" + test, + "category": None, + "evidence": "Co-located engine-parametrized native/reference oracle; inspect test and Rust import.", + } + if any( + any( + k.arg == "use_rust_rewriter" and isinstance(k.value, ast.Constant) and k.value.value is True + for k in n.keywords + ) + for n in calls + ): + return { + "test": relative + "::" + test, + "category": None, + "evidence": "Explicit use_rust_rewriter=True route in this test.", + } + return { + "test": relative + "::" + test, + "category": "real-gap", + "evidence": "Direct helper behavioral coverage has no established replay counterpart; requires native coverage adjudication, not a confirmed Rust defect.", + } + + records = [] + for node in ast.walk(tree): + kind = None + if not isinstance( + node, (ast.Call, ast.Attribute, ast.ImportFrom, ast.Assign, ast.AnnAssign, ast.For, ast.List, ast.Tuple) + ): + continue + segment_lines = source_lines[node.lineno - 1 : node.end_lineno] + segment = "".join(segment_lines) + if len(segment_lines) == 1: + segment = segment[node.col_offset : node.end_col_offset] + else: + segment = segment[node.col_offset : len(segment) - len(segment_lines[-1]) + node.end_col_offset] + if isinstance(node, ast.Call): + name = ast.unparse(node.func) + if ( + name in {"pytest.skip", "pytest.xfail", "pytest.importorskip", "_pytest.importorskip"} + or name.startswith("pytest.mark.") + and name.rsplit(".", 1)[-1] in {"skip", "skipif", "xfail"} + ): + kind = name.rsplit(".", 1)[-1] + elif any(k.arg in {"engine", "use_rust_rewriter", "rust_no_fallback"} for k in node.keywords): + kind = "engine-control" + elif ( + name == "pytest.mark.parametrize" + and len(node.args) >= 2 + and any(isinstance(v, ast.Constant) and v.value in {"python", "rust"} for v in ast.walk(node.args[1])) + ): + kind = "engine-matrix" + elif name == "pytest.fixture" and any( + k.arg == "params" + and any(isinstance(v, ast.Constant) and v.value in {"python", "rust"} for v in ast.walk(k.value)) + for k in node.keywords + ): + kind = "engine-matrix" + elif name.endswith(".addoption") and "--test-engine" in segment: + kind = "engine-control" + elif name == "os.environ.get" and "SIDEMANTIC_OSI_BACKEND" in segment: + kind = "engine-control" + elif name.endswith((".setenv", ".delenv", ".setattr")) and ( + ENGINE_ENV.search(segment) + or any(s in segment for s in HELPERS | {"SemanticLayer", "_compile_with_python", "_compile_with_rust"}) + ): + kind = "engine-control" + elif isinstance(node, ast.Attribute) and ast.unparse(node) == "pytest.mark.integration": + kind = "integration-marker" + elif isinstance(node, ast.ImportFrom): + if node.module == "sidemantic.adapters.osi" and any(a.name == "LegacyOSIAdapter" for a in node.names): + kind = "legacy-adapter-import" + elif ( + node.module + and (node.module.startswith("sidemantic.sql.") or node.module == "tests.rust_layer_adapter") + and any(a.name in HELPERS for a in node.names) + ): + kind = "implementation-import" + elif node.module == "sidemantic.core.semantic_layer" and any(a.name == "SemanticLayer" for a in node.names): + kind = "public-layer-import" + elif isinstance(node, (ast.Assign, ast.AnnAssign)) and ( + re.search(r"\[['\"]engine['\"]\]", segment) + or re.search(r"\._(?:use_rust|strict_rust|rust_module)\w*\s*=", segment) + or (ENGINE_ENV.search(segment) and not isinstance(getattr(node, "value", None), ast.Call)) + ): + kind = "engine-control" + elif isinstance(node, ast.For) and ENGINE_ENV.search(ast.unparse(node.iter)): + kind = "engine-control" + elif isinstance(node, (ast.List, ast.Tuple)) and any( + isinstance(value, ast.Constant) and value.value == "--engine" for value in node.elts + ): + kind = "engine-control" + if kind is None: + continue + scope = scope_of(node) + # A decorator belongs to the decorated test, not merely its surrounding module. + for owner in ancestors(node): + if isinstance(owner, (ast.FunctionDef, ast.AsyncFunctionDef)): + scope = function_id(owner) + break + conditions = [ast.unparse(a.test) for a in reversed(ancestors(node)) if isinstance(a, ast.If)] + context = " ".join(conditions) + category, rationale = classify(relative, scope, kind, segment, context) + symbols = ( + {a.asname or a.name for a in node.names if a.name in HELPERS} if kind == "implementation-import" else None + ) + affected_tests = affected(scope, symbols) + assessments = [] + if kind == "implementation-import" and "rust" not in segment.lower(): + assessments = [assess_helper(test) for test in affected_tests] + categories = {item["category"] for item in assessments} + category = ( + "real-gap" + if "real-gap" in categories + else "intentional-Python-only" + if "intentional-Python-only" in categories + else None + ) + rationale = "Per-test adjudication below distinguishes replay coverage, private units, and unresolved behavioral coverage." + is_exception = category is not None + direction = "none" + if is_exception: + direction = "both-engines" + if kind in {"engine-control", "implementation-import", "engine-matrix", "legacy-adapter-import"}: + direction = "rust-coverage-exclusion" + elif ( + "engine == 'python'" in context + or 'engine == "python"' in context + or "Native" in segment + or "Strict Rust" in segment + or "reparses" in segment + or "physical keys" in segment + ): + direction = "python-only-exclusion" + records.append( + { + "path": relative, + "line": node.lineno, + "scope": scope, + "kind": kind, + "category": category, + "is_exception": is_exception, + "exclusion_direction": direction, + "rationale": rationale, + "conditions": conditions, + "source": segment, + "declared_tests": [relative + "::" + name for name in affected_tests], + "test_assessments": assessments, + } + ) + return records, [relative + "::" + name for name in tests] + + +def compact_inventory(result): + """Keep actual exceptions; share repeated scope expansions and explanations.""" + scopes, scope_ids, explanations, explanation_ids = {}, {}, {}, {} + + def explanation(value): + if value not in explanation_ids: + key = f"reason-{len(explanations) + 1}" + explanation_ids[value] = key + explanations[key] = value + return explanation_ids[value] + + exceptions, helpers = [], {} + for record in result["exceptions"]: + for assessment in record["test_assessments"]: + path, test = assessment["test"].split("::", 1) + helpers.setdefault(path, {})[test] = { + "category": assessment["category"], + "evidence": explanation(assessment["evidence"]), + } + if not record["is_exception"]: + continue + compact = { + key: value + for key, value in record.items() + if key not in {"is_exception", "declared_tests", "test_assessments", "rationale", "collected_tests"} + } + compact["rationale"] = explanation(record["rationale"]) + if not compact["conditions"]: + compact.pop("conditions") + tests = [test.removeprefix(record["path"] + "::") for test in record["declared_tests"]] + if record["path"].endswith("/conftest.py") and "collected_tests" not in record: + compact["affected_scope"] = "subtree" + compact["declared_test_count"] = len(tests) + exceptions.append(compact) + continue + if tests == [record["scope"]] and "collected_tests" not in record: + compact["affected_scope"] = "self" + exceptions.append(compact) + continue + if ( + record["scope"] == "" + and record["kind"] != "implementation-import" + and "collected_tests" not in record + ): + compact["affected_scope"] = "module" + compact["declared_test_count"] = len(tests) + exceptions.append(compact) + continue + scope_key = (record["path"], tuple(tests), tuple(record.get("collected_tests", []))) + if scope_key not in scope_ids: + key = f"scope-{len(scopes) + 1}" + scope_ids[scope_key] = key + scopes[key] = {"path": record["path"], "declared_tests": tests} + if "collected_tests" in record: + scopes[key]["collected_tests"] = record["collected_tests"] + compact["affected_scope"] = scope_ids[scope_key] + exceptions.append(compact) + compact_result = { + **result, + "exceptions": exceptions, + "affected_scopes": scopes, + "helper_test_assessments": helpers, + "explanations": explanations, + } + if "execution_evidence" in result: + evidence = dict(result["execution_evidence"]) + groups = {} + for item in evidence.pop("omissions"): + group = groups.setdefault(item["reason"], {"category": item["category"], "type": item["type"], "tests": []}) + group["tests"].append(item["classname"] + "::" + item["name"]) + evidence["omissions_by_reason"] = groups + compact_result["execution_evidence"] = evidence + return compact_result + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--collected-nodeids", type=Path) + parser.add_argument( + "--junit", + type=Path, + help="Optional historical/runtime JUnit evidence; never conflated with static scope counts", + ) + parser.add_argument( + "--evidence-label", default="Unspecified execution; caller must record revision and environment" + ) + parser.add_argument("--output", type=Path, default=ROOT / "docs/rust-parity-exceptions.json") + parser.add_argument("--markdown", type=Path, default=ROOT / "docs/rust-parity-exceptions.md") + args = parser.parse_args() + records, declared = [], [] + replay = replay_contracts() + evidence_path = ROOT / "docs/rust-parity-helper-evidence.json" + if evidence_path.exists(): + evidence = json.loads(evidence_path.read_text()) + replay["helper_evidence"] = {} + for group in evidence["groups"]: + for test in group["source_tests"]: + if test in replay["helper_evidence"]: + raise ValueError(f"Duplicate reviewed helper evidence: {test}") + replay["helper_evidence"][test] = group + for path in sorted((ROOT / "tests").rglob("*.py")): + found, tests = scan_file(path, replay) + records.extend(found) + declared.extend(tests) + # Root autouse fixtures select every test, not zero tests in conftest itself. + for record in records: + if record["path"].endswith("/conftest.py") and not record["declared_tests"]: + directory = record["path"].removesuffix("conftest.py") + record["declared_tests"] = [test for test in declared if test.startswith(directory)] + config = tomllib.loads((ROOT / "pyproject.toml").read_text())["tool"]["pytest"]["ini_options"] + selection = [{"path": "pyproject.toml", "source": config.get("addopts", ""), "category": "external-service"}] + for path in sorted((ROOT / ".github/workflows").glob("*.yml")): + for lineno, line in enumerate(path.read_text().splitlines(), 1): + if re.search(r"pytest|test-engine|SIDEMANTIC_ENGINE|engine:|addopts=|--deselect|--ignore", line): + selection.append({"path": path.relative_to(ROOT).as_posix(), "line": lineno, "source": line.strip()}) + collected = None + if args.collected_nodeids: + collected = [ + line.strip() + for line in args.collected_nodeids.read_text().splitlines() + if line.startswith("tests/") and "::" in line + ] + for record in records: + bases = set(record["declared_tests"]) + record["collected_tests"] = [node for node in collected if node.split("[", 1)[0] in bases] + records.sort(key=lambda item: (item["path"], item["line"], item["kind"])) + summary = { + "source_records": len(records), + "by_kind": dict(sorted(Counter(r["kind"] for r in records).items())), + "exception_records": sum(r["is_exception"] for r in records), + "observation_records": sum(not r["is_exception"] for r in records), + "exceptions_by_category": dict(sorted(Counter(r["category"] for r in records if r["is_exception"]).items())), + "exceptions_by_direction": dict( + sorted(Counter(r["exclusion_direction"] for r in records if r["is_exception"]).items()) + ), + "declared_test_functions": len(declared), + "collected_nodeids": None if collected is None else len(collected), + } + helper_assessments = {item["test"]: item for record in records for item in record["test_assessments"]} + summary["direct_helper_tests"] = { + "native_counterpart_or_route": sum(item["category"] is None for item in helper_assessments.values()), + "intentional_python_implementation": sum( + item["category"] == "intentional-Python-only" for item in helper_assessments.values() + ), + "unresolved_native_coverage": sum(item["category"] == "real-gap" for item in helper_assessments.values()), + } + result = { + "schema_version": 3, + "summary": summary, + "limitations": [ + "Static source inventory, not execution results or proof of product defects.", + "Declared scope expansion follows local fixture/helper references conservatively; dynamic imports, cross-module fixtures, and generated parity cases require collection/runtime evidence.", + "Engine-aware imports and explicit Rust/differential routing are observations with is_exception=false and category=null.", + "real-gap includes Python-only omissions and unproven Rust coverage, not only confirmed Rust failures.", + "Module dependency gates and integration deselection can overlap behavioral omissions; records are not additive test counts.", + "Only actual exclusions appear in exceptions. affected_scope=self means the source test; module means its module; subtree means the conftest directory (conservative); other values reference affected_scopes. rationale references explanations. Routing observations contribute counts only. Empty conditions are omitted. Helper assessments retain native counterpart evidence.", + ], + "selection_rules": selection, + "exceptions": records, + } + if args.junit: + xml = ET.parse(args.junit).getroot() + cases = list(xml.iter("testcase")) + omissions = [] + for case in cases: + for skip in case.findall("skipped"): + path = case.attrib.get("classname", "").replace(".", "/") + message = skip.attrib.get("message", "") + category, rationale = classify(path, case.attrib.get("name", ""), "skip", message, "") + omissions.append( + { + "classname": case.attrib.get("classname"), + "name": case.attrib.get("name"), + "type": skip.attrib.get("type"), + "reason": message, + "category": category, + "rationale": rationale, + } + ) + result["execution_evidence"] = { + "label": args.evidence_label, + "testcases": len(cases), + "skipped": len(omissions), + "failures": sum(len(case.findall("failure")) for case in cases), + "errors": sum(len(case.findall("error")) for case in cases), + "skip_reasons": dict(sorted(Counter(item["reason"] for item in omissions).items())), + "omissions": omissions, + "limitations": "JUnit does not enumerate deselected tests. Historical results do not validate current edits.", + } + args.output.write_text(json.dumps(compact_inventory(result), indent=2) + "\n") + lines = [ + "# Rust parity exception inventory", + "", + "Generated by `uv run --no-project scripts/audit_engine_exceptions.py`.", + "", + "This is an auditable source inventory, not a passing-test claim. The JSON contains every matched source expression, enclosing condition, qualified scope, and statically affected test function.", + "", + "## Counts", + "", + "```json", + json.dumps(summary, indent=2), + "```", + "", + "## Interpretation", + "", + *["- " + item for item in result["limitations"]], + "", + "- Missing native Rust is an `optional-host` gate operationally, but unacceptable for a Rust-readiness run.", + "- `--test-engine rust` selects the public layer. Importing that layer from its implementation module does not pin Python. Direct `SQLGenerator` and `QueryRewriter` use must be assessed separately.", + "- CI runs Python 3.11–3.14 for Python and 3.12 for Rust. Both shared lanes exclude `integration`; integration.yml supplies separate engine runs. Inspect `selection_rules` for all commands and environment controls.", + "- Zero executable xfail records means the prose mention of xfail in LookML fixtures is not an active exemption.", + "", + "## Behavioral omissions and Python pins", + "", + "| Source scope | Kind | Reason |", + "| --- | --- | --- |", + ] + for record in records: + if record["category"] == "real-gap" and record["kind"] != "implementation-import": + ref = record["path"] + "::" + record["scope"] + lines.append(f"| `{ref}` | {record['kind']} | {record['rationale']} |") + lines += [ + "", + "## Direct implementation coverage", + "", + "The JSON enumerates direct helper imports and their scopes. These are coverage warnings, not assertions that every helper test should be rewritten: implementation-unit contracts can remain Python-specific when their public behavior has independent native coverage. The parity replay in `tests/core/test_pure_rust_python_test_parity.py` selects modules, signatures, and explicit node IDs; it does not replay every Python test. Its monkeypatches and `tests/rust_layer_adapter.py` routing are included in the inventory.", + "", + "To expand to parametrized IDs, save the output of an authorized collect-only run to a file, then pass `--collected-nodeids FILE`. The report does not import tests, install packages, or compile extensions.", + ] + helper_modules = {} + for item in helper_assessments.values(): + counts = helper_modules.setdefault(item["test"].split("::", 1)[0], Counter()) + counts[item["category"] or "native-counterpart"] += 1 + lines += [ + "", + "Each count below is a unique declared function, not parametrized cases. Native counterparts are identified by exact replay selection or a co-located explicit native route; unresolved means the static audit has not established coverage.", + "", + "| Helper consumer | Native counterpart / route | Private Python contract | Unresolved native coverage |", + "| --- | ---: | ---: | ---: |", + ] + for path, counts in sorted(helper_modules.items()): + lines.append( + f"| `{path}` | {counts['native-counterpart']} | {counts['intentional-Python-only']} | {counts['real-gap']} |" + ) + if args.junit: + evidence = result["execution_evidence"] + lines += [ + "", + "## Execution evidence", + "", + evidence["label"], + "", + f"JUnit: {evidence['testcases']} cases, {evidence['skipped']} skipped, {evidence['failures']} failures, {evidence['errors']} errors.", + "", + evidence["limitations"], + "", + "| Skip reason | Cases |", + "| --- | ---: |", + ] + lines += [f"| {reason.replace('|', '/')} | {count} |" for reason, count in evidence["skip_reasons"].items()] + args.markdown.write_text("\n".join(lines) + "\n") + print(json.dumps(summary, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/sidemantic-rs/src/core/graph.rs b/sidemantic-rs/src/core/graph.rs index cb9ad3e4e..36d0dafee 100644 --- a/sidemantic-rs/src/core/graph.rs +++ b/sidemantic-rs/src/core/graph.rs @@ -123,6 +123,44 @@ impl SemanticGraph { self.metric_owners.get(metric).map(String::as_str) } + /// Resolve population ownership identically before policy preparation and SQL generation. + pub(crate) fn population_metric_owner( + &self, + reference: &str, + metric: &Metric, + ) -> Result { + if let Some(owner) = self.metric_owner(reference) { + return Ok(owner.to_string()); + } + // Match the public Python entity-dimension inference contract. Do not + // guess from table count, event literals, or unrelated output columns. + let mut owners: Vec<_> = self + .models() + .filter(|model| { + metric + .entity + .as_deref() + .is_some_and(|entity| model.get_dimension(entity).is_some()) + }) + .map(|model| model.name.clone()) + .collect(); + owners.sort(); + match owners.len() { + 1 => Ok(owners.pop().unwrap()), + 0 => Err(SidemanticError::UnsupportedSemanticFeatures { + capabilities: vec![if metric.r#type == MetricType::Cohort { + "metric.cohort_owner".into() + } else { + format!("metric.graph_scope.{reference}") + }], + }), + _ => Err(SidemanticError::AmbiguousReference { + field: metric.entity.clone().unwrap(), + models: owners.join(", "), + }), + } + } + pub fn has_strict_metric_scope(&self) -> bool { self.strict_metric_scope } diff --git a/sidemantic-rs/src/semantic_input.rs b/sidemantic-rs/src/semantic_input.rs index 41b9bf2fb..409142c5b 100644 --- a/sidemantic-rs/src/semantic_input.rs +++ b/sidemantic-rs/src/semantic_input.rs @@ -573,7 +573,7 @@ fn decode_metric( let metric = project(raw, exemplar, path)?; if metric.agg == Some(crate::core::Aggregation::ApproxCountDistinct) && !model_local - && !(metric.r#type == crate::core::MetricType::Cohort && owner.is_some()) + && metric.r#type != crate::core::MetricType::Cohort { return Err(unsupported("metric.approx_count_distinct_model_scope")); } diff --git a/sidemantic-rs/src/semantic_input/policies.rs b/sidemantic-rs/src/semantic_input/policies.rs index cdbb3d708..c3d8f0bee 100644 --- a/sidemantic-rs/src/semantic_input/policies.rs +++ b/sidemantic-rs/src/semantic_input/policies.rs @@ -271,6 +271,32 @@ impl<'a> Population<'a> { reference: &str, context: Option<&str>, ) -> Result, Metric)>> { + // Bare dependencies inside a model prefer that model's local metric. + // Exact dotted graph identities still precede model-qualified parsing. + if !reference.contains('.') { + if let Some(model) = context { + if let Some(metric) = self + .graph + .get_model(model) + .and_then(|definition| definition.get_metric(reference)) + { + return Ok(Some((Some(model.to_owned()), metric.clone()))); + } + } + } + // Public graph identities may contain dots and take precedence over + // model-qualified names, matching SQL metric reference resolution. + if let Some(metric) = self.graph.get_metric(reference) { + let owner = if matches!( + metric.r#type, + MetricType::Cohort | MetricType::Conversion | MetricType::Retention + ) { + Some(self.graph.population_metric_owner(reference, metric)?) + } else { + self.graph.metric_owner(reference).map(str::to_owned) + }; + return Ok(Some((owner, metric.clone()))); + } if let Some((model, name)) = reference.split_once('.') { return Ok(self.graph.get_model(model).and_then(|definition| { definition @@ -278,21 +304,6 @@ impl<'a> Population<'a> { .map(|metric| (Some(model.to_owned()), metric.clone())) })); } - if let Some(model) = context { - if let Some(metric) = self - .graph - .get_model(model) - .and_then(|definition| definition.get_metric(reference)) - { - return Ok(Some((Some(model.to_owned()), metric.clone()))); - } - } - if let Some(metric) = self.graph.get_metric(reference) { - return Ok(Some(( - self.graph.metric_owner(reference).map(str::to_owned), - metric.clone(), - ))); - } let owners: Vec<_> = self .graph .models() @@ -385,6 +396,16 @@ impl<'a> Population<'a> { } fn column(&mut self, column: &Column, context: Option<&str>) -> Result<()> { + let reference = column.table.as_ref().map_or_else( + || column.name.name.clone(), + |table| format!("{}.{}", table.name, column.name.name), + ); + // An exact graph identity can contain a real model name as its prefix. + // Resolve its dependencies before treating that prefix as a source. + // Bare references retain their model context below. + if reference.contains('.') && self.graph.get_metric(&reference).is_some() { + return self.metric(&reference, context); + } let model = column .table .as_ref() @@ -393,10 +414,6 @@ impl<'a> Population<'a> { if let Some(model) = model { self.add_model(model); } - let reference = column.table.as_ref().map_or_else( - || column.name.name.clone(), - |table| format!("{}.{}", table.name, column.name.name), - ); // Bare physical filter columns must not bind to unrelated model metrics. if model.is_some() || self.graph.get_metric(&reference).is_some() { self.metric(&reference, context)?; @@ -423,6 +440,17 @@ fn check_visibility( candidates: &BTreeSet, metric_models: &BTreeSet, ) -> Result<()> { + let check_graph_metric = |reference: &str| -> Result { + let Some(metric) = graph.get_metric(reference) else { + return Ok(false); + }; + if !metric.public { + return Err(SidemanticError::Security(format!( + "Field '{reference}' is not public" + ))); + } + Ok(true) + }; let check = |model: &str, name: &str| -> Result<()> { let Some(model_definition) = graph.get_model(model) else { return Ok(()); @@ -445,6 +473,9 @@ fn check_visibility( Ok(()) }; for reference in query.metrics.iter().chain(&query.dimensions) { + if query.metrics.contains(reference) && check_graph_metric(reference)? { + continue; + } if let Some((model, name)) = reference.split_once('.') { check(model, name)?; } else if graph @@ -506,6 +537,13 @@ fn check_visibility( columns.extend(order_columns(order, query)?); } for column in columns { + let reference = column.table.as_ref().map_or_else( + || column.name.name.clone(), + |table| format!("{}.{}", table.name, column.name.name), + ); + if reference.contains('.') && check_graph_metric(&reference)? { + continue; + } if let Some(model) = column .table .as_ref() diff --git a/sidemantic-rs/src/sql/generator.rs b/sidemantic-rs/src/sql/generator.rs index 39363a772..a766e3e7e 100644 --- a/sidemantic-rs/src/sql/generator.rs +++ b/sidemantic-rs/src/sql/generator.rs @@ -265,6 +265,46 @@ impl<'a> SqlGenerator<'a> { // Parse all references let dimension_refs = self.parse_dimension_refs(&effective_dimensions)?; + // A scalar graph calculation has no single source grain. Beside a + // window metric, carry its reference into the grouped inner planner + // instead of forcing it through source-local metric resolution. + let mut deferred_graph_metrics = HashSet::new(); + if self.graph.has_strict_metric_scope() { + for reference in &query.metrics { + if let Some(metric) = self.graph.get_metric(reference) { + if matches!(metric.r#type, MetricType::Derived | MetricType::Ratio) + && metric.offset_window.is_none() + && self.graph_metric_owner_models(reference, metric)?.len() > 1 + { + deferred_graph_metrics.insert(reference.clone()); + } + } + } + } + if !deferred_graph_metrics.is_empty() { + let scoped_metrics: Vec<_> = query + .metrics + .iter() + .filter(|reference| !deferred_graph_metrics.contains(*reference)) + .cloned() + .collect(); + let metric_refs = self.parse_metric_refs(&scoped_metrics)?; + if self.has_cumulative_metrics(&metric_refs)? { + // Window owners remain query inputs even when their base + // aggregates belong to another source and no owner dimension + // survives in the grouped inner query. + let direct_models = self.find_required_models(&dimension_refs, &metric_refs)?; + self.ensure_queryable_sources(&direct_models)?; + self.reject_totals_route(query, "window")?; + return self.generate_with_cumulative( + query, + &effective_dimensions, + &dimension_refs, + &metric_refs, + &deferred_graph_metrics, + ); + } + } let metric_refs = self.parse_metric_refs(&query.metrics)?; let direct_required_models = self.find_required_models(&dimension_refs, &metric_refs)?; self.ensure_queryable_sources(&direct_required_models)?; @@ -300,6 +340,7 @@ impl<'a> SqlGenerator<'a> { &effective_dimensions, &dimension_refs, &metric_refs, + &HashSet::new(), ); } @@ -1410,16 +1451,17 @@ impl<'a> SqlGenerator<'a> { metric: &Metric, visiting: &mut HashSet, ) -> Result> { - // Cohort output expressions bind inner-result columns, not other metrics. - // Its source population must be declared, never inferred from those names. - if metric.r#type == MetricType::Cohort { + // Population metrics bind one source through their entity declaration. + // Cohort output expressions name inner-result columns; conversion event + // labels are values. Neither is a scalar metric dependency. + if matches!( + metric.r#type, + MetricType::Cohort | MetricType::Conversion | MetricType::Retention + ) { return self .graph - .metric_owner(reference) - .map(|owner| vec![owner.to_string()]) - .ok_or_else(|| SidemanticError::UnsupportedSemanticFeatures { - capabilities: vec!["metric.cohort_owner".into()], - }); + .population_metric_owner(reference, metric) + .map(|owner| vec![owner]); } let mut owners = HashSet::new(); let window_dependency = Self::window_output_dependency(metric)?; @@ -2688,6 +2730,7 @@ impl<'a> SqlGenerator<'a> { effective_dimensions: &[String], dimension_refs: &[DimensionRef], metric_refs: &[MetricRef], + deferred_graph_metrics: &HashSet, ) -> Result { let mut base_metrics: Vec = Vec::new(); let mut seen_metrics: HashSet = HashSet::new(); @@ -2698,7 +2741,23 @@ impl<'a> SqlGenerator<'a> { let mut retention_metrics: Vec = Vec::new(); let mut cohort_metrics: Vec = Vec::new(); - for metric_ref in metric_refs { + let mut scoped_metrics = metric_refs.iter(); + let mut scalar_outputs = Vec::new(); + for reference in &query.metrics { + if deferred_graph_metrics.contains(reference) { + for leaf in aggregate_plan::window_scalar_leaves(self, reference)? { + if seen_metrics.insert(leaf.clone()) { + base_metrics.push(leaf); + } + } + if !scalar_outputs.contains(reference) { + scalar_outputs.push(reference.clone()); + } + continue; + } + let metric_ref = scoped_metrics.next().ok_or_else(|| { + SidemanticError::SqlGeneration("Missing window metric reference".into()) + })?; let metric = self.metric_for_ref(metric_ref)?; match metric.r#type { @@ -2870,8 +2929,13 @@ impl<'a> SqlGenerator<'a> { ); } + let inner_metrics: Vec<_> = base_metrics + .iter() + .chain(&scalar_outputs) + .cloned() + .collect(); let mut inner_query = SemanticQuery::new() - .with_metrics(base_metrics.clone()) + .with_metrics(inner_metrics.clone()) .with_dimensions(effective_dimensions.to_vec()) .with_filters(query.filters.clone()) .with_segments(query.segments.clone()) @@ -2881,17 +2945,36 @@ impl<'a> SqlGenerator<'a> { inner_query.required_population_models = query.required_population_models.clone(); let inner_sql = self.generate(&inner_query)?; + // Keep one identity map for projections, window inputs and ordering. + // A metric leaf can collide with another metric or a dimension. + let grouped_outputs = self.selected_output_names(&inner_query)?; + let metric_output = |reference: &str, model: &str| -> Result { + let reference = self.metric_ref_for_inner_query(reference, model); + grouped_outputs.get(&reference).cloned().ok_or_else(|| { + SidemanticError::Validation(format!("Unknown grouped metric output '{reference}'")) + }) + }; + let mut output_dimensions = dimension_refs.to_vec(); + for (reference, dimension) in effective_dimensions.iter().zip(&mut output_dimensions) { + dimension.alias = grouped_outputs[reference].clone(); + } + let dimension_refs = output_dimensions.as_slice(); let mut select_exprs: Vec = Vec::new(); let mut lag_cte_columns: Vec = Vec::new(); for dim_ref in dimension_refs { - select_exprs.push(format!("base.{}", dim_ref.alias)); + select_exprs.push(format!("base.{}", self.quote_identifier(&dim_ref.alias))); lag_cte_columns.push(dim_ref.alias.clone()); } for base_ref in &base_metrics { - let alias = self.metric_alias_from_ref(base_ref); - select_exprs.push(format!("base.{alias}")); + let alias = metric_output(base_ref, "")?; + select_exprs.push(format!("base.{}", self.quote_identifier(&alias))); + lag_cte_columns.push(alias); + } + for reference in &scalar_outputs { + let alias = metric_output(reference, "")?; + select_exprs.push(format!("base.{}", self.quote_identifier(&alias))); lag_cte_columns.push(alias); } @@ -2903,11 +2986,13 @@ impl<'a> SqlGenerator<'a> { let exact_output = dimension_refs .iter() .any(|dimension| &dimension.alias == window_order) - || base_metrics - .iter() - .any(|reference| self.metric_alias_from_ref(reference) == *window_order); + || grouped_outputs.values().any(|alias| alias == window_order); let order_alias = if exact_output { window_order.as_str() + } else if let Some(alias) = grouped_outputs + .get(&self.metric_ref_for_inner_query(window_order, &metric_ref.model)) + { + alias } else { // Resolve only selected dimensions, preserving the requested // grain rather than falling back to a physical source column. @@ -2934,6 +3019,26 @@ impl<'a> SqlGenerator<'a> { }; if let Some(window_expr) = metric.window_expression.as_ref() { + let mut replacements = HashMap::new(); + for name in temporal::window_output_references(window_expr)? { + let reference = self.metric_ref_for_inner_query(&name, &metric_ref.model); + if let Some(alias) = grouped_outputs.get(&reference) { + replacements.insert( + (Some("base".to_string()), name), + format!("base.\"{}\"", alias.replace('"', "\"\"")), + ); + } + } + // The window composer parses its function in the handoff + // dialect; target quoting is applied only after composition. + let window_expr = polyglot_sql::generate( + &crate::core::replace_semantic_columns( + parse_semantic_expression(window_expr)?, + &replacements, + )?, + SOURCE_DIALECT, + ) + .map_err(|error| SidemanticError::SqlGeneration(error.to_string()))?; let partitions = self.temporal_partition_columns(dimension_refs, &order_col); let partition = if partitions.is_empty() { String::new() @@ -2946,9 +3051,9 @@ impl<'a> SqlGenerator<'a> { .unwrap_or("ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"); let value = self.fill_metric_expression( metric, - self.output_window_expression(window_expr, &partition, &order_col, frame)?, + self.output_window_expression(&window_expr, &partition, &order_col, frame)?, )?; - let expression = format!("{value} AS {}", metric_ref.alias); + let expression = format!("{value} AS {}", self.quote_identifier(&metric_ref.alias)); select_exprs.push(expression.clone()); cumulative_selects.push((expression, metric_ref.alias.clone())); continue; @@ -2964,7 +3069,7 @@ impl<'a> SqlGenerator<'a> { metric_ref.alias )) })?; - let base_alias = self.metric_alias_from_ref(base_ref); + let base_alias = self.quote_identifier(&metric_output(base_ref, &metric_ref.model)?); let base_col = if metric.agg == Some(Aggregation::CountDistinct) { format!("DISTINCT base.{base_alias}") } else { @@ -2993,7 +3098,7 @@ impl<'a> SqlGenerator<'a> { }; let value = self.fill_metric_expression(metric, format!("{aggregate} OVER ({window_clause})"))?; - let expression = format!("{value} AS {}", metric_ref.alias); + let expression = format!("{value} AS {}", self.quote_identifier(&metric_ref.alias)); select_exprs.push(expression.clone()); cumulative_selects.push((expression, metric_ref.alias.clone())); } @@ -3001,7 +3106,7 @@ impl<'a> SqlGenerator<'a> { let mut sql = if !offset_ratio_metrics.is_empty() || !time_comparison_metrics.is_empty() { let mut lag_selects: Vec = lag_cte_columns .iter() - .map(|column| format!("base.{column}")) + .map(|column| format!("base.{}", self.quote_identifier(column))) .collect(); for (expression, alias) in cumulative_selects { lag_selects.push(expression); @@ -3018,7 +3123,8 @@ impl<'a> SqlGenerator<'a> { metric_ref.alias )) })?; - let base_alias = self.metric_alias_from_ref(base_ref); + let base_alias = + self.quote_identifier(&metric_output(base_ref, &metric_ref.model)?); let lag_offset = self.calculate_lag_offset( metric.comparison_type.as_ref(), time_granularity.as_deref(), @@ -3049,7 +3155,8 @@ impl<'a> SqlGenerator<'a> { metric_ref.alias )) })?; - let denom_alias = self.metric_alias_from_ref(denominator); + let denom_alias = + self.quote_identifier(&metric_output(denominator, &metric_ref.model)?); let prev_alias = format!("{}_prev_denom", metric_ref.alias); let window_clause = self.lag_window_clause(dimension_refs, &time_col, None); let lag_rows = Self::offset_window_lag_rows( @@ -3077,7 +3184,10 @@ impl<'a> SqlGenerator<'a> { lag_cte_sql.push_str(&inner_sql); lag_cte_sql.push_str("\n ) AS base\n)"); - let mut final_selects = lag_cte_columns.clone(); + let mut final_selects: Vec<_> = lag_cte_columns + .iter() + .map(|column| self.quote_identifier(column)) + .collect(); for metric_ref in &time_comparison_metrics { let metric = self.metric_for_ref(metric_ref)?; @@ -3087,7 +3197,8 @@ impl<'a> SqlGenerator<'a> { metric_ref.alias )) })?; - let base_alias = self.metric_alias_from_ref(base_ref); + let base_alias = + self.quote_identifier(&metric_output(base_ref, &metric_ref.model)?); let prev_value_col = format!("{}_prev_value", metric_ref.alias); let calculation = metric .calculation @@ -3116,7 +3227,8 @@ impl<'a> SqlGenerator<'a> { metric_ref.alias )) })?; - let numerator_alias = self.metric_alias_from_ref(numerator); + let numerator_alias = + self.quote_identifier(&metric_output(numerator, &metric_ref.model)?); let prev_denom_col = format!("{}_prev_denom", metric_ref.alias); let value = self.fill_metric_expression( metric, @@ -3145,11 +3257,20 @@ impl<'a> SqlGenerator<'a> { let mut tokens = order.split_whitespace(); let field = tokens.next().unwrap_or(order); let suffix = tokens.collect::>().join(" "); - let alias = field - .split('.') - .next_back() - .map(str::to_string) - .unwrap_or_else(|| field.to_string()); + let alias = effective_dimensions + .iter() + .zip(dimension_refs) + .find(|(reference, dimension)| { + reference.as_str() == field + || format!("{}.{}", dimension.model, dimension.name) == field + }) + .map(|(_, dimension)| self.quote_identifier(&dimension.alias)) + .or_else(|| { + grouped_outputs + .get(field) + .map(|alias| self.quote_identifier(alias)) + }) + .unwrap_or_else(|| self.metric_alias_from_ref(field)); if suffix.is_empty() { order_parts.push(alias); } else { @@ -3234,7 +3355,7 @@ impl<'a> SqlGenerator<'a> { }; if dim.r#type == crate::core::DimensionType::Time { return Ok(( - format!("base.{}", dim_ref.alias), + format!("base.{}", self.quote_identifier(&dim_ref.alias)), dim_ref .granularity .clone() @@ -3271,7 +3392,7 @@ impl<'a> SqlGenerator<'a> { ) -> Vec { let mut partition_cols = Vec::new(); for dim_ref in dimension_refs { - let dim_col = format!("base.{}", dim_ref.alias); + let dim_col = format!("base.{}", self.quote_identifier(&dim_ref.alias)); if dim_col == time_col { continue; } @@ -6370,69 +6491,53 @@ impl<'a> SqlGenerator<'a> { result } - /// Check if metrics from a model are at fan-out risk - /// Returns the set of models whose metrics will be inflated due to fan-out + /// Check each source grain against the edges actually used by this query. + /// A to-many edge anywhere along a route can repeat the source's rows, + /// including a sibling reached through a shared many-to-one parent. fn detect_fan_out_risk( &self, base_model: &str, join_paths: &HashMap, ) -> HashSet { - let mut at_risk = HashSet::new(); - - // Every participating source can repeat across a Cartesian edge, - // including the target side when there is more than one anchor row. - if join_paths.values().any(|path| { - path.steps - .iter() - .any(|step| step.relationship_type == RelationshipType::Cross) - }) { - at_risk.insert(base_model.to_string()); - for path in join_paths.values() { - for step in &path.steps { - at_risk.insert(step.from_model.clone()); - at_risk.insert(step.to_model.clone()); - } + let mut neighbors: HashMap<&str, Vec<(&str, bool)>> = HashMap::new(); + neighbors.entry(base_model).or_default(); + for path in join_paths.values() { + for step in &path.steps { + neighbors + .entry(&step.from_model) + .or_default() + .push((&step.to_model, step.causes_fan_out())); + let reverse_fanout = matches!( + step.relationship_type, + RelationshipType::ManyToOne + | RelationshipType::ManyToMany + | RelationshipType::Cross + ); + neighbors + .entry(&step.to_model) + .or_default() + .push((&step.from_model, reverse_fanout)); } } - // For each model we join to, check if the path has fan-out - for (model, path) in join_paths { - if path.has_fan_out() { - // All models BEFORE the fan-out boundary are at risk - // The base model's metrics can be inflated if we join to a "many" side - if let Some(boundary) = path.fan_out_boundary() { - // If we're joining to a model that causes fan-out, - // the base model's metrics are at risk - if model != boundary { - at_risk.insert(base_model.to_string()); + let mut at_risk = HashSet::new(); + for &model in neighbors.keys() { + let mut visited = HashSet::from([model]); + let mut pending = vec![model]; + 'source: while let Some(current) = pending.pop() { + for &(target, expands) in &neighbors[current] { + // Do not traverse an edge back to its originating grain. + if !visited.insert(target) { + continue; } + if expands { + at_risk.insert(model.to_string()); + break 'source; + } + pending.push(target); } } } - - // Also check reverse: if the base model is a "many" side model - // and we're pulling metrics from a "one" side model - for (model, path) in join_paths { - if model == base_model { - continue; - } - // If the path TO this model has no fan-out, but the REVERSE would, - // then metrics from this model might be duplicated - // This is detected by checking if any step is one_to_many - for step in &path.steps { - if step.causes_fan_out() { - // The TO model of this step's metrics would be duplicated - // when viewed from the base model's grain - at_risk.insert(step.from_model.clone()); - } - if step.relationship_type == RelationshipType::ManyToOne { - // Joining from a many-side base grain to a one-side model duplicates - // metrics owned by the one-side model across the base rows. - at_risk.insert(step.to_model.clone()); - } - } - } - at_risk } diff --git a/sidemantic-rs/src/sql/generator/aggregate_plan.rs b/sidemantic-rs/src/sql/generator/aggregate_plan.rs index 76f259388..9f5e665c3 100644 --- a/sidemantic-rs/src/sql/generator/aggregate_plan.rs +++ b/sidemantic-rs/src/sql/generator/aggregate_plan.rs @@ -120,6 +120,7 @@ impl<'a, 'g> Plan<'a, 'g> { &mut self, node: &mut serde_json::Value, context: Option<&str>, + constant_owner: Option<&str>, bindings: &HashSet, logical_inputs: bool, ) -> Result<()> { @@ -139,6 +140,7 @@ impl<'a, 'g> Plan<'a, 'g> { return self.expand_calculation( &mut lambda["body"], context, + constant_owner, &bindings, logical_inputs, ); @@ -175,7 +177,7 @@ impl<'a, 'g> Plan<'a, 'g> { owners.insert(owner.to_string()); } if owners.is_empty() { - owners.extend(context.map(str::to_string)); + owners.extend(context.or(constant_owner).map(str::to_string)); } if owners.is_empty() || (owners.len() > 1 && !logical_inputs) { return Err(unsupported("cross_source_raw_input")); @@ -224,12 +226,24 @@ impl<'a, 'g> Plan<'a, 'g> { match node { serde_json::Value::Object(fields) => { for child in fields.values_mut() { - self.expand_calculation(child, context, bindings, logical_inputs)?; + self.expand_calculation( + child, + context, + constant_owner, + bindings, + logical_inputs, + )?; } } serde_json::Value::Array(children) => { for child in children { - self.expand_calculation(child, context, bindings, logical_inputs)?; + self.expand_calculation( + child, + context, + constant_owner, + bindings, + logical_inputs, + )?; } } _ => {} @@ -430,11 +444,27 @@ impl<'a, 'g> Plan<'a, 'g> { )) })?; let sql = crate::core::replace_model_placeholder(sql, resolved.context.as_deref())?; + // A columnless leaf such as COUNT(*) shares the enclosing + // Ossie expression's population only when it names one source. + // Keep scalar metric lookup unowned and reject ambiguous counts. + let expression_owners: HashSet<_> = if has_logical_inputs(metric) { + semantic_column_references(&sql)? + .into_iter() + .map(|column| column.model) + .collect() + } else { + HashSet::new() + }; + let constant_owner = (expression_owners.len() == 1) + .then(|| expression_owners.iter().next().unwrap().as_deref()) + .flatten() + .filter(|owner| self.generator.graph.get_model(owner).is_some()); let mut ast = serde_json::to_value(parse_semantic_expression(&sql)?) .map_err(|error| SidemanticError::SqlGeneration(error.to_string()))?; self.expand_calculation( &mut ast, resolved.context.as_deref(), + constant_owner, &HashSet::new(), has_logical_inputs(metric), )?; @@ -555,6 +585,34 @@ fn child_projection( Ok(projection) } +/// Resolve scalar dependencies without assigning the calculation a source grain. +/// Window wrappers expose these grouped leaves alongside the selected output. +pub(super) fn window_scalar_leaves( + generator: &SqlGenerator<'_>, + reference: &str, +) -> Result> { + let mut plan = Plan { + generator, + leaves: Vec::new(), + models: Vec::new(), + populations: Vec::new(), + expressions: HashMap::new(), + active: HashSet::new(), + cross_source_calculation: false, + inline_aggregates: false, + }; + plan.expand(reference, None)?; + // Synthetic inline aggregates are not public metric references that the + // grouped inner query can request independently. + if plan.inline_aggregates { + return Err(unsupported("window_inline_calculation")); + } + let mut references: Vec<_> = plan.leaves.into_iter().map(|leaf| leaf.reference).collect(); + references.sort(); + references.dedup(); + Ok(references) +} + /// Return None for the existing single-source/special-metric paths. Only this /// module's fully planned multi-source calculations bypass graph-owner parsing. pub(super) fn try_generate( @@ -1058,22 +1116,52 @@ pub(super) fn try_generate( )); } if !query.order_by.is_empty() { + let known_names: Vec<_> = order_names.keys().map(String::as_str).collect(); let mut order = Vec::new(); for item in &query.order_by { - let (reference, direction) = item - .rsplit_once(' ') - .filter(|(_, direction)| { - direction.eq_ignore_ascii_case("asc") || direction.eq_ignore_ascii_case("desc") - }) - .map_or((item.as_str(), ""), |(reference, direction)| { - (reference, direction) - }); + let (reference, suffix) = crate::sql::split_order_field(item, &known_names); let alias = order_names .get(reference) .ok_or_else(|| unsupported("unprojected_order_by"))?; - order.push(format!("{} {direction}", generator.quote_identifier(alias))); + // Source splitting must retain the ordinary query's NULL ordering. + let suffix = if suffix.contains("NULLS") { + suffix + } else { + let nulls = if suffix == "DESC" { "LAST" } else { "FIRST" }; + format!("{suffix} NULLS {nulls}").trim().to_owned() + }; + let mut column = Expression::column(alias); + if let Expression::Column(column) = &mut column { + if generator.quote_identifier(alias) != *alias { + column.name = Identifier::quoted(alias); + } + } + let mut ordered = polyglot_sql::expressions::Ordered::asc(column); + ordered.desc = suffix.starts_with("DESC"); + ordered.explicit_asc = suffix.starts_with("ASC"); + ordered.nulls_first = Some(suffix.ends_with("NULLS FIRST")); + // The pinned Polyglot emitter does not emulate NULL placement for + // MySQL or TSQL. Preserve the order with a scalar CASE key. + if matches!(generator.dialect, DialectType::MySQL | DialectType::TSQL) { + let nulls_first = ordered.nulls_first.take().unwrap(); + if nulls_first == ordered.desc { + let identifier = alias.replace('"', "\"\""); + let key = parse_semantic_expression(&format!( + "CASE WHEN \"{identifier}\" IS NULL THEN 1 ELSE 0 END" + ))?; + let mut null_order = polyglot_sql::expressions::Ordered::asc(key); + null_order.desc = nulls_first; + order.push(null_order); + } + } + order.push(ordered); } - sql.push_str(&format!("\nORDER BY {}", order.join(", "))); + let clause = Expression::OrderBy(Box::new(polyglot_sql::expressions::OrderBy { + expressions: order, + siblings: false, + comments: Vec::new(), + })); + sql.push_str(&format!("\n{}", generator.emit_expression(&clause)?)); } if let Some(limit) = query.limit { sql.push_str(&format!("\nLIMIT {limit}")); @@ -1152,6 +1240,26 @@ mod tests { .ok_or_else(|| unsupported("test_not_planned")) } + #[test] + fn imported_columnless_leaf_requires_one_expression_source() { + for (expression, supported) in [ + ("SUM(orders.amount) / COUNT(*)", true), + ("(SUM(orders.amount) + SUM(customers.id)) / COUNT(*)", false), + ] { + let mut graph = graph(); + let mut metric = Metric::derived("average_value", expression); + metric.sql_is_complete = true; + metric.metadata = Some(serde_json::json!({"ossie_expression_dialect": "ANSI_SQL"})); + graph.add_metric_unvalidated(metric).unwrap(); + let query = SemanticQuery::new().with_metrics(vec!["average_value".into()]); + let sql = try_generate(&SqlGenerator::new(&graph), &query).unwrap(); + assert_eq!(sql.is_some(), supported); + if let Some(sql) = sql { + assert_valid_sql(&sql); + } + } + } + #[test] fn graph_ratio_has_independent_source_aggregates() { let sql = compile(&graph(), &["ratio"], &[]).unwrap(); @@ -1571,7 +1679,7 @@ mod tests { assert!(sql.contains("__sidemantic_dimension_0 IS NOT DISTINCT FROM customers_preagg.__sidemantic_dimension_0"), "{sql}"); assert!(sql.contains("__sidemantic_dimension_1 IS NOT DISTINCT FROM customers_preagg.__sidemantic_dimension_1"), "{sql}"); assert!( - sql.contains("ORDER BY orders_region ASC, customers_region DESC"), + sql.contains("ORDER BY orders_region ASC NULLS FIRST, customers_region DESC"), "{sql}" ); assert_valid_sql(&sql); @@ -1600,7 +1708,9 @@ mod tests { "{sql}" ); assert!( - sql.contains("ORDER BY orders_revenue DESC, customers_revenue ASC"), + sql.contains( + "ORDER BY orders_revenue DESC NULLS LAST, customers_revenue ASC NULLS FIRST" + ), "{sql}" ); assert_valid_sql(&sql); diff --git a/sidemantic-rs/src/sql/generator/cohort.rs b/sidemantic-rs/src/sql/generator/cohort.rs index f77d25c73..fd732abe0 100644 --- a/sidemantic-rs/src/sql/generator/cohort.rs +++ b/sidemantic-rs/src/sql/generator/cohort.rs @@ -154,11 +154,8 @@ impl SqlGenerator<'_> { // Direct query identifiers use target syntax. The source-expression // binders above retain canonical quotes until AST emission. let quote = |name: &str| self.cohort_target_identifier(name); - if reference.graph_metric - && self.graph.metric_owner(&reference.name) != Some(reference.model.as_str()) - { - return Err(unsupported("owner")); - } + // Metric reference resolution already enforces a declared owner or a + // unique entity source for graph-level cohorts. let model = self .graph .get_model(&reference.model) diff --git a/sidemantic-rs/src/sql/generator/fanout_complete.rs b/sidemantic-rs/src/sql/generator/fanout_complete.rs index c1bec9fcc..513d6b1b9 100644 --- a/sidemantic-rs/src/sql/generator/fanout_complete.rs +++ b/sidemantic-rs/src/sql/generator/fanout_complete.rs @@ -103,12 +103,29 @@ pub(super) fn generate_entity_aggregates( if deduplicate { for source in sources { let source_model = generator.graph.get_model(source).unwrap(); - if source_model.primary_keys().is_empty() { + let mut keys = source_model.primary_keys(); + // Ossie unique keys identify entity rows just like a primary key. + // Use the imported declaration locally without changing the graph + // or inferring primary keys for native models. + if keys.is_empty() + && source_model + .metadata + .as_ref() + .is_some_and(|metadata| metadata.get("ossie_source_kind").is_some()) + { + keys = source_model + .unique_keys + .as_ref() + .and_then(|keys| keys.first()) + .cloned() + .unwrap_or_default(); + } + if keys.is_empty() { return Err(SidemanticError::Validation(format!( "Model '{source}' has no primary key; cannot safely aggregate across a fanout join" ))); } - for key in source_model.primary_keys() { + for key in keys { inputs.add(source, generator.key_sql(source_model, &key, None)?, &[]); } } diff --git a/sidemantic-rs/src/sql/generator/options.rs b/sidemantic-rs/src/sql/generator/options.rs index 4ce4f33fc..37a09f10f 100644 --- a/sidemantic-rs/src/sql/generator/options.rs +++ b/sidemantic-rs/src/sql/generator/options.rs @@ -12,9 +12,8 @@ impl SqlGenerator<'_> { Ok(()) } - /// Resolve the public output names before renaming. Internal CTE, metric, - /// snapshot and window references must retain their original names. - pub(super) fn selected_aliases( + /// Resolve each selected semantic reference to its public output identity. + pub(super) fn selected_output_names( &self, query: &SemanticQuery, ) -> Result> { @@ -71,11 +70,26 @@ impl SqlGenerator<'_> { } Ok(fields .into_iter() - .filter_map(|(reference, model, name)| { + .map(|(reference, model, name)| { + (reference, self.output_alias(&model, &name, &collisions)) + }) + .collect()) + } + + /// Resolve the public output names before renaming. Internal CTE, metric, + /// snapshot and window references must retain their original names. + pub(super) fn selected_aliases( + &self, + query: &SemanticQuery, + ) -> Result> { + Ok(self + .selected_output_names(query)? + .into_iter() + .filter_map(|(reference, output)| { query .aliases .get(&reference) - .map(|alias| (self.output_alias(&model, &name, &collisions), alias.clone())) + .map(|alias| (output, alias.clone())) }) .collect()) } diff --git a/sidemantic-rs/src/sql/generator/retention.rs b/sidemantic-rs/src/sql/generator/retention.rs index 23c7836a6..d748e774e 100644 --- a/sidemantic-rs/src/sql/generator/retention.rs +++ b/sidemantic-rs/src/sql/generator/retention.rs @@ -113,9 +113,8 @@ impl SqlGenerator<'_> { reference: &MetricRef, query: &SemanticQuery, ) -> Result { - if reference.graph_metric { - return Err(unsupported("graph_scope")); - } + // Graph-level retention references have the same uniquely resolved + // entity source as model-local references by this point. if !query.dimensions.is_empty() || query.ungrouped || !query.table_calculations.is_empty() { return Err(unsupported("query_shape")); } diff --git a/sidemantic/core/dependency_analyzer.py b/sidemantic/core/dependency_analyzer.py index 5b879f7ff..1b27451db 100644 --- a/sidemantic/core/dependency_analyzer.py +++ b/sidemantic/core/dependency_analyzer.py @@ -103,7 +103,20 @@ def extract_metric_dependencies(metric_obj, graph=None, model_context=None) -> s if resolved: continue - # Try to resolve as metric first + # Bare dependencies prefer the owning model, as promised by + # model_context. A same-named graph metric must not redirect + # either compilation or source-policy discovery. + if not qualifier and model_context: + try: + model = graph.get_model(model_context) + if model and model.get_metric(ref): + deps.add(f"{model_context}.{ref}") + continue + except (KeyError, AttributeError): + pass + + # Top-level names and unresolved qualified references retain + # their existing graph-metric fallback. try: if graph.get_metric(ref): deps.add(ref) @@ -112,8 +125,8 @@ def extract_metric_dependencies(metric_obj, graph=None, model_context=None) -> s except KeyError: pass - # If we have model context, check that model first - if not resolved and model_context: + # Preserve contextual fallback for unresolved qualified names. + if not resolved and qualifier and model_context: try: model = graph.get_model(model_context) if model and model.get_metric(ref): diff --git a/sidemantic/sql/generator.py b/sidemantic/sql/generator.py index a83e61340..f4dbc2a26 100644 --- a/sidemantic/sql/generator.py +++ b/sidemantic/sql/generator.py @@ -1331,6 +1331,11 @@ def _specialized_order_clause(self, order_by: list[str] | None, output_names: li """Order specialized results by their exposed columns, never raw SQL.""" fields = [] for field in order_by or []: + reference, suffix = split_order_field(field, output_names) + if reference in output_names: + # Public graph identities may contain dots or spaces. Quote + # the exact selected name before parsing SQL qualification. + field = f"{exp.column(reference, quoted=True).sql(dialect=self.dialect)} {suffix}" try: order = parse_query_fragment(field, self.dialect, order_by=True) except ValueError: @@ -1991,6 +1996,18 @@ def collect_models_from_metric(metric_ref: str): owning_model = self.graph.metric_owners.get(metric_ref) if owning_model: add_model(owning_model) + elif metric.type in {"cohort", "conversion", "retention"}: + # Population generators infer their source from the entity + # dimension. Resolve it before the security pass so inferred + # graph metrics receive the same policies as explicitly owned ones. + candidates = [model.name for model in self.graph.models.values() if model.get_dimension(metric.entity)] + if len(candidates) > 1: + raise ValueError( + f"Ambiguous model for {metric.type} metric '{metric_ref}': " + f"entity dimension '{metric.entity}' found in multiple models: {', '.join(sorted(candidates))}" + ) + if candidates: + add_model(candidates[0]) if metric.type == "ratio": if metric.numerator: collect_models_from_metric(metric.numerator) @@ -3214,7 +3231,12 @@ def expand_metric(reference: str, context: str | None = None, stack: tuple[str, group_name = complete_groups[reference] else: group_name = model_name - if reference in complete_metrics or (model_name is not None and aggregate_models == {model_name}): + # Scalar formulas must run after the full join, including model-local + # formulas: absent source counts/defaults still feed their arithmetic. + scalar_calculation = metric.type in ("derived", "ratio") and not metric.sql_is_complete + if reference in complete_metrics or ( + model_name is not None and aggregate_models == {model_name} and not scalar_calculation + ): if reference not in leaf_refs: leaf_refs.append(reference) child_aliases[reference] = f"__sidemantic_metric_{len(leaf_refs) - 1}" @@ -3381,6 +3403,10 @@ def expand_metric(reference: str, context: str | None = None, stack: tuple[str, limit=None, offset=None, aliases=child_aliases, + # The parent already resolved the public dimension grain. + # Defaults here would create hidden groups for graph metrics + # or reintroduce defaults the caller explicitly skipped. + skip_default_time_dimensions=True, use_preaggregations=use_preaggregations, user_attributes=user_attributes, ) @@ -3535,17 +3561,22 @@ def dimension_output_name(dim_ref: str, dim_name: str, gran: str | None) -> str: if order_by: order_clauses = [] for field in order_by: - parts = field.rsplit(" ", 1) - direction = "" - field_ref = field - if len(parts) == 2 and parts[1].upper() in {"ASC", "DESC"}: - field_ref = parts[0] - direction = f" {parts[1].upper()}" - + field_ref, suffix = split_order_field(field, [*output_names, *output_names.values()]) + # Match the ordinary SQLGlot query builder's public ordering + # contract, rather than inheriting a database-specific default. + if "NULLS" not in suffix: + nulls = "LAST" if suffix == "DESC" else "FIRST" + suffix = f"{suffix} NULLS {nulls}".strip() field_name = field_ref.split(".", 1)[1] if "." in field_ref else field_ref output_name = output_names.get(field_ref) or output_names.get(field_name) or field_ref - order_clauses.append(f"{self._quote_alias(output_name)}{direction}") - final_query += f"\nORDER BY {', '.join(order_clauses)}" + order_clauses.append( + exp.Ordered( + this=exp.column(output_name, quoted=True), + desc=suffix.startswith("DESC"), + nulls_first=suffix.endswith("NULLS FIRST"), + ) + ) + final_query += "\n" + exp.Order(expressions=order_clauses).sql(dialect=self.dialect) # Add LIMIT and OFFSET if limit is not None: @@ -5388,8 +5419,8 @@ def _generate_cohort_metric_query( """ import re as _re - # Resolve the metric - if "." in metric_name: + # Exact graph identities may contain dots and precede qualified names. + if "." in metric_name and metric_name not in self.graph.metrics: model_name, local_name = metric_name.split(".", 1) else: local_name = metric_name @@ -5705,7 +5736,7 @@ def _generate_retention_query( metric = None model = None - if "." in metric_name: + if "." in metric_name and metric_name not in self.graph.metrics: model_name, measure_name = metric_name.split(".", 1) model = self.graph.get_model(model_name) if model: @@ -5719,6 +5750,11 @@ def _generate_retention_query( if not metric or not metric.entity or not metric.cohort_event: raise ValueError(f"Retention metric {metric_name} missing required fields (entity, cohort_event)") + if not model and metric_name in self.graph.metric_owners: + # Explicit ownership is authoritative, including when another model + # declares the same entity dimension. Missing owners must fail. + model = self.graph.get_model(self.graph.metric_owners[metric_name]) + # Find the model that owns this metric if not already found if not model: for m_name, m in self.graph.models.items(): @@ -5925,7 +5961,7 @@ def _generate_conversion_query( metric = None model = None - if "." in metric_name: + if "." in metric_name and metric_name not in self.graph.metrics: # model.metric format model_name, measure_name = metric_name.split(".", 1) model = self.graph.get_model(model_name) @@ -6094,7 +6130,7 @@ def _generate_conversion_query( AND conv.event_time BETWEEN base.event_time AND base.event_time + {self._build_interval(window_num, window_unit)} ) SELECT -{dim_select} COUNT(DISTINCT conversions.entity)::FLOAT / NULLIF(COUNT(DISTINCT base_events.entity), 0) AS {metric.name} +{dim_select} COUNT(DISTINCT conversions.entity)::FLOAT / NULLIF(COUNT(DISTINCT base_events.entity), 0) AS {self._quote_alias(metric.name)} FROM base_events LEFT JOIN conversions ON {join_condition}{group_by}{order_clause}{limit_clause} """ @@ -6137,7 +6173,9 @@ def _generate_multistep_conversion_query( # Find the model that owns this metric model = None - if "." in metric_name: + if metric_name in self.graph.metric_owners: + model = self.graph.get_model(self.graph.metric_owners[metric_name]) + elif "." in metric_name and metric_name not in self.graph.metrics: model_name, _ = metric_name.split(".", 1) model = self.graph.get_model(model_name) if not model: @@ -6333,7 +6371,7 @@ def _normalize_expr_for_subquery(sql_expr: str, table_alias: str, qualify_bare: # Build final SELECT: count distinct entities from each step CTE # Also alias the last step count to the metric name for ORDER BY compatibility - metric_name_only = metric_name.split(".", 1)[-1] if "." in metric_name else metric_name + metric_name_only = metric.name final_select_parts = [] for alias in dim_aliases: final_select_parts.append(f"step_1.{alias} AS {alias}") @@ -6341,7 +6379,7 @@ def _normalize_expr_for_subquery(sql_expr: str, table_alias: str, qualify_bare: for i in range(1, num_steps + 1): final_select_parts.append(f"COUNT(DISTINCT step_{i}.entity) AS step_{i}_count") # Add metric-named column (last step count) so ORDER BY metric_name works - final_select_parts.append(f"COUNT(DISTINCT step_{num_steps}.entity) AS {metric_name_only}") + final_select_parts.append(f"COUNT(DISTINCT step_{num_steps}.entity) AS {self._quote_alias(metric_name_only)}") final_select = ",\n ".join(final_select_parts) # Build LEFT JOIN chain: step_1 LEFT JOIN step_2 LEFT JOIN step_3 ... @@ -6421,12 +6459,15 @@ def _generate_with_window_functions( time_comparison_base_plans = {} regular_expression_metric_plans = {} precomputed_cumulative_metrics = [] + metric_output_aliases = {} def add_unique(items: list[str], value: str | None) -> None: if value and value not in items: items.append(value) def metric_ref_alias(metric_ref: str) -> str: + if metric_ref in metric_output_aliases: + return metric_output_aliases[metric_ref] return metric_ref.split(".", 1)[1] if "." in metric_ref else metric_ref def canonical_ref(metric_ref: str, model_context: str | None = None) -> str: @@ -6445,6 +6486,10 @@ def canonical_ref(metric_ref: str, model_context: str | None = None) -> str: def resolve_metric_ref(metric_ref: str, model_context: str | None = None): if "." in metric_ref: + # Exact graph identities precede model-qualified names, just + # as they do in public query dispatch and policy discovery. + if metric_ref in self.graph.metrics: + return self.graph.get_metric(metric_ref), self.graph.metric_owners.get(metric_ref) model_name, metric_name = metric_ref.split(".", 1) try: model = self.graph.get_model(model_name) @@ -6454,10 +6499,7 @@ def resolve_metric_ref(metric_ref: str, model_context: str | None = None): model_metric = model.get_metric(metric_name) if model_metric: return model_metric, model_name - try: - return self.graph.get_metric(metric_ref), model_context - except KeyError: - return None, model_context + return None, model_context if model_context: try: @@ -6470,7 +6512,7 @@ def resolve_metric_ref(metric_ref: str, model_context: str | None = None): return context_metric, model_context try: - return self.graph.get_metric(metric_ref), model_context + return self.graph.get_metric(metric_ref), self.graph.metric_owners.get(metric_ref, model_context) except KeyError: pass @@ -6513,7 +6555,7 @@ def collect_leaf_base_metrics( if not dependencies: add_unique(base_metrics, canon_ref) return - for dep in dependencies: + for dep in sorted(dependencies): collect_leaf_base_metrics(dep, resolved_context, visited) return @@ -6535,8 +6577,18 @@ def collect_leaf_base_metrics( # Classify metric by type if metric and metric.type == "cumulative": add_unique(cumulative_metrics, m) + if self.dialect == "redshift" and metric.agg == "approx_count_distinct": + raise QueryValidationError( + "Redshift does not support approximate distinct window functions " + "(metric.approx_count_distinct_window_redshift)" + ) if metric.window_expression: expression = sqlglot.parse_one(metric.window_expression, read=self.dialect) + if self.dialect == "redshift" and expression.find(exp.ApproxDistinct): + raise QueryValidationError( + "Redshift does not support approximate distinct window functions " + "(metric.approx_count_distinct_window_redshift)" + ) for column in expression.find_all(exp.Column): if column.table.lower() != "base": continue @@ -6604,7 +6656,11 @@ def collect_leaf_base_metrics( ) ) if is_expression_metric: + first_dependency = len(base_metrics) collect_leaf_base_metrics(metric_ref, resolved_context) + # Dependency sets must not make the public column order + # depend on the interpreter's hash seed. + base_metrics[first_dependency:] = sorted(base_metrics[first_dependency:]) regular_expression_metric_plans[m] = { "metric_ref": metric_ref, "metric_context": resolved_context, @@ -6670,7 +6726,6 @@ def collect_leaf_base_metrics( # Build inner query with base aggregations # Dedupe base_metrics to avoid duplicate column names base_metrics = list(dict.fromkeys(base_metrics)) - base_metric_aliases = {metric_ref_alias(m) for m in base_metrics} inner_query = self.generate( metrics=base_metrics, @@ -6684,6 +6739,34 @@ def collect_leaf_base_metrics( # Parse dimensions for outer SELECT parsed_dims = self._parse_dimension_refs(dimensions) + # Bind window inputs to the actual grouped outputs. Colliding dimension + # names are prefixed by the inner planner (items_label, refunds_label). + inner_outputs = sqlglot.parse_one(inner_query, read=self.dialect).named_selects + dimension_aliases = dict(zip(parsed_dims, inner_outputs[: len(parsed_dims)], strict=True)) + # Resolve metric identity with the same collision policy as grouped + # output, and verify against the emitted projection. Nested window + # queries can expose extra dependencies, so positional metric matching + # would bind the wrong column. + resolved_base_metrics = {} + output_name_counts = {} + for dim_ref, gran in parsed_dims: + name = f"{dim_ref.split('.')[-1]}__{gran}" if gran else dim_ref.split(".")[-1] + output_name_counts[name] = output_name_counts.get(name, 0) + 1 + for reference in base_metrics: + metric, owner = resolve_metric_ref(reference) + name = metric.name if metric else metric_ref_alias(reference) + resolved_base_metrics[reference] = (name, owner) + output_name_counts[name] = output_name_counts.get(name, 0) + 1 + for reference, (name, owner) in resolved_base_metrics.items(): + alias = f"{owner}_{name}" if owner and output_name_counts[name] > 1 else name + if alias not in inner_outputs: + # Existing time-comparison outputs retain their qualified name. + if reference in inner_outputs: + alias = reference + else: + raise ValueError(f"Missing grouped metric output for '{reference}'") + metric_output_aliases[reference] = alias + base_metric_aliases = set(metric_output_aliases.values()) def sql_identifier(name: str) -> str: import re @@ -6755,12 +6838,8 @@ def build_time_comparison_base_expression( # Add dimensions for dim_ref, gran in parsed_dims: - # Inner query uses simple alias without model prefix - dim_name = dim_ref.split(".")[1] if "." in dim_ref else dim_ref - alias = dim_name - if gran: - alias = f"{alias}__{gran}" - select_exprs.append(f"base.{alias}") + alias = dimension_aliases[dim_ref, gran] + select_exprs.append(f"base.{sql_identifier(alias)}") # Add base metrics (pass through) for m in base_metrics: @@ -6780,30 +6859,11 @@ def build_time_comparison_base_expression( # Add cumulative metrics with window functions for m in cumulative_metrics: - # Handle both qualified (model.measure) and unqualified references - metric = None - if "." in m: - model_name, measure_name = m.split(".", 1) - try: - model = self.graph.get_model(model_name) - metric = model.get_metric(measure_name) if model else None - except KeyError: - pass - # Fall back to graph-level metric with dotted name - if not metric: - try: - metric = self.graph.get_metric(m) - except KeyError: - pass - # Use just the measure name as alias if it's model.measure, otherwise full name - # Quote to handle any special characters - metric_alias = self._quote_alias(measure_name if metric and "." not in metric.name else m) - else: - metric = self.graph.get_metric(m) - # Quote to handle dotted metric names - metric_alias = self._quote_alias(m) + # Use the same graph-first identity and owner as dependency collection. + metric, metric_context = resolve_metric_ref(m) if not metric or (not metric.sql and not metric.window_expression): continue + metric_alias = self._quote_alias(metric.name) # Find the time dimension to order by time_dim = None @@ -6815,23 +6875,21 @@ def build_time_comparison_base_expression( if model: dim = model.get_dimension(dim_name) if dim and dim.type == "time": - # Use simple alias without model prefix - time_dim = f"base.{dim_name}" - if gran: - time_dim = f"base.{dim_name}__{gran}" + time_dim = f"base.{sql_identifier(dimension_aliases[dim_ref, gran])}" break # Allow window_order to override auto-detected time dimension if metric.window_order: - output_aliases = { - f"{ref.split('.')[-1]}__{gran}" if gran else ref.split(".")[-1] for ref, gran in parsed_dims - } | {metric_ref_alias(ref) for ref in base_metrics} + output_aliases = set(dimension_aliases.values()) | {metric_ref_alias(ref) for ref in base_metrics} order_alias = metric.window_order + order_reference = canonical_ref(order_alias, metric_context) + if order_reference in metric_output_aliases: + order_alias = metric_output_aliases[order_reference] if order_alias not in output_aliases: # A selected dimension may be materialized at an explicit or # default grain, so bind its semantic name to that output. matches = [ - f"{ref.split('.')[-1]}__{gran}" if gran else ref.split(".")[-1] + dimension_aliases[ref, gran] for ref, gran in parsed_dims if order_alias in (ref, ref.split(".")[-1]) ] @@ -6851,7 +6909,7 @@ def build_time_comparison_base_expression( dimension = self.graph.get_model(partition_model).get_dimension(dim_name) if dimension and dimension.type == "time": continue - alias = f"{dim_name}__{gran}" if gran else dim_name + alias = dimension_aliases[dim_ref, gran] column = f"base.{self._quote_alias(alias)}" if column != time_dim and column not in partition_cols: partition_cols.append(column) @@ -6878,7 +6936,18 @@ def build_time_comparison_base_expression( if metric.window_expression: order_col = time_dim frame = frame or "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" - window_value = f"{metric.window_expression} OVER ({partition_clause}ORDER BY {order_col} {frame})" + window_expression = sqlglot.parse_one(metric.window_expression, read=self.dialect) + + def bind_window_input(node): + if isinstance(node, exp.Column) and node.table.lower() == "base": + reference = canonical_ref(node.name, metric_context) + alias = metric_output_aliases.get(reference) + if alias: + return exp.column(alias, table="base", quoted=True) + return node + + window_expression = window_expression.transform(bind_window_input).sql(dialect=self.dialect) + window_value = f"{window_expression} OVER ({partition_clause}ORDER BY {order_col} {frame})" window_expr = f"{self._wrap_with_fill_nulls(window_value, metric)} AS {metric_alias}" select_exprs.append(window_expr) cumulative_window_entries.append((window_expr, metric_alias)) @@ -6886,33 +6955,8 @@ def build_time_comparison_base_expression( # Option A: Use agg + sql (supports AVG, COUNT, etc.) # Get base measure/metric to apply window function to - base_ref = metric.sql - if "." in base_ref: - # It's a direct measure reference - extract just the measure name - base_alias = base_ref.split(".")[1] - else: - # It's an unqualified reference - check model first, then graph-level - base_metric = None - # Get model name from the cumulative metric reference - cum_model_name = m.split(".")[0] if "." in m else None - if cum_model_name: - cum_model = self.graph.get_model(cum_model_name) - if cum_model: - base_metric = cum_model.get_metric(base_ref) - - # Fallback to graph-level metric - if not base_metric: - try: - base_metric = self.graph.get_metric(base_ref) - except KeyError: - pass - - if base_metric and base_metric.sql: - # Window over the base query's metric alias, not the raw column behind that metric. - base_alias = base_metric.name - else: - # Fallback to the metric name itself - base_alias = base_ref + base_ref = canonical_ref(metric.sql, metric_context) + base_alias = sql_identifier(metric_ref_alias(base_ref)) # Determine aggregation function (default to SUM for backwards compatibility) agg_func = self._agg_sql_name(metric.agg or "sum") @@ -6964,10 +7008,7 @@ def build_time_comparison_base_expression( # Add dimensions and base metrics for dim_ref, gran in parsed_dims: - dim_name = dim_ref.split(".")[1] if "." in dim_ref else dim_ref - alias = dim_name - if gran: - alias = f"{alias}__{gran}" + alias = dimension_aliases[dim_ref, gran] lag_selects.append(f"base.{sql_identifier(alias)}") lag_cte_columns.append(alias) @@ -7008,9 +7049,7 @@ def build_time_comparison_base_expression( if model: dim = model.get_dimension(dim_name) if dim and dim.type == "time": - time_dim = f"base.{dim_name}" - if gran: - time_dim = f"base.{dim_name}__{gran}" + time_dim = f"base.{sql_identifier(dimension_aliases[dim_ref, gran])}" time_dim_gran = gran or dim.granularity break @@ -7020,13 +7059,8 @@ def build_time_comparison_base_expression( # Partition by non-time dimensions to avoid cross-group leakage. partition_cols = [] for partition_dim_ref, partition_gran in parsed_dims: - partition_dim_name = ( - partition_dim_ref.split(".")[1] if "." in partition_dim_ref else partition_dim_ref - ) - partition_alias = partition_dim_name - if partition_gran: - partition_alias = f"{partition_alias}__{partition_gran}" - partition_col = f"base.{partition_alias}" + partition_alias = dimension_aliases[partition_dim_ref, partition_gran] + partition_col = f"base.{sql_identifier(partition_alias)}" if partition_col != time_dim and partition_col not in partition_cols: partition_cols.append(partition_col) partition_clause = "" @@ -7067,7 +7101,7 @@ def build_time_comparison_base_expression( # Add LAG expressions for each offset ratio metric for m in offset_ratio_metrics: metric_context = m.split(".", 1)[0] if "." in m else None - metric, _ = resolve_metric_ref(m, metric_context) + metric, resolved_context = resolve_metric_ref(m, metric_context) if not metric or not metric.numerator or not metric.denominator: continue @@ -7082,9 +7116,7 @@ def build_time_comparison_base_expression( if model: dim = model.get_dimension(dim_name) if dim and dim.type == "time": - time_dim = f"base.{dim_name}" - if gran: - time_dim = f"base.{dim_name}__{gran}" + time_dim = f"base.{sql_identifier(dimension_aliases[dim_ref, gran])}" # Fall back to the dimension's own base granularity when the # query did not request an explicit __gran suffix, so an # offset_window like "7 days" maps to the right number of rows. @@ -7097,13 +7129,8 @@ def build_time_comparison_base_expression( # Partition by non-time dimensions to avoid cross-group leakage. partition_cols = [] for partition_dim_ref, partition_gran in parsed_dims: - partition_dim_name = ( - partition_dim_ref.split(".")[1] if "." in partition_dim_ref else partition_dim_ref - ) - partition_alias = partition_dim_name - if partition_gran: - partition_alias = f"{partition_alias}__{partition_gran}" - partition_col = f"base.{partition_alias}" + partition_alias = dimension_aliases[partition_dim_ref, partition_gran] + partition_col = f"base.{sql_identifier(partition_alias)}" if partition_col != time_dim and partition_col not in partition_cols: partition_cols.append(partition_col) partition_clause = "" @@ -7111,7 +7138,7 @@ def build_time_comparison_base_expression( partition_clause = f"PARTITION BY {', '.join(partition_cols)} " # Get denominator alias - denom_alias = metric_ref_alias(metric.denominator) + denom_alias = metric_ref_alias(canonical_ref(metric.denominator, resolved_context)) denominator_expr = f"base.{sql_identifier(denom_alias)}" interval = self._parse_period_interval(metric.offset_window) if time_dim_gran else None @@ -7139,7 +7166,7 @@ def build_time_comparison_base_expression( # Re-add dimensions and base metrics from lag_cte for col in lag_cte_columns: - final_selects.append(col) + final_selects.append(sql_identifier(col)) # Add time comparison metrics for m in time_comparison_metrics: @@ -7173,11 +7200,11 @@ def build_time_comparison_base_expression( # Add offset ratio metrics for m in offset_ratio_metrics: metric_context = m.split(".", 1)[0] if "." in m else None - metric, _ = resolve_metric_ref(m, metric_context) + metric, resolved_context = resolve_metric_ref(m, metric_context) if not metric: continue - num_alias = sql_identifier(metric_ref_alias(metric.numerator)) + num_alias = sql_identifier(metric_ref_alias(canonical_ref(metric.numerator, resolved_context))) # Quote aliases to handle dotted metric names prev_denom_col = self._quote_alias(f"{m}_prev_denom") @@ -7199,7 +7226,17 @@ def build_time_comparison_base_expression( # Add ORDER BY if specified if order_by: output_names = sqlglot.parse_one(outer_query, read=self.dialect).named_selects - outer_query += self._specialized_order_clause(order_by, output_names) + dimension_order_aliases = { + f"{reference}__{grain}" if grain else reference: alias + for (reference, grain), alias in dimension_aliases.items() + } + dimension_order_aliases.update(metric_output_aliases) + resolved_order = [] + for field in order_by: + reference, suffix = split_order_field(field, [*dimension_order_aliases, *output_names]) + alias = dimension_order_aliases.get(reference) + resolved_order.append(f"{self._quote_alias(alias)} {suffix}" if alias else field) + outer_query += self._specialized_order_clause(resolved_order, output_names) # Add LIMIT and OFFSET if specified if limit is not None: diff --git a/sidemantic/viz.py b/sidemantic/viz.py index e7a15d5d5..b2c747dbe 100644 --- a/sidemantic/viz.py +++ b/sidemantic/viz.py @@ -4104,7 +4104,9 @@ def _crossfilter_body(safe_json: str) -> str: function comparableValue(value) { if (value instanceof Date) return value.getTime(); if (typeof value === 'string') { - const parsed = Date.parse(value); + // Treat date-only bounds like naive timestamp buckets, both in local time. + const dateValue = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/.test(value) ? `${value}T00:00:00` : value; + const parsed = Date.parse(dateValue); if (Number.isFinite(parsed)) return parsed; } const number = Number(value); diff --git a/tests/adapters/cube/test_kitchen_sink.py b/tests/adapters/cube/test_kitchen_sink.py index 8c9bd85c0..daa53a4d6 100644 --- a/tests/adapters/cube/test_kitchen_sink.py +++ b/tests/adapters/cube/test_kitchen_sink.py @@ -761,23 +761,16 @@ def test_filter_on_joined_model(self, kitchen_sink_layer): assert rows[0]["count"] == 5 def test_segment_from_joined_model(self, kitchen_sink_layer): - """Test using a segment from a joined model. + """Filter employees by a company segment across the department join.""" + kitchen_sink_layer.adapter.execute("UPDATE companies SET is_active = false WHERE name = 'TechCorp'") - This might be a hole - do segments work across joins? - """ - # This would use companies.active_companies segment when querying employees - # Many semantic layers don't support this - try: - result = kitchen_sink_layer.query( - metrics=["employees.count"], - segments=["companies.active_companies"], - ) - rows = fetch_dicts(result) - # Should only include employees from active companies - # Excludes RetailCo which has no employees anyway in our data - assert rows[0]["count"] == 10 - except Exception as e: - pytest.skip(f"Cross-model segments not supported: {e}") + assert fetch_dicts(kitchen_sink_layer.query(metrics=["employees.count"])) == [{"count": 10}] + result = kitchen_sink_layer.query( + metrics=["employees.count"], + segments=["companies.active_companies"], + ) + # TechCorp's five employees must be excluded even without a company dimension. + assert fetch_dicts(result) == [{"count": 5}] def test_having_clause_on_aggregate(self, kitchen_sink_layer): """Test HAVING clause (filter on aggregated value). diff --git a/tests/adapters/test_fixture_functionality_contracts.py b/tests/adapters/test_fixture_functionality_contracts.py index bb26da8b0..9b3db7b8d 100644 --- a/tests/adapters/test_fixture_functionality_contracts.py +++ b/tests/adapters/test_fixture_functionality_contracts.py @@ -1,7 +1,6 @@ from __future__ import annotations from collections import Counter -from datetime import date from functools import cache from pathlib import Path @@ -33,6 +32,7 @@ _pick_execution_query, _prepare_graph_for_execution, ) +from tests.duckdb_compat import date_bucket def test_execution_candidate_materializes_invariant_filter_columns(): @@ -265,7 +265,7 @@ def test_execution_candidate_materializes_invariant_filter_columns(): "query_kind": "dimension", "dimension_type": "time", "field_name": "order_date", - "expected_values": {date(2024, 1, 1), date(2024, 1, 2)}, + "expected_values": {date_bucket(2024, 1, 1), date_bucket(2024, 1, 2)}, }, ) @@ -475,7 +475,7 @@ def _assert_exact_deterministic_result(query_spec: dict, rows: list[tuple], fixt result_values = {row[0] for row in rows} dimension_type = query_spec["dimension_type"] if dimension_type == "time": - assert result_values == {date(2024, 1, 1), date(2024, 1, 2)}, ( + assert result_values == {date_bucket(2024, 1, 1), date_bucket(2024, 1, 2)}, ( f"{fixture_path}: expected time values [2024-01-01, 2024-01-02], got {sorted(result_values)}" ) elif dimension_type == "numeric": diff --git a/tests/adapters/thoughtspot/test_parsing.py b/tests/adapters/thoughtspot/test_parsing.py index f70865f14..0dbbda173 100644 --- a/tests/adapters/thoughtspot/test_parsing.py +++ b/tests/adapters/thoughtspot/test_parsing.py @@ -8,6 +8,7 @@ from sidemantic import SemanticLayer from sidemantic.adapters.thoughtspot import ThoughtSpotAdapter, _extract_all_join_refs from sidemantic.loaders import load_from_directory +from tests.duckdb_compat import date_bucket # ============================================================================= # BASIC PARSING TESTS @@ -886,7 +887,7 @@ def test_thoughtspot_joined_model_is_queryable(): dimensions=["sales_model.order_date", "sales_model.customer_name", "sales_model.region_name"], ) rows = con.execute(sql).fetchall() - assert rows == [(__import__("datetime").date(2024, 1, 1), "Acme", "West", 150.0, 135.0, 2)] + assert rows == [(date_bucket(2024, 1, 1), "Acme", "West", 150.0, 135.0, 2)] def test_thoughtspot_role_playing_joins_stay_distinct(): diff --git a/tests/db/test_postgres_integration.py b/tests/db/test_postgres_integration.py index 4cc3d41e6..4e66a7b2e 100644 --- a/tests/db/test_postgres_integration.py +++ b/tests/db/test_postgres_integration.py @@ -408,7 +408,6 @@ def test_semantic_layer_postgres_limit(clean_postgres): assert len(rows) == 2 -@pytest.mark.skip(reason="Date functions test - may have issues with validation") def test_semantic_layer_postgres_date_functions(clean_postgres): """Test date/time functions in dimensions.""" clean_postgres.execute( @@ -435,8 +434,9 @@ def test_semantic_layer_postgres_date_functions(clean_postgres): table="events", primary_key="event_id", dimensions=[ - Dimension(name="month", type="time", sql="TO_CHAR(event_date, 'YYYY-MM')", granularity="month"), - Dimension(name="year", type="time", sql="EXTRACT(YEAR FROM event_date)::TEXT", granularity="year"), + # Formatted dates are strings, so they must not be truncated again. + Dimension(name="month", type="categorical", sql="TO_CHAR(event_date, 'YYYY-MM')"), + Dimension(name="year", type="categorical", sql="EXTRACT(YEAR FROM event_date)::TEXT"), ], metrics=[Metric(name="event_count", agg="count", sql="event_id")], ) @@ -448,6 +448,7 @@ def test_semantic_layer_postgres_date_functions(clean_postgres): assert results_dict["2024-01"] == 2 assert results_dict["2024-02"] == 2 + assert layer.query(dimensions=["events.year"], metrics=["events.event_count"]).fetchall() == [("2024", 4)] def test_semantic_layer_postgres_symmetric_aggregates(clean_postgres): diff --git a/tests/duckdb_compat.py b/tests/duckdb_compat.py new file mode 100644 index 000000000..10d0131a7 --- /dev/null +++ b/tests/duckdb_compat.py @@ -0,0 +1,25 @@ +"""DuckDB-version-aware expectations for day-or-coarser date_trunc buckets.""" + +from datetime import date, datetime, time +from functools import cache + +import duckdb + + +@cache +def _bucket_type(): + # DuckDB 1.4 returns DATE for these overloads; 1.5 returns TIMESTAMP. + # Probe only the type: the expected bucket values remain independent. + with duckdb.connect() as connection: + row = connection.execute( + "select date_trunc('month', date '2000-01-02'), date_trunc('day', timestamp '2000-01-02 12:34:56')" + ).fetchone() + assert type(row[0]) is type(row[1]) + assert type(row[0]) in (date, datetime) + return type(row[0]) + + +def date_bucket(year: int, month: int, day: int) -> date | datetime: + """Expected coarse bucket, without coercing any actual query result.""" + value = date(year, month, day) + return datetime.combine(value, time()) if _bucket_type() is datetime else value diff --git a/tests/interchange/ossie/test_expression_conformance.py b/tests/interchange/ossie/test_expression_conformance.py index f22465c21..ad0fa3e8e 100644 --- a/tests/interchange/ossie/test_expression_conformance.py +++ b/tests/interchange/ossie/test_expression_conformance.py @@ -43,14 +43,14 @@ def _lower( def test_metric_references_bind_computed_fields_before_physical_fallback(sql, flat): result = _lower(sql=sql, flat=flat) assert result.valid, result.diagnostics - layer = SemanticLayer.from_catalog(result.catalog, engine="python", fallback=False, auto_register=False) + layer = SemanticLayer.from_catalog(result.catalog, fallback=False, auto_register=False) assert layer.query(metrics=["total"]).fetchall() == [(60,)] def test_quoted_declarations_bind_without_losing_their_identity(): result = _lower(dataset='"orders"', field='"amount"', sql='SUM("orders"."amount")') assert result.valid, result.diagnostics - layer = SemanticLayer.from_catalog(result.catalog, engine="python", fallback=False, auto_register=False) + layer = SemanticLayer.from_catalog(result.catalog, fallback=False, auto_register=False) assert layer.query(metrics=["total"]).fetchall() == [(60,)] @@ -89,7 +89,7 @@ def test_invalid_row_expressions_are_rejected_before_querying(field_sql, flat): def test_metric_dependencies_expand_after_normalized_lookup(): result = _lower(sql="BASE * 2", extra_metrics=[{"name": "base", "expression": _expression("SUM(orders.amount)")}]) assert result.valid, result.diagnostics - layer = SemanticLayer.from_catalog(result.catalog, engine="python", fallback=False, auto_register=False) + layer = SemanticLayer.from_catalog(result.catalog, fallback=False, auto_register=False) assert layer.query(metrics=["total"]).fetchall() == [(120,)] @@ -121,6 +121,6 @@ def test_quoted_and_regular_dataset_names_do_not_merge_runtime_identity(): graph = result.catalog["commerce"].graph assert len(graph.models) == 2 assert {model.metadata["ossie_source_name"] for model in graph.models.values()} == {"Orders", '"Orders"'} - layer = SemanticLayer.from_catalog(result.catalog, engine="python", fallback=False, auto_register=False) + layer = SemanticLayer.from_catalog(result.catalog, fallback=False, auto_register=False) assert layer.query(metrics=["regular"]).fetchall() == [(10,)] assert layer.query(metrics=["quoted"]).fetchall() == [(20,)] diff --git a/tests/interchange/ossie/test_runtime_queries.py b/tests/interchange/ossie/test_runtime_queries.py index 92901fa49..a6b272783 100644 --- a/tests/interchange/ossie/test_runtime_queries.py +++ b/tests/interchange/ossie/test_runtime_queries.py @@ -63,7 +63,7 @@ def commerce(*, source_key="customer_id", target_key="id", key_kind="primary_key parsed = parse_ossie_document(json.dumps(document).encode(), options=OssieParseOptions(target_dialect="duckdb")) lowered = lower_ossie_document(parsed) assert lowered.valid, lowered.diagnostics - layer = SemanticLayer.from_catalog(lowered.catalog, engine="python", fallback=False, auto_register=False) + layer = SemanticLayer.from_catalog(lowered.catalog, fallback=False, auto_register=False) layer.adapter.conn.execute("create table orders(id int, customer_id int, amount int)") layer.adapter.conn.execute("insert into orders values (1,1,10),(2,1,20),(3,2,30)") layer.adapter.conn.execute("create table customers(id int, name varchar, budget int)") @@ -160,7 +160,7 @@ def test_qualified_fields_bind_to_the_dataset_source(source): parsed = parse_ossie_document(json.dumps(document).encode(), options=OssieParseOptions(target_dialect="duckdb")) lowered = lower_ossie_document(parsed) assert lowered.valid, lowered.diagnostics - layer = SemanticLayer.from_catalog(lowered.catalog, engine="python", fallback=False, auto_register=False) + layer = SemanticLayer.from_catalog(lowered.catalog, fallback=False, auto_register=False) layer.adapter.conn.execute("create table raw_orders(id int, amount int)") layer.adapter.conn.execute("insert into raw_orders values (1, 10), (2, 20)") diff --git a/tests/interchange/ossie/test_synthesis.py b/tests/interchange/ossie/test_synthesis.py index 3c8caa5ba..a7dee6b01 100644 --- a/tests/interchange/ossie/test_synthesis.py +++ b/tests/interchange/ossie/test_synthesis.py @@ -743,7 +743,7 @@ def test_imported_identifier_provenance_remains_portable_with_bound_runtime_name assert reloaded.valid, reloaded.diagnostics metric_name = next(iter(graph.metrics)) for catalog in (lowered.catalog, reloaded.catalog): - layer = SemanticLayer.from_catalog(catalog, engine="python", fallback=False, auto_register=False) + layer = SemanticLayer.from_catalog(catalog, fallback=False, auto_register=False) assert layer.query(metrics=[metric_name]).fetchall() == [(10,)] model = next(iter(graph.models.values())) model.dimensions[0].metadata["custom_behavior"] = "preserve" diff --git a/tests/metrics/test_advanced.py b/tests/metrics/test_advanced.py index a54640ae2..a72c09683 100644 --- a/tests/metrics/test_advanced.py +++ b/tests/metrics/test_advanced.py @@ -8,6 +8,7 @@ from sidemantic.core.model import Model from sidemantic.core.semantic_graph import SemanticGraph from sidemantic.sql.generator import SQLGenerator +from tests.duckdb_compat import date_bucket from tests.utils import df_rows @@ -35,7 +36,7 @@ def test_month_to_date_metric(): graph.add_metric(mtd_revenue) generator = SQLGenerator(graph) - sql = generator.generate(metrics=["mtd_revenue"], dimensions=["sales.sale_date"]) + sql = generator.generate(metrics=["mtd_revenue"], dimensions=["sales.sale_date"], order_by=["sales.sale_date"]) print("\nMTD SQL:") print(sql) @@ -694,11 +695,12 @@ def test_month_comparison_does_not_use_previous_available_sparse_row(): sql = SQLGenerator(graph).generate( metrics=["revenue_mom"], dimensions=["sales.sale_date__month"], + order_by=["sales.sale_date__month"], ) rows = df_rows(duckdb.connect(":memory:").execute(sql)) assert "RANGE BETWEEN INTERVAL '1 month' PRECEDING AND INTERVAL '1 month' PRECEDING" in sql - assert rows[1][0].isoformat() == "2024-03-01" + assert rows[1][0] == date_bucket(2024, 3, 1) assert rows[1][2] is None diff --git a/tests/metrics/test_cohort.py b/tests/metrics/test_cohort.py index b813b0c28..8f017184a 100644 --- a/tests/metrics/test_cohort.py +++ b/tests/metrics/test_cohort.py @@ -8,6 +8,7 @@ from sidemantic.core.model import Model from sidemantic.core.semantic_graph import SemanticGraph from sidemantic.sql.generator import SQLGenerator +from tests.duckdb_compat import date_bucket from tests.utils import df_rows @@ -166,9 +167,9 @@ def test_cohort_with_time_grain_uses_grained_output_alias(): result = duckdb.connect(":memory:").execute(sql) assert [column[0] for column in result.description] == ["ts__month", "multi_platform_users"] - assert [(row[0].isoformat(), row[1]) for row in df_rows(result)] == [ - ("2024-01-01", 1), - ("2024-02-01", 1), + assert [(row[0], row[1]) for row in df_rows(result)] == [ + (date_bucket(2024, 1, 1), 1), + (date_bucket(2024, 2, 1), 1), ] diff --git a/tests/metrics/test_cumulative.py b/tests/metrics/test_cumulative.py index 14f2c8e69..879d35ca7 100644 --- a/tests/metrics/test_cumulative.py +++ b/tests/metrics/test_cumulative.py @@ -8,6 +8,7 @@ import pytest from sidemantic import Dimension, Metric, Model +from tests.duckdb_compat import date_bucket @pytest.mark.parametrize( @@ -61,8 +62,9 @@ def test_cumulative_partitions_groups_and_nulls(layer, options, expected, with_c result = layer.query(metrics=metrics, dimensions=["grouped_sales.day", "grouped_sales.category"]) columns = [column[0] for column in result.description] records = [dict(zip(columns, row)) for row in result.fetchall()] - by_group_day = {(row["category"], str(row["day"])): row for row in records} + by_group_day = {(row["category"], row["day"]): row for row in records} assert len(by_group_day) == 9 + dates = [date_bucket(2024, 1, 28), date_bucket(2024, 1, 31), date_bucket(2024, 2, 1)] for category, factor in groups: for day, amount in zip(dates, expected): assert by_group_day[category, day]["cumulative"] == factor * amount diff --git a/tests/native_compat/test_basic_model_fixture.py b/tests/native_compat/test_basic_model_fixture.py index d77e420d5..231e491e2 100644 --- a/tests/native_compat/test_basic_model_fixture.py +++ b/tests/native_compat/test_basic_model_fixture.py @@ -14,6 +14,7 @@ from sidemantic.loaders import load_from_directory from sidemantic.sql.query_rewriter import QueryRewriter from sidemantic.sql.table_calc_processor import TableCalculationProcessor +from tests.duckdb_compat import date_bucket FIXTURE_SUITE_ROOT = Path(__file__).parents[1] / "native-fixtures" @@ -146,6 +147,19 @@ def test_native_fixture_loads_compiles_and_executes(fixture, query_manifest): ] expected = json.loads((fixture_root / expected_result).read_text()) + # Only these fixtures execute date_trunc. In particular, the routed + # preaggregation fixture reads an already-materialized DATE column. + bucket_columns = { + ("default_time_dimension", "revenue_by_default_month"): "created_at__month", + ("advanced_metrics", "cumulative_revenue_by_month"): "event_date__month", + ("advanced_metrics", "revenue_mom_by_month_region"): "event_date__month", + } + bucket_column = bucket_columns.get((fixture["name"], query_manifest["name"])) + if bucket_column: + for row in expected: + value = date.fromisoformat(row[bucket_column]) + row[bucket_column] = date_bucket(value.year, value.month, value.day).isoformat() + assert actual == expected diff --git a/tests/queries/test_basic.py b/tests/queries/test_basic.py index cb6a5675d..4e03e880f 100644 --- a/tests/queries/test_basic.py +++ b/tests/queries/test_basic.py @@ -7,6 +7,7 @@ from sidemantic import Dimension, Metric, Model, Relationship, Segment, SemanticLayer from sidemantic.validation import QueryValidationError +from tests.duckdb_compat import date_bucket from tests.utils import df_rows @@ -523,7 +524,6 @@ def test_compiles_and_executes_columns_with_spaces(): """Regression: dimensions whose names contain spaces (common in imported Power BI / TMDL models, e.g. "Order Date") must be quoted in generated SQL so queries parse and execute, rather than failing with a sqlglot ParseError on the unquoted identifier.""" - from datetime import date conn = duckdb.connect(":memory:") conn.execute('CREATE TABLE sales (id INTEGER, "Order Date" DATE, "Order Status" VARCHAR, quantity INTEGER)') @@ -553,7 +553,7 @@ def test_compiles_and_executes_columns_with_spaces(): by_month = df_rows( layer.query(metrics=["Sales.qty"], dimensions=["Sales.Order Date"], order_by=["Sales.Order Date"]) ) - assert by_month == [(date(2024, 1, 1), 8), (date(2024, 2, 1), 7)] + assert by_month == [(date_bucket(2024, 1, 1), 8), (date_bucket(2024, 2, 1), 7)] # Group by a spaced categorical dimension, ordered by it. by_status = df_rows( diff --git a/tests/queries/test_yardstick_measures_replay.py b/tests/queries/test_yardstick_measures_replay.py index 88f037c05..8604c85e1 100644 --- a/tests/queries/test_yardstick_measures_replay.py +++ b/tests/queries/test_yardstick_measures_replay.py @@ -16,6 +16,7 @@ from sidemantic import SemanticLayer from sidemantic.adapters.yardstick import YardstickAdapter +from tests.duckdb_compat import date_bucket from tests.utils import fetch_rows @@ -292,6 +293,11 @@ def _cell_matches(actual: object, expected: object) -> bool: actual_text = _stringify_value(actual) if actual_text == expected: return True + if isinstance(actual, datetime) and len(expected) > 10: + try: + return actual == datetime.fromisoformat(expected) + except ValueError: + return False if isinstance(actual, date) and not isinstance(actual, datetime): return f"{actual.isoformat()} 00:00:00" == expected return False @@ -319,8 +325,45 @@ def _cell_matches(actual: object, expected: object) -> bool: return str(actual) == str(expected) +@pytest.mark.parametrize("expected", ["2023-01-01 12:34:56", "2023-01-01T12:34:56"]) +def test_timestamp_fixture_separator_does_not_change_value(expected): + assert _cell_matches(datetime(2023, 1, 1, 12, 34, 56), expected) + assert not _cell_matches(datetime(2023, 1, 1), expected) + assert not _cell_matches(datetime(2023, 1, 1), "2023-01-01") + + +@pytest.mark.parametrize("expected", ["2023-01-01", "2023-01-01 00:00:00", "2023-01-01T00:00:00", "NULL"]) +def test_coarse_bucket_fixture_accepts_date_and_timestamp_spellings(expected): + query = _QueryBlock(1, "query I", "SEMANTIC SELECT date_trunc('year', sale_date)", [expected], False) + actual = None if expected == "NULL" else date_bucket(2023, 1, 1) + _assert_query_rows_match(query, [(actual,)]) + + +def test_coarse_bucket_fixture_does_not_discard_expected_time(): + query = _QueryBlock(1, "query I", "SEMANTIC SELECT date_trunc('year', sale_date)", ["2023-01-01 12:00:00"], False) + with pytest.raises(pytest.fail.Exception, match="Value mismatch"): + _assert_query_rows_match(query, [(date_bucket(2023, 1, 1),)]) + + def _assert_query_rows_match(query: _QueryBlock, actual_rows: list[tuple[object, ...]]) -> None: expected_rows = [row.split("\t") for row in query.expected_rows] + # Vendored and live fixtures use DATE or midnight TIMESTAMP for these coarse + # buckets. Keep nonmidnight values and raw DATE/TIMESTAMP comparisons intact. + sql = " ".join(query.sql.lower().split()) + if ( + sql.startswith("semantic select month, region,") + and "from monthly_sales_v" in sql + or sql.startswith("semantic select date_trunc('year', sale_date)") + ): + for row in expected_rows: + if row[0] == "NULL": + continue + value = datetime.fromisoformat(row[0]) + row[0] = ( + date_bucket(value.year, value.month, value.day).isoformat() + if value.time() == time() and value.tzinfo is None + else value.isoformat() + ) if query.rowsort: actual_rows = sorted(actual_rows, key=lambda row: tuple(_stringify_value(value) for value in row)) diff --git a/tests/queries/test_yardstick_query_rewriter.py b/tests/queries/test_yardstick_query_rewriter.py index a352d8b8d..9bdec7c03 100644 --- a/tests/queries/test_yardstick_query_rewriter.py +++ b/tests/queries/test_yardstick_query_rewriter.py @@ -7,6 +7,7 @@ from sidemantic import SemanticLayer from sidemantic.loaders import load_from_directory from sidemantic.sql.query_rewriter import QueryRewriter +from tests.duckdb_compat import date_bucket from tests.utils import fetch_dicts @@ -1376,10 +1377,10 @@ def test_yardstick_group_by_alias_expression_dimension(tmp_path): rows = fetch_dicts(result) values = {(str(row["month"]), row["region"]): (float(row["revenue"]), float(row["month_total"])) for row in rows} assert values == { - ("2023-01-01", "EU"): (50.0, 150.0), - ("2023-01-01", "US"): (100.0, 150.0), - ("2023-02-01", "EU"): (20.0, 220.0), - ("2023-02-01", "US"): (200.0, 220.0), + (str(date_bucket(2023, 1, 1)), "EU"): (50.0, 150.0), + (str(date_bucket(2023, 1, 1)), "US"): (100.0, 150.0), + (str(date_bucket(2023, 2, 1)), "EU"): (20.0, 220.0), + (str(date_bucket(2023, 2, 1)), "US"): (200.0, 220.0), } @@ -2060,8 +2061,8 @@ def test_yardstick_duckdb_scalar_functions(tmp_path): ) ) assert {(str(row["yr"]), float(row["revenue"])) for row in by_year_trunc} == { - ("2023-01-01", 530.0), - ("2024-01-01", 430.0), + (str(date_bucket(2023, 1, 1)), 530.0), + (str(date_bucket(2024, 1, 1)), 430.0), } category_left = fetch_dicts( diff --git a/tests/rust_layer_adapter.py b/tests/rust_layer_adapter.py index a16673ade..81073c3f5 100644 --- a/tests/rust_layer_adapter.py +++ b/tests/rust_layer_adapter.py @@ -3,10 +3,11 @@ from __future__ import annotations import json -import os import re +import shutil import subprocess from dataclasses import dataclass +from functools import lru_cache from pathlib import Path from typing import Any @@ -21,8 +22,6 @@ ROOT = Path(__file__).resolve().parents[1] RUST_MANIFEST = ROOT / "sidemantic-rs" / "Cargo.toml" -RUST_TARGET_DIR = Path("/tmp/sidemantic-rs-parity-target") -RUST_ADAPTER_BIN = RUST_TARGET_DIR / "debug" / "examples" / f"parity_adapter{'.exe' if os.name == 'nt' else ''}" class RustRuntimeSemanticLayer(ProductionSemanticLayer): @@ -909,9 +908,9 @@ def _graph_yaml_from_graph(graph) -> str: def _rust_request(payload: dict[str, Any]) -> dict[str, Any]: - _ensure_rust_adapter_binary() + binary = _ensure_rust_adapter_binary() result = subprocess.run( - [str(RUST_ADAPTER_BIN)], + [str(binary)], input=json.dumps(payload), text=True, capture_output=True, @@ -953,35 +952,34 @@ def _normalize_graph_error(error: str) -> str: return message.replace("'", "") -def _ensure_rust_adapter_binary() -> None: - if RUST_ADAPTER_BIN.exists() and not _rust_sources_newer_than_binary(): - return +@lru_cache(maxsize=1) +def _ensure_rust_adapter_binary() -> Path: + # Cargo validates source, lockfile, toolchain and feature fingerprints. A + # shared /tmp executable plus source mtimes can reuse another checkout's + # binary, and bypassing rustc-wrapper defeats the configured build cache. result = subprocess.run( [ - "cargo", + shutil.which("mbx") or "cargo", "build", - "--quiet", "--manifest-path", str(RUST_MANIFEST), "--example", "parity_adapter", + "--message-format=json", ], text=True, capture_output=True, cwd=ROOT, - env={ - **os.environ, - "CARGO_BUILD_RUSTC_WRAPPER": "", - "CARGO_TARGET_DIR": str(RUST_TARGET_DIR), - }, check=False, ) if result.returncode != 0: raise RuntimeError(result.stderr or result.stdout) - - -def _rust_sources_newer_than_binary() -> bool: - binary_mtime = RUST_ADAPTER_BIN.stat().st_mtime - rust_root = ROOT / "sidemantic-rs" - candidates = [RUST_MANIFEST, *(rust_root / "src").rglob("*.rs"), *(rust_root / "examples").rglob("*.rs")] - return any(path.stat().st_mtime > binary_mtime for path in candidates) + for line in result.stdout.splitlines(): + try: + artifact = json.loads(line) + except json.JSONDecodeError: + continue + if artifact.get("reason") == "compiler-artifact" and artifact.get("target", {}).get("name") == "parity_adapter": + if executable := artifact.get("executable"): + return Path(executable) + raise RuntimeError("Cargo did not report the parity_adapter executable") diff --git a/tests/semantic_conformance/differential/README.md b/tests/semantic_conformance/differential/README.md new file mode 100644 index 000000000..626070768 --- /dev/null +++ b/tests/semantic_conformance/differential/README.md @@ -0,0 +1,128 @@ +# Seeded compiler differential tests + +`test_generated_differential.py` compiles every valid case through production +`SemanticLayer(engine="python", fallback=False)` and +`SemanticLayer(engine="rust", fallback=False)`, executes both SQL statements in +the same one-thread DuckDB database, and checks their public columns and rows. +The Rust layer also has a Python compiler tripwire, and both engine selections +must report the requested engine without a fallback reason. These tests require +the installed Rust extension built from the checkout being evaluated. + +The default campaign has 52 cases. Thirteen rotating families generate base, +derived, nested derived, ratio, cumulative, filtered and graph-level metrics; +single-source, many-to-one, composite-key, one-to-many, double-fanout and +cross-source graphs; time grains; query and metric filters; segments; source +invariants; null defaults; empty populations; nulls (including time keys), +unmatched join keys, and ordered limits/offsets. Relational families also select +filtered, derived, ratio, nested and cumulative metrics, so joins/fanout interact +with metric semantics instead of being isolated feature buckets. +The default-time family deliberately omits explicit time grouping to exercise +implicit default groups in cross-source calculations; it has no ordering or +pagination, so hidden group keys cannot invalidate deterministic tie breakers. +Definitions vary aggregation, arithmetic, SQL dimension expressions, source +types, window sizes, grouping, predicates and selections as well as data. +Each `(seed, index)` is independently reproducible. + +Run the actual pytest campaign at higher volume: + +```sh +SIDEMANTIC_DIFFERENTIAL_REQUIRE_RUST=1 \ +SIDEMANTIC_DIFFERENTIAL_SEED=20261005 \ +SIDEMANTIC_DIFFERENTIAL_CASES=100000 \ +SIDEMANTIC_DIFFERENTIAL_OUTPUT=/tmp/sidemantic-differential \ +uv run --no-sync pytest --no-cov -q tests/semantic_conformance/test_generated_differential.py +``` + +`SIDEMANTIC_DIFFERENTIAL_START` selects the first index for a shard or a resumed +range. Use disjoint output directories for concurrent shards. A missing Rust +extension normally skips this module; `REQUIRE_RUST=1` makes it an error for +readiness gates. Compiler errors from either or both engines always fail the +campaign. Invalid generated definitions/data are separately counted failures, +never counted as successful parity cases. + +For many data populations per compiler input, opt into compilation reuse: + +```sh +SIDEMANTIC_DIFFERENTIAL_REQUIRE_RUST=1 \ +SIDEMANTIC_DIFFERENTIAL_CASES=5000 \ +SIDEMANTIC_DIFFERENTIAL_DATA_VARIANTS=40 \ +SIDEMANTIC_DIFFERENTIAL_OUTPUT=/tmp/sidemantic-differential-populations \ +uv run --no-sync pytest --no-cov -q tests/semantic_conformance/test_generated_differential.py +``` + +This requests **5,000 generated model/query inputs and 200,000 executed data +populations**, not 200,000 distinct compilations. The first population retains +the original generator data. Others independently seed rows using the model +seed, case index, and stored `data_variant`; exact duplicate populations within +an input are discarded and redrawn. Schemas and semantic definitions stay +unchanged while keys, fanout, nulls, empty sources and values vary. Every fixture +contains the complete actual population and replays without caching. + +The cache reuses only successful compilation with the exact same canonical +model definitions, graph metrics, query, and typed table schemas. Every actual +compile checks strict engine selection; reused SQL executes again against the +new population. Successful immutable definition validation is also reused for +that exact key; every population still checks row shape, non-null unique primary +keys, and actual DuckDB insertion/type validity. Only the latest key per engine +and latest validated definition are retained. Default +`DATA_VARIANTS=1`, replay, and minimization always compile fresh. Reports expose +`unique_compiler_inputs`, per-engine `actual_compile_attempts`, +`actual_successful_compilations`, `compilation_cache_hits`, and +`checked_populations`; engine-selection counts refer to actual compilations, +while successful-execution counts include all populations. Cache reuse measures +data-dependent correctness at lower compile cost; it does not expand compiler +input coverage. + +The campaign continues after failures and records counts by failure class, +fingerprint, family and feature. It records compile/execution wall time per +engine, successful execution and actual engine-selection counts, reduction time, +total elapsed time and checked/passed counts in +`report.json`, checkpointed every 100 cases and at exit. Counts describe generated +features, not proof that every defined feature was selected. The report path is +also a pytest/JUnit property. Fingerprints distinguish failure phase and exception +type/message, or result mismatches by family and public columns; they are +deduplication heuristics, not proof of distinct root causes. + +Up to `SIDEMANTIC_DIFFERENTIAL_EXAMPLES` (default 12) distinct fingerprints get an +original JSON case, minimized `.case.json`, and `.evidence.json` containing SQL, +results/errors and reducer accounting. Further failures remain counted. Set +`SIDEMANTIC_DIFFERENTIAL_REDUCTIONS` (default 100) to limit attempts per example, +or zero to retain original cases without reducing them. A reducer accepts only +schema/reference-valid candidates with the original failure class and normalized +exception diagnostic (retaining referenced owner/column names); it removes +rows, query clauses, unused models/definitions, unused physical columns and their +cells, and simplifies non-key values. +Result mismatches additionally retain their kind (cardinality, ordering only, +or values), both public column lists, and a concrete differing-row witness. +Cardinality failures retain which engine has more rows. These conservative +constraints prevent swapping the defective metric or a hidden-group discrepancy +for another failure, at the cost of sometimes retaining otherwise removable +columns or data. Reduction is deterministic and budgeted, not a claim of a globally smallest +reproducer. Replay uses the saved definitions/data, not the current generator: + +```sh +SIDEMANTIC_DIFFERENTIAL_REQUIRE_RUST=1 \ +SIDEMANTIC_DIFFERENTIAL_REPLAY=/tmp/sidemantic-differential \ +uv run --no-sync pytest --no-cov -q tests/semantic_conformance/test_generated_differential.py -k replay +``` + +`REPLAY` accepts a directory of `.case.json` files or one exact file. Without it, +replay discovers checked-in `differential/fixtures/*.case.json` regression cases. +Replay asserts parity, so a previously failing fixture becomes a permanent +regression contract after the production defect is fixed. + +Unordered output uses duplicate-preserving bipartite multiset matching. Numeric +tolerance is `rel_tol=abs_tol=1e-9`; integer-to-integer comparisons stay exact. +Nulls, booleans, NaNs and infinities retain their own semantics. DATE and midnight +TIMESTAMP values are equivalent time buckets. Ordered output compares the actual +row sequence. Every grouping key is an explicit final tie breaker whenever order +is requested, and pagination is never generated without that deterministic order. + +This is differential evidence, not an independent semantic oracle: identical +compiler bugs can pass. It complements the hand-authored conformance corpus with +independent expected results. It currently executes DuckDB only, uses a bounded +grammar rather than arbitrary SQL fuzzing, and does not cover security, remote +databases, adapter imports, calendars/timezones, or every advanced metric family. +Hundreds of thousands of cases are supported without keeping all cases/results +in memory; runtime is workload-dependent and no such volume is implied by the +52-case default. diff --git a/tests/semantic_conformance/differential/__init__.py b/tests/semantic_conformance/differential/__init__.py new file mode 100644 index 000000000..aacd51dd8 --- /dev/null +++ b/tests/semantic_conformance/differential/__init__.py @@ -0,0 +1 @@ +"""Replayable, seeded differential checks of the production semantic compilers.""" diff --git a/tests/semantic_conformance/differential/fixtures/README.md b/tests/semantic_conformance/differential/fixtures/README.md new file mode 100644 index 000000000..a332fe750 --- /dev/null +++ b/tests/semantic_conformance/differential/fixtures/README.md @@ -0,0 +1,19 @@ +# Reduced generated regressions + +These fixtures retain their original seed/index and actual reduced definitions, +query, and data. Feature labels describe the original generated case, not a claim +that every feature remains after reduction. Replay uses the stored case directly. + +| Fixture | Adjudication | Independent result test | +| --- | --- | --- | +| `sibling-fanout.case.json` | One item worth 3 must contribute once when two refunds share a label. Rust incorrectly returned 6. | `test_sibling_fanout_parity.py` | +| `scalar-default-time.case.json` | A graph calculation with no time grouping combines independent source totals. Python incorrectly reapplied a model default inside its source subquery. | `test_default_time_differential.py` | +| `cumulative-null-date.case.json` | A NULL date remains NULL, and a cumulative window follows known periods before the NULL bucket. DuckDB 1.3.2 produced different results for equivalent projections; 1.4.0 exposed a date sentinel. Both independent cases pass on 1.4.4 and 1.5.0. | `test_cumulative_null_dates.py` | +| `cross-source-cumulative.case.json` | A cross-source scalar calculation beside a cumulative metric retains independent grouped source totals. Rust rejected the graph calculation as if it required one owner. | `test_cross_source_windows.py` | +| `cumulative-dimension-collision.case.json` | Window inputs must use the grouped aliases for both sibling labels. Both engines referenced missing `base.label` instead of `base.items_label` and `base.refunds_label`. | `test_cross_source_windows.py` | +| `absent-local-calculation.case.json` | A model-local scalar formula uses count zero and metric defaults for a group introduced by another source. Python computed the formula before the full join and returned NULL instead. | `test_absent_counts.py` | + +The initial reductions were budgeted and preserve the original failure class; +they are not claims of globally minimal inputs. Their independent result tests +establish the specific semantic regression. The current reducer additionally +preserves a concrete result-mismatch witness. diff --git a/tests/semantic_conformance/differential/fixtures/absent-local-calculation.case.json b/tests/semantic_conformance/differential/fixtures/absent-local-calculation.case.json new file mode 100644 index 000000000..5b10b4ce4 --- /dev/null +++ b/tests/semantic_conformance/differential/fixtures/absent-local-calculation.case.json @@ -0,0 +1,167 @@ +{ + "data_variant": 0, + "family": "multi_source", + "features": [ + "multi_source", + "numeric:decimal(12,2)", + "aggregation:max", + "null_values", + "grain:day", + "many_to_one", + "selected:combined", + "selected:accounts.quota", + "selected:facts.derived", + "selected:facts.rows", + "null_time", + "limit" + ], + "index": 241, + "metrics": [ + { + "name": "combined", + "sql": "facts.total + accounts.quota", + "type": "derived" + } + ], + "models": [ + { + "dimensions": [ + { + "name": "status", + "type": "categorical" + }, + { + "granularity": "day", + "name": "day", + "type": "time" + } + ], + "metrics": [ + { + "agg": "sum", + "fill_nulls_with": 0, + "name": "total", + "sql": "amount - quantity" + }, + { + "agg": "count", + "name": "rows" + }, + { + "name": "derived", + "sql": "total + rows * 6", + "type": "derived" + } + ], + "name": "facts", + "primary_key": "id", + "relationships": [ + { + "foreign_key": "account_id", + "name": "accounts", + "type": "many_to_one" + } + ], + "segments": [], + "table": "generated_facts" + }, + { + "dimensions": [ + { + "name": "region", + "type": "categorical" + } + ], + "metrics": [ + { + "agg": "sum", + "name": "quota", + "sql": "quota" + } + ], + "name": "accounts", + "primary_key": "id", + "table": "generated_accounts" + } + ], + "query": { + "dimensions": [ + "facts.day__day", + "facts.status", + "accounts.region" + ], + "metrics": [ + "combined", + "accounts.quota", + "facts.derived", + "facts.rows" + ] + }, + "seed": 20261005, + "tables": [ + { + "columns": [ + [ + "id", + "integer" + ], + [ + "status", + "varchar" + ], + [ + "amount", + "decimal(12,2)" + ], + [ + "quantity", + "integer" + ], + [ + "account_id", + "integer" + ], + [ + "day", + "date" + ] + ], + "name": "generated_facts", + "rows": [ + [ + 13, + null, + null, + 2, + 2, + "2024-01-01" + ] + ] + }, + { + "columns": [ + [ + "id", + "integer" + ], + [ + "region", + "varchar" + ], + [ + "quota", + "decimal(12,2)" + ] + ], + "name": "generated_accounts", + "rows": [ + [ + 4, + "east", + 0 + ] + ] + } + ], + "version": 1 +} diff --git a/tests/semantic_conformance/differential/fixtures/cross-source-cumulative.case.json b/tests/semantic_conformance/differential/fixtures/cross-source-cumulative.case.json new file mode 100644 index 000000000..f8de17968 --- /dev/null +++ b/tests/semantic_conformance/differential/fixtures/cross-source-cumulative.case.json @@ -0,0 +1,126 @@ +{ + "data_variant": 0, + "family": "multi_source", + "features": [ + "multi_source", + "numeric:integer", + "aggregation:sum", + "empty_source", + "grain:day", + "many_to_one", + "selected:combined", + "selected:accounts.quota", + "selected:facts.running", + "selected:facts.rows", + "limit" + ], + "index": 33, + "metrics": [ + { + "name": "combined", + "sql": "facts.total + accounts.quota", + "type": "derived" + } + ], + "models": [ + { + "dimensions": [ + { + "granularity": "day", + "name": "day", + "type": "time" + } + ], + "metrics": [ + { + "agg": "sum", + "fill_nulls_with": 0, + "name": "total", + "sql": "amount - quantity" + }, + { + "name": "running", + "sql": "total", + "type": "cumulative" + } + ], + "name": "facts", + "primary_key": "id", + "relationships": [ + { + "foreign_key": "account_id", + "name": "accounts", + "type": "many_to_one" + } + ], + "segments": [], + "table": "generated_facts" + }, + { + "dimensions": [], + "metrics": [ + { + "agg": "sum", + "name": "quota", + "sql": "quota" + } + ], + "name": "accounts", + "primary_key": "id", + "table": "generated_accounts" + } + ], + "query": { + "dimensions": [ + "facts.day__day" + ], + "metrics": [ + "combined", + "facts.running" + ] + }, + "seed": 20261005, + "tables": [ + { + "columns": [ + [ + "id", + "integer" + ], + [ + "amount", + "integer" + ], + [ + "quantity", + "integer" + ], + [ + "account_id", + "integer" + ], + [ + "day", + "date" + ] + ], + "name": "generated_facts", + "rows": [] + }, + { + "columns": [ + [ + "id", + "integer" + ], + [ + "quota", + "integer" + ] + ], + "name": "generated_accounts", + "rows": [] + } + ], + "version": 1 +} diff --git a/tests/semantic_conformance/differential/fixtures/cumulative-dimension-collision.case.json b/tests/semantic_conformance/differential/fixtures/cumulative-dimension-collision.case.json new file mode 100644 index 000000000..54b9aafb3 --- /dev/null +++ b/tests/semantic_conformance/differential/fixtures/cumulative-dimension-collision.case.json @@ -0,0 +1,166 @@ +{ + "data_variant": 0, + "family": "double_fanout", + "features": [ + "double_fanout", + "numeric:integer", + "aggregation:max", + "empty_source", + "grain:year", + "one_to_many", + "selected:facts.running", + "selected:facts.rows" + ], + "index": 21, + "metrics": [], + "models": [ + { + "dimensions": [ + { + "granularity": "day", + "name": "day", + "type": "time" + } + ], + "invariant_filters": [], + "metrics": [ + { + "agg": "sum", + "fill_nulls_with": -1, + "name": "total", + "sql": "amount" + }, + { + "name": "running", + "sql": "total", + "type": "cumulative" + } + ], + "name": "facts", + "primary_key": "id", + "relationships": [ + { + "foreign_key": "fact_id", + "name": "items", + "type": "one_to_many" + }, + { + "foreign_key": "fact_id", + "name": "refunds", + "type": "one_to_many" + } + ], + "segments": [], + "table": "generated_facts" + }, + { + "dimensions": [ + { + "name": "label", + "type": "categorical" + } + ], + "metrics": [], + "name": "items", + "primary_key": "id", + "table": "generated_items" + }, + { + "dimensions": [ + { + "name": "label", + "type": "categorical" + } + ], + "metrics": [], + "name": "refunds", + "primary_key": "id", + "table": "generated_refunds" + } + ], + "query": { + "dimensions": [ + "facts.day__year", + "items.label", + "refunds.label" + ], + "filters": [], + "metrics": [ + "facts.running" + ] + }, + "seed": 20261005, + "tables": [ + { + "columns": [ + [ + "id", + "integer" + ], + [ + "category", + "varchar" + ], + [ + "status", + "varchar" + ], + [ + "amount", + "integer" + ], + [ + "day", + "date" + ] + ], + "name": "generated_facts", + "rows": [] + }, + { + "columns": [ + [ + "id", + "integer" + ], + [ + "fact_id", + "integer" + ], + [ + "label", + "varchar" + ], + [ + "value", + "integer" + ] + ], + "name": "generated_items", + "rows": [] + }, + { + "columns": [ + [ + "id", + "integer" + ], + [ + "fact_id", + "integer" + ], + [ + "label", + "varchar" + ], + [ + "value", + "integer" + ] + ], + "name": "generated_refunds", + "rows": [] + } + ], + "version": 1 +} diff --git a/tests/semantic_conformance/differential/fixtures/cumulative-null-date.case.json b/tests/semantic_conformance/differential/fixtures/cumulative-null-date.case.json new file mode 100644 index 000000000..dd71a6836 --- /dev/null +++ b/tests/semantic_conformance/differential/fixtures/cumulative-null-date.case.json @@ -0,0 +1,114 @@ +{ + "family": "cumulative", + "features": [ + "cumulative", + "numeric:integer", + "aggregation:min", + "null_values", + "grain:month", + "selected:facts.running", + "null_time" + ], + "index": 27, + "metrics": [], + "models": [ + { + "default_time_dimension": "day", + "dimensions": [ + { + "name": "status", + "type": "categorical" + }, + { + "granularity": "day", + "name": "day", + "type": "time" + } + ], + "invariant_filters": [], + "metrics": [ + { + "agg": "sum", + "name": "total", + "sql": "amount" + }, + { + "name": "running", + "sql": "total", + "type": "cumulative" + } + ], + "name": "facts", + "primary_key": "id", + "relationships": [], + "segments": [], + "table": "generated_facts" + } + ], + "query": { + "dimensions": [ + "facts.day__month", + "facts.status" + ], + "metrics": [ + "facts.running" + ] + }, + "seed": 20261005, + "tables": [ + { + "columns": [ + [ + "id", + "integer" + ], + [ + "category", + "varchar" + ], + [ + "status", + "varchar" + ], + [ + "amount", + "integer" + ], + [ + "quantity", + "integer" + ], + [ + "account_id", + "integer" + ], + [ + "day", + "date" + ] + ], + "name": "generated_facts", + "rows": [ + [ + 10, + null, + "paid", + 0, + null, + null, + "2000-01-01" + ], + [ + 11, + null, + "paid", + null, + null, + null, + null + ] + ] + } + ], + "version": 1 +} diff --git a/tests/semantic_conformance/differential/fixtures/scalar-default-time.case.json b/tests/semantic_conformance/differential/fixtures/scalar-default-time.case.json new file mode 100644 index 000000000..70b910892 --- /dev/null +++ b/tests/semantic_conformance/differential/fixtures/scalar-default-time.case.json @@ -0,0 +1,176 @@ +{ + "family": "multi_source", + "features": [ + "multi_source", + "numeric:double", + "aggregation:avg", + "null_values", + "many_to_one", + "selected:combined", + "selected:accounts.quota", + "selected:facts.filtered", + "selected:facts.rows", + "null_time" + ], + "index": 31, + "metrics": [ + { + "name": "combined", + "sql": "facts.total + accounts.quota", + "type": "derived" + } + ], + "models": [ + { + "default_time_dimension": "day", + "dimensions": [ + { + "granularity": "day", + "name": "day", + "type": "time" + } + ], + "metrics": [ + { + "agg": "sum", + "name": "total", + "sql": "amount * quantity" + } + ], + "name": "facts", + "primary_key": "id", + "relationships": [ + { + "foreign_key": "account_id", + "name": "accounts", + "type": "many_to_one" + } + ], + "segments": [], + "table": "generated_facts" + }, + { + "dimensions": [], + "metrics": [ + { + "agg": "sum", + "name": "quota", + "sql": "quota" + } + ], + "name": "accounts", + "primary_key": "id", + "table": "generated_accounts" + } + ], + "query": { + "dimensions": [], + "metrics": [ + "combined" + ] + }, + "seed": 20261005, + "tables": [ + { + "columns": [ + [ + "id", + "integer" + ], + [ + "category", + "varchar" + ], + [ + "status", + "varchar" + ], + [ + "amount", + "double" + ], + [ + "quantity", + "integer" + ], + [ + "account_id", + "integer" + ], + [ + "day", + "date" + ] + ], + "name": "generated_facts", + "rows": [ + [ + 1, + "O'Brien", + null, + 1, + 2, + null, + null + ], + [ + 2, + "O'Brien", + "open", + 8, + 0, + 2, + "2024-01-07" + ], + [ + 4, + "b", + null, + 8, + 1, + null, + "2024-02-01" + ], + [ + 5, + "b", + "paid", + 1, + 2, + 3, + "2024-01-07" + ] + ] + }, + { + "columns": [ + [ + "id", + "integer" + ], + [ + "region", + "varchar" + ], + [ + "quota", + "double" + ] + ], + "name": "generated_accounts", + "rows": [ + [ + 3, + "east", + 10 + ], + [ + 4, + "west", + 10 + ] + ] + } + ], + "version": 1 +} diff --git a/tests/semantic_conformance/differential/fixtures/sibling-fanout.case.json b/tests/semantic_conformance/differential/fixtures/sibling-fanout.case.json new file mode 100644 index 000000000..ab4a1e123 --- /dev/null +++ b/tests/semantic_conformance/differential/fixtures/sibling-fanout.case.json @@ -0,0 +1,187 @@ +{ + "family": "double_fanout", + "features": [ + "double_fanout", + "numeric:integer", + "aggregation:min", + "null_values", + "one_to_many", + "selected:facts.filtered", + "selected:facts.rows", + "selected:items.items_value", + "null_time", + "segment", + "limit" + ], + "index": 8, + "metrics": [], + "models": [ + { + "dimensions": [], + "metrics": [], + "name": "facts", + "primary_key": "id", + "relationships": [ + { + "foreign_key": "fact_id", + "name": "items", + "type": "one_to_many" + }, + { + "foreign_key": "fact_id", + "name": "refunds", + "type": "one_to_many" + } + ], + "segments": [], + "table": "generated_facts" + }, + { + "dimensions": [], + "metrics": [ + { + "agg": "sum", + "name": "items_value", + "sql": "value" + } + ], + "name": "items", + "primary_key": "id", + "table": "generated_items" + }, + { + "dimensions": [ + { + "name": "label", + "type": "categorical" + } + ], + "metrics": [], + "name": "refunds", + "primary_key": "id", + "table": "generated_refunds" + } + ], + "query": { + "dimensions": [ + "refunds.label" + ], + "filters": [], + "metrics": [ + "items.items_value" + ], + "segments": [] + }, + "seed": 20261005, + "tables": [ + { + "columns": [ + [ + "id", + "integer" + ], + [ + "category", + "varchar" + ], + [ + "status", + "varchar" + ], + [ + "amount", + "integer" + ], + [ + "quantity", + "integer" + ], + [ + "account_id", + "integer" + ], + [ + "day", + "date" + ] + ], + "name": "generated_facts", + "rows": [ + [ + 1, + "a", + "paid", + 1, + 1, + 3, + null + ] + ] + }, + { + "columns": [ + [ + "id", + "integer" + ], + [ + "fact_id", + "integer" + ], + [ + "label", + "varchar" + ], + [ + "value", + "integer" + ] + ], + "name": "generated_items", + "rows": [ + [ + 101, + 1, + "duplicate", + 3 + ] + ] + }, + { + "columns": [ + [ + "id", + "integer" + ], + [ + "fact_id", + "integer" + ], + [ + "label", + "varchar" + ], + [ + "value", + "integer" + ] + ], + "name": "generated_refunds", + "rows": [ + [ + 9, + 1, + "x", + 3 + ], + [ + 11, + 1, + "x", + 3 + ] + ] + } + ], + "version": 1 +} diff --git a/tests/semantic_conformance/differential/generator.py b/tests/semantic_conformance/differential/generator.py new file mode 100644 index 000000000..c4e313e78 --- /dev/null +++ b/tests/semantic_conformance/differential/generator.py @@ -0,0 +1,375 @@ +"""Generate bounded, valid semantic graphs, queries, and physical populations. + +The index determines the family; a private RNG determines everything else. A +case can therefore be regenerated without generating any preceding cases. +""" + +import json +import random +from copy import deepcopy +from datetime import date, timedelta + +from .harness import Case + +FAMILIES = ( + "base", + "derived", + "ratio", + "cumulative", + "filtered", + "dimension_join", + "fanout", + "multi_source", + "double_fanout", + "nested_derived", + "graph_metrics", + "composite_join", + "default_time", +) + + +def generate_case(seed: int, index: int) -> Case: + rng = random.Random(f"sidemantic-differential-v1:{seed}:{index}") + family = FAMILIES[index % len(FAMILIES)] + numeric_type = rng.choice(["integer", "double", "decimal(12,2)"]) + amount = rng.choice(["amount", "amount * quantity", "coalesce(amount, 0)", "amount - quantity"]) + aggregation = rng.choice(["sum", "avg", "min", "max", "count", "count_distinct"]) + metric_filter = rng.choice(["status = 'paid'", "amount > 0", "status IS NULL", "quantity >= 2"]) + models = [ + { + "name": "facts", + "table": "generated_facts", + "primary_key": "id", + "dimensions": [ + {"name": "id", "type": "numeric"}, + {"name": "category", "type": "categorical", "sql": rng.choice(["category", "upper(category)"])}, + {"name": "status", "type": "categorical"}, + {"name": "amount", "type": "numeric"}, + {"name": "quantity", "type": "numeric"}, + {"name": "account_id", "type": "numeric"}, + {"name": "day", "type": "time", "granularity": "day"}, + ], + "metrics": [ + {"name": "total", "agg": "sum", "sql": amount}, + {"name": "observed", "agg": aggregation, "sql": rng.choice(["amount", "quantity"])}, + {"name": "rows", "agg": "count"}, + { + "name": "filtered", + "agg": rng.choice(["sum", "count", "avg"]), + "sql": amount, + "filters": [metric_filter], + }, + {"name": "derived", "type": "derived", "sql": f"total + rows * {rng.randint(1, 7)}"}, + { + "name": "ratio", + "type": "ratio", + "numerator": "total", + "denominator": rng.choice(["rows", "observed", "filtered"]), + }, + {"name": "running", "type": "cumulative", "sql": "total"}, + {"name": "nested", "type": "derived", "sql": "derived + coalesce(ratio, 0)"}, + ], + "segments": [ + { + "name": "selected", + "sql": rng.choice( + ["{model}.quantity >= 1", "{model}.status = 'paid'", "{model}.category IS NOT NULL"] + ), + } + ], + "relationships": [], + } + ] + facts = models[0] + if rng.randrange(4) == 0: + facts["metrics"][0]["fill_nulls_with"] = rng.choice([0, -1]) + if rng.randrange(5) == 0: + facts["invariant_filters"] = ["quantity >= 0"] + if family == "cumulative": + window = rng.choice([None, "7 days", "1 month"]) + if window: + facts["metrics"][6]["window"] = window + row_count = rng.choice([0, 1, 2, 5, 9, 17]) + rows = [] + for row_id in range(1, row_count + 1): + rows.append( + [ + row_id, + rng.choice([None, "a", "b", "a", "O'Brien"]), + rng.choice([None, "paid", "open"]), + rng.choice([None, 0, -4, 1, 1, 8, 12.5]) + if numeric_type != "integer" + else rng.choice([None, 0, -4, 1, 1, 8]), + rng.choice([0, 1, 2, 3]), + rng.choice([None, 1, 2, 3, 99]), + None + if rng.randrange(8) == 0 + else (date(2024, 1, 1) + timedelta(days=rng.choice([0, 0, 1, 6, 31, 65]))).isoformat(), + ] + ) + tables = [ + { + "name": "generated_facts", + "columns": [ + ["id", "integer"], + ["category", "varchar"], + ["status", "varchar"], + ["amount", numeric_type], + ["quantity", "integer"], + ["account_id", "integer"], + ["day", "date"], + ], + "rows": rows, + } + ] + dimensions = rng.sample(["facts.category", "facts.status"], rng.randrange(3)) + selected = { + "base": ["total", "observed", "rows"], + "derived": ["derived"], + "ratio": ["ratio", "rows"], + "cumulative": ["running"], + "filtered": ["filtered", "rows"], + "nested_derived": ["nested", "derived"], + }.get(family, ["total", "rows", "observed"]) + relational_families = ["dimension_join", "fanout", "multi_source", "double_fanout", "composite_join"] + if family in relational_families: + # Cross metric semantics with relational topology, rather than keeping + # filtering/windows/ratios isolated in their simplest single-table form. + metric_shapes = ["total", "filtered", "derived", "ratio", "running", "nested"] + shape_index = (index // len(FAMILIES) + relational_families.index(family)) % len(metric_shapes) + selected = [metric_shapes[shape_index], "rows"] + metrics = [f"facts.{name}" for name in selected] + global_metrics = [] + features = [family, f"numeric:{numeric_type}", f"aggregation:{aggregation}"] + if not rows: + features.append("empty_source") + if any(value is None for row in rows for value in row): + features.append("null_values") + if family == "default_time": + facts["default_time_dimension"] = "day" + elif "running" in selected or rng.randrange(4) == 0: + grain = rng.choice(["day", "week", "month", "quarter", "year"]) + dimensions.insert(0, f"facts.day__{grain}") + features.append(f"grain:{grain}") + + if family in {"dimension_join", "multi_source", "composite_join", "default_time"}: + accounts = { + "name": "accounts", + "table": "generated_accounts", + "primary_key": "id", + "dimensions": [{"name": "region", "type": "categorical"}], + "metrics": [{"name": "quota", "agg": "sum", "sql": "quota"}], + } + relationship = {"name": "accounts", "type": "many_to_one", "foreign_key": "account_id"} + account_columns = [["id", "integer"], ["region", "varchar"], ["quota", numeric_type]] + account_rows = [[i, rng.choice([None, "east", "west"]), rng.choice([None, 0, 10, 25])] for i in range(1, 5)] + if family == "composite_join": + accounts["primary_key"] = ["id", "tenant"] + account_columns.append(["tenant", "integer"]) + for row in account_rows: + row.append(1) + account_rows += [[i, "other", 999, 2] for i in range(1, 3)] + tables[0]["columns"].append(["tenant", "integer"]) + for row in rows: + row.append(rng.choice([1, 2])) + relationship.update(foreign_key=["account_id", "tenant"], primary_key=["id", "tenant"]) + facts["relationships"].append(relationship) + models.append(accounts) + tables.append({"name": "generated_accounts", "columns": account_columns, "rows": account_rows}) + if family != "default_time": + dimensions.append("accounts.region") + features.append("many_to_one") + if family in {"multi_source", "default_time"}: + global_metrics.append({"name": "combined", "type": "derived", "sql": "facts.total + accounts.quota"}) + metrics = ["combined", "accounts.quota", *metrics] + if family == "default_time": + metrics = ["combined"] + dimensions = [] + + if family in {"fanout", "double_fanout"}: + for child in ["items", "refunds"] if family == "double_fanout" else ["items"]: + facts["relationships"].append({"name": child, "type": "one_to_many", "foreign_key": "fact_id"}) + models.append( + { + "name": child, + "table": f"generated_{child}", + "primary_key": "id", + "dimensions": [{"name": "label", "type": "categorical"}], + "metrics": [{"name": f"{child}_value", "agg": "sum", "sql": "value"}], + } + ) + child_rows = [ + [ + i, + rng.choice(list(range(1, row_count + 1)) + [None, 99]), + rng.choice([None, "x", "y"]), + rng.choice([None, 0, 3, 5]), + ] + for i in range(1, rng.randint(3, 20)) + ] + tables.append( + { + "name": f"generated_{child}", + "columns": [["id", "integer"], ["fact_id", "integer"], ["label", "varchar"], ["value", "integer"]], + "rows": child_rows, + } + ) + dimensions.append(f"{child}.label") + if rng.choice([False, True]): + metrics.append(f"{child}.{child}_value") + features.append("one_to_many") + # Explicit duplication means fanout coverage does not depend on chance. + if rows: + tables[1]["rows"].extend([[100, 1, "duplicate", 2], [101, 1, "duplicate", 3]]) + + if family == "graph_metrics": + global_metrics = [ + {"name": "global_derived", "type": "derived", "sql": "facts.total - facts.rows"}, + {"name": "global_ratio", "type": "ratio", "numerator": "facts.filtered", "denominator": "facts.rows"}, + ] + metrics = [metric["name"] for metric in global_metrics] + + features.extend(f"selected:{metric}" for metric in metrics) + if any(row[6] is None for row in rows): + features.append("null_time") + query = {"metrics": metrics, "dimensions": dimensions} + if rng.randrange(3) == 0: + query["segments"] = ["facts.selected"] + features.append("segment") + filters = [] + if rng.randrange(3) == 0: + filters.append( + rng.choice( + ["facts.amount IS NULL", "facts.quantity >= 2", "facts.status != 'open'", "facts.category = 'absent'"] + ) + ) + if "facts.running" not in metrics and rng.randrange(4) == 0: + filters.append(f"{metrics[0]} > {rng.choice([-1, 0, 5])}") + features.append("metric_filter") + if filters: + query["filters"] = filters + if family != "default_time" and rng.randrange(3) != 0: + # Every group key is a final tie breaker, including nullable keys. + query["order_by"] = ([f"{metrics[0]} DESC"] if rng.choice([False, True]) else []) + dimensions + if not query["order_by"]: + query.pop("order_by") + if dimensions and rng.choice([False, True]): + query["limit"] = rng.randint(1, 5) + features.append("limit") + if rng.randrange(3) == 0: + query["offset"] = rng.randint(1, 3) + features.append("offset") + return Case( + seed=seed, + index=index, + family=family, + models=models, + metrics=global_metrics, + query=query, + tables=tables, + features=features, + ) + + +def data_variant(case: Case, variant: int) -> Case: + """Independently seed physical rows without changing any compiler input.""" + if variant == 0: + return deepcopy(case) + result = deepcopy(case) + result.data_variant = variant + rng = random.Random(f"sidemantic-population-v1:{case.seed}:{case.index}:{variant}") + models_by_table = {model["table"]: model for model in result.models} + models_by_name = {model["name"]: model for model in result.models} + table_by_name = {table["name"]: table for table in result.tables} + for table in result.tables: + model = models_by_table[table["name"]] + primary = model.get("primary_key") or [] + primary = [primary] if isinstance(primary, str) else primary + rows = [] + for row_index in range(rng.choice([0, 1, 2, 5, 9, 17])): + row = [] + for column, dtype in table["columns"]: + if column in primary: + # Exercise composite targets with repeated first-key values. + value = row_index // 2 + 1 if len(primary) > 1 and column == primary[0] else row_index + 1 + if len(primary) > 1 and column == primary[1]: + value = row_index % 2 + 1 + elif dtype == "date": + value = ( + None + if rng.randrange(5) == 0 + else (date(2024, 1, 1) + timedelta(days=rng.choice([0, 1, 6, 31, 65]))).isoformat() + ) + elif dtype == "varchar": + choices = { + "category": [None, "a", "b", "O'Brien"], + "status": [None, "paid", "open"], + "region": [None, "east", "west"], + }.get(column, [None, "x", "y", "duplicate"]) + value = rng.choice(choices) + elif column == "quantity": + value = rng.choice([0, 1, 2, 3]) + else: + value = rng.choice([None, 0, 0, -4, 1, 3, 8, 25]) + if value is not None and dtype != "integer" and rng.choice([False, True]): + value += rng.choice([0.25, 0.5, 0.75]) + row.append(value) + rows.append(row) + table["rows"] = rows + + # Assign foreign-key tuples together after all parent populations exist. + # Repeated references, absent parents and null keys remain valid data. + for model in result.models: + for relationship in model.get("relationships", []): + target = models_by_name[relationship.get("target_model", relationship["name"])] + parent, child = (target, model) if relationship["type"] == "many_to_one" else (model, target) + foreign = relationship["foreign_key"] + foreign = [foreign] if isinstance(foreign, str) else foreign + primary = relationship.get("primary_key") or parent["primary_key"] + primary = [primary] if isinstance(primary, str) else primary + parent_table = table_by_name[parent["table"]] + child_table = table_by_name[child["table"]] + parent_positions = [ + next(i for i, c in enumerate(parent_table["columns"]) if c[0] == key) for key in primary + ] + child_positions = [next(i for i, c in enumerate(child_table["columns"]) if c[0] == key) for key in foreign] + references = [tuple(row[i] for i in parent_positions) for row in parent_table["rows"]] + choices = references + [tuple(None for _ in primary), tuple(999 for _ in primary)] + for row in child_table["rows"]: + values = rng.choice(choices) + for position, value in zip(child_positions, values): + row[position] = value + result.features = [ + feature for feature in result.features if feature not in {"empty_source", "null_values", "null_time"} + ] + if not result.tables[0]["rows"]: + result.features.append("empty_source") + if any(value is None for table in result.tables for row in table["rows"] for value in row): + result.features.append("null_values") + if any( + row[position] is None + for table in result.tables + for position, (_, dtype) in enumerate(table["columns"]) + if dtype == "date" + for row in table["rows"] + ): + result.features.append("null_time") + return result + + +def population_cases(case: Case, count: int): + """Yield distinct populations per immutable compiler input, reproducibly. + + Empty-source draws may repeat. Skip exact duplicate populations so requested + volume never includes the same data twice for a model/query/schema input. + The stored variant index identifies the actual RNG draw, including retries. + """ + seen = set() + variant = 0 + while len(seen) < count: + candidate = data_variant(case, variant) + variant += 1 + signature = json.dumps(candidate.tables, sort_keys=True, separators=(",", ":")) + if signature not in seen: + seen.add(signature) + yield candidate diff --git a/tests/semantic_conformance/differential/harness.py b/tests/semantic_conformance/differential/harness.py new file mode 100644 index 000000000..22abeff04 --- /dev/null +++ b/tests/semantic_conformance/differential/harness.py @@ -0,0 +1,515 @@ +"""Strict engine execution, multiset comparison, and replayable case validation.""" + +import hashlib +import importlib +import inspect +import json +import math +import re +import sys +from copy import deepcopy +from dataclasses import asdict, dataclass, field, replace +from datetime import date, datetime +from decimal import Decimal +from pathlib import Path +from time import perf_counter +from typing import Any + +import duckdb +import sqlglot +from sqlglot import exp + +from sidemantic import Metric, Model, SemanticLayer +from sidemantic.core.semantic_graph import SemanticGraph +from sidemantic.db.duckdb import DuckDBAdapter +from sidemantic.validation import validate_model, validate_query + + +@dataclass +class Case: + seed: int + index: int + family: str + models: list[dict] + metrics: list[dict] + query: dict + tables: list[dict] + features: list[str] = field(default_factory=list) + version: int = 1 + data_variant: int = 0 + + def to_dict(self) -> dict: + return asdict(self) + + def write(self, path: Path) -> None: + path.write_text(json.dumps(self.to_dict(), indent=2, sort_keys=True) + "\n") + + @classmethod + def read(cls, path: Path) -> "Case": + return cls(**json.loads(path.read_text())) + + @property + def ordered(self) -> bool: + return bool(self.query.get("order_by")) + + +class InvalidCaseError(ValueError): + """Generator/schema/definition errors, distinct from engine failures.""" + + +def make_graph(case: Case) -> SemanticGraph: + graph = SemanticGraph() + for definition in case.models: + graph.add_model(Model.model_validate(definition)) + for definition in case.metrics: + graph.add_metric(Metric.model_validate(definition)) + return graph + + +def _keys(value: str | list[str] | None) -> list[str]: + return [value] if isinstance(value, str) else (value or []) + + +def validate_population(case: Case) -> None: + """Validate every population, even when its immutable definition is cached.""" + try: + if case.version != 1: + raise ValueError(f"Unsupported fixture version {case.version}") + tables = {table["name"]: table for table in case.tables} + for table in case.tables: + if any(len(row) != len(table["columns"]) for row in table["rows"]): + raise ValueError("Data does not match table schema") + for model in case.models: + keys = _keys(model.get("primary_key")) + if not keys: + continue + table = tables[model["table"]] + names = [column[0] for column in table["columns"]] + positions = [names.index(key) for key in keys] + values = [tuple(row[position] for position in positions) for row in table["rows"]] + if any(None in value for value in values) or len(set(values)) != len(values): + raise ValueError("Primary key is nullable or duplicated") + except (ValueError, KeyError, TypeError, IndexError) as exc: + raise InvalidCaseError(str(exc)) from exc + + +def validate_case(case: Case) -> SemanticGraph: + """Check definitions and references without asking either compiler to work. + + Engine compile/execute failures remain failures even when both engines raise. + This intentionally validates the generated grammar rather than claiming to + validate every possible Sidemantic feature. + """ + try: + validate_population(case) + graph = make_graph(case) + tables = {table["name"]: table for table in case.tables} + if len(tables) != len(case.tables) or len(graph.models) != len(case.models): + raise ValueError("Duplicate table or model") + schemas = {} + for table in case.tables: + names = [column[0] for column in table["columns"]] + if len(set(names)) != len(names) or not names: + raise ValueError("Duplicate or empty schema") + for name in [table["name"], *names]: + if not re.fullmatch(r"[a-z][a-z0-9_]*", name): + raise ValueError(f"Invalid generated identifier: {name}") + if any(not re.fullmatch(r"integer|double|varchar|date|decimal\(12,2\)", c[1]) for c in table["columns"]): + raise ValueError("Unsupported generated column type") + schemas[table["name"]] = set(names) + + def expression(sql: str, owner: str | None, physical: bool = False) -> None: + parsed = sqlglot.parse_one(sql.replace("{model}", owner or ""), read="duckdb") + for column in parsed.find_all(exp.Column): + model_name = column.table or owner + name = column.name.split("__", 1)[0] + if not column.table and name in graph.metrics: + continue + if model_name not in graph.models: + raise ValueError(f"Unknown expression owner: {column.sql()}") + model = graph.models[model_name] + available = {d.name for d in model.dimensions} | {m.name for m in model.metrics} + if physical: + available = schemas[model.table] + if name not in available: + raise ValueError(f"Unknown expression field: {column.sql()}") + + for model in graph.models.values(): + errors = validate_model(model) + if errors: + raise ValueError("; ".join(errors)) + if model.table not in tables: + raise ValueError(f"Missing table {model.table}") + schema = schemas[model.table] + key_names = _keys(model.primary_key) + if not set(key_names) <= schema: + raise ValueError("Primary key not in schema") + for dimension in model.dimensions: + expression(dimension.sql or dimension.name, model.name, physical=True) + if not dimension.sql and dimension.name not in schema: + raise ValueError(f"Dimension {dimension.name} missing physical column") + for segment in model.segments: + expression(segment.sql, model.name, physical=True) + for predicate in model.invariant_filters or []: + expression(predicate, model.name, physical=True) + for relationship in model.relationships: + target = graph.models.get(relationship.related_model) + if target is None: + raise ValueError("Missing relationship target") + target_schema = schemas[target.table] + foreign = relationship.foreign_key_columns + primary = relationship.primary_key_columns or _keys( + target.primary_key if relationship.type == "many_to_one" else model.primary_key + ) + foreign_schema, primary_schema = ( + (schema, target_schema) if relationship.type == "many_to_one" else (target_schema, schema) + ) + if ( + len(foreign) != len(primary) + or not set(foreign) <= foreign_schema + or not set(primary) <= primary_schema + ): + raise ValueError("Invalid relationship keys") + for metric in model.metrics: + for sql in [metric.sql, metric.numerator, metric.denominator, *(metric.filters or [])]: + if sql: + expression(sql, model.name, physical=metric.type is None or sql in (metric.filters or [])) + for metric in graph.metrics.values(): + for sql in [metric.sql, metric.numerator, metric.denominator]: + if sql: + expression(sql, None) + if not case.query.get("metrics") and not case.query.get("dimensions"): + raise ValueError("Empty query") + errors = validate_query(case.query.get("metrics", []), case.query.get("dimensions", []), graph) + if errors: + raise ValueError("; ".join(errors)) + for predicate in case.query.get("filters", []): + expression(predicate, None) + for segment in case.query.get("segments", []): + owner, name = segment.split(".") + if owner not in graph.models or name not in {s.name for s in graph.models[owner].segments}: + raise ValueError("Unknown query segment") + order = [re.sub(r"\s+(ASC|DESC)$", "", item, flags=re.I) for item in case.query.get("order_by", [])] + selected = case.query.get("metrics", []) + case.query.get("dimensions", []) + if any(item not in selected for item in order): + raise ValueError("Order expression must be selected") + if order and not set(case.query.get("dimensions", [])) <= set(order): + raise ValueError("Order must contain every group key as a tie breaker") + if (case.query.get("limit") is not None or case.query.get("offset") is not None) and not order: + raise ValueError("Pagination requires deterministic ordering") + # A selected cumulative metric requires a time grouping. This also + # prevents reducers from turning a semantic mismatch into invalid input. + for reference in case.query.get("metrics", []): + _, metric = graph.resolve_metric_reference(reference) + if metric.type == "cumulative" and not any( + graph.models[ref.split(".")[0]].get_dimension(ref.split(".")[1].split("__")[0]).type == "time" + for ref in case.query.get("dimensions", []) + ): + raise ValueError("Cumulative query requires a time dimension") + return graph + except (ValueError, KeyError, TypeError, AttributeError, sqlglot.errors.ParseError) as exc: + raise InvalidCaseError(str(exc)) from exc + + +def _value_equal(left: Any, right: Any, *, rel_tol: float, abs_tol: float) -> bool: + if left is None or right is None: + return left is right + # DATE and midnight TIMESTAMP are equal semantic time buckets. Other time + # components remain observable; strings are never coerced into dates. + if isinstance(left, date) and isinstance(right, date): + + def timestamp(value): + return value if isinstance(value, datetime) else datetime.combine(value, datetime.min.time()) + + return timestamp(left) == timestamp(right) + numeric = (int, float, Decimal) + if isinstance(left, numeric) and isinstance(right, numeric): + if isinstance(left, bool) or isinstance(right, bool): + return type(left) is type(right) and left == right + if isinstance(left, int) and isinstance(right, int): + return left == right + if math.isnan(float(left)) or math.isnan(float(right)): + return math.isnan(float(left)) and math.isnan(float(right)) + return math.isclose(left, right, rel_tol=rel_tol, abs_tol=abs_tol) + return type(left) is type(right) and left == right + + +def rows_equal(left: list, right: list, *, ordered: bool, rel_tol=1e-9, abs_tol=1e-9) -> bool: + """Compare multisets with duplicate multiplicity and tolerant numeric values. + + Tolerance is not transitive. A bipartite matching avoids the false negatives + produced by greedy matching or sorting near-equal numeric rows. + """ + if len(left) != len(right): + return False + + if ordered: + return all(_row_equal(a, b, rel_tol=rel_tol, abs_tol=abs_tol) for a, b in zip(left, right)) + return len(_multiset_matches(left, right, rel_tol=rel_tol, abs_tol=abs_tol)) == len(left) + + +def _row_equal(left, right, *, rel_tol=1e-9, abs_tol=1e-9): + return len(left) == len(right) and all( + _value_equal(x, y, rel_tol=rel_tol, abs_tol=abs_tol) for x, y in zip(left, right) + ) + + +def _multiset_matches(left, right, *, rel_tol=1e-9, abs_tol=1e-9): + edges = [[j for j, b in enumerate(right) if _row_equal(a, b, rel_tol=rel_tol, abs_tol=abs_tol)] for a in left] + matched = {} + + def augment(i, seen): + for j in edges[i]: + if j in seen: + continue + seen.add(j) + if j not in matched or augment(matched[j], seen): + matched[j] = i + return True + return False + + for i in range(len(left)): + augment(i, set()) + return matched + + +def _canonical_row(row): + def value(item): + if item is None: + return "null", "" + if isinstance(item, bool): + return "bool", str(item) + if isinstance(item, (int, float, Decimal)): + return "number", str(Decimal(str(item)).normalize()) + if isinstance(item, date): + timestamp = item if isinstance(item, datetime) else datetime.combine(item, datetime.min.time()) + return "time", timestamp.isoformat() + return type(item).__name__, str(item) + + return tuple(value(item) for item in row) + + +@dataclass +class EngineResult: + columns: list[str] = field(default_factory=list) + rows: list = field(default_factory=list) + sql: str | None = None + error: str | None = None + error_type: str | None = None + stage: str = "compile" + selection: dict | None = None + compile_seconds: float = 0 + execute_seconds: float = 0 + compilation_reused: bool = False + + +@dataclass +class Outcome: + failure_class: str | None + python: EngineResult | None = None + rust: EngineResult | None = None + detail: str | None = None + + def failure_identity(self) -> tuple: + """Preserve the diagnostic or public-result discrepancy being reduced. + + Result identities intentionally retain all public columns and a concrete + witness. This can prevent otherwise useful reductions, but cannot trade + a missing group for an unrelated ordering/metric discrepancy. + """ + if self.failure_class in {"rows", "columns"} and self.python and self.rust: + columns = tuple(self.python.columns), tuple(self.rust.columns) + if self.failure_class == "columns": + return "columns", columns + left, right = self.python.rows, self.rust.rows + if len(left) == len(right) and rows_equal(left, right, ordered=False): + witness = next( + (_canonical_row(a), _canonical_row(b)) for a, b in zip(left, right) if not _row_equal(a, b) + ) + return "rows", "order", columns, witness + left = sorted(left, key=_canonical_row) + right = sorted(right, key=_canonical_row) + matched = _multiset_matches(left, right) + matched_left = set(matched.values()) + unmatched_left = [_canonical_row(row) for i, row in enumerate(left) if i not in matched_left] + unmatched_right = [_canonical_row(row) for i, row in enumerate(right) if i not in matched] + witness = ( + unmatched_left[0] if unmatched_left else None, + unmatched_right[0] if unmatched_right else None, + ) + if len(left) != len(right): + return "rows", "cardinality", columns, len(left) > len(right), witness + return "rows", "values", columns, witness + diagnostics = [] + for result in [self.python, self.rust]: + if result and result.error: + # Retain referenced owner/column names and multi-line semantic + # validation detail; remove SQL excerpts and variable locations. + message = re.split(r"\n(?:LINE \d+:|\s*\^)|\n\n", result.error, maxsplit=1)[0] + message = re.sub(r"\b\d+(?:\.\d+)?\b", "#", message) + diagnostics.append(" ".join(message.split())) + else: + diagnostics.append(None) + return self.failure_class, *diagnostics + + def fingerprint(self, case: Case) -> str: + parts = list(self.failure_identity()) + if self.failure_class == "rows" and self.python and self.rust: + # Collection groups similar failures across data populations; the + # reducer alone pins the concrete witness within each saved case. + parts.pop() + if self.failure_class == "invalid_case": + parts.append(self.detail) + if self.failure_class in {"rows", "columns"}: + parts.append(case.family) + return hashlib.sha256(json.dumps(parts, sort_keys=True).encode()).hexdigest()[:16] + + +class DifferentialRunner: + """Reuse one single-thread DuckDB connection; recreate graphs for every case.""" + + def __init__(self): + self.adapter = DuckDBAdapter(config={"threads": 1}) + self.table_names: list[str] = [] + # Retain only the last immutable input per engine. Volume campaigns + # process all populations together; memory does not grow with the run. + self.compiled: dict[str, tuple[str, EngineResult]] = {} + self.validated_key: str | None = None + self.definition_validations = 0 + self.definition_validation_cache_hits = 0 + + def close(self): + self.adapter.close() + + def _load(self, case: Case): + for name in self.table_names: + self.adapter.execute(f'DROP TABLE "{name}"') + self.table_names = [] + for table in case.tables: + name = table["name"] + columns = ", ".join(f'"{column}" {dtype}' for column, dtype in table["columns"]) + self.adapter.execute(f'CREATE TABLE "{name}" ({columns})') + self.table_names.append(name) + if table["rows"]: + placeholders = ", ".join("?" for _ in table["columns"]) + self.adapter.executemany(f'INSERT INTO "{name}" VALUES ({placeholders})', table["rows"]) + + @staticmethod + def compilation_key(case: Case) -> str: + return json.dumps( + { + "version": case.version, + "models": case.models, + "metrics": case.metrics, + "query": case.query, + "schemas": [{"name": t["name"], "columns": t["columns"]} for t in case.tables], + }, + sort_keys=True, + separators=(",", ":"), + ) + + def _compile(self, case: Case, engine: str) -> EngineResult: + result = EngineResult() + started = perf_counter() + try: + layer = SemanticLayer(connection=self.adapter, engine=engine, fallback=False, auto_register=False) + layer.graph = make_graph(case) + if engine == "rust": + + def forbidden_python(*args, **kwargs): + raise AssertionError("Rust compilation entered the Python fallback") + + layer._compile_with_python = forbidden_python + # Some compiler planning paths expand mutable selection lists. Give + # each engine an independent request, preserving the replay fixture. + result.sql = layer.compile(**deepcopy(case.query)) + result.compile_seconds = perf_counter() - started + result.selection = layer.last_engine_selection + result.stage = "selection" + if result.selection != {"engine": engine, "reason": None}: + raise AssertionError(f"Expected strict {engine} selection, got {result.selection}") + result.stage = "execute" + except Exception as exc: + result.error_type = type(exc).__name__ + result.error = str(exc) + if result.stage == "compile": + result.compile_seconds = perf_counter() - started + return result + + def _engine(self, case: Case, engine: str, *, reuse_compilation: bool = False) -> EngineResult: + key = self.compilation_key(case) if reuse_compilation else None + cached = self.compiled.get(engine) if reuse_compilation else None + if cached and cached[0] == key: + result = replace(cached[1], compile_seconds=0, compilation_reused=True) + else: + result = self._compile(case, engine) + # Never cache a failed compile or unexpected engine selection. + if reuse_compilation and result.error is None: + self.compiled[engine] = (key, replace(result)) + if result.error is not None: + return result + started = perf_counter() + try: + cursor = self.adapter.execute(result.sql) + result.columns = [column[0] for column in cursor.description] + result.rows = cursor.fetchall() + result.stage = "complete" + except Exception as exc: + result.error_type = type(exc).__name__ + result.error = str(exc) + result.execute_seconds = perf_counter() - started + return result + + def evaluate(self, case: Case, *, reuse_compilation: bool = False) -> Outcome: + try: + key = self.compilation_key(case) if reuse_compilation else None + if reuse_compilation and key == self.validated_key: + validate_population(case) + self.definition_validation_cache_hits += 1 + else: + validate_case(case) + self.definition_validations += 1 + if reuse_compilation: + self.validated_key = key + self._load(case) + except Exception as exc: + return Outcome("invalid_case", detail=f"{type(exc).__name__}: {exc}") + if reuse_compilation: + python = self._engine(case, "python", reuse_compilation=True) + rust = self._engine(case, "rust", reuse_compilation=True) + else: + python = self._engine(case, "python") + rust = self._engine(case, "rust") + errors = [ + f"{engine}:{result.stage}:{result.error_type}" + for engine, result in [("python", python), ("rust", rust)] + if result.error is not None + ] + if errors: + return Outcome("|".join(errors), python, rust) + if python.columns != rust.columns: + return Outcome("columns", python, rust) + if not rows_equal(python.rows, rust.rows, ordered=case.ordered): + return Outcome("rows", python, rust) + return Outcome(None, python, rust) + + +def outcome_dict(outcome: Outcome) -> dict: + """Diagnostic JSON conversion; fixtures themselves retain exact source data.""" + return json.loads(json.dumps(asdict(outcome), default=str)) + + +def runtime_provenance() -> dict: + """Identify the actual source package and loaded native artifact in reports.""" + native = importlib.import_module("sidemantic_rs.sidemantic_rs") + native_path = Path(native.__file__).resolve() + with native_path.open("rb") as binary: + digest = hashlib.file_digest(binary, "sha256").hexdigest() + return { + "python_executable": sys.executable, + "semantic_layer_source": inspect.getfile(SemanticLayer), + "rust_extension": str(native_path), + "rust_extension_sha256": digest, + "duckdb_version": duckdb.__version__, + "duckdb_threads": 1, + } diff --git a/tests/semantic_conformance/differential/minimize.py b/tests/semantic_conformance/differential/minimize.py new file mode 100644 index 000000000..f4f2b4595 --- /dev/null +++ b/tests/semantic_conformance/differential/minimize.py @@ -0,0 +1,183 @@ +"""Deterministic bounded delta reduction preserving a concrete failure class.""" + +from collections.abc import Callable +from copy import deepcopy +from dataclasses import dataclass + +from .harness import Case, InvalidCaseError, Outcome, validate_case + + +@dataclass +class Reduction: + case: Case + outcome: Outcome + attempts: int + accepted: int + exhausted: bool + + +def minimize(case: Case, evaluate: Callable[[Case], Outcome], *, max_attempts: int = 150) -> Reduction: + """Reduce query, graph definitions, rows, and non-key values to a fixed point. + + Accepted candidates must pass schema/reference validation and reproduce the + original failure class and normalized exception diagnostic or result + discrepancy kind, public columns, and concrete unmatched-row witness. A + budget bounds expensive failure collection. Exhaustion is reported, not + described as global minimality. + """ + validate_case(case) + current = deepcopy(case) + outcome = evaluate(current) + if not outcome.failure_class or outcome.failure_class == "invalid_case": + raise ValueError("Reducer requires a valid case with a reproducible engine failure") + target = outcome.failure_identity() + attempts = accepted = 0 + + def attempt(candidate: Case) -> bool: + nonlocal current, outcome, attempts, accepted + if attempts >= max_attempts: + return False + attempts += 1 + try: + validate_case(candidate) + except InvalidCaseError: + return False + candidate_outcome = evaluate(candidate) + if candidate_outcome.failure_identity() != target: + return False + current, outcome = candidate, candidate_outcome + accepted += 1 + return True + + def repair_order(candidate: Case) -> None: + query = candidate.query + if query.get("order_by"): + selected = query.get("metrics", []) + query.get("dimensions", []) + query["order_by"] = [item for item in query["order_by"] if item.split()[0] in selected] + if not query["order_by"]: + query.pop("order_by") + query.pop("limit", None) + query.pop("offset", None) + + def reduce_list(get_values, remove) -> None: + # Classic complement-based ddmin, followed by individual deletions. + granularity = 2 + while attempts < max_attempts: + length = len(get_values(current)) + if length == 0: + return + chunk = max(1, (length + granularity - 1) // granularity) + changed = False + for start in range(0, length, chunk): + candidate = deepcopy(current) + remove(candidate, start, min(start + chunk, length)) + if attempt(candidate): + granularity = max(2, granularity - 1) + changed = True + break + if attempts >= max_attempts: + return + if changed: + continue + if chunk == 1: + return + granularity = min(length, granularity * 2) + + # Data reduction first keeps later compiler probes cheap and rapidly yields + # a small reproducer even when the failure is independent of physical rows. + for table_index in range(len(current.tables)): + + def remove_rows(candidate, start, stop, ti=table_index): + del candidate.tables[ti]["rows"][start:stop] + + reduce_list(lambda item, ti=table_index: item.tables[ti]["rows"], remove_rows) + + previous = -1 + while attempts < max_attempts and accepted != previous: + previous = accepted + for field in ["limit", "offset", "order_by"]: + if field in current.query: + candidate = deepcopy(current) + candidate.query.pop(field) + attempt(candidate) + for field in ["filters", "segments", "metrics", "dimensions"]: + + def remove_query(candidate, start, stop, name=field): + del candidate.query[name][start:stop] + repair_order(candidate) + + reduce_list(lambda item, name=field: item.query.get(name, []), remove_query) + + def remove_models(candidate, start, stop): + removed = {model["name"] for model in candidate.models[start:stop]} + del candidate.models[start:stop] + for model in candidate.models: + model["relationships"] = [ + r for r in model.get("relationships", []) if r.get("target_model", r["name"]) not in removed + ] + tables = {model["table"] for model in candidate.models} + candidate.tables = [table for table in candidate.tables if table["name"] in tables] + + reduce_list(lambda item: item.models, remove_models) + + def remove_metrics(candidate, start, stop): + del candidate.metrics[start:stop] + + reduce_list(lambda item: item.metrics, remove_metrics) + + for model_index in range(len(current.models)): + for field in ["metrics", "segments", "relationships", "dimensions", "invariant_filters"]: + + def remove_fields(candidate, start, stop, mi=model_index, name=field): + model = candidate.models[mi] + del model[name][start:stop] + if name == "dimensions" and model.get("default_time_dimension") not in { + d["name"] for d in model[name] + }: + model.pop("default_time_dimension", None) + + reduce_list(lambda item, mi=model_index, name=field: item.models[mi].get(name, []), remove_fields) + + for table_index in range(len(current.tables)): + + def remove_columns(candidate, start, stop, ti=table_index): + table = candidate.tables[ti] + del table["columns"][start:stop] + for row in table["rows"]: + del row[start:stop] + + reduce_list(lambda item, ti=table_index: item.tables[ti]["columns"], remove_columns) + + # Keep key columns intact. Changing foreign keys is valid SQL but makes a + # reduced relational population harder to understand and can defeat fanout. + for table_index, table in enumerate(current.tables): + key_columns = set() + for model in current.models: + if model["table"] == table["name"]: + keys = model.get("primary_key") or [] + key_columns.update([keys] if isinstance(keys, str) else keys) + for relationship in model.get("relationships", []): + target = next( + (m for m in current.models if m["name"] == relationship.get("target_model", relationship["name"])), + None, + ) + owner = model if relationship["type"] == "many_to_one" else target + if owner and owner["table"] == table["name"]: + keys = relationship.get("foreign_key") or [] + key_columns.update([keys] if isinstance(keys, str) else keys) + for row_index, row in enumerate(table["rows"]): + for column_index, value in enumerate(row): + if attempts >= max_attempts: + break + column, dtype = table["columns"][column_index] + if column in key_columns or value is None: + continue + simple = "2000-01-01" if dtype == "date" else "" if dtype == "varchar" else 0 + for replacement in [None, simple]: + if value == replacement: + continue + candidate = deepcopy(current) + candidate.tables[table_index]["rows"][row_index][column_index] = replacement + if attempt(candidate): + break + return Reduction(current, outcome, attempts, accepted, attempts >= max_attempts) diff --git a/tests/semantic_conformance/differential/test_harness.py b/tests/semantic_conformance/differential/test_harness.py new file mode 100644 index 000000000..73eacfc3f --- /dev/null +++ b/tests/semantic_conformance/differential/test_harness.py @@ -0,0 +1,397 @@ +"""Behavioral contracts for generation, comparison, classification and reduction.""" + +import json +from copy import deepcopy +from datetime import date, datetime +from decimal import Decimal + +import pytest + +from .generator import FAMILIES, data_variant, generate_case, population_cases +from .harness import Case, DifferentialRunner, EngineResult, InvalidCaseError, Outcome, rows_equal, validate_case +from .minimize import minimize + + +@pytest.mark.parametrize( + "left,right,ordered,expected", + [ + ([(None, 1), ("a", 2)], [("a", 2), (None, 1)], False, True), + ([(None, 1), ("a", 2)], [("a", 2), (None, 1)], True, False), + ([(1,), (1,)], [(1,), (2,)], False, False), + ([(Decimal("1.25"),)], [(1.2500000001,)], False, True), + ([(1.25,)], [(1.2501,)], False, False), + ([(2**60,)], [(2**60 + 1,)], False, False), + ([(None,)], [(0,)], False, False), + ([(True,)], [(1,)], False, False), + ([(float("nan"),)], [(float("nan"),)], False, True), + ([(float("inf"),)], [(-float("inf"),)], False, False), + ([(date(2024, 1, 1),)], [(datetime(2024, 1, 1),)], False, True), + ([(date(2024, 1, 1),)], [(datetime(2024, 1, 1, 1),)], False, False), + ([(1,)], [(1, 2)], False, False), + ([], [(1,)], False, False), + ], +) +def test_comparison_preserves_values_order_and_multiplicity(left, right, ordered, expected): + assert rows_equal(left, right, ordered=ordered) is expected + + +def test_tolerant_multiset_matching_reassigns_an_earlier_match(): + # The first left row matches either right row, but the second only matches + # the first. A greedy matcher would incorrectly reject equal multisets. + assert rows_equal([(0.1,), (0.0,)], [(0.0,), (0.2,)], ordered=False, abs_tol=0.11, rel_tol=0) + + +def test_seeded_generation_is_valid_replayable_and_varies_definitions(tmp_path): + cases = [generate_case(20261005, index) for index in range(120)] + assert {case.family for case in cases} == set(FAMILIES) + assert len({json.dumps(case.models, sort_keys=True) for case in cases}) > 90 + joined_metrics = {metric for case in cases[:52] if len(case.models) > 1 for metric in case.query["metrics"]} + assert {"facts.filtered", "facts.derived", "facts.ratio", "facts.running", "facts.nested"} <= joined_metrics + for case in cases: + if case.family == "default_time": + assert case.models[0]["default_time_dimension"] == "day" + assert case.query["dimensions"] == [] + assert not {"order_by", "limit", "offset"} & case.query.keys() + for case in cases: + validate_case(case) + assert case.to_dict() == generate_case(case.seed, case.index).to_dict() + assert case.to_dict() != generate_case(case.seed + 1, case.index).to_dict() + path = tmp_path / "replay.case.json" + cases[7].write(path) + assert Case.read(path).to_dict() == cases[7].to_dict() + + +def small_case(): + return Case( + seed=1, + index=0, + family="injected_sum_regression", + models=[ + { + "name": "facts", + "table": "generated_facts", + "primary_key": "id", + "dimensions": [{"name": "category", "type": "categorical"}], + "metrics": [{"name": "total", "agg": "sum", "sql": "amount"}, {"name": "unused", "agg": "count"}], + }, + { + "name": "unused", + "table": "generated_unused", + "primary_key": "id", + "dimensions": [{"name": "id", "type": "numeric"}], + }, + ], + metrics=[], + query={ + "metrics": ["facts.total"], + "dimensions": ["facts.category"], + "order_by": ["facts.category"], + "filters": ["facts.category = 'a'"], + }, + tables=[ + { + "name": "generated_facts", + "columns": [["id", "integer"], ["category", "varchar"], ["amount", "integer"]], + "rows": [[1, "a", 2], [2, "a", 3], [3, "a", 0]], + }, + {"name": "generated_unused", "columns": [["id", "integer"]], "rows": [[9]]}, + ], + ) + + +def test_minimizer_preserves_real_result_failure_and_emits_replay(tmp_path): + runner = DifferentialRunner() + + def injected_aggregate_regression(case): + # Execute genuine Python-compiled SQL, then inject SUM -> MAX into a + # second executable query. This creates a known observable discrepancy + # without depending on any outstanding production compiler defect. + runner._load(case) + result = runner._engine(case, "python") + if result.error: + return Outcome("python_error", result) + faulty = result.sql.replace("SUM(", "MAX(") + cursor = runner.adapter.execute(faulty) + wrong = EngineResult(columns=[c[0] for c in cursor.description], rows=cursor.fetchall(), sql=faulty) + return Outcome(None if rows_equal(result.rows, wrong.rows, ordered=case.ordered) else "rows", result, wrong) + + try: + original = small_case() + first = minimize(original, injected_aggregate_regression, max_attempts=250) + second = minimize(original, injected_aggregate_regression, max_attempts=250) + assert first.case.to_dict() == second.case.to_dict() + assert first.outcome.failure_class == "rows" + assert first.accepted > 0 + assert len(first.case.tables) == len(first.case.models) == 1 + assert len(first.case.tables[0]["rows"]) == 2 + assert first.case.tables[0]["columns"] == [["id", "integer"], ["category", "varchar"], ["amount", "integer"]] + assert first.case.query == {"metrics": ["facts.total"], "dimensions": ["facts.category"], "filters": []} + assert [m["name"] for m in first.case.models[0]["metrics"]] == ["total"] + validate_case(first.case) + path = tmp_path / "reduced.case.json" + first.case.write(path) + assert injected_aggregate_regression(Case.read(path)).failure_class == "rows" + assert original.to_dict() == small_case().to_dict() + # Removing either necessary row eliminates the injected failure. + for index in range(2): + candidate = deepcopy(first.case) + candidate.tables[0]["rows"].pop(index) + assert injected_aggregate_regression(candidate).failure_class is None + finally: + runner.close() + + +def test_minimizer_respects_budget_and_rejects_changed_failure_class(): + case = small_case() + + def failure(candidate): + return Outcome("rows" if candidate.to_dict() == case.to_dict() else "rust:compile:ValueError") + + reduction = minimize(case, failure, max_attempts=3) + assert reduction.attempts == 3 and reduction.exhausted + assert reduction.case.to_dict() == case.to_dict() + + +def test_minimizer_does_not_exchange_one_binder_failure_for_another(): + case = small_case() + + def failure(candidate): + diagnostic = ( + 'Referenced table "facts" not found' + if candidate.to_dict() == case.to_dict() + else 'Referenced column "missing" not found' + ) + return Outcome( + "rust:execute:BinderException", + rust=EngineResult(error=diagnostic, error_type="BinderException", stage="execute"), + ) + + reduction = minimize(case, failure, max_attempts=15) + assert reduction.accepted == 0 + assert reduction.case.to_dict() == case.to_dict() + + +@pytest.mark.parametrize("change", ["cardinality", "order_only", "column", "witness", "different_metric"]) +def test_minimizer_cannot_substitute_an_unrelated_result_discrepancy(change): + case = small_case() + + def failure(candidate): + columns = ["total", "unused"] + left, right = [(5, 10)], [(3, 10)] + if candidate.to_dict() != case.to_dict(): + if change == "cardinality": + left = [(5, 10), (9, 10)] + elif change == "order_only": + left, right = [(5, 10), (3, 10)], [(3, 10), (5, 10)] + elif change == "column": + columns = ["another_metric", "unused"] + elif change == "witness": + left, right = [(7, 10)], [(4, 10)] + else: + right = [(5, 7)] + return Outcome("rows", EngineResult(columns=columns, rows=left), EngineResult(columns=columns, rows=right)) + + reduction = minimize(case, failure, max_attempts=20) + assert reduction.accepted == 0 + assert reduction.case.to_dict() == case.to_dict() + + +def test_result_witness_is_stable_under_unordered_row_permutations(): + first = Outcome( + "rows", + EngineResult(columns=["total"], rows=[(1,), (5,), (3,)]), + EngineResult(columns=["total"], rows=[(1,), (6,), (3,)]), + ) + permuted = deepcopy(first) + permuted.python.rows.reverse() + permuted.rust.rows = [(6,), (3,), (1,)] + assert first.failure_identity() == permuted.failure_identity() + assert first.failure_identity()[1] == "values" + + +@pytest.mark.parametrize("engines", [{"python"}, {"rust"}, {"python", "rust"}]) +def test_one_or_both_engine_errors_are_failures(monkeypatch, engines): + runner = DifferentialRunner() + + def execute(case, engine): + if engine in engines: + return EngineResult(error="deliberate compiler failure", error_type="ValueError", stage="compile") + return EngineResult(columns=["total"], rows=[(5,)], stage="complete") + + monkeypatch.setattr(runner, "_engine", execute) + try: + outcome = runner.evaluate(small_case()) + assert outcome.failure_class is not None + assert outcome.failure_class != "invalid_case" + for engine in engines: + assert f"{engine}:compile:ValueError" in outcome.failure_class + finally: + runner.close() + + +def test_engine_planning_cannot_mutate_the_other_request_or_fixture(monkeypatch): + case = small_case() + original = deepcopy(case.to_dict()) + seen = [] + from sidemantic import SemanticLayer + + def compile_mutating_request(self, **query): + seen.append(deepcopy(query)) + query["dimensions"].append("mutated") + self.last_engine_selection = {"engine": "python", "reason": None} + return "SELECT 1 AS total" + + monkeypatch.setattr(SemanticLayer, "compile", compile_mutating_request) + runner = DifferentialRunner() + try: + for _ in range(2): + assert runner._engine(case, "python").error is None + assert seen == [original["query"], original["query"]] + assert case.to_dict() == original + finally: + runner.close() + + +def test_independently_seeded_populations_preserve_immutable_inputs(): + for index in range(len(FAMILIES)): + base = generate_case(20261005, index) + original = deepcopy(base.to_dict()) + variants = list(population_cases(base, 12)) + assert len({json.dumps(case.tables, sort_keys=True) for case in variants}) == 12 + assert {DifferentialRunner.compilation_key(case) for case in variants} == { + DifferentialRunner.compilation_key(base) + } + for case in variants: + validate_case(case) + assert data_variant(base, case.data_variant).to_dict() == case.to_dict() + assert base.to_dict() == original + + +def test_compile_reuse_still_executes_new_population_and_default_bypasses_cache(monkeypatch): + runner = DifferentialRunner() + original_compile = runner._compile + calls = [] + + def compile(case, engine): + calls.append(engine) + return original_compile(case, engine) + + monkeypatch.setattr(runner, "_compile", compile) + try: + first = small_case() + runner._load(first) + initial = runner._engine(first, "python", reuse_compilation=True) + second = deepcopy(first) + second.tables[0]["rows"][0][2] = 4 + runner._load(second) + changed = runner._engine(second, "python", reuse_compilation=True) + assert not initial.compilation_reused and changed.compilation_reused + assert initial.rows == [("a", 5)] and changed.rows == [("a", 7)] + assert calls == ["python"] + assert changed.selection == {"engine": "python", "reason": None} + # Replay and minimization omit reuse_compilation and must compile again. + replayed = runner._engine(second, "python") + assert not replayed.compilation_reused + assert replayed.rows == changed.rows + assert calls == ["python", "python"] + finally: + runner.close() + + +@pytest.mark.parametrize("change", ["model", "query", "schema", "graph_metric"]) +def test_compile_reuse_rejects_any_changed_compiler_input(monkeypatch, change): + runner = DifferentialRunner() + original_compile = runner._compile + calls = [] + + def compile(case, engine): + calls.append(engine) + return original_compile(case, engine) + + monkeypatch.setattr(runner, "_compile", compile) + try: + case = small_case() + runner._load(case) + assert runner._engine(case, "python", reuse_compilation=True).error is None + changed = deepcopy(case) + if change == "model": + changed.models[0]["metrics"][0]["agg"] = "max" + elif change == "query": + changed.query["filters"] = [] + elif change == "schema": + changed.tables[0]["columns"][2][1] = "double" + else: + changed.metrics = [{"name": "global", "type": "derived", "sql": "facts.total + 1"}] + validate_case(changed) + runner._load(changed) + result = runner._engine(changed, "python", reuse_compilation=True) + assert result.error is None + assert not result.compilation_reused + assert calls == ["python", "python"] + finally: + runner.close() + + +@pytest.mark.parametrize("damage", ["row_width", "duplicate_key", "null_key", "type", "model", "schema", "version"]) +def test_validation_reuse_checks_every_population_and_invalidates_changed_definitions(monkeypatch, damage): + runner = DifferentialRunner() + executions = [] + + def execute(case, engine, **kwargs): + executions.append(engine) + return EngineResult(columns=["total"], rows=[(5,)], stage="complete") + + monkeypatch.setattr(runner, "_engine", execute) + try: + case = small_case() + assert runner.evaluate(case, reuse_compilation=True).failure_class is None + changed = deepcopy(case) + changed.tables[0]["rows"][0][2] = 8 + assert runner.evaluate(changed, reuse_compilation=True).failure_class is None + assert runner.definition_validations == 1 + assert runner.definition_validation_cache_hits == 1 + damaged = deepcopy(changed) + if damage == "row_width": + damaged.tables[0]["rows"][0].pop() + elif damage == "duplicate_key": + damaged.tables[0]["rows"][1][0] = damaged.tables[0]["rows"][0][0] + elif damage == "null_key": + damaged.tables[0]["rows"][0][0] = None + elif damage == "type": + damaged.tables[0]["rows"][0][2] = "not a number" + elif damage == "model": + damaged.models[0]["metrics"][0]["sql"] = "missing_physical_column" + elif damage == "schema": + damaged.tables[0]["columns"][2][0] = "changed_column" + else: + damaged.version = 2 + outcome = runner.evaluate(damaged, reuse_compilation=True) + assert outcome.failure_class == "invalid_case" + assert len(executions) == 4 + # Replay/minimization always repeat full definition validation too. + assert runner.evaluate(changed).failure_class is None + assert runner.definition_validations == 2 + finally: + runner.close() + + +@pytest.mark.parametrize("damage", ["reference", "schema", "order", "primary_key"]) +def test_invalid_generator_cases_are_separate(damage): + case = small_case() + if damage == "reference": + case.query["metrics"] = ["facts.missing"] + elif damage == "schema": + case.tables[0]["rows"][0].pop() + elif damage == "order": + case.query["order_by"] = ["facts.total"] + else: + case.tables[0]["rows"][1][0] = 1 + with pytest.raises(InvalidCaseError): + validate_case(case) + runner = DifferentialRunner() + try: + outcome = runner.evaluate(case) + assert outcome.failure_class == "invalid_case" + assert outcome.python is outcome.rust is None + finally: + runner.close() diff --git a/tests/semantic_conformance/fixtures/source_null_ordering.json b/tests/semantic_conformance/fixtures/source_null_ordering.json new file mode 100644 index 000000000..95fdb7b53 --- /dev/null +++ b/tests/semantic_conformance/fixtures/source_null_ordering.json @@ -0,0 +1,120 @@ +{ + "data_variant": 6, + "family": "fanout", + "features": [ + "fanout", + "numeric:double", + "aggregation:max", + "one_to_many", + "selected:facts.filtered", + "selected:facts.rows", + "null_values", + "null_time" + ], + "index": 6, + "metrics": [], + "models": [ + { + "dimensions": [ + { + "name": "status", + "type": "categorical" + } + ], + "metrics": [ + { + "agg": "count", + "name": "rows" + } + ], + "name": "facts", + "primary_key": "id", + "relationships": [ + { + "foreign_key": "fact_id", + "name": "items", + "type": "one_to_many" + } + ], + "segments": [], + "table": "generated_facts" + }, + { + "dimensions": [ + { + "name": "label", + "type": "categorical" + } + ], + "metrics": [], + "name": "items", + "primary_key": "id", + "table": "generated_items" + } + ], + "query": { + "dimensions": [ + "facts.status", + "items.label" + ], + "filters": [], + "metrics": [ + "facts.rows" + ], + "order_by": [ + "facts.status", + "items.label" + ] + }, + "seed": 20261005, + "tables": [ + { + "columns": [ + [ + "id", + "integer" + ], + [ + "status", + "varchar" + ] + ], + "name": "generated_facts", + "rows": [ + [ + 3, + "paid" + ], + [ + 7, + "paid" + ] + ] + }, + { + "columns": [ + [ + "id", + "integer" + ], + [ + "fact_id", + "integer" + ], + [ + "label", + "varchar" + ] + ], + "name": "generated_items", + "rows": [ + [ + 4, + 7, + "x" + ] + ] + } + ], + "version": 1 +} diff --git a/tests/semantic_conformance/test_absent_counts.py b/tests/semantic_conformance/test_absent_counts.py index 34d0c6048..d6b8b6b4e 100644 --- a/tests/semantic_conformance/test_absent_counts.py +++ b/tests/semantic_conformance/test_absent_counts.py @@ -114,12 +114,30 @@ def test_source_populations_preserve_orphans_with_zero_customer_count(layer): ) ) assert cursor.fetchall() == [ + (None, 1, 1, 0, 1, -1, 0), ("empty", 0, 0, 1, 1, 0, -2), ("matched", 2, 1, 1, 3, 2, 0.5), - (None, 1, 1, 0, 1, -1, 0), ] +def test_local_calculations_use_absent_source_defaults(layer): + layer.graph.models["orders"].metrics.extend( + [ + Metric(name="shifted", type="derived", sql="rows + 1"), + Metric(name="nested", type="derived", sql="shifted * 2"), + Metric(name="fraction", type="ratio", numerator="rows", denominator="shifted"), + Metric(name="nullable", type="derived", sql="amount + rows"), + ] + ) + result = layer.query( + metrics=["orders.shifted", "orders.nested", "orders.fraction", "orders.nullable", "customers.customers"], + dimensions=["customers.region"], + filters=["customers.region IS NOT NULL"], + order_by=["customers.region"], + ) + assert result.fetchall() == [("empty", 1, 2, 0, None, 1), ("matched", 3, 6, pytest.approx(2 / 3), 32, 1)] + + def test_policy_does_not_restore_unauthorized_groups(layer): layer.graph.models["customers"].security = SecurityPolicy(row_filters=["region = {{ user.region }}"]) cursor = layer.adapter.execute( @@ -154,7 +172,7 @@ def test_three_source_groups_merge_when_the_first_source_has_no_row(layer): ) # The empty group exists in the second and third sources, but not the first. # Joining every later source only against the first would split it into two rows. - assert cursor.fetchall() == [("empty", 0, 1, 1), ("matched", 2, 1, 0), (None, 1, 0, 0)] + assert cursor.fetchall() == [(None, 1, 0, 0), ("empty", 0, 1, 1), ("matched", 2, 1, 0)] def test_absent_count_zero_is_used_by_aggregate_filter_and_order(layer): diff --git a/tests/semantic_conformance/test_aggregate_aliases.py b/tests/semantic_conformance/test_aggregate_aliases.py index 3a69ec842..2e5b8f8f7 100644 --- a/tests/semantic_conformance/test_aggregate_aliases.py +++ b/tests/semantic_conformance/test_aggregate_aliases.py @@ -91,7 +91,7 @@ def test_two_grouping_dimensions_share_basename(layer, reverse_dimensions, rever dimensions = ["orders.region", "customers.region"] metrics = ["orders.revenue", "customers.quota"] columns = ["orders_region", "customers_region", "revenue", "quota"] - expected = [("east", "north", 30, 2), ("west", "south", 40, 4), (None, "west", None, 7), (None, None, None, 5)] + expected = [(None, None, None, 5), (None, "west", None, 7), ("east", "north", 30, 2), ("west", "south", 40, 4)] if reverse_dimensions: dimensions.reverse() columns[:2] = reversed(columns[:2]) diff --git a/tests/semantic_conformance/test_approximate_distinct.py b/tests/semantic_conformance/test_approximate_distinct.py index da60a5110..81402829d 100644 --- a/tests/semantic_conformance/test_approximate_distinct.py +++ b/tests/semantic_conformance/test_approximate_distinct.py @@ -254,7 +254,7 @@ def test_approximate_dialect_rendering_and_population_results(layer, dialect, fu with pytest.raises(Exception, match="metric.approx_count_distinct_output_dialect"): layer.compile(metrics=[metric], dimensions=dimensions, order_by=dimensions, dialect=dialect) return - if layer.engine == "rust" and dialect == "redshift" and shape in {"cumulative", "window"}: + if dialect == "redshift" and shape in {"cumulative", "window"}: with pytest.raises(Exception, match="metric.approx_count_distinct_window_redshift"): layer.compile(metrics=[metric], dimensions=dimensions, order_by=dimensions, dialect=dialect) return diff --git a/tests/semantic_conformance/test_cli.py b/tests/semantic_conformance/test_cli.py index 8ed4130ab..1bfba331e 100644 --- a/tests/semantic_conformance/test_cli.py +++ b/tests/semantic_conformance/test_cli.py @@ -7,6 +7,7 @@ from typer.testing import CliRunner from sidemantic.cli import app +from tests.duckdb_compat import date_bucket FIXTURES = Path(__file__).parent / "fixtures" @@ -39,13 +40,13 @@ "native/monthly", "select monthly.sale_date__month as month, revenue_mom as change from metrics order by month", ["month", "change"], - [("2024-01-01", None), ("2024-03-01", None)], + [(date_bucket(2024, 1, 1).isoformat(), None), (date_bucket(2024, 3, 1).isoformat(), None)], ), ( "native/monthly", "select monthly.sale_date__month, revenue_mom from metrics order by monthly.sale_date__month", ["sale_date__month", "revenue_mom"], - [("2024-01-01", None), ("2024-03-01", None)], + [(date_bucket(2024, 1, 1).isoformat(), None), (date_bucket(2024, 3, 1).isoformat(), None)], ), ( "native/roles", diff --git a/tests/semantic_conformance/test_cohort_parity.py b/tests/semantic_conformance/test_cohort_parity.py index 8af6dcf96..b636c6dc5 100644 --- a/tests/semantic_conformance/test_cohort_parity.py +++ b/tests/semantic_conformance/test_cohort_parity.py @@ -312,12 +312,10 @@ def test_nonexistent_explicit_owner_does_not_fall_back_to_entity_match(layer): @pytest.mark.parametrize("layer", ["rust_owned"], indirect=True) -@pytest.mark.parametrize("mutation", ["unowned", "unknown_metric", "wrapper", "joined_dimension"]) +@pytest.mark.parametrize("mutation", ["unknown_metric", "wrapper", "joined_dimension"]) def test_owned_graph_cohort_unsupported_shapes_remain_gated(layer, mutation): query = {} - if mutation == "unowned": - layer.graph.metric_owners.clear() - elif mutation == "unknown_metric": + if mutation == "unknown_metric": layer.graph.metric_owners["ghost"] = "events" elif mutation == "wrapper": layer.graph.add_metric(Metric(name="wrapped", type="derived", sql="qualified * 2")) diff --git a/tests/semantic_conformance/test_complete_filters.py b/tests/semantic_conformance/test_complete_filters.py index e95d110b7..1eb4101e6 100644 --- a/tests/semantic_conformance/test_complete_filters.py +++ b/tests/semantic_conformance/test_complete_filters.py @@ -593,22 +593,36 @@ def test_complete_row_count_generator_reuse_observes_graph_changes(row_count_lay assert generator.graph is layer.graph -@pytest.mark.parametrize("layer", ["python"], indirect=True) @pytest.mark.parametrize("sql,predicate", [("COUNT(*)", "status = ("), ("SUM(", "true")]) def test_unused_invalid_complete_metric_does_not_break_other_query(row_count_layer, sql, predicate): row_count_layer.graph.models["orders"].metrics.append( Metric(name="unused", sql=sql, sql_is_complete=True, filters=[predicate]) ) - assert_result(row_count_layer, {"metrics": ["orders.paid_rows"]}, ["paid_rows"], [(3,)]) + # Python lowers selected metrics lazily; Rust validates the entire semantic + # input and rejects malformed definitions even when they are not selected. + # This is validation timing for invalid SQL, not a gap in valid semantics. + if row_count_layer.engine == "rust": + with pytest.raises(UnsupportedSemanticFeaturesError) as caught: + row_count_layer.compile(metrics=["orders.paid_rows"]) + assert set(caught.value.capabilities) == {"metric.complete_filters"} + else: + assert_result(row_count_layer, {"metrics": ["orders.paid_rows"]}, ["paid_rows"], [(3,)]) -@pytest.mark.parametrize("layer", ["python"], indirect=True) def test_selected_complete_row_count_invalid_filter_is_rejected(row_count_layer): import duckdb row_count_layer.graph.models["orders"].get_metric("paid_rows").filters = ["status = ("] - with pytest.raises(duckdb.ParserException): - row_count_layer.adapter.execute(row_count_layer.compile(metrics=["orders.paid_rows"])) + # Rust rejects this malformed filter before SQL reaches the database; + # Python retains its database-time parser rejection contract. + if row_count_layer.engine == "rust": + with pytest.raises(UnsupportedSemanticFeaturesError) as caught: + row_count_layer.compile(metrics=["orders.paid_rows"]) + assert set(caught.value.capabilities) == {"metric.complete_filters"} + else: + sql = row_count_layer.compile(metrics=["orders.paid_rows"]) + with pytest.raises(duckdb.ParserException): + row_count_layer.adapter.execute(sql) @pytest.mark.parametrize("layer", ["python"], indirect=True) diff --git a/tests/semantic_conformance/test_computed_keys.py b/tests/semantic_conformance/test_computed_keys.py index 9338a0121..cfe08d872 100644 --- a/tests/semantic_conformance/test_computed_keys.py +++ b/tests/semantic_conformance/test_computed_keys.py @@ -5,6 +5,7 @@ from sidemantic import Dimension, Metric, Model, Relationship, SemanticLayer from sidemantic.rust_bridge import rewrite_semantic_input from sidemantic.semantic_handoff import UnsupportedSemanticFeaturesError +from tests.duckdb_compat import date_bucket @pytest.fixture @@ -187,13 +188,12 @@ def test_disconnected_computed_model_does_not_block_temporal_query(layer): create table key_sales(id integer, day date, amount integer); insert into key_sales values (1, '2026-01-01', 3), (2, '2026-01-02', 4); """) - from datetime import date result( layer, {"metrics": ["sales.running"], "dimensions": ["sales.day"], "order_by": ["sales.day"]}, ["day", "revenue", "running"], - [(date(2026, 1, 1), 3, 3), (date(2026, 1, 2), 4, 7)], + [(date_bucket(2026, 1, 1), 3, 3), (date_bucket(2026, 1, 2), 4, 7)], ) diff --git a/tests/semantic_conformance/test_cross_source_windows.py b/tests/semantic_conformance/test_cross_source_windows.py new file mode 100644 index 000000000..f6a971104 --- /dev/null +++ b/tests/semantic_conformance/test_cross_source_windows.py @@ -0,0 +1,292 @@ +"""Window wrappers preserve independent source grains and grouped output names.""" + +import pytest +import sqlglot +from sqlglot import exp + +from sidemantic import Dimension, Metric, Model, Relationship, SemanticLayer +from tests.duckdb_compat import date_bucket + + +@pytest.mark.parametrize("dialect", ["duckdb", "postgres", "tsql", "mysql", "bigquery"]) +@pytest.mark.parametrize("metric_name", ["order", "daily amount"]) +@pytest.mark.parametrize("day_name", ["day", "order day"]) +def test_native_window_expression_preserves_quoted_input_across_dialects(dialect, metric_name, day_name): + pytest.importorskip("sidemantic_rs") + # Authored expressions use the layer's input dialect, including its quoting. + window_input = exp.column(metric_name, table="base", quoted=True).sql(dialect=dialect) + with SemanticLayer(engine="rust", fallback=False, dialect=dialect, auto_register=False) as layer: + layer.add_model( + Model( + name="events", + table="events", + dimensions=[Dimension(name=day_name, type="time", granularity="day")], + metrics=[ + Metric(name=metric_name, agg="sum", sql="amount"), + Metric(name="running amount", type="cumulative", window_expression=f"SUM({window_input})"), + ], + ) + ) + sql = layer.compile(metrics=["events.running amount"], dimensions=[f"events.{day_name}"]) + parsed = sqlglot.parse_one(sql, read=dialect) + window = next(parsed.find_all(exp.Window)) + columns = list(window.this.find_all(exp.Column)) + assert [(column.table, column.name) for column in columns] == [("base", metric_name)] + assert window.parent.alias == "running amount" + assert window.args["order"].expressions[0].this.name == day_name + assert layer.last_engine_selection == {"engine": "rust", "reason": None} + + +@pytest.fixture(params=["python", "rust"]) +def layer(request): + if request.param == "rust": + pytest.importorskip("sidemantic_rs", reason="Cross-source window acceptance requires the real Rust extension") + layer = SemanticLayer(engine=request.param, fallback=False, auto_register=False) + try: + yield layer + finally: + layer.adapter.close() + + +@pytest.mark.parametrize("population", ["populated", "empty_facts", "empty_accounts", "both_empty"]) +@pytest.mark.parametrize("reverse", [False, True]) +def test_cross_source_calculation_beside_cumulative_preserves_leaf_grains(layer, population, reverse): + layer.add_model( + Model( + name="facts", + table="window_facts", + primary_key="id", + dimensions=[Dimension(name="day", type="time", granularity="day")], + metrics=[ + Metric(name="total", agg="sum", sql="amount", fill_nulls_with=0), + Metric(name="running", type="cumulative", sql="total"), + ], + relationships=[Relationship(name="accounts", type="many_to_one", foreign_key="account_id")], + ) + ) + layer.add_model( + Model( + name="accounts", + table="window_accounts", + primary_key="id", + metrics=[Metric(name="quota", agg="sum", sql="quota")], + ) + ) + layer.add_metric(Metric(name="combined", type="derived", sql="facts.total + accounts.quota")) + layer.adapter.execute(""" + create table window_facts(id integer, account_id integer, day date, amount integer); + create table window_accounts(id integer, quota integer); + """) + if population not in {"empty_facts", "both_empty"}: + layer.adapter.execute(""" + insert into window_facts values + (1, 1, '2024-01-01', 2), (2, 1, '2024-01-01', 3), + (3, 1, '2024-01-02', 7), (4, 2, '2024-01-02', 11); + """) + if population not in {"empty_accounts", "both_empty"}: + layer.adapter.execute("insert into window_accounts values (1, 10), (2, 20)") + + metrics = ["combined", "facts.running"] + if reverse: + metrics.reverse() + sql = layer.compile(metrics=metrics, dimensions=["facts.day"], order_by=["facts.day"]) + assert layer.last_engine_selection["engine"] == layer.engine + result = layer.adapter.execute(sql) + columns = [column[0] for column in result.description] + leaves = ["total", "quota"] if reverse else ["quota", "total"] + assert columns == ["day", *leaves, "combined", "running"] + rows = result.fetchall() + records = [dict(zip(columns, row, strict=True)) for row in rows] + actual = [(r["day"], r["quota"], r["total"], r["combined"], r["running"]) for r in records] + expected = { + "populated": [(date_bucket(2024, 1, 1), 10, 5, 15, 5), (date_bucket(2024, 1, 2), 30, 18, 48, 23)], + "empty_facts": [(None, 30, 0, 30, 0)], + "empty_accounts": [(date_bucket(2024, 1, 1), None, 5, None, 5), (date_bucket(2024, 1, 2), None, 18, None, 23)], + "both_empty": [], + } + assert actual == expected[population] + + +@pytest.mark.parametrize("window_kind", ["running", "expression", "lag"]) +def test_window_partitions_bind_both_colliding_sibling_dimensions(layer, window_kind): + metrics = [Metric(name="total", agg="sum", sql="amount")] + if window_kind == "lag": + metrics.append( + Metric( + name="change", + type="time_comparison", + base_metric="total", + comparison_type="dod", + calculation="difference", + ) + ) + selected = "facts.change" + else: + controls = {"window_expression": "SUM(base.total)"} if window_kind == "expression" else {"sql": "total"} + metrics.append(Metric(name="running", type="cumulative", **controls)) + selected = "facts.running" + layer.add_model( + Model( + name="facts", + table="collision_facts", + primary_key="id", + dimensions=[Dimension(name="day", type="time", granularity="day")], + metrics=metrics, + relationships=[ + Relationship(name="items", type="one_to_many", foreign_key="fact_id"), + Relationship(name="refunds", type="one_to_many", foreign_key="fact_id"), + ], + ) + ) + for name in ["items", "refunds"]: + layer.add_model( + Model( + name=name, + table=f"collision_{name}", + primary_key="id", + dimensions=[Dimension(name="label", type="categorical")], + ) + ) + layer.adapter.execute(""" + create table collision_facts(id integer, day date, amount integer); + create table collision_items(id integer, fact_id integer, label varchar); + create table collision_refunds(id integer, fact_id integer, label varchar); + insert into collision_facts values + (1, '2024-01-01', 2), (2, '2024-01-02', 3), + (3, '2024-01-01', 10), (4, '2024-01-02', 20); + insert into collision_items values + (1, 1, 'a'), (2, 1, 'a'), (3, 2, 'a'), (4, 3, 'b'), (5, 4, 'b'); + insert into collision_refunds values + (1, 1, 'x'), (2, 1, 'x'), (3, 1, 'y'), (4, 2, 'x'), + (5, 2, 'y'), (6, 3, 'x'), (7, 4, 'x'); + """) + sql = layer.compile( + metrics=[selected], + dimensions=["facts.day", "items.label", "refunds.label"], + order_by=["items.label", "refunds.label", "facts.day"], + ) + assert layer.last_engine_selection["engine"] == layer.engine + result = layer.adapter.execute(sql) + columns = [column[0] for column in result.description] + assert columns[:4] == ["day", "items_label", "refunds_label", "total"] + rows = result.fetchall() + expected_windows = [None, 1, None, 1, None, 10] if window_kind == "lag" else [2, 5, 2, 5, 10, 30] + expected_groups = [ + (date_bucket(2024, 1, 1), "a", "x", 2), + (date_bucket(2024, 1, 2), "a", "x", 3), + (date_bucket(2024, 1, 1), "a", "y", 2), + (date_bucket(2024, 1, 2), "a", "y", 3), + (date_bucket(2024, 1, 1), "b", "x", 10), + (date_bucket(2024, 1, 2), "b", "x", 20), + ] + assert rows == [(*group, window) for group, window in zip(expected_groups, expected_windows, strict=True)] + + +@pytest.mark.parametrize("collision_kind", ["metric", "dimension"]) +@pytest.mark.parametrize("window_kind", ["running", "expression", "lag", "ratio"]) +def test_window_inputs_keep_qualified_metric_identity(layer, collision_kind, window_kind): + account_metric = "total" if collision_kind == "metric" else "quota" + if window_kind == "lag": + window = Metric( + name="windowed", + type="time_comparison", + base_metric="total", + comparison_type="dod", + calculation="difference", + ) + elif window_kind == "ratio": + window = Metric(name="windowed", type="ratio", numerator="total", denominator="total", offset_window="1 day") + else: + controls = {"window_expression": "SUM(base.total)"} if window_kind == "expression" else {"sql": "total"} + window = Metric(name="windowed", type="cumulative", window_order="facts.total", **controls) + layer.add_model( + Model( + name="facts", + table="alias_facts", + primary_key="id", + dimensions=[Dimension(name="day", type="time", granularity="day")], + metrics=[Metric(name="total", agg="sum", sql="amount"), window], + relationships=[Relationship(name="accounts", type="many_to_one", foreign_key="account_id")], + ) + ) + layer.add_model( + Model( + name="accounts", + table="alias_accounts", + primary_key="id", + dimensions=[Dimension(name="total", type="categorical", sql="category")] + if collision_kind == "dimension" + else [], + metrics=[Metric(name=account_metric, agg="sum", sql="quota")], + ) + ) + layer.add_metric(Metric(name="combined", type="derived", sql=f"facts.total + accounts.{account_metric}")) + layer.adapter.execute(""" + create table alias_facts(id integer, account_id integer, day date, amount integer); + create table alias_accounts(id integer, category varchar, quota integer); + insert into alias_accounts values (1, 'retail', 10); + insert into alias_facts values + (1, 1, '2024-01-01', 2), (2, 1, '2024-01-01', 3), (3, 1, '2024-01-02', 7); + """) + dimensions = ["facts.day"] + if collision_kind == "dimension": + dimensions.append("accounts.total") + sql = layer.compile(metrics=["combined", "facts.windowed"], dimensions=dimensions, order_by=["facts.total DESC"]) + assert layer.last_engine_selection["engine"] == layer.engine + result = layer.adapter.execute(sql) + columns = [column[0] for column in result.description] + records = [dict(zip(columns, row, strict=True)) for row in result.fetchall()] + window_alias = "facts.windowed" if "facts.windowed" in columns else "windowed" + expected_window = { + "running": [12, 5], + "expression": [12, 5], + "lag": [2, None], + "ratio": [1.4, None], + }[window_kind] + assert [(row["facts_total"], row["combined"], row[window_alias]) for row in records] == [ + (7, 17, expected_window[0]), + (5, 15, expected_window[1]), + ] + assert [row["accounts_total"] for row in records] == ( + [10, 10] if collision_kind == "metric" else ["retail", "retail"] + ) + + +@pytest.mark.parametrize("layer", ["rust"], indirect=True) +@pytest.mark.parametrize("include_calculation", [False, True]) +def test_deferred_calculation_keeps_unqueryable_window_owner_validation(layer, include_calculation): + layer.add_model( + Model( + name="facts", + table="guard_facts", + primary_key="id", + dimensions=[Dimension(name="day", type="time", granularity="day")], + metrics=[Metric(name="total", agg="sum", sql="amount")], + relationships=[ + Relationship(name="accounts", type="many_to_one", foreign_key="account_id"), + Relationship(name="unavailable", type="many_to_one", foreign_key="unavailable_id"), + ], + ) + ) + layer.add_model( + Model( + name="accounts", + table="guard_accounts", + primary_key="id", + metrics=[Metric(name="quota", agg="sum", sql="quota")], + ) + ) + layer.add_model( + Model( + name="unavailable", + source_uri="s3://warehouse/unavailable.parquet", + primary_key="id", + metrics=[Metric(name="running", type="cumulative", sql="facts.total")], + ) + ) + layer.add_metric(Metric(name="combined", type="derived", sql="facts.total + accounts.quota")) + metrics = ["unavailable.running"] + if include_calculation: + metrics.insert(0, "combined") + with pytest.raises(Exception, match="unavailable.*source_uri|source_uri.*unavailable"): + layer.compile(metrics=metrics, dimensions=["facts.day"]) diff --git a/tests/semantic_conformance/test_cumulative_null_dates.py b/tests/semantic_conformance/test_cumulative_null_dates.py new file mode 100644 index 000000000..9f98fd3bf --- /dev/null +++ b/tests/semantic_conformance/test_cumulative_null_dates.py @@ -0,0 +1,53 @@ +"""Minimized generated regression for nullable dates in cumulative queries.""" + +from datetime import date, datetime + +import pytest + +from sidemantic import Dimension, Metric, Model, SemanticLayer + + +@pytest.mark.parametrize("engine", ["python", "rust"]) +@pytest.mark.parametrize("null_amount", [None, 7]) +def test_cumulative_null_date_follows_known_periods(engine, null_amount): + """DuckDB must keep NULL dates NULL and apply its NULLS LAST window order. + + Seed 20261005/index 27 exposed a DuckDB 1.3.2 optimizer discrepancy: the + Python projection returned a NULL running total while the Rust projection + returned zero, despite equivalent window clauses. DuckDB 1.4.0 additionally + exposed the internal NULL date sentinel as a real date. This independent + oracle guards against both compilers agreeing on an incorrect host result. + """ + with SemanticLayer(engine=engine, fallback=False, auto_register=False) as layer: + layer.adapter.execute("create table facts (id integer, day date, amount integer, status varchar)") + layer.adapter.executemany( + "insert into facts values (?, ?, ?, ?)", + [(1, "2000-01-01", 0, "paid"), (2, None, null_amount, "paid")], + ) + layer.add_model( + Model( + name="facts", + table="facts", + primary_key="id", + dimensions=[ + Dimension(name="day", type="time", granularity="day"), + Dimension(name="status", type="categorical"), + ], + metrics=[ + Metric(name="total", agg="sum", sql="amount"), + Metric(name="running", type="cumulative", sql="total"), + ], + ) + ) + result = layer.query( + metrics=["facts.running"], + dimensions=["facts.day__month", "facts.status"], + order_by=["facts.day__month"], + ) + assert [column[0] for column in result.description] == ["day__month", "status", "total", "running"] + rows = [ + (period.date() if isinstance(period, datetime) else period, status, total, running) + for period, status, total, running in result.fetchall() + ] + assert rows == [(date(2000, 1, 1), "paid", 0, 0), (None, "paid", null_amount, null_amount or 0)] + assert layer.last_engine_selection == {"engine": engine, "reason": None} diff --git a/tests/semantic_conformance/test_default_time_differential.py b/tests/semantic_conformance/test_default_time_differential.py new file mode 100644 index 000000000..4ed84fe12 --- /dev/null +++ b/tests/semantic_conformance/test_default_time_differential.py @@ -0,0 +1,75 @@ +"""Default time grain must be resolved once, before splitting metric sources.""" + +import pytest + +from sidemantic import Dimension, Metric, Model, Relationship, SemanticLayer +from sidemantic.rust_bridge import compile_semantic_input +from sidemantic.sql.generator import SQLGenerator +from tests.duckdb_compat import date_bucket + + +@pytest.fixture(params=["python", "rust"]) +def layer(request): + if request.param == "rust": + pytest.importorskip("sidemantic_rs", reason="Requires real native extension") + layer = SemanticLayer(engine=request.param, fallback=False, auto_register=False) + layer.add_model( + Model( + name="facts", + table="facts", + primary_key="id", + default_time_dimension="day", + dimensions=[Dimension(name="day", type="time", granularity="day")], + metrics=[Metric(name="total", agg="sum", sql="amount")], + relationships=[Relationship(name="accounts", type="many_to_one", foreign_key="account_id")], + ) + ) + layer.add_model( + Model( + name="accounts", + table="accounts", + primary_key="id", + metrics=[Metric(name="quota", agg="sum", sql="quota")], + ) + ) + layer.add_metric(Metric(name="combined", type="derived", sql="facts.total + accounts.quota")) + layer.adapter.execute("create table facts(id integer, account_id integer, day date, amount integer)") + layer.adapter.execute("insert into facts values (1, 1, '2024-01-07', 2), (2, 1, '2024-02-01', 8)") + layer.adapter.execute("create table accounts(id integer, quota integer)") + layer.adapter.execute("insert into accounts values (1, 10), (2, 10)") + yield layer + layer.adapter.close() + + +def test_graph_calculation_without_dimensions_is_scalar(layer): + result = layer.query(metrics=["combined"]) + assert [column[0] for column in result.description] == ["combined"] + # Each source contributes its independent total: (2 + 8) + (10 + 10). + assert result.fetchall() == [(30,)] + + +def test_skipped_model_defaults_remain_skipped_in_source_children(layer): + # This lower-level compiler option is used by callers such as the widget. + query = {"metrics": ["facts.total", "accounts.quota"], "skip_default_time_dimensions": True} + sql = ( + compile_semantic_input(layer.graph, query) + if layer.engine == "rust" + else SQLGenerator(layer.graph).generate(**query) + ) + result = layer.adapter.execute(sql) + assert [column[0] for column in result.description] == ["total", "quota"] + assert result.fetchall() == [(10, 20)] + + +@pytest.mark.parametrize("explicit", [False, True]) +def test_model_default_or_explicit_time_grain_is_projected(layer, explicit): + query = {"dimensions": ["facts.day"]} if explicit else {} + result = layer.query(metrics=["facts.total", "accounts.quota"], **query) + assert [column[0] for column in result.description] == ["day", "total", "quota"] + # The account linked to both days contributes once per day. The unmatched + # account retains its own NULL-day group in the full source reconciliation. + assert set(result.fetchall()) == { + (date_bucket(2024, 1, 7), 2, 10), + (date_bucket(2024, 2, 1), 8, 10), + (None, None, 10), + } diff --git a/tests/semantic_conformance/test_feature_parity.py b/tests/semantic_conformance/test_feature_parity.py index 2f0f35f8b..61b9e35a6 100644 --- a/tests/semantic_conformance/test_feature_parity.py +++ b/tests/semantic_conformance/test_feature_parity.py @@ -13,6 +13,7 @@ from sidemantic.adapters.sidemantic import SidemanticAdapter from sidemantic.core.semantic_layer import SecurityError from sidemantic.validation import QueryValidationError +from tests.duckdb_compat import date_bucket FIXTURES = Path(__file__).parent / "fixtures" @@ -155,12 +156,12 @@ def test_sparse_comparison_uses_calendar_month_and_category(layer_for): }, ["day__month", "category", "revenue", "month_change"], [ - ("2024-01-01", "a", 100, None), - ("2024-03-01", "a", 180, None), - ("2024-04-01", "a", 210, 30), - ("2024-01-01", "b", 10, None), - ("2024-03-01", "b", 30, None), - ("2024-04-01", "b", 50, 20), + (date_bucket(2024, 1, 1).isoformat(), "a", 100, None), + (date_bucket(2024, 3, 1).isoformat(), "a", 180, None), + (date_bucket(2024, 4, 1).isoformat(), "a", 210, 30), + (date_bucket(2024, 1, 1).isoformat(), "b", 10, None), + (date_bucket(2024, 3, 1).isoformat(), "b", 30, None), + (date_bucket(2024, 4, 1).isoformat(), "b", 50, 20), ], ) @@ -198,12 +199,12 @@ def test_rolling_sum_partitions_categories(layer_for): }, ["day__month", "category", "revenue", "rolling_revenue"], [ - ("2024-01-01", "a", 100, 100), - ("2024-03-01", "a", 180, 280), - ("2024-04-01", "a", 210, 390), - ("2024-01-01", "b", 10, 10), - ("2024-03-01", "b", 30, 40), - ("2024-04-01", "b", 50, 80), + (date_bucket(2024, 1, 1).isoformat(), "a", 100, 100), + (date_bucket(2024, 3, 1).isoformat(), "a", 180, 280), + (date_bucket(2024, 4, 1).isoformat(), "a", 210, 390), + (date_bucket(2024, 1, 1).isoformat(), "b", 10, 10), + (date_bucket(2024, 3, 1).isoformat(), "b", 30, 40), + (date_bucket(2024, 4, 1).isoformat(), "b", 50, 80), ], ) @@ -221,8 +222,8 @@ def test_policy_survives_temporal_child_queries(layer_for): }, ["day__month", "revenue", "rolling_revenue", "month_change"], [ - ("2024-01-01", 100, 100, None), - ("2024-03-01", 180, 280, None), - ("2024-04-01", 210, 390, 30), + (date_bucket(2024, 1, 1).isoformat(), 100, 100, None), + (date_bucket(2024, 3, 1).isoformat(), 180, 280, None), + (date_bucket(2024, 4, 1).isoformat(), 210, 390, 30), ], ) diff --git a/tests/semantic_conformance/test_filtered_count_family.py b/tests/semantic_conformance/test_filtered_count_family.py index a3f6d8b2d..100f4fe15 100644 --- a/tests/semantic_conformance/test_filtered_count_family.py +++ b/tests/semantic_conformance/test_filtered_count_family.py @@ -7,6 +7,7 @@ from sidemantic import Dimension, Metric, Model, Relationship, SecurityPolicy, SemanticLayer from sidemantic.core.semantic_layer import SecurityError from sidemantic.semantic_handoff import graph_to_semantic_input +from tests.duckdb_compat import date_bucket @pytest.fixture(params=["python", "rust"]) @@ -186,7 +187,7 @@ def test_count_family_cross_source_counts_restore_absent_zero(counts, restricted ) assert result(counts, metrics=["combined"], dimensions=["regions.region"], order_by=["regions.region"]) == ( ["region", "combined"], - [("a", 12), ("b", 20), (None, None)] if restricted else [("a", 13), ("b", 21), ("c", 30), (None, None)], + [(None, None), ("a", 12), ("b", 20)] if restricted else [(None, None), ("a", 13), ("b", 21), ("c", 30)], ) @@ -251,8 +252,6 @@ def test_owned_count_generator_sees_live_graph_changes(counts): @pytest.mark.parametrize("counts", ["graph"], indirect=True) @pytest.mark.parametrize("name,expected", [("star", [2, 2, 3]), ("one", [2, 2, 3]), ("nulls", [0, 0, 0])]) def test_owned_count_as_cumulative_base_preserves_public_output(counts, name, expected): - from datetime import date - layer, refs = counts layer.adapter.execute( "alter table count_family_orders add column day date; update count_family_orders set day = case when id in (1,2,4,5) then date '2024-01-01' when id in (3,7,8) then date '2024-01-02' else date '2024-01-03' end" @@ -262,7 +261,7 @@ def test_owned_count_as_cumulative_base_preserves_public_output(counts, name, ex columns, rows = result(counts, metrics=["running"], dimensions=["orders.day"], order_by=["orders.day"]) assert columns == ["day", name, "running"] daily = [2, 0, 1] if name != "nulls" else [0, 0, 0] - assert rows == [(date(2024, 1, index + 1), daily[index], expected[index]) for index in range(3)] + assert rows == [(date_bucket(2024, 1, index + 1), daily[index], expected[index]) for index in range(3)] @pytest.mark.parametrize("expression", ["COUNT(*)", "COUNT(1)", "COUNT(NULL)"]) diff --git a/tests/semantic_conformance/test_generated_differential.py b/tests/semantic_conformance/test_generated_differential.py new file mode 100644 index 000000000..715a3ce51 --- /dev/null +++ b/tests/semantic_conformance/test_generated_differential.py @@ -0,0 +1,179 @@ +"""Seeded differential campaigns and replay of minimized JSON fixtures. + +Configuration is environment-scoped to this module; no global pytest options +or engine defaults are changed. See differential/README.md for volume runs. +""" + +import hashlib +import json +import os +from collections import Counter +from pathlib import Path +from time import perf_counter + +import pytest + +from tests.semantic_conformance.differential.generator import generate_case, population_cases +from tests.semantic_conformance.differential.harness import Case, DifferentialRunner, outcome_dict, runtime_provenance +from tests.semantic_conformance.differential.minimize import minimize + + +def positive_env(name, default, *, allow_zero=False): + value = int(os.environ.get(name, default)) + if value < (0 if allow_zero else 1): + raise ValueError(f"{name} must be {'nonnegative' if allow_zero else 'positive'}") + return value + + +@pytest.fixture +def runner(): + if os.environ.get("SIDEMANTIC_DIFFERENTIAL_REQUIRE_RUST", "0") == "1": + __import__("sidemantic_rs") + else: + pytest.importorskip("sidemantic_rs", reason="Differential execution requires the real Rust extension") + instance = DifferentialRunner() + yield instance + instance.close() + + +def test_seeded_differential_campaign(runner, tmp_path, record_property): + seed = int(os.environ.get("SIDEMANTIC_DIFFERENTIAL_SEED", "20261005")) + count = positive_env("SIDEMANTIC_DIFFERENTIAL_CASES", "52") + variants = positive_env("SIDEMANTIC_DIFFERENTIAL_DATA_VARIANTS", "1") + start = positive_env("SIDEMANTIC_DIFFERENTIAL_START", "0", allow_zero=True) + example_limit = positive_env("SIDEMANTIC_DIFFERENTIAL_EXAMPLES", "12", allow_zero=True) + reduction_budget = positive_env("SIDEMANTIC_DIFFERENTIAL_REDUCTIONS", "100", allow_zero=True) + output = Path(os.environ.get("SIDEMANTIC_DIFFERENTIAL_OUTPUT", str(tmp_path / "differential"))) + output.mkdir(parents=True, exist_ok=True) + provenance = runtime_provenance() + started = perf_counter() + classes, fingerprints, families, features = Counter(), Counter(), Counter(), Counter() + timing = Counter() + selections, execution_successes = Counter(), Counter() + compile_attempts, compile_successes, cache_hits = Counter(), Counter(), Counter() + compiler_inputs = set() + examples = [] + reduction_seconds = 0 + checked = 0 + + def report(): + return { + "runtime": provenance, + "seed": seed, + "start": start, + "requested": count * variants, + "requested_model_query_cases": count, + "data_variants_per_input": variants, + "unique_compiler_inputs": len(compiler_inputs), + "actual_compile_attempts": dict(compile_attempts), + "actual_successful_compilations": dict(compile_successes), + "compilation_cache_hits": dict(cache_hits), + "checked": checked, + "checked_populations": checked, + "passed": checked - sum(classes.values()), + "failures": dict(classes), + "fingerprints": dict(fingerprints), + "families": dict(families), + "features": dict(features), + "timing_seconds": dict(timing), + "reduction_seconds": reduction_seconds, + "engine_selections": dict(selections), + "successful_executions": dict(execution_successes), + "elapsed_seconds": perf_counter() - started, + "populations_per_second_excluding_reduction": checked + / max(1e-9, perf_counter() - started - reduction_seconds), + "examples": examples, + } + + def cases(): + for index in range(start, start + count): + yield from population_cases(generate_case(seed, index), variants) + + try: + for case in cases(): + if case.data_variant == 0: + compiler_inputs.add(hashlib.sha256(runner.compilation_key(case).encode()).hexdigest()) + outcome = runner.evaluate(case, reuse_compilation=variants > 1) + checked += 1 + families[case.family] += 1 + features.update(case.features) + for engine in ["python", "rust"]: + result = getattr(outcome, engine) + if result: + timing[f"{engine}_compile"] += result.compile_seconds + timing[f"{engine}_execute"] += result.execute_seconds + if result.compilation_reused: + cache_hits[engine] += 1 + else: + compile_attempts[engine] += 1 + if result.selection and not result.compilation_reused: + selections[f"{engine}:{result.selection['engine']}"] += 1 + if result.stage not in {"compile", "selection"}: + compile_successes[engine] += 1 + if result.stage == "complete": + execution_successes[engine] += 1 + if outcome.failure_class: + classes[outcome.failure_class] += 1 + fingerprint = outcome.fingerprint(case) + fingerprints[fingerprint] += 1 + if fingerprints[fingerprint] == 1 and len(examples) < example_limit: + prefix = f"{seed}-{case.index}-v{case.data_variant}-{fingerprint}" + case.write(output / f"{prefix}.original.json") + original_outcome = outcome_dict(outcome) + (output / f"{prefix}.evidence.json").write_text( + json.dumps({"original": original_outcome, "reduction_pending": True}, indent=2) + "\n" + ) + (output / "report.json").write_text(json.dumps(report(), indent=2) + "\n") + reduction = None + if outcome.failure_class != "invalid_case" and reduction_budget: + reduction_started = perf_counter() + reduction = minimize(case, runner.evaluate, max_attempts=reduction_budget) + reduction_seconds += perf_counter() - reduction_started + reduction.case.write(output / f"{prefix}.case.json") + else: + case.write(output / f"{prefix}.case.json") + evidence = { + "original": original_outcome, + "minimized": outcome_dict(reduction.outcome) if reduction else None, + "attempts": reduction.attempts if reduction else 0, + "accepted": reduction.accepted if reduction else 0, + "budget_exhausted": reduction.exhausted if reduction else False, + } + (output / f"{prefix}.evidence.json").write_text(json.dumps(evidence, indent=2) + "\n") + examples.append( + {"fingerprint": fingerprint, "class": outcome.failure_class, "fixture": f"{prefix}.case.json"} + ) + # Checkpoint long runs so interruption retains useful accounting. + if checked % 100 == 0: + (output / "report.json").write_text(json.dumps(report(), indent=2) + "\n") + finally: + result = report() + (output / "report.json").write_text(json.dumps(result, indent=2) + "\n") + record_property("differential_report", str(output / "report.json")) + record_property("differential_cases", checked) + assert not classes, ( + f"Differential failures: {dict(classes)}; {len(fingerprints)} fingerprints; evidence: {output / 'report.json'}" + ) + + +def replay_paths(): + supplied = os.environ.get("SIDEMANTIC_DIFFERENTIAL_REPLAY") + if supplied: + path = Path(supplied) + return sorted(path.glob("*.case.json")) if path.is_dir() else [path] + return sorted((Path(__file__).parent / "differential" / "fixtures").glob("*.case.json")) + + +REPLAY_PATHS = replay_paths() +if REPLAY_PATHS: + + @pytest.mark.parametrize("path", REPLAY_PATHS, ids=lambda path: path.name) + def test_replay_differential_fixture(runner, path): + case = Case.read(path) + outcome = runner.evaluate(case) + assert outcome.failure_class is None, json.dumps(outcome_dict(outcome), indent=2) + +elif os.environ.get("SIDEMANTIC_DIFFERENTIAL_REPLAY"): + + def test_replay_path_contains_fixtures(): + pytest.fail("SIDEMANTIC_DIFFERENTIAL_REPLAY did not contain any *.case.json fixtures") diff --git a/tests/semantic_conformance/test_graph_population_ownership.py b/tests/semantic_conformance/test_graph_population_ownership.py new file mode 100644 index 000000000..90b5854cf --- /dev/null +++ b/tests/semantic_conformance/test_graph_population_ownership.py @@ -0,0 +1,210 @@ +"""Graph-level population metrics infer a unique declared entity source.""" + +from datetime import date + +import pytest + +from sidemantic import Dimension, Metric, Model, SecurityPolicy, SemanticLayer +from sidemantic.core.semantic_graph import SemanticGraph +from sidemantic.core.semantic_layer import SecurityError +from sidemantic.rust_bridge import compile_semantic_input, rewrite_semantic_input +from sidemantic.semantic_handoff import graph_to_semantic_input + + +@pytest.fixture(params=["python", "rust"]) +def layer(request): + if request.param == "rust": + pytest.importorskip("sidemantic_rs") + layer = SemanticLayer(engine=request.param, fallback=False, auto_register=False) + layer.add_model( + Model( + name="events", + table="events", + primary_key="id", + dimensions=[ + Dimension(name="user_id", type="categorical"), + Dimension(name="event_type", type="categorical"), + Dimension(name="day", type="time", granularity="day"), + ], + security=SecurityPolicy(row_filters=["tenant = {{ user.tenant }}"]), + ) + ) + # Inference must use the entity declaration, not a one-model shortcut. + layer.add_model(Model(name="unrelated", table="must_not_read", primary_key="id")) + layer.adapter.execute(""" + create table events(id integer, user_id integer, event_type varchar, day date, tenant integer); + insert into events values + (1,1,'signup','2024-01-01',1), (2,1,'purchase','2024-01-02',1), + (3,2,'signup','2024-01-01',1), (4,2,'browse','2024-01-02',1), + (5,3,'signup','2024-01-01',1), + (6,9,'signup','2024-01-01',2), (7,9,'purchase','2024-01-02',2); + """) + try: + yield layer + finally: + layer.adapter.close() + + +def population_metric(kind): + options = { + "cohort": { + "agg": "count", + "inner_metrics": [{"name": "events_seen", "agg": "count_distinct", "sql": "event_type"}], + "having": "events_seen >= 2", + }, + "conversion": {"base_event": "signup", "conversion_event": "purchase", "conversion_window": "7 days"}, + "retention": { + "cohort_event": "event_type = 'signup'", + "activity_event": "true", + "periods": 2, + "retention_granularity": "day", + }, + } + return Metric(name="population", type=kind, entity="user_id", **options[kind]) + + +@pytest.mark.parametrize("entrypoint", ["compile", "rewrite"]) +@pytest.mark.parametrize("prefix", ["analytics", "events"]) +@pytest.mark.parametrize("reference_location", ["select", "filter", "order"]) +def test_native_dotted_graph_population_visibility(entrypoint, prefix, reference_location): + pytest.importorskip("sidemantic_rs") + graph = SemanticGraph() + graph.add_model(Model(name="events", table="events", dimensions=[Dimension(name="user_id", type="categorical")])) + graph.add_model(Model(name="analytics", table="must_not_read")) + hidden = population_metric("cohort") + hidden.name = f"{prefix}.population" + hidden.public = False + graph.add_metric(hidden) + visible = population_metric("cohort") + visible.name = "visible" + graph.add_metric(visible) + query = {"metrics": [hidden.name if reference_location == "select" else visible.name], "enforce_visibility": True} + sql = f'select "{query["metrics"][0]}" from metrics' + if reference_location == "filter": + query["filters"] = [f"{hidden.name} > 0"] + sql += f' where "{hidden.name}" > 0' + elif reference_location == "order": + query["order_by"] = [hidden.name] + sql += f' order by "{hidden.name}"' + with pytest.raises(SecurityError, match="not public"): + if entrypoint == "compile": + compile_semantic_input(graph, query) + else: + rewrite_semantic_input(graph, sql, enforce_visibility=True) + + +@pytest.mark.parametrize("kind", ["cohort", "conversion", "retention"]) +@pytest.mark.parametrize("ownership", ["inferred", "explicit"]) +def test_graph_population_metric_infers_unique_entity_and_preserves_policy(layer, kind, ownership): + if ownership == "explicit": + layer.graph.models["unrelated"].dimensions.append(Dimension(name="user_id", type="categorical")) + layer.graph.add_metric(population_metric(kind), model_name="events" if ownership == "explicit" else None) + before = graph_to_semantic_input(layer.graph) + result = layer.query(metrics=["population"], user_attributes={"tenant": 1}) + columns = [column[0] for column in result.description] + rows = result.fetchall() + assert graph_to_semantic_input(layer.graph) == before + if layer.engine == "rust": + assert layer.last_engine_selection["engine"] == "rust" + if kind == "cohort": + assert columns == ["population"] + assert rows == [(2,)] + elif kind == "conversion": + assert dict(zip(columns, rows[0]))["population"] == pytest.approx(1 / 3) + assert len(rows) == 1 + else: + assert rows == [(date(2024, 1, 1), 0, 3, 3, 100.0), (date(2024, 1, 1), 1, 2, 3, 66.7)] + + +@pytest.mark.parametrize("kind", ["cohort", "conversion", "retention"]) +def test_graph_population_metric_rejects_ambiguous_entity_sources(layer, kind): + layer.graph.models["unrelated"].dimensions.append(Dimension(name="user_id", type="categorical")) + layer.graph.add_metric(population_metric(kind)) + with pytest.raises(ValueError, match="[Aa]mbiguous"): + layer.compile(metrics=["population"], user_attributes={"tenant": 1}) + + +@pytest.mark.parametrize("kind", ["cohort", "conversion", "retention"]) +@pytest.mark.parametrize("prefix", ["analytics", "events"]) +def test_dotted_graph_population_identity_preserves_source_policy(layer, kind, prefix): + # The graph identity also wins when it shadows a real model-local metric. + layer.graph.models["events"].metrics.append(Metric(name="population", agg="count")) + metric = population_metric(kind) + metric.name = f"{prefix}.population" + layer.graph.add_metric(metric) + result = layer.query(metrics=[metric.name], user_attributes={"tenant": 1}) + if kind == "cohort": + assert result.fetchall() == [(2,)] + elif kind == "conversion": + assert result.fetchall() == [(pytest.approx(1 / 3),)] + else: + assert result.fetchall() == [(date(2024, 1, 1), 0, 3, 3, 100.0), (date(2024, 1, 1), 1, 2, 3, 66.7)] + if kind != "retention": + assert [column[0] for column in result.description] == [metric.name] + + +def test_local_dependency_precedes_global_name_during_policy_discovery(layer): + # Bare dependencies resolve locally before graph names; + # policy discovery must follow that same binding rather than visit a shadow. + layer.graph.models["events"].metrics.extend( + [Metric(name="total", agg="sum", sql="id"), Metric(name="double_total", type="derived", sql="total * 2")] + ) + layer.graph.models["unrelated"].security = SecurityPolicy(access=False) + layer.graph.add_metric(Metric(name="total", agg="sum", sql="unrelated.id")) + assert layer.query(metrics=["events.double_total"], user_attributes={"tenant": 1}).fetchall() == [(30,)] + + +@pytest.mark.parametrize("kind", ["cohort", "conversion"]) +def test_dotted_graph_population_order_does_not_add_prefix_model_to_policy_population(layer, kind): + layer.graph.models["unrelated"].security = SecurityPolicy(access=False) + metric = population_metric(kind) + metric.name = "unrelated.population" + layer.graph.add_metric(metric) + result = layer.query(metrics=[metric.name], order_by=[metric.name], user_attributes={"tenant": 1}) + assert [column[0] for column in result.description] == [metric.name] + assert result.fetchall() == ([(2,)] if kind == "cohort" else [(pytest.approx(1 / 3),)]) + if layer.engine == "rust": + assert layer.last_engine_selection == {"engine": "rust", "reason": None} + + +def test_dotted_graph_multistep_conversion_preserves_identity_and_policy(layer): + layer.graph.add_metric( + Metric( + name="analytics.funnel", + type="conversion", + entity="user_id", + steps=["event_type = 'signup'", "event_type = 'purchase'"], + ) + ) + result = layer.query(metrics=["analytics.funnel"], user_attributes={"tenant": 1}) + assert [column[0] for column in result.description] == [ + "total_entities", + "step_1_count", + "step_2_count", + "analytics.funnel", + ] + assert result.fetchall() == [(3, 3, 1, 1)] + + +def test_inferred_graph_cohort_approximate_count_uses_authorized_entities(layer): + metric = population_metric("cohort") + metric.agg = "approx_count_distinct" + metric.sql = "user_id" + layer.graph.add_metric(metric) + assert layer.query(metrics=["population"], user_attributes={"tenant": 1}).fetchall() == [(2,)] + + +@pytest.mark.parametrize("source_state", ["missing", "ambiguous"]) +def test_graph_cohort_approximate_count_requires_unambiguous_entity_source(layer, source_state): + metric = population_metric("cohort") + metric.agg = "approx_count_distinct" + metric.sql = "user_id" + if source_state == "missing": + metric.entity = "missing_entity" + error = "metric.cohort_owner" if layer.engine == "rust" else "No model found" + else: + layer.graph.models["unrelated"].dimensions.append(Dimension(name="user_id", type="categorical")) + error = "[Aa]mbiguous" + layer.graph.add_metric(metric) + with pytest.raises(ValueError, match=error): + layer.compile(metrics=["population"], user_attributes={"tenant": 1}) diff --git a/tests/semantic_conformance/test_multistep_conversion_parity.py b/tests/semantic_conformance/test_multistep_conversion_parity.py index a56b3c9fe..0c611188e 100644 --- a/tests/semantic_conformance/test_multistep_conversion_parity.py +++ b/tests/semantic_conformance/test_multistep_conversion_parity.py @@ -1,11 +1,10 @@ """Sequential funnel populations from independently specified synthetic events.""" -from datetime import date - import pytest from sidemantic import Dimension, Metric, Model, SecurityPolicy, SemanticLayer from sidemantic.core.semantic_layer import SecurityError +from tests.duckdb_compat import date_bucket @pytest.fixture(params=["python", "rust"]) @@ -150,7 +149,7 @@ def test_step_literal_is_not_rewritten_as_model_reference(layer): def test_time_bucket_belongs_to_first_step(layer): assert result(layer, dimensions=["events.occurred__month"], order_by=["events.occurred__month"]) == ( ["occurred__month", *COLUMNS], - [(date(2024, 1, 1), 5, 5, 3, 2, 2), (None, 1, 1, 0, 0, 0)], + [(date_bucket(2024, 1, 1), 5, 5, 3, 2, 2), (None, 1, 1, 0, 0, 0)], ) diff --git a/tests/semantic_conformance/test_reference.py b/tests/semantic_conformance/test_reference.py index 95e4211e4..402f0712e 100644 --- a/tests/semantic_conformance/test_reference.py +++ b/tests/semantic_conformance/test_reference.py @@ -14,6 +14,7 @@ from sidemantic.core.semantic_layer import SecurityError from sidemantic.semantic_handoff import UnsupportedSemanticFeaturesError, graph_to_semantic_input from sidemantic.validation import QueryValidationError +from tests.duckdb_compat import date_bucket FIXTURES = Path(__file__).parent / "fixtures" CASES = yaml.safe_load((FIXTURES / "cases.yml").read_text()) @@ -64,6 +65,9 @@ def test_compiler_results(case, engine): sql = layer.compile(**case["query"]) result = layer.adapter.execute(sql) assert [column[0] for column in result.description] == case["columns"] - assert [[normalize(value) for value in row] for row in result.fetchall()] == case["rows"] + expected = case["rows"] + if case["name"] == "sparse_month_comparison": + expected = [[date_bucket(*map(int, row[0].split("-"))).isoformat(), *row[1:]] for row in expected] + assert [[normalize(value) for value in row] for row in result.fetchall()] == expected finally: layer.adapter.close() diff --git a/tests/semantic_conformance/test_rollup_routing.py b/tests/semantic_conformance/test_rollup_routing.py index 76ac2fea5..7fe5c7696 100644 --- a/tests/semantic_conformance/test_rollup_routing.py +++ b/tests/semantic_conformance/test_rollup_routing.py @@ -1,12 +1,13 @@ """Actual rollup builds and routed execution with independent population contracts.""" -from datetime import date, datetime +from datetime import datetime import pytest from sidemantic import Dimension, Metric, Model, PreAggregation, Relationship, SecurityPolicy, SemanticLayer from sidemantic.core.semantic_layer import SecurityError from sidemantic.rust_bridge import generate_preaggregation_materialization_sql_with_rust +from tests.duckdb_compat import date_bucket @pytest.fixture @@ -100,7 +101,7 @@ def assert_result(layer, query, rows, *, routed): "dimensions": ["orders.created__month"], "order_by": ["orders.created__month"], }, - [(date(2026, 1, 1), 970), (date(2026, 2, 1), None)], + [(date_bucket(2026, 1, 1), 970), (date_bucket(2026, 2, 1), None)], ), ({"metrics": ["orders.revenue"], "filters": ["orders.status in ('paid')"]}, [(930,)]), ], @@ -217,7 +218,7 @@ def test_week_rollup_cannot_serve_calendar_month(layer): assert_result( layer, {"metrics": ["orders.revenue"], "dimensions": ["orders.created__month"], "order_by": ["orders.created__month"]}, - [(date(2026, 1, 1), 970), (date(2026, 2, 1), None)], + [(date_bucket(2026, 1, 1), 970), (date_bucket(2026, 2, 1), None)], routed=False, ) diff --git a/tests/semantic_conformance/test_selected_table_calculations.py b/tests/semantic_conformance/test_selected_table_calculations.py index 86706d8a9..7799972ce 100644 --- a/tests/semantic_conformance/test_selected_table_calculations.py +++ b/tests/semantic_conformance/test_selected_table_calculations.py @@ -77,7 +77,6 @@ def test_postprocess_keeps_paginated_calculations(layer): assert_rows(actual, layer.query(**query).fetchall()) -@pytest.mark.parametrize("layer", ["python"], indirect=True) @pytest.mark.parametrize("alias", ["gross", "Gross Revenue"]) @pytest.mark.parametrize("qualified", [True, False]) def test_sequential_calculations_order_by_custom_output_aliases(layer, alias, qualified): diff --git a/tests/semantic_conformance/test_sibling_fanout_parity.py b/tests/semantic_conformance/test_sibling_fanout_parity.py new file mode 100644 index 000000000..3b870d4dc --- /dev/null +++ b/tests/semantic_conformance/test_sibling_fanout_parity.py @@ -0,0 +1,164 @@ +"""Measures retain their source identity across sibling one-to-many joins.""" + +import pytest + +from sidemantic import Dimension, Metric, Model, Relationship, SemanticLayer + + +@pytest.fixture(params=["python", "rust"]) +def layer(request): + if request.param == "rust": + pytest.importorskip("sidemantic_rs", reason="Sibling fanout acceptance requires the real Rust extension") + layer = SemanticLayer(engine=request.param, fallback=False, auto_register=False) + layer.add_model( + Model( + name="facts", + table="sibling_facts", + primary_key="id", + metrics=[Metric(name="total", agg="sum", sql="amount")], + relationships=[ + Relationship(name="items", type="one_to_many", foreign_key="fact_id"), + Relationship(name="refunds", type="one_to_many", foreign_key="fact_id"), + ], + ) + ) + layer.add_model( + Model( + name="items", + table="sibling_items", + primary_key="id", + metrics=[ + Metric(name="items_value", agg="sum", sql="value"), + Metric(name="average", agg="avg", sql="value"), + Metric(name="values", agg="count", sql="value"), + Metric(name="rows", agg="count"), + ], + ) + ) + layer.add_model( + Model( + name="refunds", + table="sibling_refunds", + primary_key="id", + dimensions=[Dimension(name="label", type="categorical")], + relationships=[Relationship(name="events", type="one_to_many", foreign_key="refund_id")], + ) + ) + layer.add_model( + Model( + name="events", + table="sibling_events", + primary_key="id", + dimensions=[Dimension(name="tag", type="categorical")], + ) + ) + layer.adapter.execute(""" + create table sibling_facts(id integer, amount integer); + create table sibling_items(id integer, fact_id integer, value integer); + create table sibling_refunds(id integer, fact_id integer, label varchar); + create table sibling_events(id integer, refund_id integer, tag varchar); + """) + try: + yield layer + finally: + layer.adapter.close() + + +def execute(layer, **query): + sql = layer.compile(**query) + assert layer.last_engine_selection["engine"] == layer.engine + return layer.adapter.execute(sql).fetchall() + + +def test_minimized_generated_sibling_fanout(layer): + """Seed 20261005, case 8: one item worth 3 was incorrectly summed to 6.""" + layer.adapter.execute(""" + insert into sibling_facts values (1, 1); + insert into sibling_items values (101, 1, 3); + insert into sibling_refunds values (9, 1, 'x'), (11, 1, 'x'); + """) + expected = layer.adapter.execute(""" + select refund_groups.label, sum(items.value) + from (select distinct fact_id, label from sibling_refunds) as refund_groups + join sibling_facts as facts on refund_groups.fact_id = facts.id + join sibling_items as items on facts.id = items.fact_id + group by refund_groups.label + """).fetchall() + assert expected == [("x", 3)] + assert execute(layer, metrics=["items.items_value"], dimensions=["refunds.label"]) == expected + + +@pytest.mark.parametrize("include_parent", [False, True]) +def test_sibling_groups_preserve_each_item_and_null_population(layer, include_parent): + layer.adapter.execute(""" + insert into sibling_facts values (1, 10), (2, 20), (3, 30), (4, 40); + insert into sibling_items values + (101, 1, 3), (102, 1, 3), (103, 1, null), + (201, 2, 9), (202, 2, -2), (301, 3, null); + insert into sibling_refunds values + (1, 1, 'x'), (2, 1, 'x'), (3, 1, 'y'), + (4, 2, 'x'), (5, 2, 'x'), (6, 2, 'x'), + (7, 3, 'z'), (8, 3, 'z'), + (9, 4, 'empty'), (10, 4, 'empty'); + """) + # Deduplicate group membership before joining measure rows. Equal values + # from different item identities still contribute separately. + expected = layer.adapter.execute(""" + with refund_groups as ( + select distinct fact_id, label from sibling_refunds + ) + select refund_groups.label, sum(items.value), avg(items.value), count(items.value), count(items.id) + from refund_groups + left join sibling_facts as facts on refund_groups.fact_id = facts.id + left join sibling_items as items on facts.id = items.fact_id + group by refund_groups.label + order by refund_groups.label + """).fetchall() + assert expected == [ + ("empty", None, None, 0, 0), + ("x", 13, 3.25, 4, 5), + ("y", 6, 3.0, 2, 3), + ("z", None, None, 0, 1), + ] + metrics = ["items.items_value", "items.average", "items.values", "items.rows"] + if include_parent: + metrics.append("facts.total") + expected = [(*row, total) for row, total in zip(expected, [40, 30, 10, 30], strict=True)] + assert execute(layer, metrics=metrics, dimensions=["refunds.label"], order_by=["refunds.label"]) == expected + + +def test_empty_sibling_population_has_no_groups(layer): + layer.adapter.execute(""" + insert into sibling_facts values (1, 1); + insert into sibling_items values (101, 1, 3); + """) + assert execute(layer, metrics=["items.items_value", "items.rows"], dimensions=["refunds.label"]) == [] + + +def test_source_identity_survives_three_edge_fanout_path(layer): + """Items -> facts -> refunds -> events must retain each item's grain.""" + layer.adapter.execute(""" + insert into sibling_facts values (1, 1); + insert into sibling_items values (101, 1, 3), (102, 1, 7); + insert into sibling_refunds values (9, 1, 'unused'), (11, 1, 'unused'); + insert into sibling_events values + (1, 9, 'x'), (2, 9, 'x'), (3, 11, 'x'), (4, 11, 'y'); + """) + expected = layer.adapter.execute(""" + with fact_tags as ( + select distinct refunds.fact_id, events.tag + from sibling_refunds as refunds + join sibling_events as events on refunds.id = events.refund_id + ) + select fact_tags.tag, sum(items.value), count(items.id) + from fact_tags + join sibling_facts as facts on fact_tags.fact_id = facts.id + join sibling_items as items on facts.id = items.fact_id + group by fact_tags.tag + order by fact_tags.tag + """).fetchall() + assert expected == [("x", 10, 2), ("y", 10, 2)] + assert ( + execute(layer, metrics=["items.items_value", "items.rows"], dimensions=["events.tag"], order_by=["events.tag"]) + == expected + ) diff --git a/tests/semantic_conformance/test_source_null_ordering.py b/tests/semantic_conformance/test_source_null_ordering.py new file mode 100644 index 000000000..4b79c1dd2 --- /dev/null +++ b/tests/semantic_conformance/test_source_null_ordering.py @@ -0,0 +1,113 @@ +"""Source reconciliation preserves public NULL ordering before pagination.""" + +from pathlib import Path + +import pytest + +from sidemantic import Dimension, Metric, Model, Relationship, SemanticLayer + + +@pytest.fixture(params=["python", "rust"]) +def layer(request): + if request.param == "rust": + pytest.importorskip("sidemantic_rs", reason="Requires real native extension") + layer = SemanticLayer(engine=request.param, fallback=False, auto_register=False) + layer.add_model( + Model( + name="facts", + table="facts", + primary_key="id", + dimensions=[Dimension(name="label", type="categorical")], + metrics=[Metric(name="total", agg="sum", sql="amount")], + relationships=[Relationship(name="items", type="one_to_many", foreign_key="fact_id")], + ) + ) + layer.add_model( + Model( + name="items", + table="items", + primary_key="id", + dimensions=[Dimension(name="label", type="categorical")], + metrics=[Metric(name="value", agg="sum", sql="amount")], + ) + ) + layer.adapter.execute("create table facts(id integer, label varchar, amount integer)") + layer.adapter.execute("insert into facts values (1, NULL, 10), (2, 'a', NULL), (3, 'b', 30)") + layer.adapter.execute("create table items(id integer, fact_id integer, label varchar, amount integer)") + layer.adapter.execute( + "insert into items values (1, 1, NULL, 40), (2, 1, NULL, 60), (3, 2, 'a', 200), (4, 3, 'b', 300)" + ) + yield layer + layer.adapter.close() + + +@pytest.mark.parametrize("plan", ["ordinary", "fanout", "multi_source"]) +@pytest.mark.parametrize("field", ["dimension", "metric"]) +@pytest.mark.parametrize("suffix", ["", " ASC", " DESC", " ASC NULLS LAST", " DESC NULLS FIRST"]) +@pytest.mark.parametrize("page", [False, True]) +def test_source_ordering_matches_independent_rows(layer, plan, field, suffix, page): + dimension = "facts.label" if plan == "ordinary" else "items.label" + metrics = ["facts.total", "items.value"] if plan == "multi_source" else ["facts.total"] + rows = [(None, 10, 100), ("a", None, 200), ("b", 30, 300)] + index = 0 if field == "dimension" else 1 + descending = suffix.strip().startswith("DESC") + nulls_first = suffix.endswith("NULLS FIRST") or ("NULLS" not in suffix and not descending) + nonnull = sorted((row for row in rows if row[index] is not None), key=lambda row: row[index], reverse=descending) + null = [row for row in rows if row[index] is None] + expected = null + nonnull if nulls_first else nonnull + null + if plan != "multi_source": + expected = [row[:2] for row in expected] + if page: + expected = expected[1:2] + result = layer.query( + metrics=metrics, + dimensions=[dimension], + order_by=[(dimension if field == "dimension" else "facts.total") + suffix], + **({"limit": 1, "offset": 1} if page else {}), + ) + assert [column[0] for column in result.description] == [ + "label", + "total", + *(["value"] if plan == "multi_source" else []), + ] + assert result.fetchall() == expected + + +def test_minimized_nullable_fanout_case(): + from tests.semantic_conformance.differential.harness import Case, DifferentialRunner + + pytest.importorskip("sidemantic_rs", reason="Requires real native extension") + case = Case.read(Path(__file__).parent / "fixtures" / "source_null_ordering.json") + runner = DifferentialRunner() + try: + outcome = runner.evaluate(case) + finally: + runner.close() + assert outcome.failure_class is None, outcome + for result in [outcome.python, outcome.rust]: + assert result.columns == ["status", "label", "rows"] + assert result.rows == [("paid", None, 1), ("paid", "x", 1)] + + +@pytest.mark.parametrize("dialect", ["tsql", "mysql"]) +@pytest.mark.parametrize("suffix", [" ASC", " DESC", " ASC NULLS LAST", " DESC NULLS FIRST"]) +def test_multi_source_ordering_renders_target_dialect(layer, dialect, suffix): + import sqlglot + + sql = layer.compile( + metrics=["facts.total", "items.value"], + dimensions=["items.label"], + order_by=["items.label" + suffix], + dialect=dialect, + ) + # Check the newly emitted clause independently of unrelated source-join + # dialect capabilities. Neither SQL Server nor MySQL accepts NULLS syntax. + order = sql.rsplit("ORDER BY", 1)[1].split("-- sidemantic:", 1)[0].strip() + assert "NULLS FIRST" not in order and "NULLS LAST" not in order + probe = sqlglot.parse_one("select label from facts order by " + order, read=dialect) + actual = layer.adapter.execute(probe.sql(dialect="duckdb")).fetchall() + descending = suffix.strip().startswith("DESC") + nulls_first = suffix.endswith("NULLS FIRST") or ("NULLS" not in suffix and not descending) + expected = [("b",), ("a",)] if descending else [("a",), ("b",)] + expected.insert(0 if nulls_first else len(expected), (None,)) + assert actual == expected diff --git a/tests/semantic_conformance/test_special_population.py b/tests/semantic_conformance/test_special_population.py index ebfb07ffc..7f5334a3b 100644 --- a/tests/semantic_conformance/test_special_population.py +++ b/tests/semantic_conformance/test_special_population.py @@ -1,10 +1,9 @@ """Special aggregate routes preserve Explore populations and computed join keys.""" -from datetime import date - import pytest from sidemantic import Dimension, Explore, Metric, Model, Relationship, SecurityPolicy, SemanticLayer +from tests.duckdb_compat import date_bucket @pytest.fixture(params=["python", "rust"]) @@ -86,7 +85,7 @@ def test_query_row_filter_restricts_every_independent_leaf(layer): def test_cumulative_computed_population_excludes_orphans_and_hidden_rows(layer): result = rows(layer, metrics=["events.running"], dimensions=["events.day"], order_by=["events.day"]) - assert result == [(date(2024, 1, 1), 3, 3), (date(2024, 1, 2), 12, 15), (None, None, 15)] + assert result == [(date_bucket(2024, 1, 1), 3, 3), (date_bucket(2024, 1, 2), 12, 15), (None, None, 15)] def test_snapshot_computed_population_and_null_unmatched_group(layer): diff --git a/tests/semantic_conformance/test_time_key_projection.py b/tests/semantic_conformance/test_time_key_projection.py index 57da708af..ab72494cf 100644 --- a/tests/semantic_conformance/test_time_key_projection.py +++ b/tests/semantic_conformance/test_time_key_projection.py @@ -1,10 +1,9 @@ """Time-key display buckets do not replace row identity for joins or fanout.""" -from datetime import date - import pytest from sidemantic import Dimension, Metric, Model, Relationship, SemanticLayer +from tests.duckdb_compat import date_bucket @pytest.fixture(params=["python", "rust"]) @@ -46,9 +45,9 @@ def execute(layer, **query): @pytest.mark.parametrize("dimension", ["events.event_time", "events.event_time__day"]) @pytest.mark.parametrize("timezone", [None, "America/Los_Angeles"]) def test_time_identity_projection_uses_requested_or_default_grain(layer, dimension, timezone): - first, second = (date(2026, 1, 1), date(2026, 1, 2)) + first, second = (date_bucket(2026, 1, 1), date_bucket(2026, 1, 2)) if timezone: - first, second = date(2025, 12, 31), date(2026, 1, 1) + first, second = date_bucket(2025, 12, 31), date_bucket(2026, 1, 1) columns, rows = execute( layer, metrics=["events.amount"], dimensions=[dimension], order_by=[dimension], timezone=timezone ) @@ -92,5 +91,5 @@ def test_time_identity_stays_unbucketed_for_join_and_fanout(layer): order_by=["events.event_time__day", "logs.category"], ) == ( ["event_time__day", "category", "amount", "people"], - [(date(2026, 1, 1), "x", 7, 2), (date(2026, 1, 2), "y", 8, 1)], + [(date_bucket(2026, 1, 1), "x", 7, 2), (date_bucket(2026, 1, 2), "y", 8, 1)], ) diff --git a/tests/semantic_conformance/test_window_metric_identity.py b/tests/semantic_conformance/test_window_metric_identity.py new file mode 100644 index 000000000..8ed025465 --- /dev/null +++ b/tests/semantic_conformance/test_window_metric_identity.py @@ -0,0 +1,36 @@ +"""Window binding respects exact graph identities beside model-local names.""" + +import pytest + +from sidemantic import Dimension, Metric, Model, SemanticLayer +from tests.duckdb_compat import date_bucket + + +@pytest.mark.parametrize("engine", ["python", "rust"]) +@pytest.mark.parametrize("expression", [False, True]) +def test_dotted_graph_window_shadows_local_metric(engine, expression): + layer = SemanticLayer(engine=engine, fallback=False, auto_register=False) + layer.add_model( + Model( + name="events", + table="identity_events", + primary_key="id", + dimensions=[Dimension(name="day", type="time", granularity="day")], + metrics=[ + Metric(name="total", agg="sum", sql="amount"), + Metric(name="running", agg="sum", sql="shadow"), + ], + ) + ) + controls = {"window_expression": "SUM(base.total)"} if expression else {"sql": "total"} + layer.graph.add_metric(Metric(name="events.running", type="cumulative", **controls), model_name="events") + try: + layer.adapter.execute("create table identity_events(id integer, day date, amount integer, shadow integer)") + layer.adapter.execute( + "insert into identity_events values (1, '2024-01-01', 10, 900), (2, '2024-01-02', 20, 800)" + ) + result = layer.query(metrics=["events.running"], dimensions=["events.day"], order_by=["events.day"]) + assert [column[0] for column in result.description] == ["day", "total", "events.running"] + assert result.fetchall() == [(date_bucket(2024, 1, 1), 10, 10), (date_bucket(2024, 1, 2), 20, 30)] + finally: + layer.adapter.close() diff --git a/tests/semantic_conformance/test_window_output_parity.py b/tests/semantic_conformance/test_window_output_parity.py index 2a621cea4..1cc3a3ba1 100644 --- a/tests/semantic_conformance/test_window_output_parity.py +++ b/tests/semantic_conformance/test_window_output_parity.py @@ -5,6 +5,7 @@ import pytest from sidemantic import Dimension, Metric, Model, SecurityPolicy, SemanticLayer +from tests.duckdb_compat import date_bucket @pytest.fixture(params=["python", "rust"]) @@ -50,10 +51,10 @@ def test_window_dimension_replaces_same_named_source_for_grouping_and_filters(la "dimensions": ["events.day"], "user_attributes": {"tenant": 1}, } - assert layer.query(**query).fetchall() == [(date(2024, 1, 1), 82)] + assert layer.query(**query).fetchall() == [(date_bucket(2024, 1, 1), 82)] for predicate in ["events.day > '2024-01-02'", "coalesce(events.day, '2024-01-01') > '2024-01-02'"]: assert layer.query(**query, filters=[predicate]).fetchall() == [] - assert layer.query(**query, filters=["events.day = '2024-01-01'"]).fetchall() == [(date(2024, 1, 1), 82)] + assert layer.query(**query, filters=["events.day = '2024-01-01'"]).fetchall() == [(date_bucket(2024, 1, 1), 82)] def test_graph_calculation_keeps_its_identity_beside_cumulative_metric(layer): @@ -68,9 +69,9 @@ def test_graph_calculation_keeps_its_identity_beside_cumulative_metric(layer): columns = [column[0] for column in cursor.description] records = [dict(zip(columns, row)) for row in cursor.fetchall()] assert [(record["day"], record["total"], record["running"]) for record in records] == [ - (date(2024, 1, 1), 15, 15), - (date(2024, 1, 3), 27, 42), - (date(2024, 1, 4), 40, 82), + (date_bucket(2024, 1, 1), 15, 15), + (date_bucket(2024, 1, 3), 27, 42), + (date_bucket(2024, 1, 4), 40, 82), ] diff --git a/tests/test_dependencies.py b/tests/test_dependencies.py index 5e644f17c..abfd34f54 100644 --- a/tests/test_dependencies.py +++ b/tests/test_dependencies.py @@ -1,7 +1,29 @@ """Test automatic dependency detection.""" +import pytest + from sidemantic.core.dependency_analyzer import extract_column_references from sidemantic.core.metric import Metric +from sidemantic.core.model import Model +from sidemantic.core.semantic_graph import SemanticGraph + + +@pytest.mark.parametrize( + "sql, context, expected", + [ + ("total * 2", "events", {"events.total"}), + ("total * 2", None, {"total"}), + ("other.total * 2", "events", {"other.total"}), + ("missing.total * 2", "events", {"total"}), + ], +) +def test_derived_dependency_context_precedes_global_shadow_only_for_bare_names(sql, context, expected): + graph = SemanticGraph() + for name in ["events", "other"]: + graph.add_model(Model(name=name, table=name, metrics=[Metric(name="total", agg="sum", sql="amount")])) + graph.add_metric(Metric(name="total", agg="sum", sql="other.amount")) + metric = Metric(name="double_total", type="derived", sql=sql) + assert metric.get_dependencies(graph, context) == expected def test_extract_column_references_simple(): diff --git a/tests/test_loaders.py b/tests/test_loaders.py index 434aac661..1252292e5 100644 --- a/tests/test_loaders.py +++ b/tests/test_loaders.py @@ -99,7 +99,7 @@ def test_directory_loader_does_not_infer_joins_over_malloy_role_alias(tmp_path): } """ ) - layer = SemanticLayer(auto_register=False, engine="python") + layer = SemanticLayer(auto_register=False) layer.adapter.execute("create table customers (id integer)") layer.adapter.execute("create table orders (id integer, customer_id integer)") diff --git a/tests/test_viz_browser.py b/tests/test_viz_browser.py index eab20646a..e2ff5c7b0 100644 --- a/tests/test_viz_browser.py +++ b/tests/test_viz_browser.py @@ -6,6 +6,7 @@ from playwright.sync_api import Browser, Page, expect, sync_playwright from sidemantic import DashboardDocument, Dimension, Metric, Model, SemanticLayer +from tests.duckdb_compat import date_bucket def _build_layer() -> SemanticLayer: @@ -57,7 +58,7 @@ def browser() -> Iterator[Browser]: @pytest.fixture def browser_page(browser: Browser) -> Iterator[tuple[Page, list[str]]]: - page = browser.new_page(viewport={"width": 1280, "height": 900}) + page = browser.new_page(viewport={"width": 1280, "height": 900}, timezone_id="America/Los_Angeles") errors: list[str] = [] page.on("pageerror", lambda error: errors.append(f"pageerror: {error}")) page.on( @@ -275,7 +276,12 @@ def handle_query(route, request): ) assert requests[-1]["filters"] == [ - {"type": "xRange", "field": "created_at__month", "min": "2024-01-01", "max": "2024-02-01"} + { + "type": "xRange", + "field": "created_at__month", + "min": date_bucket(2024, 1, 1).isoformat(), + "max": date_bucket(2024, 2, 1).isoformat(), + } ] assert requests[-1]["interaction_preaggregations"] is False assert page.evaluate("window.__SIDEMANTIC_CROSSFILTER__.totalRows") == 4 diff --git a/uv.lock b/uv.lock index 044ec4f97..7bcb01930 100644 --- a/uv.lock +++ b/uv.lock @@ -840,31 +840,38 @@ wheels = [ [[package]] name = "duckdb" -version = "1.3.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/47/24/a2e7fb78fba577641c286fe33185789ab1e1569ccdf4d142e005995991d2/duckdb-1.3.2.tar.gz", hash = "sha256:c658df8a1bc78704f702ad0d954d82a1edd4518d7a04f00027ec53e40f591ff5", size = 11627775, upload-time = "2025-07-08T10:41:14.444Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/38/16/4cde40c37dd1f48d2f9ffa63027e8b668391c5cc32cbb59f7ca8b1cec6e2/duckdb-1.3.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:e1872cf63aae28c3f1dc2e19b5e23940339fc39fb3425a06196c5d00a8d01040", size = 15520798, upload-time = "2025-07-08T10:40:13.867Z" }, - { url = "https://files.pythonhosted.org/packages/22/ca/9ca65db51868604007114a27cc7d44864d89328ad6a934668626618147ff/duckdb-1.3.2-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:db256c206056468ae6a9e931776bdf7debaffc58e19a0ff4fa9e7e1e82d38b3b", size = 32502242, upload-time = "2025-07-08T10:40:15.949Z" }, - { url = "https://files.pythonhosted.org/packages/9e/ca/7f7cf01dd7731d358632fb516521f2962070a627558fb6fc3137e594bbaa/duckdb-1.3.2-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:1d57df2149d6e4e0bd5198689316c5e2ceec7f6ac0a9ec11bc2b216502a57b34", size = 17091841, upload-time = "2025-07-08T10:40:18.539Z" }, - { url = "https://files.pythonhosted.org/packages/4c/7f/38e518b8f51299410dcad9f1e99f1c99f3592516581467a2da344d3b5951/duckdb-1.3.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:54f76c8b1e2a19dfe194027894209ce9ddb073fd9db69af729a524d2860e4680", size = 19158775, upload-time = "2025-07-08T10:40:20.804Z" }, - { url = "https://files.pythonhosted.org/packages/90/a3/41f3d42fddd9629846aac328eb295170e76782d8dfc5e58b3584b96fa296/duckdb-1.3.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:45bea70b3e93c6bf766ce2f80fc3876efa94c4ee4de72036417a7bd1e32142fe", size = 21093951, upload-time = "2025-07-08T10:40:22.686Z" }, - { url = "https://files.pythonhosted.org/packages/11/8e/c5444b6890ae7f00836fd0cd17799abbcc3066bbab32e90b04aa8a8a5087/duckdb-1.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:003f7d36f0d8a430cb0e00521f18b7d5ee49ec98aaa541914c6d0e008c306f1a", size = 22743891, upload-time = "2025-07-08T10:40:24.987Z" }, - { url = "https://files.pythonhosted.org/packages/87/a1/e240bd07671542ddf2084962e68a7d5c9b068d8da3f938e935af69441355/duckdb-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:0eb210cedf08b067fa90c666339688f1c874844a54708562282bc54b0189aac6", size = 11387047, upload-time = "2025-07-08T10:40:27.443Z" }, - { url = "https://files.pythonhosted.org/packages/6c/5d/77f15528857c2b186ebec07778dc199ccc04aafb69fb7b15227af4f19ac9/duckdb-1.3.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2455b1ffef4e3d3c7ef8b806977c0e3973c10ec85aa28f08c993ab7f2598e8dd", size = 15538413, upload-time = "2025-07-08T10:40:29.551Z" }, - { url = "https://files.pythonhosted.org/packages/78/67/7e4964f688b846676c813a4acc527cd3454be8a9cafa10f3a9aa78d0d165/duckdb-1.3.2-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:9d0ae509713da3461c000af27496d5413f839d26111d2a609242d9d17b37d464", size = 32535307, upload-time = "2025-07-08T10:40:31.632Z" }, - { url = "https://files.pythonhosted.org/packages/95/3d/2d7f8078194130dbf30b5ae154ce454bfc208c91aa5f3e802531a3e09bca/duckdb-1.3.2-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:72ca6143d23c0bf6426396400f01fcbe4785ad9ceec771bd9a4acc5b5ef9a075", size = 17110219, upload-time = "2025-07-08T10:40:34.072Z" }, - { url = "https://files.pythonhosted.org/packages/cd/05/36ff9000b9c6d2a68c1b248f133ee316fcac10c0ff817112cbf5214dbe91/duckdb-1.3.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b49a11afba36b98436db83770df10faa03ebded06514cb9b180b513d8be7f392", size = 19178569, upload-time = "2025-07-08T10:40:35.995Z" }, - { url = "https://files.pythonhosted.org/packages/ac/73/f85acbb3ac319a86abbf6b46103d58594d73529123377219980f11b388e9/duckdb-1.3.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:36abdfe0d1704fe09b08d233165f312dad7d7d0ecaaca5fb3bb869f4838a2d0b", size = 21129975, upload-time = "2025-07-08T10:40:38.3Z" }, - { url = "https://files.pythonhosted.org/packages/32/40/9aa3267f3631ae06b30fb1045a48628f4dba7beb2efb485c0282b4a73367/duckdb-1.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3380aae1c4f2af3f37b0bf223fabd62077dd0493c84ef441e69b45167188e7b6", size = 22781859, upload-time = "2025-07-08T10:40:41.691Z" }, - { url = "https://files.pythonhosted.org/packages/8c/8d/47bf95f6999b327cf4da677e150cfce802abf9057b61a93a1f91e89d748c/duckdb-1.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:11af73963ae174aafd90ea45fb0317f1b2e28a7f1d9902819d47c67cc957d49c", size = 11395337, upload-time = "2025-07-08T10:40:43.651Z" }, - { url = "https://files.pythonhosted.org/packages/f5/f0/8cac9713735864899e8abc4065bbdb3d1617f2130006d508a80e1b1a6c53/duckdb-1.3.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:a3418c973b06ac4e97f178f803e032c30c9a9f56a3e3b43a866f33223dfbf60b", size = 15535350, upload-time = "2025-07-08T10:40:45.562Z" }, - { url = "https://files.pythonhosted.org/packages/c5/26/6698bbb30b7bce8b8b17697599f1517611c61e4bd68b37eaeaf4f5ddd915/duckdb-1.3.2-cp313-cp313-macosx_12_0_universal2.whl", hash = "sha256:2a741eae2cf110fd2223eeebe4151e22c0c02803e1cfac6880dbe8a39fecab6a", size = 32534715, upload-time = "2025-07-08T10:40:47.615Z" }, - { url = "https://files.pythonhosted.org/packages/10/75/8ab4da3099a2fac7335ecebce4246706d19bdd5dad167aa436b5b27c43c4/duckdb-1.3.2-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:51e62541341ea1a9e31f0f1ade2496a39b742caf513bebd52396f42ddd6525a0", size = 17110300, upload-time = "2025-07-08T10:40:49.674Z" }, - { url = "https://files.pythonhosted.org/packages/d1/46/af81b10d4a66a0f27c248df296d1b41ff2a305a235ed8488f93240f6f8b5/duckdb-1.3.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3e519de5640e5671f1731b3ae6b496e0ed7e4de4a1c25c7a2f34c991ab64d71", size = 19180082, upload-time = "2025-07-08T10:40:51.679Z" }, - { url = "https://files.pythonhosted.org/packages/68/fc/259a54fc22111a847981927aa58528d766e8b228c6d41deb0ad8a1959f9f/duckdb-1.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4732fb8cc60566b60e7e53b8c19972cb5ed12d285147a3063b16cc64a79f6d9f", size = 21128404, upload-time = "2025-07-08T10:40:53.772Z" }, - { url = "https://files.pythonhosted.org/packages/ab/dc/5d5140383e40661173dacdceaddee2a97c3f6721a5e8d76e08258110595e/duckdb-1.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:97f7a22dcaa1cca889d12c3dc43a999468375cdb6f6fe56edf840e062d4a8293", size = 22779786, upload-time = "2025-07-08T10:40:55.826Z" }, - { url = "https://files.pythonhosted.org/packages/51/c9/2fcd86ab7530a5b6caff42dbe516ce7a86277e12c499d1c1f5acd266ffb2/duckdb-1.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:cd3d717bf9c49ef4b1016c2216517572258fa645c2923e91c5234053defa3fb5", size = 11395370, upload-time = "2025-07-08T10:40:57.655Z" }, +version = "1.5.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/59/0b/d65ea3be00ea79aa276a8388bec588a9cbf409ce637c6d306e5316210d15/duckdb-1.5.6.tar.gz", hash = "sha256:166a91dbfacfc0c9f08cc76c0243cb6d3d4296bfab5bad72a3cfb63140a5b7c8", size = 18032957, upload-time = "2026-09-28T13:38:37.978Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/e5/01e03d30b7ba33a030a4269fdca16ce445ce10f9d29b84a10fdbe0636ad2/duckdb-1.5.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c88700d0ee68ad149a0cc624df21b0f21efc136ea2449aaadd7cd0c9a564962a", size = 32757482, upload-time = "2026-09-28T13:37:29.916Z" }, + { url = "https://files.pythonhosted.org/packages/ba/4f/7f7be626a4649a3948ca646c84d6afc1a00121f292f98e6f0d9ed68330df/duckdb-1.5.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:03e4f1b10a8b8ff476eb2b73955590fadbcef978da1167c593114c5edf763960", size = 17372997, upload-time = "2026-09-28T13:37:32.363Z" }, + { url = "https://files.pythonhosted.org/packages/1a/66/9d57573729348d800a0eebdd508f1a833d3714f72e984fef79b47f0e6c45/duckdb-1.5.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34623eaabd2c66ba5c20f1a39486321c3b7d32e4e0e001ced95f81e3372dd361", size = 15514224, upload-time = "2026-09-28T13:37:34.467Z" }, + { url = "https://files.pythonhosted.org/packages/57/ec/97f595214b3a27b4ca42b8cab6d8121c06f3537dcc4d2da7bca0332de4c5/duckdb-1.5.6-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56c0f71c6bee982e9c30568bb12371bf66b26bf129c75d8d7f60bc69d6590a2c", size = 19428776, upload-time = "2026-09-28T13:37:36.689Z" }, + { url = "https://files.pythonhosted.org/packages/68/4a/ab59f4c1f76fb89e28d23f19b2729538e0723c8d328a07e1b8c37f9ee128/duckdb-1.5.6-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73b108c04c932b36c2fa4e41110cc1c3c8cd510eb49f065f92d050be8e6929fd", size = 21537771, upload-time = "2026-09-28T13:37:39.548Z" }, + { url = "https://files.pythonhosted.org/packages/31/4f/9306c442ecad76f2a4d19f249e7fc8861f139dcf748315102eb69de8ca56/duckdb-1.5.6-cp311-cp311-win_amd64.whl", hash = "sha256:dda311932cf5aae955a53fe28a4fc1700c2ab5fa02dc1f165abdd5ec6c39141e", size = 13179009, upload-time = "2026-09-28T13:37:41.981Z" }, + { url = "https://files.pythonhosted.org/packages/a0/40/8a370e998293d3ebbbac4d926db30bb4ac5f700851a06ac31e7093bee386/duckdb-1.5.6-cp311-cp311-win_arm64.whl", hash = "sha256:df5ae02af278e084f54a9730a9f4f211ed736d0bd8f3bc12af925c2effb5b33d", size = 14046340, upload-time = "2026-09-28T13:37:44.187Z" }, + { url = "https://files.pythonhosted.org/packages/d9/d5/d0ab77a0a1702a43171c93874f44c1f6481e30038bd3987df0d77a16a5c6/duckdb-1.5.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:48d07d0651aaeac2c3974afd37599970154b7b79b54c18f27c319c14ccf98d9d", size = 32810486, upload-time = "2026-09-28T13:37:47.254Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cd/b22201de5377faa3be6c38d5f3eaa504cb480392a448bed6a4d2239469b4/duckdb-1.5.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:79de3dfa8705b1ba0d59e7e3252e40ff399e0afd12f485502a6c7bf7c2fd809a", size = 17405278, upload-time = "2026-09-28T13:37:50.135Z" }, + { url = "https://files.pythonhosted.org/packages/9c/6d/f9cfb1493bbdc2f095693a402e42dce1192077f9e11573f00baed6a748de/duckdb-1.5.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dcccce20965e6986cd083fdf192c461685ad0b93cd1ccd0b2a8207f1185f078b", size = 15532943, upload-time = "2026-09-28T13:37:52.927Z" }, + { url = "https://files.pythonhosted.org/packages/53/04/f65ccfaa5a833f2e570c4a140f03c8f95da416da9fe8ed08401f81f8242a/duckdb-1.5.6-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce89a1025a5317ebe9c520876c48032b5247ac574865486648b1a004f6009875", size = 19454940, upload-time = "2026-09-28T13:37:55.732Z" }, + { url = "https://files.pythonhosted.org/packages/4c/99/be75c788a492f8d77b7a1cdc1b19939ae7be0007f2028691ad371a1a33ee/duckdb-1.5.6-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bc9619ed7d4ffa117b5155d84b44794366bb6635178d78ed5e13a6024845c757", size = 21568087, upload-time = "2026-09-28T13:37:58.191Z" }, + { url = "https://files.pythonhosted.org/packages/b5/95/889f8508960e47c0a7c75cc5bf57cde8512fc24f8db7b3129cca5388da42/duckdb-1.5.6-cp312-cp312-win_amd64.whl", hash = "sha256:09ff51b230219f0d8b47fc8a1e17fb595ba9fab0c3d96a6de4d00b8ff86b3cf1", size = 13190189, upload-time = "2026-09-28T13:38:00.407Z" }, + { url = "https://files.pythonhosted.org/packages/a4/c9/baab503364a68309f8368c88e77f5341e7d94927bdf3e6d703f0e5035f3e/duckdb-1.5.6-cp312-cp312-win_arm64.whl", hash = "sha256:b8d795c8b2d5634b3269f974aa97f1fdf878f62f032317a52252a151b693fb1e", size = 14021977, upload-time = "2026-09-28T13:38:02.682Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/a476197fcba557738a588ec844747a19bc0a24b0e6f1809e308f29d68c0e/duckdb-1.5.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ae352646374cacf48e9981cf031191c494865192fc436d13667a2531fc5d1da3", size = 32810376, upload-time = "2026-09-28T13:38:05.148Z" }, + { url = "https://files.pythonhosted.org/packages/0c/6d/5466a2b53ddd557644dfa47a763f68748efccdf282e6ae7c4f1bcfb3da69/duckdb-1.5.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a1261e90785e9d29953293e44f60fa073bd1137098924e8de21a037a861b051", size = 17405385, upload-time = "2026-09-28T13:38:07.363Z" }, + { url = "https://files.pythonhosted.org/packages/d4/a0/bf87071170835ee4a34fe764fc11c1c6e7040a0e021b36c1b6f834a4c22f/duckdb-1.5.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:97dd7a555b8f5298b76bc7d48a11cb2c64336e8de9bfde783cffb86ea9f54807", size = 15533132, upload-time = "2026-09-28T13:38:09.681Z" }, + { url = "https://files.pythonhosted.org/packages/31/e0/38095c8e140ecfbe847519ac07bcba94301b8fbb76b2870015e33e07f179/duckdb-1.5.6-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:364992ba1089a2b327391cfcb68fd0bd0ce9090cf293baef861a0ba6847abfee", size = 19454994, upload-time = "2026-09-28T13:38:11.836Z" }, + { url = "https://files.pythonhosted.org/packages/70/21/61dd2876bbaa69cf77d7b5c620e52e8b25faae7096f4d2e4a812b52095d7/duckdb-1.5.6-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:644f54ce99b3b61844bc9a3fe80e0aecb1ea4084b1fffc4396d1569db6111679", size = 21568700, upload-time = "2026-09-28T13:38:14.258Z" }, + { url = "https://files.pythonhosted.org/packages/4a/4a/100730e7785e85268be4d4d5bd62cfc8314e261d2f42efa208243eef35cb/duckdb-1.5.6-cp313-cp313-win_amd64.whl", hash = "sha256:ced693d33ddcee2e5345f077d342c87d2aaa80e41c514e64c9ff2d4e5963c251", size = 13190707, upload-time = "2026-09-28T13:38:16.875Z" }, + { url = "https://files.pythonhosted.org/packages/f3/2e/bc7f44eab4e89ee5c1cb427bb1168ad021d985042e6841ec0694c3d3d501/duckdb-1.5.6-cp313-cp313-win_arm64.whl", hash = "sha256:41ecc75bb9328d72d154a705c1a653d2c5c60f686a5c0c6578aa80020753c884", size = 14020962, upload-time = "2026-09-28T13:38:19.007Z" }, + { url = "https://files.pythonhosted.org/packages/fb/62/a8a30a4c6b94c0861d348ed5633b963f6745a5525527530f02f3c1a7c931/duckdb-1.5.6-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:aa21d2ad803b2524326e8622d7d96b2bb1ff1d5b60368e1978ee805df9c21fb3", size = 32828003, upload-time = "2026-09-28T13:38:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/71/b7/1dcca0005eb8c67adf9fc06bf0cbb1d2bf4ea1974cc89e7a7c2ad66aac28/duckdb-1.5.6-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:8a1b2ad27d414068cbca06c55cfa802eece10f86ea4812ff082f8ab4cb25fc85", size = 17413912, upload-time = "2026-09-28T13:38:23.915Z" }, + { url = "https://files.pythonhosted.org/packages/93/b0/e3ac175443550f3464f2d95731a8b0aae9b4dc3875c3a186c352262b43c2/duckdb-1.5.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c79c6d222b1d015cde73b5139087186b00db65357fb4e2c94c2308fbbf465a72", size = 15543122, upload-time = "2026-09-28T13:38:26.317Z" }, + { url = "https://files.pythonhosted.org/packages/9d/08/cc510a7952aba69d5cdca17f3ef61c95713d86143f2ee9aa3e097d38f50b/duckdb-1.5.6-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1052b8050ef5696e2c0d8c836949c72f3dd11f0690466acbea739613e8e2750b", size = 19457946, upload-time = "2026-09-28T13:38:28.877Z" }, + { url = "https://files.pythonhosted.org/packages/ef/a5/6f8099d9a5a02ddff89e5c85875df3465054845b0920fb0703fbdf8dd2ec/duckdb-1.5.6-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:19c5e485e59613b8878d1670bcaa7a010f53c5a4da5ae8e08863e5e529ca6182", size = 21575132, upload-time = "2026-09-28T13:38:31.231Z" }, + { url = "https://files.pythonhosted.org/packages/9f/58/762f7159662d7859e201fa05ca29f306795daeabf84f3e087215a966b001/duckdb-1.5.6-cp314-cp314-win_amd64.whl", hash = "sha256:ebcbd09cd8578ab1093393e9b16289cda0e8f1791ac595bf00eb5bad75c3cf00", size = 13713963, upload-time = "2026-09-28T13:38:33.543Z" }, + { url = "https://files.pythonhosted.org/packages/46/69/64d165db322de13f5c3e75d377b6b9694df1821155ad1fa4b14b04601abc/duckdb-1.5.6-cp314-cp314-win_arm64.whl", hash = "sha256:820a8384faef11cd86068ea48c5da57ce2d8f1c7b3d2bdb9be3398317a7c3728", size = 14514368, upload-time = "2026-09-28T13:38:35.676Z" }, ] [[package]] @@ -3733,7 +3740,7 @@ requires-dist = [ { name = "click", specifier = ">=8.0.0" }, { name = "clickhouse-connect", marker = "extra == 'clickhouse'", specifier = ">=0.6.0" }, { name = "databricks-sql-connector", marker = "extra == 'databricks'", specifier = ">=2.0.0" }, - { name = "duckdb", specifier = ">=1.0.0" }, + { name = "duckdb", specifier = ">=1.4.4" }, { name = "fastapi", marker = "extra == 'api'", specifier = ">=0.115.0" }, { name = "fastapi", marker = "extra == 'dev'", specifier = ">=0.115.0" }, { name = "google-cloud-bigquery", marker = "extra == 'bigquery'", specifier = ">=3.0.0" },