sql-code-graph 1.34.0__tar.gz → 1.34.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/PKG-INFO +1 -1
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/pyproject.toml +1 -1
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/__init__.py +1 -1
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/commands/git.py +46 -17
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/commands/reindex.py +65 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/test_git_hook_install.py +132 -5
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_git_hooks.py +39 -22
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_hook_reindex_detach.py +188 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/uv.lock +1 -1
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.claude/agents/api-documenter.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.claude/agents/architect-planner.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.claude/agents/architect-reviewer.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.claude/agents/code-reviewer.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.claude/agents/developer.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.claude/agents/plan-reviewer.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.claude/agents/sprint-planner.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.github/workflows/benchmark.yml +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.github/workflows/e2e-tests.yml +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.github/workflows/release.yml +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.github/workflows/test.yml +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.gitignore +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.pre-commit-config.yaml +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/.sqlcgignore +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/ARCHITECTURE_REVIEW.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/ARCHITECTURE_REVIEW_ARCHIVE.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/CHANGELOG.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/CLAUDE.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/README.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/docs/AIRBNB_PARSE_REPORT.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/docs/cli.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/docs/getting-started.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/docs/releasing-pypi.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/e2e_firstuser_report.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/e2e_run_20260528_101413.output +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/main.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/WORKFLOW.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/measurements/pr2_catalog_load_eval.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/measurements/pr3_repo_native_plateau.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/measurements/pr4_transform_kinds.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/measurements/pr5_extraction_recall_taxonomy.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/measurements/sprint_08_changelogs_fullindex.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/measurements/sprint_08_fullcorpus_index.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/metrics/gain_1.29.0_05c6943.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/metrics/gain_1.30.0_2c8ac25.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/metrics/gain_1.30.1_26271fc.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/metrics/gain_1.31.0_a40c837.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/metrics/gain_1.32.0_c1bec3c.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/metrics/lineage5_dwh_after_pr5.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/metrics/lineage5_dwh_before_master.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/metrics/schema_comparison_with_schema.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/metrics/schema_comparison_without_schema.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/metrics/sprint_08_changelogs_fullindex.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/metrics/sprint_08_fullcorpus_index.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/metrics/sprint_pool_300s_plan.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/reports/column_coverage_diagnostic.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/reports/column_coverage_findings.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/reports/dwh_graph_analysis.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/reports/dwh_positional_insert_column_blindspot.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/reports/feature_acceptance_dwh.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/reports/graph_health_sprint_postmortem.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/reports/island_lever_live_verification.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/reports/issue38_pr2_live_acceptance.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/reports/issue38_pr3_live_acceptance.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/reports/lineage_identity_sprint_postmortem.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/reports/pr_impact_followups_2026-06-14.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/reports/sprint_03_v0.3.1_postmortem.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/reports/sprint_3.1_postmortem.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/reports/v1_14_dialect_query_config_postmortem.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/research/blueprint.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/research/coverage_parse_failure_diagnosis.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/research/investigation_e5_e4.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/research/observed_usage_overlay_query_history_tableau.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/research/parse_diagnostics.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/research/parsing_errors_experiment.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/research/snowflake_en_test_suite.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/research/sql_only_coverage_lever_post_pr2.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/research/sqlcg.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/bundle_claude_skill.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/ci_tests_pool_flake_fix.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/column_lineage_recall_metric.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/coverage_p1_p3_p4.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/coverage_p1_p5_metric.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/coverage_parse_failures.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/diff-impact-producer-file.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/e8_dual_emission.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/feature_34_unused_presentation_segregation.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/feature_35_external_downstream_injection.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/feature_F2_bundle_claude_skill.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/feature_kuzu_to_duckdb_migration.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/fix_backward_self_heal_index_at_sha.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/fix_downstream_sink_location.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/fix_dynamic_table_parsing.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/fix_expand_qualify_perf.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/fix_firstuser_findings.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/fix_issue29_live_test_followups.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/fix_schema_case_mismatch.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/gain_coverage_metrics.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/graph_health_catalog_and_metrics.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/hygiene_config_path_and_survivors.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/issue-38-backfill-cte-bridge.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/issue-38-residual-source-extraction.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/issue-38-selects-from-island-lever.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/living_codebase_resync.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/mcp_server_self_healing.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/positional_insert_clone_blindspot.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_01.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_01_deployment_pypi.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_02.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_02_v0.3.0_core.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_03.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_04_column_lineage.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_04_column_lineage_fix.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_05_star_resolution.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_06_lineage_coverage.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_07_open_ecodes.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_07_perf_and_live_test.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_08_perf_upsert.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_09_lineage_coverage.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_10_anchor_tools.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_11_v1.0.2_bugfix.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_12_v1.1.0.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_13_v1.1.0_cluster_b.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_lineage_identity_and_session_context.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/sprint_postmortem_fixes.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/temp_table_namespacing.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/trust_layer.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/unfilled_table_impact.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/v1.1.0_cluster_b_provenance_trust.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/v1.1.0_live_graph_freshness.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/v1.1.1_batch_upsert_perf.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/v1.14.0_dialect_and_query_config_fixes.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/v1_1_2_bugfix.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/v1_1_3_union_cte_star.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/v1_2_0_read_proxy.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/v1_2_1_bugfix.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/plan/sprints/version-parity-and-restart.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/profile.html +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/pyrightconfig.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/scripts/collect_parse_errors.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/scripts/column_coverage_check.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/scripts/generate_cli_docs.sh +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/__main__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/commands/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/commands/analyze.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/commands/catalog.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/commands/db.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/commands/find.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/commands/gain.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/commands/index.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/commands/install.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/commands/mcp.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/commands/report.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/commands/uninstall.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/commands/watch.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/coverage.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/cli/main.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/core/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/core/config.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/core/duckdb_backend.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/core/freshness.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/core/graph_db.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/core/jobs.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/core/noise_match.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/core/queries.cypher +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/core/queries.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/core/queries.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/core/schema.cypher +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/core/schema.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/indexer/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/indexer/dbt_adapter.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/indexer/error_classify.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/indexer/git_delta.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/indexer/indexer.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/indexer/pool.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/indexer/walker.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/indexer/watcher.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/lineage/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/lineage/aggregator.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/lineage/schema_resolver.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/metrics/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/metrics/store.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/parsers/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/parsers/ansi_parser.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/parsers/base.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/parsers/bigquery_parser.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/parsers/postgres_parser.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/parsers/registry.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/parsers/snowflake_parser.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/parsers/tsql_parser.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/server/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/server/control.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/server/exceptions.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/server/models.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/server/noise_filter.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/server/read_client.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/server/selfheal.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/server/server.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/server/skill.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/server/tools.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/server/writer.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/utils/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/utils/hashing.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/utils/ignore.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/src/sqlcg/utils/logging.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/adversarial/200_join.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/adversarial/500_union.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/bench_indexer.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/conftest.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/golden_corpus/snowflake/case_normalization.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/golden_corpus/snowflake/colon_cast.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/golden_corpus/snowflake/colon_reserved_word.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/golden_corpus/snowflake/copy_into.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/golden_corpus/snowflake/create_procedure.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/golden_corpus/snowflake/identifier_dynamic.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/golden_corpus/snowflake/lateral_flatten.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/golden_corpus/snowflake/qualify.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/golden_corpus/snowflake/scripting_block.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/golden_corpus/snowflake/three_part.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/tpch/q01.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/tpch/q02.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/tpch/q03.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/tpch/q04.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/benchmarks/tpch/q05.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/conftest.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/conftest.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/test_F2_skill_install_e2e.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/test_airbnb_e2e.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/test_cli_index.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/test_empty_impact_cli_e2e.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/test_golden_lineage.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/test_mcp_lifecycle.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/test_mcp_tools.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/test_parse_diagnostics_cli.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/test_pr_impact_cli_e2e.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/test_selfheal_e2e.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/test_star_resolution_e2e.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/e2e/test_watch.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/airbnb/dim_hosts_cleansed.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/airbnb/dim_listings_cleansed.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/airbnb/fct_reviews.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/airbnb/mart_fullmoon_reviews.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/airbnb/raw_hosts.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/airbnb/raw_listings.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/airbnb/raw_reviews.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/airbnb/src_hosts.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/airbnb/src_listings.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/airbnb/src_reviews.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/bigquery/.gitkeep +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/duckdb_parity/kuzu_reference.json +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/jaffle_shop/customers.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/jaffle_shop/orders.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/jaffle_shop/raw_orders.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/snowflake/base_tables.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/snowflake/reports.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/snowflake/views.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/star_corpus/ddl_src.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/star_corpus/ddl_tgt.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/star_corpus/etl_alias_star.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/star_corpus/etl_star.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/synthetic/base_tables.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/synthetic/reports.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/fixtures/synthetic/views.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/snowflake/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/snowflake/test_insert_select.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/snowflake/test_qualify_bare_tables_command_guard_integration.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_T34_presentation_segregation.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_T35_external_consumers.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_analyze_case_fold.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_anchor_tools.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_backfill_impact_consistency.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_bare_column_cte_lineage.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_bulk_upsert.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_case_split_seed_regression.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_catalog_kind_upgrade.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_catalog_load_integration.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_cli_index_clear_before_rebuild.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_column_coverage_patterns.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_column_lineage_e2e.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_coverage_metrics_integration.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_cross_file_lineage.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_cte_key_namespacing_integration.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_cte_recall_guard.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_cte_schema_alias_guard.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_cte_source_node_invariant.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_dialect_auto_resolution.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_dialect_matrix.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_duckdb_parity.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_e36_xfile_regression_guard.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_empty_impact_blast_radius.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_empty_index_rollback_guard.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_freshness_mcp.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_gating_join_retrofit.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_hygiene_config_root_reconciliation.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_identity_counters_integration.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_impact_consumer_parity.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_index_degraded_files_metric.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_index_filter_node_exclusion.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_indexer_batching.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_indexer_commits.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_indexer_to_graph.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_issue38_cte_insert_regression.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_join_col_resolution.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_key_normalization_chokepoint.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_live_anchors.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_mvcc_rebuild.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_parse_diagnostics.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_pr1_confidence_reason.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_pr2_source_location.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_pr3_kind_tagging.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_pr_impact_integration.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_qualify_failed_persist.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_read_via_server.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_readonly_under_lock.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_reindex_via_server.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_repo_relative_cte_namespaces.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_resolvable_write_col_edges_integration.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_resync.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_selects_from_completeness.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_selects_from_cte_body_source.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_selects_from_subscope_source.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_single_writer_queue.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_skip_counts_integration.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_star_resolution.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_temp_table_lineage.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_temp_table_namespacing.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_tool_version_stamp_integration.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_union_cte_star_recall_guard.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_usage_derived_catalog.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_use_schema_session_context_integration.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_user_surface_recall_guard.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_v141_surface_guards.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_v1_14_0_dialect_and_query_config_fixes.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_view_kind_in_graph.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/integration/test_write_memory_ceiling.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/perf/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/perf/test_perf.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E10/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E11/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E12/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E12/e12_json_path.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E12/e12_lateral_flatten.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E12/test_e12.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E13/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E14/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E15/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E16/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E16/e16_merge.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E16/e16_merge_delete.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E16/test_e16.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E17/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E18/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E18/e18_decode.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E18/e18_iff_decode.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E18/e18_nvl2.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E18/test_e18.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E19/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E2/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E2/e2_expr_alias.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E2/e2_function_alias.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E2/e2_multiply_alias.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E2/test_e2.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E20/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E21/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E21/e21_alias_forward_ref.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E21/e21_three_level_chain.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E21/test_e21.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E22/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E23/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E23/e23_stored_proc.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E23/e23_stored_proc_multi.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E23/test_e23.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E24/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E25/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E25/e25_cross_db.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E25/e25_two_part.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E25/test_e25.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E25/test_e25_full_id.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E26/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E27/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E27/e27_nested_udf.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E27/e27_udf.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E27/test_e27.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E28/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E29/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E3/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E3/e3_alter_table.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E3/e3_create_sequence.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E3/e3_ddl_only.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E3/test_e3.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E30/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E31/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E32/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E33/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E34/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E35/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E36/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E36/e36_temp_multi_use.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E36/e36_temp_table.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E36/test_e36.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E36/test_e36_xfile.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E37/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E38/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E4/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E4/e4_execute_immediate.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E4/e4_if_not_exists.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E4/e4_unexpected_token.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E4/e4_unpivot.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E4/test_e4.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E5/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E5/e5_cte_missing_source.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E5/e5_multi_cte.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E5/e5_nested_cte.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E5/test_e5.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E5/test_e5_cte_projection.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E8/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E8/e8_dynamic_sources.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E8/e8_seq_nextval.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E8/e8_uuid.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E8/test_e8.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E9/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E_aggregates/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E_aggregates/fixture_sum_absent_cross_schema.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E_aggregates/fixture_sum_case_when.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E_aggregates/fixture_sum_present_source.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E_aggregates/test_e_aggregates.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E_date_functions/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E_date_functions/fixture_date_aliased.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E_date_functions/fixture_date_unaliased.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E_date_functions/fixture_datediff_unaliased.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E_date_functions/fixture_year_unaliased.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/E_date_functions/test_e_date_functions.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/README.md +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/anchors/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/anchors/fixture_etl.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/anchors/fixture_omloopsnelheid.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/anchors/fixture_semantic.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/anchors/fixture_source.sql +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/anchors/test_anchor_ma_aantal_op_order.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/anchors/test_anchor_omloopsnelheid.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/conftest.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/snowflake/test_plan_review_gates.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/snowflake/__init__.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/snowflake/test_qualify_bare_tables_command_guard.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/snowflake/test_scripting_noise.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_BugB_escalation_uses_init_path.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_BugC_hook_upgrade.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_F2_install_skill.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_F2_skill_render.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_F2_uninstall_skill.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_T09_01_qualify_once.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_T09_02_ddl_skip.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_T09_04_subprocess_isolate.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_T09_06_log_verbosity.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_T35_config_external_consumers.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_aggregator.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_aggregator_skip.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_analyze_case_fold.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_base_parser.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_branch_monitor.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_bulk_upsert_invariant.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_canonical_target_resolution.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_catalog_csv_parsing.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_catalog_missing_warning.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_cli.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_cli_doc_flag_staleness.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_cli_help.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_clone_positional_insert_blindspot.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_closure_depth.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_column_lineage_wiring.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_config.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_coverage_metrics.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_cte_key_namespacing.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_cte_source_gap_metric.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_data_models.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_db_info.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_db_info_coverage.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_db_path_isolation_fixture.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_doc_links.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_doc_markdown_link_existence.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_dominant_cause.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_duckdb_backend.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_duckdb_backend_shared.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_e5_view_alias_resolution.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_e8_dual_emission.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_e8_temp_chain_key_mismatch.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_empty_propagation_unit.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_extract_select_output_columns.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_file_ignore_defaults.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_find_cmd.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_firstuser_findings.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_freshness_helper.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_gain_coverage.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_gain_ratio.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_gating_join_field_docstrings.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_git_delta.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_git_hooks_notify.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_graph_backend.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_graph_completeness_invariant.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_hard_kill_pool.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_has_column_precedence_upsert.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_hygiene_config_warning.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_identity_counters.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_include_working_tree.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_index_cmd.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_index_filter_config.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_index_flags.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_index_progress.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_index_summary_degraded_metric.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_indexer_progress.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_indexer_quality.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_install.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_install_message.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_issue_63_readonly_lock.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_jobs.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_join_col_resolve_marker.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_judgement.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_lineage_conversion.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_literal_column_skip.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_mcp_best_practices.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_mcp_control.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_mcp_stdio_smoke.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_metrics.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_noise_filter.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_normalize_keys.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_parse_failed_classification.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_parse_file_dependency_filter.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_parse_quality.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_parser.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_perf_scaling_guard.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_pr07_observability.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_pr6_execute_immediate_unwrap.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_pr_impact_unit.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_qualify_failed_unit.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_queries_loader.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_read_client.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_repo_relative_cte_namespaces.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_resolvable_write_col_edges_unit.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_resolve_join_columns_sql.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_resolve_pass2_passes_dependency_filter.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_schema_resolver.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_selects_from_completeness_unit.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_selfheal_detector.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_selfheal_pr1_messages.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_selfheal_reexec.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_selfheal_watcher.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_server.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_skip_counts_persistence.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_snowflake_strip_alter_set_tag.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_sprint_06_t04_t05.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_star_resolution_unit.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_star_schema_unit.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_submit_feedback.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_subprocess_isolate.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_t02_expression_name_extraction.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_t03_ddl_skip.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_temp_table_namespacing.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_timeout_cancel.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_tool_version_stamp.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_tools_hints.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_tools_warnings.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_transform_kind_classification.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_uninstall.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_unknown_sentinel_skip.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_unqualified_fallback.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_upsert_batch_invariant.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_use_schema_session_context.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_version_parity.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_view_classification.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_walker.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_watcher.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_worker_error_classification.py +0 -0
- {sql_code_graph-1.34.0 → sql_code_graph-1.34.1}/tests/unit/test_writer_queue.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sql-code-graph
|
|
3
|
-
Version: 1.34.
|
|
3
|
+
Version: 1.34.1
|
|
4
4
|
Summary: SQL code graph analyzer and lineage tracer
|
|
5
5
|
Project-URL: Homepage, https://github.com/Warhorze/sql-code-graph
|
|
6
6
|
Project-URL: Repository, https://github.com/Warhorze/sql-code-graph
|
|
@@ -23,6 +23,29 @@ class _HookSpec(NamedTuple):
|
|
|
23
23
|
# Hook script templates — use {sqlcg_bin} as the placeholder for the resolved binary.
|
|
24
24
|
# The sentinel comments (e.g. "# sqlcg post-checkout hook") must stay byte-for-byte
|
|
25
25
|
# unchanged so R9 idempotency is preserved: _install_single_hook matches them verbatim.
|
|
26
|
+
#
|
|
27
|
+
# Run-time binary resolution (#126 + #1): the hook no longer trusts the single embedded
|
|
28
|
+
# absolute literal to stay valid forever (a venv rebuild or tool upgrade makes the
|
|
29
|
+
# install-time path stale and the resync would then run a wrong/missing binary). Instead
|
|
30
|
+
# the shared _RESOLVE_PREAMBLE resolves the binary at *run time* with a hybrid order:
|
|
31
|
+
# 1. the preferred path rendered in at install time ({sqlcg_bin}, normally the stable
|
|
32
|
+
# user-base binary from _resolve_sqlcg_bin) — the fast path, used if still executable;
|
|
33
|
+
# 2. `command -v sqlcg` on $PATH — covers uv-tool, user-base-on-PATH, and active-venv;
|
|
34
|
+
# 3. neither resolves → print a loud stderr error and exit non-zero (never silent).
|
|
35
|
+
# The shell never recomputes getuserbase() — the preferred path is rendered in by Python.
|
|
36
|
+
# It exports SQLCG_BIN for the hook body to invoke.
|
|
37
|
+
_RESOLVE_PREAMBLE = (
|
|
38
|
+
'if [ -x "{sqlcg_bin}" ]; then\n'
|
|
39
|
+
' SQLCG_BIN="{sqlcg_bin}"\n'
|
|
40
|
+
"elif command -v sqlcg >/dev/null 2>&1; then\n"
|
|
41
|
+
' SQLCG_BIN="$(command -v sqlcg)"\n'
|
|
42
|
+
"else\n"
|
|
43
|
+
" echo \"sqlcg: cannot find the sqlcg binary (tried '{sqlcg_bin}' and \\$PATH)"
|
|
44
|
+
" -- run 'sqlcg git install-hooks' to repoint this hook\" >&2\n"
|
|
45
|
+
" exit 1\n"
|
|
46
|
+
"fi\n"
|
|
47
|
+
)
|
|
48
|
+
|
|
26
49
|
_HOOKS: list[_HookSpec] = [
|
|
27
50
|
_HookSpec(
|
|
28
51
|
filename="post-checkout",
|
|
@@ -32,7 +55,8 @@ _HOOKS: list[_HookSpec] = [
|
|
|
32
55
|
"# sqlcg post-checkout hook — incremental resync after branch switch\n"
|
|
33
56
|
"# $3 == 1 means branch checkout (not file checkout); skip file checkouts\n"
|
|
34
57
|
'[ "$3" = "1" ] || exit 0\n'
|
|
35
|
-
|
|
58
|
+
+ _RESOLVE_PREAMBLE
|
|
59
|
+
+ '"$SQLCG_BIN" reindex --from "$1" --to "$2"'
|
|
36
60
|
' "$(git rev-parse --show-toplevel)" --dialect auto --quiet --notify'
|
|
37
61
|
' || echo "sqlcg: graph not updated (reindex failed)'
|
|
38
62
|
" -- run 'sqlcg mcp status'\" >&2\n"
|
|
@@ -41,22 +65,27 @@ _HOOKS: list[_HookSpec] = [
|
|
|
41
65
|
_HookSpec(
|
|
42
66
|
filename="post-merge",
|
|
43
67
|
sentinel="# sqlcg post-merge hook",
|
|
44
|
-
script_template=
|
|
45
|
-
#!/bin/sh
|
|
46
|
-
# sqlcg post-merge hook — incremental resync after pull/merge
|
|
47
|
-
# git sets ORIG_HEAD to the pre-merge HEAD; pass it as --from so --notify
|
|
48
|
-
# through a running server (same path as post-checkout). If
|
|
49
|
-
# first-ever merge / gc'd), fall back to the
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|| echo "sqlcg: graph not updated (reindex failed)
|
|
58
|
-
|
|
59
|
-
""
|
|
68
|
+
script_template=(
|
|
69
|
+
"#!/bin/sh\n"
|
|
70
|
+
"# sqlcg post-merge hook — incremental resync after pull/merge\n"
|
|
71
|
+
"# git sets ORIG_HEAD to the pre-merge HEAD; pass it as --from so --notify\n"
|
|
72
|
+
"# can route through a running server (same path as post-checkout). If\n"
|
|
73
|
+
"# ORIG_HEAD is unset (e.g. first-ever merge / gc'd), fall back to the\n"
|
|
74
|
+
"# standalone stored-SHA delta (direct write).\n"
|
|
75
|
+
+ _RESOLVE_PREAMBLE
|
|
76
|
+
+ "PREV=$(git rev-parse --verify --quiet ORIG_HEAD)\n"
|
|
77
|
+
"TOP=$(git rev-parse --show-toplevel)\n"
|
|
78
|
+
'if [ -n "$PREV" ]; then\n'
|
|
79
|
+
' "$SQLCG_BIN" reindex --from "$PREV" --to HEAD "$TOP" --dialect auto'
|
|
80
|
+
" --quiet --notify \\\n"
|
|
81
|
+
' || echo "sqlcg: graph not updated (reindex failed)'
|
|
82
|
+
" -- run 'sqlcg mcp status'\" >&2\n"
|
|
83
|
+
"else\n"
|
|
84
|
+
' "$SQLCG_BIN" reindex "$TOP" --dialect auto --quiet --notify \\\n'
|
|
85
|
+
' || echo "sqlcg: graph not updated (reindex failed)'
|
|
86
|
+
" -- run 'sqlcg mcp status'\" >&2\n"
|
|
87
|
+
"fi\n"
|
|
88
|
+
),
|
|
60
89
|
),
|
|
61
90
|
]
|
|
62
91
|
|
|
@@ -129,6 +129,11 @@ def reindex_cmd( # noqa: B008
|
|
|
129
129
|
# below) and return to git immediately. The respawn guard env var prevents
|
|
130
130
|
# the detached child from detaching again.
|
|
131
131
|
if _is_hook_path and os.environ.get(_HOOK_DETACHED_ENV) != "1":
|
|
132
|
+
# #1 — loud foreground preflight BEFORE detaching. The detached child's
|
|
133
|
+
# schema gate (below) writes its Exit(1) to the hook-resync log, invisible
|
|
134
|
+
# to the user, so a stale-binary schema skew dies silently (exit 0 to git).
|
|
135
|
+
# Surface a real mismatch in the foreground, where git's terminal can see it.
|
|
136
|
+
_hook_preflight_schema_check()
|
|
132
137
|
_spawn_detached_hook_resync(path)
|
|
133
138
|
return
|
|
134
139
|
|
|
@@ -291,6 +296,66 @@ def _spawn_detached_hook_resync(path: Path) -> None:
|
|
|
291
296
|
console.print(f"sqlcg: resyncing graph in background (log: {log_path})")
|
|
292
297
|
|
|
293
298
|
|
|
299
|
+
def _hook_preflight_schema_check() -> None:
|
|
300
|
+
"""Surface a stale-binary schema/version skew in the FOREGROUND hook process (#1).
|
|
301
|
+
|
|
302
|
+
On the hook path the resync is detached (#77), so the existing schema gate
|
|
303
|
+
(``reindex_cmd`` at ~:150) runs in the detached child whose stdout/stderr go to
|
|
304
|
+
``hook-resync.log`` — its ``Exit(1)`` never reaches the user's terminal and the
|
|
305
|
+
graph silently never refreshes. This preflight runs *before* the detach and, on a
|
|
306
|
+
REAL mismatch, prints a visible, actionable stderr message and exits non-zero
|
|
307
|
+
without detaching.
|
|
308
|
+
|
|
309
|
+
Git runs post-checkout/post-merge AFTER the operation and ignores the hook exit
|
|
310
|
+
status, so the **stderr message** is the load-bearing part (not the exit code).
|
|
311
|
+
|
|
312
|
+
BOUNDED, FAIL-SOFT open (plan-review B1 — MANDATED). DuckDB takes an exclusive
|
|
313
|
+
file lock: per ``config.py`` ``get_backend`` docstring, a second process cannot
|
|
314
|
+
open the DB at all (even read-only) while another holds it — it raises
|
|
315
|
+
``duckdb.IOException`` (#63). On rapid successive checkouts a prior detached
|
|
316
|
+
resync still holds the lock, so this open WILL contend. We therefore do a SINGLE
|
|
317
|
+
open attempt (NOT ``_open_backend_with_lock_retry``'s ~31 s retry, which would
|
|
318
|
+
stall ``git checkout`` — a #77-class regression) and, on ``IOException`` (lock
|
|
319
|
+
held ⇒ a resync is already in flight), treat it as "cannot determine — fall
|
|
320
|
+
through to the existing detach path unchanged": never block, never emit a
|
|
321
|
+
schema-mismatch error. Only a SUCCESSFUL read showing a real mismatch triggers
|
|
322
|
+
the loud exit. The backend is opened read-only and released before returning so
|
|
323
|
+
the detached child can still acquire the lock.
|
|
324
|
+
"""
|
|
325
|
+
import duckdb
|
|
326
|
+
|
|
327
|
+
from sqlcg.core.config import get_backend
|
|
328
|
+
from sqlcg.core.schema import SCHEMA_VERSION
|
|
329
|
+
|
|
330
|
+
try:
|
|
331
|
+
backend = get_backend(read_only=True)
|
|
332
|
+
except duckdb.IOException:
|
|
333
|
+
# Lock held by an in-flight resync — cannot determine; fall through to detach.
|
|
334
|
+
return
|
|
335
|
+
|
|
336
|
+
try:
|
|
337
|
+
with backend:
|
|
338
|
+
stored_version = backend.get_schema_version()
|
|
339
|
+
if stored_version is None or stored_version == SCHEMA_VERSION:
|
|
340
|
+
# Matches (or no stored version yet on a fresh graph) — detach as today.
|
|
341
|
+
return
|
|
342
|
+
indexed_tool_version = backend.get_indexed_version()
|
|
343
|
+
except duckdb.IOException:
|
|
344
|
+
# Lock raced after the open (e.g. closed-then-reopened by the writer);
|
|
345
|
+
# fail soft exactly as the open-time IOException path.
|
|
346
|
+
return
|
|
347
|
+
|
|
348
|
+
skew = f" (graph last indexed by sqlcg {indexed_tool_version})" if indexed_tool_version else ""
|
|
349
|
+
print(
|
|
350
|
+
f"sqlcg: graph schema is v{stored_version} but this tool needs "
|
|
351
|
+
f"v{SCHEMA_VERSION}{skew} — the hook binary is stale. "
|
|
352
|
+
"Run 'sqlcg git install-hooks' to repoint the hook, then "
|
|
353
|
+
"'sqlcg db reset && sqlcg index <root>'.",
|
|
354
|
+
file=sys.stderr,
|
|
355
|
+
)
|
|
356
|
+
raise typer.Exit(1)
|
|
357
|
+
|
|
358
|
+
|
|
294
359
|
def _open_backend_with_lock_retry() -> "GraphBackend":
|
|
295
360
|
"""Open the DuckDB backend, retrying with backoff if it is locked.
|
|
296
361
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""End-to-end tests for git hook installation and execution."""
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
+
import shutil
|
|
4
5
|
import subprocess
|
|
5
6
|
import tempfile
|
|
6
7
|
from pathlib import Path
|
|
@@ -86,8 +87,10 @@ def test_hook_runs_sqlcg_reindex_on_branch_checkout(temp_git_repo):
|
|
|
86
87
|
|
|
87
88
|
hook_content = hook_path.read_text()
|
|
88
89
|
|
|
89
|
-
# post-checkout must call
|
|
90
|
-
|
|
90
|
+
# post-checkout must call reindex via the run-time-resolved $SQLCG_BIN (#126/#1):
|
|
91
|
+
# preferred path -> command -v sqlcg -> loud error.
|
|
92
|
+
assert '"$SQLCG_BIN" reindex' in hook_content
|
|
93
|
+
assert "command -v sqlcg" in hook_content
|
|
91
94
|
assert '--from "$1"' in hook_content
|
|
92
95
|
assert '--to "$2"' in hook_content
|
|
93
96
|
assert "--dialect auto" in hook_content
|
|
@@ -112,8 +115,8 @@ def test_idempotency_no_duplicate_hook_lines(temp_git_repo):
|
|
|
112
115
|
assert sentinel_count == 1, f"Expected 1 sentinel, found {sentinel_count}"
|
|
113
116
|
|
|
114
117
|
# All three installs should report success/idempotency
|
|
115
|
-
hook_lines = content.count("
|
|
116
|
-
assert hook_lines == 1, f"Expected 1
|
|
118
|
+
hook_lines = content.count('"$SQLCG_BIN" reindex')
|
|
119
|
+
assert hook_lines == 1, f"Expected 1 reindex line, found {hook_lines}"
|
|
117
120
|
|
|
118
121
|
|
|
119
122
|
# ---------------------------------------------------------------------------
|
|
@@ -147,7 +150,7 @@ def test_post_merge_hook_content_orig_head_guard(temp_git_repo):
|
|
|
147
150
|
# The else branch must contain a reindex call without --from
|
|
148
151
|
else_idx = content.index("else")
|
|
149
152
|
fallback_section = content[else_idx:]
|
|
150
|
-
assert "
|
|
153
|
+
assert '"$SQLCG_BIN" reindex' in fallback_section
|
|
151
154
|
|
|
152
155
|
|
|
153
156
|
def test_post_merge_hook_idempotent(temp_git_repo):
|
|
@@ -292,3 +295,127 @@ def test_post_merge_hook_orig_head_set_routes_with_shas(temp_git_repo):
|
|
|
292
295
|
)
|
|
293
296
|
assert "--to HEAD" in argv_recorded, f"Expected --to HEAD in argv; got: {argv_recorded!r}"
|
|
294
297
|
assert "--notify" in argv_recorded
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
# ---------------------------------------------------------------------------
|
|
301
|
+
# #126 + #1 — run-time binary resolution survives a stale preferred path
|
|
302
|
+
# ---------------------------------------------------------------------------
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def _install_hook_with_preferred_bin(repo: Path, preferred_bin: Path) -> Path:
|
|
306
|
+
"""Install the post-checkout hook with ``preferred_bin`` rendered as the entry."""
|
|
307
|
+
import sqlcg.cli.commands.git as _git_mod
|
|
308
|
+
|
|
309
|
+
original = _git_mod._resolve_sqlcg_bin
|
|
310
|
+
_git_mod._resolve_sqlcg_bin = lambda: str(preferred_bin)
|
|
311
|
+
try:
|
|
312
|
+
runner.invoke(app, ["git", "install-hooks", "--repo", str(repo)])
|
|
313
|
+
finally:
|
|
314
|
+
_git_mod._resolve_sqlcg_bin = original
|
|
315
|
+
return repo / ".git" / "hooks" / "post-checkout"
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
def test_hook_resolves_path_binary_after_preferred_path_deleted(temp_git_repo):
|
|
319
|
+
"""venv-rebuild sim: preferred path gone -> hook resolves a $PATH sqlcg, exit 0.
|
|
320
|
+
|
|
321
|
+
Models an editable .venv install whose embedded path is deleted by a venv
|
|
322
|
+
rebuild. The run-time preamble must fall back to `command -v sqlcg` and invoke
|
|
323
|
+
the working $PATH binary. Guards the git-hook binary-resolution plan
|
|
324
|
+
([plan doc](plan/sprints/bugfix_githook_binary_resolution.md)).
|
|
325
|
+
"""
|
|
326
|
+
venv_dir = temp_git_repo / ".venv" / "bin"
|
|
327
|
+
venv_dir.mkdir(parents=True)
|
|
328
|
+
preferred = venv_dir / "sqlcg"
|
|
329
|
+
preferred.write_text("#!/bin/sh\nexit 0\n")
|
|
330
|
+
preferred.chmod(0o755)
|
|
331
|
+
|
|
332
|
+
hook_path = _install_hook_with_preferred_bin(temp_git_repo, preferred)
|
|
333
|
+
assert f'if [ -x "{preferred}"' in hook_path.read_text()
|
|
334
|
+
|
|
335
|
+
# Simulate the venv rebuild: the preferred path no longer exists.
|
|
336
|
+
preferred.unlink()
|
|
337
|
+
|
|
338
|
+
# Provide a working sqlcg on $PATH that records its invocation.
|
|
339
|
+
path_dir = temp_git_repo / "pathbin"
|
|
340
|
+
path_dir.mkdir()
|
|
341
|
+
argv_file = temp_git_repo / "argv.txt"
|
|
342
|
+
path_bin = path_dir / "sqlcg"
|
|
343
|
+
path_bin.write_text(f'#!/bin/sh\necho "$@" >> {argv_file}\nexit 0\n')
|
|
344
|
+
path_bin.chmod(0o755)
|
|
345
|
+
|
|
346
|
+
env = os.environ.copy()
|
|
347
|
+
env["PATH"] = f"{path_dir}:{env['PATH']}"
|
|
348
|
+
result = subprocess.run(
|
|
349
|
+
["sh", str(hook_path), "abc123", "def456", "1"],
|
|
350
|
+
cwd=str(temp_git_repo),
|
|
351
|
+
env=env,
|
|
352
|
+
capture_output=True,
|
|
353
|
+
text=True,
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
assert result.returncode == 0, result.stderr
|
|
357
|
+
assert argv_file.exists(), "the $PATH sqlcg binary was never invoked"
|
|
358
|
+
assert "reindex" in argv_file.read_text()
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def test_hook_loud_error_when_no_binary_resolvable_anywhere(temp_git_repo):
|
|
362
|
+
"""No sqlcg anywhere -> hook exits NON-ZERO with a stderr message, never silent 0.
|
|
363
|
+
|
|
364
|
+
The exact #1 failure inversion at the hook-script layer. Guards the git-hook
|
|
365
|
+
binary-resolution plan
|
|
366
|
+
([plan doc](plan/sprints/bugfix_githook_binary_resolution.md)).
|
|
367
|
+
"""
|
|
368
|
+
missing = temp_git_repo / "gone" / "sqlcg" # never created
|
|
369
|
+
hook_path = _install_hook_with_preferred_bin(temp_git_repo, missing)
|
|
370
|
+
|
|
371
|
+
# Run with a PATH that has the system shell dirs (so `sh`/`command` resolve)
|
|
372
|
+
# but no sqlcg anywhere — i.e. drop the test runner's venv/user-base dirs.
|
|
373
|
+
sh_bin = shutil.which("sh") or "/bin/sh"
|
|
374
|
+
sh_dir = str(Path(sh_bin).parent)
|
|
375
|
+
empty_path_dir = temp_git_repo / "emptybin"
|
|
376
|
+
empty_path_dir.mkdir()
|
|
377
|
+
env = os.environ.copy()
|
|
378
|
+
env["PATH"] = f"{empty_path_dir}:{sh_dir}:/usr/bin:/bin"
|
|
379
|
+
assert shutil.which("sqlcg", path=env["PATH"]) is None, "test setup: sqlcg still on PATH"
|
|
380
|
+
result = subprocess.run(
|
|
381
|
+
[sh_bin, str(hook_path), "abc123", "def456", "1"],
|
|
382
|
+
cwd=str(temp_git_repo),
|
|
383
|
+
env=env,
|
|
384
|
+
capture_output=True,
|
|
385
|
+
text=True,
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
assert result.returncode != 0, f"hook must exit non-zero when no binary resolves: {result!r}"
|
|
389
|
+
assert "cannot find the sqlcg binary" in result.stderr
|
|
390
|
+
assert "sqlcg git install-hooks" in result.stderr
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def test_reinstall_upgrades_stale_template_hook(temp_git_repo):
|
|
394
|
+
"""A pre-#126 fixed-path hook is auto-upgraded to the run-time-resilient template.
|
|
395
|
+
|
|
396
|
+
The self-upgrade branch (sentinel present, body differs -> overwrite) rewrites a
|
|
397
|
+
stale v1.33.1-era hook and prints 'Upgraded git hook:'. Guards the git-hook
|
|
398
|
+
binary-resolution plan
|
|
399
|
+
([plan doc](plan/sprints/bugfix_githook_binary_resolution.md)).
|
|
400
|
+
"""
|
|
401
|
+
hooks_dir = temp_git_repo / ".git" / "hooks"
|
|
402
|
+
hooks_dir.mkdir(parents=True, exist_ok=True)
|
|
403
|
+
stale = hooks_dir / "post-checkout"
|
|
404
|
+
# Old v1.33.1-era template: fixed embedded literal, no run-time preamble.
|
|
405
|
+
stale.write_text(
|
|
406
|
+
"#!/bin/sh\n"
|
|
407
|
+
"# sqlcg post-checkout hook — incremental resync after branch switch\n"
|
|
408
|
+
'[ "$3" = "1" ] || exit 0\n'
|
|
409
|
+
'/old/path/sqlcg reindex --from "$1" --to "$2" "$(git rev-parse --show-toplevel)"'
|
|
410
|
+
" --dialect auto --quiet --notify\n"
|
|
411
|
+
)
|
|
412
|
+
stale.chmod(0o755)
|
|
413
|
+
|
|
414
|
+
result = runner.invoke(app, ["git", "install-hooks", "--repo", str(temp_git_repo)])
|
|
415
|
+
|
|
416
|
+
assert result.exit_code == 0
|
|
417
|
+
assert "Upgraded git hook:" in result.output
|
|
418
|
+
upgraded = stale.read_text()
|
|
419
|
+
assert "command -v sqlcg" in upgraded
|
|
420
|
+
assert '"$SQLCG_BIN" reindex' in upgraded
|
|
421
|
+
assert "/old/path/sqlcg reindex" not in upgraded
|
|
@@ -55,7 +55,11 @@ def test_post_checkout_contains_reindex_with_sha_args(temp_git_repo):
|
|
|
55
55
|
runner.invoke(app, ["git", "install-hooks", "--repo", str(temp_git_repo)])
|
|
56
56
|
|
|
57
57
|
content = hook_path.read_text()
|
|
58
|
-
|
|
58
|
+
# Run-time resolution (#126/#1): the binary is invoked via $SQLCG_BIN, resolved
|
|
59
|
+
# by the preamble (preferred path -> command -v sqlcg -> loud error), not a fixed
|
|
60
|
+
# embedded literal.
|
|
61
|
+
assert '"$SQLCG_BIN" reindex' in content
|
|
62
|
+
assert "command -v sqlcg" in content
|
|
59
63
|
assert '--from "$1"' in content
|
|
60
64
|
assert '--to "$2"' in content
|
|
61
65
|
assert "--dialect auto" in content
|
|
@@ -101,7 +105,8 @@ def test_post_merge_contains_orig_head_guard(temp_git_repo):
|
|
|
101
105
|
runner.invoke(app, ["git", "install-hooks", "--repo", str(temp_git_repo)])
|
|
102
106
|
|
|
103
107
|
content = hook_path.read_text()
|
|
104
|
-
assert "
|
|
108
|
+
assert '"$SQLCG_BIN" reindex' in content
|
|
109
|
+
assert "command -v sqlcg" in content
|
|
105
110
|
# ORIG_HEAD guard — reads pre-merge HEAD via git rev-parse
|
|
106
111
|
assert "git rev-parse --verify --quiet ORIG_HEAD" in content
|
|
107
112
|
# If-branch: passes explicit SHAs to enable server routing
|
|
@@ -444,11 +449,14 @@ def test_install_hooks_fails_outside_git_repo():
|
|
|
444
449
|
|
|
445
450
|
|
|
446
451
|
def test_install_hooks_embeds_absolute_binary_path(temp_git_repo, monkeypatch):
|
|
447
|
-
"""Scenario E:
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
+
"""Scenario E: the resolved absolute path is the PREFERRED run-time entry.
|
|
453
|
+
|
|
454
|
+
Run-time resolution (#126/#1): the absolute path is no longer the literal that
|
|
455
|
+
invokes reindex. It is rendered into the preamble's preferred branch
|
|
456
|
+
(`if [ -x "<abs>" ]`); the body invokes `$SQLCG_BIN`, with `command -v sqlcg`
|
|
457
|
+
as the run-time fallback. Asserts:
|
|
458
|
+
- the resolved absolute path appears as the preferred preamble entry
|
|
459
|
+
- the body invokes "$SQLCG_BIN" reindex (not a fixed literal that can go stale)
|
|
452
460
|
- sentinel comments are present (R9 idempotency preserved)
|
|
453
461
|
"""
|
|
454
462
|
import sqlcg.cli.commands.git as _git_mod
|
|
@@ -464,18 +472,19 @@ def test_install_hooks_embeds_absolute_binary_path(temp_git_repo, monkeypatch):
|
|
|
464
472
|
co_content = co_hook.read_text()
|
|
465
473
|
pm_content = pm_hook.read_text()
|
|
466
474
|
|
|
467
|
-
#
|
|
468
|
-
assert f"{abs_bin}
|
|
469
|
-
f"post-checkout must
|
|
475
|
+
# The absolute path is the preferred run-time entry in the resolution preamble.
|
|
476
|
+
assert f'if [ -x "{abs_bin}" ]' in co_content, (
|
|
477
|
+
f"post-checkout must prefer the absolute path. Got:\n{co_content}"
|
|
470
478
|
)
|
|
471
|
-
assert f"{abs_bin}
|
|
472
|
-
f"post-merge must
|
|
479
|
+
assert f'if [ -x "{abs_bin}" ]' in pm_content, (
|
|
480
|
+
f"post-merge must prefer the absolute path. Got:\n{pm_content}"
|
|
473
481
|
)
|
|
474
482
|
|
|
475
|
-
#
|
|
476
|
-
|
|
477
|
-
assert "
|
|
478
|
-
assert "
|
|
483
|
+
# The body invokes the resolved $SQLCG_BIN, with command -v sqlcg as the fallback.
|
|
484
|
+
assert '"$SQLCG_BIN" reindex' in co_content
|
|
485
|
+
assert '"$SQLCG_BIN" reindex' in pm_content
|
|
486
|
+
assert "command -v sqlcg" in co_content
|
|
487
|
+
assert "command -v sqlcg" in pm_content
|
|
479
488
|
|
|
480
489
|
# Sentinels must be unchanged (R9 idempotency)
|
|
481
490
|
assert "# sqlcg post-checkout hook" in co_content
|
|
@@ -516,11 +525,15 @@ def test_install_hooks_idempotent_with_absolute_path(temp_git_repo, monkeypatch)
|
|
|
516
525
|
|
|
517
526
|
|
|
518
527
|
def test_install_hooks_bare_fallback_when_no_binary_resolvable(temp_git_repo, monkeypatch):
|
|
519
|
-
"""Scenario G:
|
|
528
|
+
"""Scenario G: no resolvable binary at install -> bare 'sqlcg' preferred entry + warning.
|
|
520
529
|
|
|
521
|
-
|
|
530
|
+
Run-time resolution (#126/#1): even when install-time resolution returns the bare
|
|
531
|
+
'sqlcg' literal, the rendered hook still relies on the run-time preamble — the bare
|
|
532
|
+
'sqlcg' is the preferred entry and `command -v sqlcg` is the run-time fallback, with
|
|
533
|
+
a loud error branch if neither resolves. Asserts:
|
|
522
534
|
- install-hooks does NOT hard-fail
|
|
523
|
-
- the
|
|
535
|
+
- the preamble renders the bare 'sqlcg' preferred entry + command -v fallback
|
|
536
|
+
- the body invokes "$SQLCG_BIN" reindex
|
|
524
537
|
- a one-line warning is printed to output
|
|
525
538
|
"""
|
|
526
539
|
import sqlcg.cli.commands.git as _git_mod
|
|
@@ -540,9 +553,13 @@ def test_install_hooks_bare_fallback_when_no_binary_resolvable(temp_git_repo, mo
|
|
|
540
553
|
co_content = (temp_git_repo / ".git" / "hooks" / "post-checkout").read_text()
|
|
541
554
|
pm_content = (temp_git_repo / ".git" / "hooks" / "post-merge").read_text()
|
|
542
555
|
|
|
543
|
-
#
|
|
544
|
-
assert "sqlcg
|
|
545
|
-
assert "sqlcg
|
|
556
|
+
# Bare 'sqlcg' is rendered as the preferred preamble entry; run-time fallback is PATH.
|
|
557
|
+
assert 'if [ -x "sqlcg" ]' in co_content
|
|
558
|
+
assert 'if [ -x "sqlcg" ]' in pm_content
|
|
559
|
+
assert "command -v sqlcg" in co_content
|
|
560
|
+
assert "command -v sqlcg" in pm_content
|
|
561
|
+
assert '"$SQLCG_BIN" reindex' in co_content
|
|
562
|
+
assert '"$SQLCG_BIN" reindex' in pm_content
|
|
546
563
|
|
|
547
564
|
# Warning must be printed
|
|
548
565
|
assert "warning" in result.output.lower() or "warn" in result.output.lower(), (
|
|
@@ -479,3 +479,191 @@ class TestHookResyncLogPath:
|
|
|
479
479
|
log_path = reindex_module._hook_resync_log_path()
|
|
480
480
|
|
|
481
481
|
assert log_path == db_path.parent / "hook-resync.log"
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
# ---------------------------------------------------------------------------
|
|
485
|
+
# #1 — loud foreground preflight on schema/version skew before detaching
|
|
486
|
+
# ---------------------------------------------------------------------------
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
def _seed_db_with_schema_version(db_path: Path, version: str) -> None:
|
|
490
|
+
"""Create a graph whose stored SchemaVersion row has the given version.
|
|
491
|
+
|
|
492
|
+
Writes the row directly so we can simulate a *stale-binary* graph whose
|
|
493
|
+
stored schema version differs from the current build's ``SCHEMA_VERSION``.
|
|
494
|
+
"""
|
|
495
|
+
from sqlcg.core.duckdb_backend import DuckDBBackend
|
|
496
|
+
|
|
497
|
+
backend = DuckDBBackend(str(db_path))
|
|
498
|
+
backend.init_schema()
|
|
499
|
+
backend._conn.execute('DELETE FROM "SchemaVersion"')
|
|
500
|
+
backend._conn.execute(
|
|
501
|
+
'INSERT INTO "SchemaVersion" (version, indexed_sha, sqlcg_version) VALUES (?, ?, ?)',
|
|
502
|
+
[version, "deadbeef", "1.25.6"],
|
|
503
|
+
)
|
|
504
|
+
backend.close()
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
class TestHookPreflightSchemaSkew:
|
|
508
|
+
"""A stale-binary schema skew on the hook path fails LOUDLY, never silently (#1)."""
|
|
509
|
+
|
|
510
|
+
def test_schema_mismatch_exits_nonzero_with_message_and_no_detach(
|
|
511
|
+
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
512
|
+
):
|
|
513
|
+
"""Stored schema != current -> non-zero exit, visible message, NO detach spawn.
|
|
514
|
+
|
|
515
|
+
Inverts the #1 silent-exit-0 failure mode: before the fix the schema gate
|
|
516
|
+
ran in the detached child (log file only); now the foreground preflight
|
|
517
|
+
surfaces it. Guards the git-hook binary-resolution plan
|
|
518
|
+
([plan doc](plan/sprints/bugfix_githook_binary_resolution.md)).
|
|
519
|
+
"""
|
|
520
|
+
repo = _git_repo(tmp_path)
|
|
521
|
+
sha_a = subprocess.run(
|
|
522
|
+
["git", "rev-parse", "HEAD"], cwd=repo, check=True, capture_output=True, text=True
|
|
523
|
+
).stdout.strip()
|
|
524
|
+
(repo / "added.sql").write_text("CREATE TABLE ADDED (id INT);\n")
|
|
525
|
+
sha_b = _commit_all(repo, "add table")
|
|
526
|
+
|
|
527
|
+
db_path = tmp_path / "stale.db"
|
|
528
|
+
monkeypatch.setenv("SQLCG_DB_PATH", str(db_path))
|
|
529
|
+
_seed_db_with_schema_version(db_path, "8") # stale: build needs "10"
|
|
530
|
+
|
|
531
|
+
mock_popen = _DetachPopenSpy()
|
|
532
|
+
monkeypatch.setattr(reindex_module.subprocess, "Popen", mock_popen)
|
|
533
|
+
|
|
534
|
+
result = runner.invoke(
|
|
535
|
+
app,
|
|
536
|
+
[
|
|
537
|
+
"reindex",
|
|
538
|
+
str(repo),
|
|
539
|
+
"--from",
|
|
540
|
+
sha_a,
|
|
541
|
+
"--to",
|
|
542
|
+
sha_b,
|
|
543
|
+
"--dialect",
|
|
544
|
+
"ansi",
|
|
545
|
+
"--quiet",
|
|
546
|
+
"--notify",
|
|
547
|
+
],
|
|
548
|
+
)
|
|
549
|
+
|
|
550
|
+
assert result.exit_code != 0, result.output
|
|
551
|
+
assert "schema is v8" in result.output
|
|
552
|
+
assert "hook binary is stale" in result.output
|
|
553
|
+
assert "sqlcg git install-hooks" in result.output
|
|
554
|
+
# The whole point: it did NOT detach a doomed background resync.
|
|
555
|
+
mock_popen.assert_not_called()
|
|
556
|
+
|
|
557
|
+
def test_matching_schema_detaches_and_exits_zero(
|
|
558
|
+
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
559
|
+
):
|
|
560
|
+
"""Stored schema == current -> preflight is silent, detach proceeds, exit 0.
|
|
561
|
+
|
|
562
|
+
Regression guard that the preflight does not break the legitimate async
|
|
563
|
+
path. Guards the git-hook binary-resolution plan
|
|
564
|
+
([plan doc](plan/sprints/bugfix_githook_binary_resolution.md)).
|
|
565
|
+
"""
|
|
566
|
+
from sqlcg.core.schema import SCHEMA_VERSION
|
|
567
|
+
|
|
568
|
+
repo = _git_repo(tmp_path)
|
|
569
|
+
sha_a = subprocess.run(
|
|
570
|
+
["git", "rev-parse", "HEAD"], cwd=repo, check=True, capture_output=True, text=True
|
|
571
|
+
).stdout.strip()
|
|
572
|
+
(repo / "added.sql").write_text("CREATE TABLE ADDED (id INT);\n")
|
|
573
|
+
sha_b = _commit_all(repo, "add table")
|
|
574
|
+
|
|
575
|
+
db_path = tmp_path / "current.db"
|
|
576
|
+
monkeypatch.setenv("SQLCG_DB_PATH", str(db_path))
|
|
577
|
+
_seed_db_with_schema_version(db_path, SCHEMA_VERSION)
|
|
578
|
+
|
|
579
|
+
mock_popen = _DetachPopenSpy()
|
|
580
|
+
monkeypatch.setattr(reindex_module.subprocess, "Popen", mock_popen)
|
|
581
|
+
|
|
582
|
+
result = runner.invoke(
|
|
583
|
+
app,
|
|
584
|
+
[
|
|
585
|
+
"reindex",
|
|
586
|
+
str(repo),
|
|
587
|
+
"--from",
|
|
588
|
+
sha_a,
|
|
589
|
+
"--to",
|
|
590
|
+
sha_b,
|
|
591
|
+
"--dialect",
|
|
592
|
+
"ansi",
|
|
593
|
+
"--quiet",
|
|
594
|
+
"--notify",
|
|
595
|
+
],
|
|
596
|
+
)
|
|
597
|
+
|
|
598
|
+
assert result.exit_code == 0, result.output
|
|
599
|
+
assert "hook binary is stale" not in result.output
|
|
600
|
+
mock_popen.assert_called_once()
|
|
601
|
+
|
|
602
|
+
def test_locked_db_falls_through_to_detach_without_blocking_or_false_error(
|
|
603
|
+
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
604
|
+
):
|
|
605
|
+
"""B1 hot-path safety: lock held -> single fast open, fall through to detach.
|
|
606
|
+
|
|
607
|
+
Simulates a concurrent resync holding the DuckDB exclusive lock: the
|
|
608
|
+
preflight's open raises IOException. It MUST NOT retry ~31 s (a #77-class
|
|
609
|
+
stall) and MUST NOT emit a false stale-schema error — it falls through to
|
|
610
|
+
the detach path unchanged. Proves we did not reintroduce #77. Guards the
|
|
611
|
+
git-hook binary-resolution plan
|
|
612
|
+
([plan doc](plan/sprints/bugfix_githook_binary_resolution.md)).
|
|
613
|
+
"""
|
|
614
|
+
repo = _git_repo(tmp_path)
|
|
615
|
+
sha_a = subprocess.run(
|
|
616
|
+
["git", "rev-parse", "HEAD"], cwd=repo, check=True, capture_output=True, text=True
|
|
617
|
+
).stdout.strip()
|
|
618
|
+
(repo / "added.sql").write_text("CREATE TABLE ADDED (id INT);\n")
|
|
619
|
+
sha_b = _commit_all(repo, "add table")
|
|
620
|
+
|
|
621
|
+
db_path = tmp_path / "locked.db"
|
|
622
|
+
monkeypatch.setenv("SQLCG_DB_PATH", str(db_path))
|
|
623
|
+
|
|
624
|
+
# Make the preflight's read-only open raise IOException (lock held), and
|
|
625
|
+
# count calls so we can assert it was a SINGLE attempt (no 31 s retry).
|
|
626
|
+
open_calls = {"n": 0}
|
|
627
|
+
|
|
628
|
+
def _always_locked(read_only: bool = False):
|
|
629
|
+
open_calls["n"] += 1
|
|
630
|
+
raise duckdb.IOException("Conflicting lock is held — another sqlcg process is running.")
|
|
631
|
+
|
|
632
|
+
import sqlcg.core.config as config_module
|
|
633
|
+
|
|
634
|
+
monkeypatch.setattr(config_module, "get_backend", _always_locked)
|
|
635
|
+
# If the preflight ever slept (retry), fail loudly — it must be a single
|
|
636
|
+
# bounded open, not the lock-retry path.
|
|
637
|
+
monkeypatch.setattr(
|
|
638
|
+
reindex_module.time,
|
|
639
|
+
"sleep",
|
|
640
|
+
lambda _s: (_ for _ in ()).throw(
|
|
641
|
+
AssertionError("preflight must not sleep/retry on a held lock")
|
|
642
|
+
),
|
|
643
|
+
)
|
|
644
|
+
|
|
645
|
+
mock_popen = _DetachPopenSpy()
|
|
646
|
+
monkeypatch.setattr(reindex_module.subprocess, "Popen", mock_popen)
|
|
647
|
+
|
|
648
|
+
result = runner.invoke(
|
|
649
|
+
app,
|
|
650
|
+
[
|
|
651
|
+
"reindex",
|
|
652
|
+
str(repo),
|
|
653
|
+
"--from",
|
|
654
|
+
sha_a,
|
|
655
|
+
"--to",
|
|
656
|
+
sha_b,
|
|
657
|
+
"--dialect",
|
|
658
|
+
"ansi",
|
|
659
|
+
"--quiet",
|
|
660
|
+
"--notify",
|
|
661
|
+
],
|
|
662
|
+
)
|
|
663
|
+
|
|
664
|
+
assert result.exit_code == 0, result.output
|
|
665
|
+
# Fell through to detach, no false stale-schema error.
|
|
666
|
+
assert "hook binary is stale" not in result.output
|
|
667
|
+
mock_popen.assert_called_once()
|
|
668
|
+
# Single bounded open — the preflight opened exactly once (not 5x retry).
|
|
669
|
+
assert open_calls["n"] == 1, f"preflight opened {open_calls['n']} times (must be 1)"
|