sql-code-graph 1.35.0__tar.gz → 1.35.2__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.35.0 → sql_code_graph-1.35.2}/PKG-INFO +1 -1
- sql_code_graph-1.35.2/plan/metrics/pr_b_phantom_after.json +32 -0
- sql_code_graph-1.35.2/plan/metrics/pr_b_phantom_before.json +32 -0
- sql_code_graph-1.35.2/plan/metrics/pr_c_merge_after.json +31 -0
- sql_code_graph-1.35.2/plan/metrics/pr_c_merge_before.json +31 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/pyproject.toml +1 -1
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/__init__.py +1 -1
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/parsers/ansi_parser.py +35 -16
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/parsers/base.py +193 -18
- sql_code_graph-1.35.2/src/sqlcg/parsers/dynamic_name.py +170 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_non_table_create_kind_in_graph.py +35 -30
- sql_code_graph-1.35.2/tests/integration/test_phantom_non_table_create_node.py +80 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_skip_counts_integration.py +12 -10
- sql_code_graph-1.35.2/tests/snowflake/E16/test_e16.py +59 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/test_plan_review_gates.py +9 -12
- sql_code_graph-1.35.2/tests/unit/test_dynamic_name_resolution.py +148 -0
- sql_code_graph-1.35.2/tests/unit/test_merge_column_lineage.py +154 -0
- sql_code_graph-1.35.2/tests/unit/test_phantom_non_table_create_source.py +149 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/uv.lock +1 -1
- sql_code_graph-1.35.0/tests/snowflake/E16/test_e16.py +0 -51
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.claude/agents/api-documenter.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.claude/agents/architect-planner.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.claude/agents/architect-reviewer.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.claude/agents/code-reviewer.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.claude/agents/developer.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.claude/agents/plan-reviewer.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.claude/agents/sprint-planner.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.github/workflows/benchmark.yml +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.github/workflows/e2e-tests.yml +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.github/workflows/release.yml +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.github/workflows/test.yml +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.gitignore +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.pre-commit-config.yaml +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/.sqlcgignore +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/ARCHITECTURE_REVIEW.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/ARCHITECTURE_REVIEW_ARCHIVE.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/CHANGELOG.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/CLAUDE.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/README.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/docs/AIRBNB_PARSE_REPORT.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/docs/cli.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/docs/getting-started.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/docs/releasing-pypi.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/e2e_firstuser_report.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/e2e_run_20260528_101413.output +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/main.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/WORKFLOW.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/measurements/pr2_catalog_load_eval.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/measurements/pr3_repo_native_plateau.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/measurements/pr4_transform_kinds.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/measurements/pr5_extraction_recall_taxonomy.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/measurements/sprint_08_changelogs_fullindex.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/measurements/sprint_08_fullcorpus_index.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/createkind_dwh_after.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/createkind_dwh_before.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/gain_1.29.0_05c6943.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/gain_1.30.0_2c8ac25.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/gain_1.30.1_26271fc.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/gain_1.31.0_a40c837.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/gain_1.32.0_c1bec3c.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/lineage5_dwh_after_pr5.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/lineage5_dwh_before_master.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/pr4_star_promote_after.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/pr4_star_promote_before.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/schema_comparison_with_schema.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/schema_comparison_without_schema.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/sprint_08_changelogs_fullindex.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/sprint_08_fullcorpus_index.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/metrics/sprint_pool_300s_plan.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/reports/column_coverage_diagnostic.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/reports/column_coverage_findings.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/reports/dwh_graph_analysis.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/reports/dwh_positional_insert_column_blindspot.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/reports/feature_acceptance_dwh.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/reports/graph_health_sprint_postmortem.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/reports/island_lever_live_verification.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/reports/issue38_pr2_live_acceptance.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/reports/issue38_pr3_live_acceptance.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/reports/lineage_identity_sprint_postmortem.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/reports/pr_impact_followups_2026-06-14.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/reports/sprint_03_v0.3.1_postmortem.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/reports/sprint_3.1_postmortem.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/reports/v1_14_dialect_query_config_postmortem.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/research/blueprint.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/research/coverage_parse_failure_diagnosis.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/research/investigation_e5_e4.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/research/observed_usage_overlay_query_history_tableau.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/research/parse_diagnostics.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/research/parsing_errors_experiment.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/research/snowflake_en_test_suite.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/research/sql_only_coverage_lever_post_pr2.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/research/sqlcg.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/bundle_claude_skill.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/ci_tests_pool_flake_fix.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/column_lineage_recall_metric.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/coverage_p1_p3_p4.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/coverage_p1_p5_metric.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/coverage_parse_failures.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/diff-impact-producer-file.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/e8_dual_emission.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/feature_34_unused_presentation_segregation.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/feature_35_external_downstream_injection.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/feature_F2_bundle_claude_skill.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/feature_kuzu_to_duckdb_migration.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/fix_backward_self_heal_index_at_sha.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/fix_downstream_sink_location.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/fix_dynamic_table_parsing.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/fix_expand_qualify_perf.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/fix_firstuser_findings.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/fix_issue29_live_test_followups.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/fix_schema_case_mismatch.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/gain_coverage_metrics.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/graph_health_catalog_and_metrics.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/hygiene_config_path_and_survivors.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/issue-38-backfill-cte-bridge.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/issue-38-residual-source-extraction.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/issue-38-selects-from-island-lever.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/living_codebase_resync.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/mcp_server_self_healing.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/positional_insert_clone_blindspot.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_01.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_01_deployment_pypi.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_02.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_02_v0.3.0_core.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_03.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_04_column_lineage.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_04_column_lineage_fix.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_05_star_resolution.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_06_lineage_coverage.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_07_open_ecodes.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_07_perf_and_live_test.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_08_perf_upsert.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_09_lineage_coverage.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_10_anchor_tools.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_11_v1.0.2_bugfix.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_12_v1.1.0.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_13_v1.1.0_cluster_b.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_lineage_identity_and_session_context.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/sprint_postmortem_fixes.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/temp_table_namespacing.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/trust_layer.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/unfilled_table_impact.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/v1.1.0_cluster_b_provenance_trust.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/v1.1.0_live_graph_freshness.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/v1.1.1_batch_upsert_perf.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/v1.14.0_dialect_and_query_config_fixes.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/v1_1_2_bugfix.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/v1_1_3_union_cte_star.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/v1_2_0_read_proxy.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/v1_2_1_bugfix.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/plan/sprints/version-parity-and-restart.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/profile.html +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/pyrightconfig.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/scripts/collect_parse_errors.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/scripts/column_coverage_check.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/scripts/generate_cli_docs.sh +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/__main__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/analyze.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/catalog.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/db.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/find.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/gain.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/git.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/index.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/install.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/mcp.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/reindex.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/report.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/uninstall.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/viz.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/commands/watch.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/coverage.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/cli/main.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/core/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/core/config.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/core/duckdb_backend.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/core/freshness.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/core/graph_db.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/core/jobs.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/core/noise_match.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/core/queries.cypher +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/core/queries.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/core/queries.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/core/schema.cypher +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/core/schema.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/indexer/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/indexer/dbt_adapter.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/indexer/error_classify.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/indexer/git_delta.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/indexer/indexer.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/indexer/pool.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/indexer/walker.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/indexer/watcher.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/lineage/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/lineage/aggregator.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/lineage/schema_resolver.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/metrics/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/metrics/store.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/parsers/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/parsers/bigquery_parser.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/parsers/postgres_parser.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/parsers/registry.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/parsers/snowflake_parser.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/parsers/tsql_parser.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/server/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/server/control.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/server/exceptions.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/server/models.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/server/noise_filter.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/server/read_client.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/server/selfheal.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/server/server.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/server/skill.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/server/tools.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/server/writer.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/utils/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/utils/hashing.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/utils/ignore.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/utils/logging.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/viz/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/viz/assets/force-graph.min.js +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/viz/assets/template.html +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/viz/data.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/viz/render.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/src/sqlcg/viz/tags.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/adversarial/200_join.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/adversarial/500_union.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/bench_indexer.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/conftest.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/golden_corpus/snowflake/case_normalization.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/golden_corpus/snowflake/colon_cast.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/golden_corpus/snowflake/colon_reserved_word.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/golden_corpus/snowflake/copy_into.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/golden_corpus/snowflake/create_procedure.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/golden_corpus/snowflake/identifier_dynamic.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/golden_corpus/snowflake/lateral_flatten.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/golden_corpus/snowflake/qualify.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/golden_corpus/snowflake/scripting_block.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/golden_corpus/snowflake/three_part.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/tpch/q01.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/tpch/q02.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/tpch/q03.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/tpch/q04.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/benchmarks/tpch/q05.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/conftest.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/conftest.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/test_F2_skill_install_e2e.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/test_airbnb_e2e.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/test_cli_index.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/test_empty_impact_cli_e2e.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/test_git_hook_install.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/test_golden_lineage.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/test_mcp_lifecycle.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/test_mcp_tools.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/test_parse_diagnostics_cli.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/test_pr_impact_cli_e2e.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/test_selfheal_e2e.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/test_star_resolution_e2e.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/test_viz_cli_e2e.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/e2e/test_watch.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/airbnb/dim_hosts_cleansed.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/airbnb/dim_listings_cleansed.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/airbnb/fct_reviews.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/airbnb/mart_fullmoon_reviews.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/airbnb/raw_hosts.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/airbnb/raw_listings.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/airbnb/raw_reviews.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/airbnb/src_hosts.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/airbnb/src_listings.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/airbnb/src_reviews.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/bigquery/.gitkeep +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/duckdb_parity/kuzu_reference.json +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/jaffle_shop/customers.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/jaffle_shop/orders.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/jaffle_shop/raw_orders.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/snowflake/base_tables.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/snowflake/reports.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/snowflake/views.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/star_corpus/ddl_src.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/star_corpus/ddl_tgt.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/star_corpus/etl_alias_star.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/star_corpus/etl_star.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/synthetic/base_tables.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/synthetic/reports.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/fixtures/synthetic/views.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/snowflake/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/snowflake/test_insert_select.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/snowflake/test_qualify_bare_tables_command_guard_integration.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_T34_presentation_segregation.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_T35_external_consumers.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_analyze_case_fold.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_anchor_tools.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_backfill_impact_consistency.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_bare_column_cte_lineage.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_bulk_upsert.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_case_split_seed_regression.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_catalog_kind_upgrade.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_catalog_load_integration.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_cli_index_clear_before_rebuild.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_column_coverage_patterns.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_column_lineage_e2e.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_coverage_metrics_integration.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_cross_file_lineage.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_cte_key_namespacing_integration.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_cte_recall_guard.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_cte_schema_alias_guard.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_cte_source_node_invariant.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_dialect_auto_resolution.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_dialect_matrix.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_duckdb_parity.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_e36_xfile_regression_guard.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_empty_impact_blast_radius.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_empty_index_rollback_guard.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_freshness_mcp.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_gating_join_retrofit.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_hygiene_config_root_reconciliation.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_identity_counters_integration.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_impact_consumer_parity.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_index_degraded_files_metric.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_index_filter_node_exclusion.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_indexer_batching.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_indexer_commits.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_indexer_to_graph.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_issue38_cte_insert_regression.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_join_col_resolution.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_key_normalization_chokepoint.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_live_anchors.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_mvcc_rebuild.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_non_table_create_coverage_no_regression.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_parse_diagnostics.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_pr1_confidence_reason.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_pr2_source_location.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_pr3_kind_tagging.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_pr_impact_integration.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_qualify_failed_persist.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_read_via_server.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_readonly_under_lock.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_reindex_via_server.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_repo_relative_cte_namespaces.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_resolvable_write_col_edges_integration.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_resync.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_selects_from_completeness.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_selects_from_cte_body_source.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_selects_from_subscope_source.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_single_writer_queue.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_star_promote_temp_columns.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_star_resolution.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_temp_table_lineage.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_temp_table_namespacing.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_tool_version_stamp_integration.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_union_cte_star_recall_guard.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_usage_derived_catalog.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_use_schema_session_context_integration.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_user_surface_recall_guard.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_v141_surface_guards.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_v1_14_0_dialect_and_query_config_fixes.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_view_kind_in_graph.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_viz_data_build.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/integration/test_write_memory_ceiling.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/perf/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/perf/test_perf.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E10/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E11/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E12/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E12/e12_json_path.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E12/e12_lateral_flatten.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E12/test_e12.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E13/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E14/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E15/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E16/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E16/e16_merge.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E16/e16_merge_delete.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E17/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E18/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E18/e18_decode.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E18/e18_iff_decode.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E18/e18_nvl2.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E18/test_e18.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E19/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E2/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E2/e2_expr_alias.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E2/e2_function_alias.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E2/e2_multiply_alias.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E2/test_e2.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E20/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E21/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E21/e21_alias_forward_ref.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E21/e21_three_level_chain.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E21/test_e21.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E22/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E23/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E23/e23_stored_proc.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E23/e23_stored_proc_multi.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E23/test_e23.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E24/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E25/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E25/e25_cross_db.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E25/e25_two_part.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E25/test_e25.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E25/test_e25_full_id.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E26/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E27/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E27/e27_nested_udf.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E27/e27_udf.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E27/test_e27.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E28/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E29/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E3/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E3/e3_alter_table.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E3/e3_create_sequence.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E3/e3_ddl_only.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E3/test_e3.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E30/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E31/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E32/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E33/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E34/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E35/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E36/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E36/e36_temp_multi_use.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E36/e36_temp_table.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E36/test_e36.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E36/test_e36_xfile.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E37/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E38/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E4/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E4/e4_execute_immediate.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E4/e4_if_not_exists.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E4/e4_unexpected_token.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E4/e4_unpivot.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E4/test_e4.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E5/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E5/e5_cte_missing_source.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E5/e5_multi_cte.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E5/e5_nested_cte.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E5/test_e5.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E5/test_e5_cte_projection.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E8/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E8/e8_dynamic_sources.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E8/e8_seq_nextval.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E8/e8_uuid.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E8/test_e8.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E9/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E_aggregates/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E_aggregates/fixture_sum_absent_cross_schema.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E_aggregates/fixture_sum_case_when.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E_aggregates/fixture_sum_present_source.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E_aggregates/test_e_aggregates.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E_date_functions/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E_date_functions/fixture_date_aliased.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E_date_functions/fixture_date_unaliased.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E_date_functions/fixture_datediff_unaliased.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E_date_functions/fixture_year_unaliased.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/E_date_functions/test_e_date_functions.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/README.md +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/anchors/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/anchors/fixture_etl.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/anchors/fixture_omloopsnelheid.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/anchors/fixture_semantic.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/anchors/fixture_source.sql +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/anchors/test_anchor_ma_aantal_op_order.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/anchors/test_anchor_omloopsnelheid.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/snowflake/conftest.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/snowflake/__init__.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/snowflake/test_qualify_bare_tables_command_guard.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/snowflake/test_scripting_noise.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_BugB_escalation_uses_init_path.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_BugC_hook_upgrade.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_F2_install_skill.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_F2_skill_render.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_F2_uninstall_skill.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_T09_01_qualify_once.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_T09_02_ddl_skip.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_T09_04_subprocess_isolate.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_T09_06_log_verbosity.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_T35_config_external_consumers.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_aggregator.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_aggregator_skip.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_analyze_case_fold.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_base_parser.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_branch_monitor.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_bulk_upsert_invariant.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_canonical_target_resolution.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_catalog_csv_parsing.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_catalog_missing_warning.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_classify_non_table_create_kind.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_cli.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_cli_doc_flag_staleness.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_cli_help.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_clone_positional_insert_blindspot.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_closure_depth.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_column_lineage_wiring.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_config.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_coverage_metrics.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_cte_key_namespacing.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_cte_source_gap_metric.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_data_models.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_db_info.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_db_info_coverage.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_db_path_isolation_fixture.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_doc_links.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_doc_markdown_link_existence.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_dominant_cause.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_duckdb_backend.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_duckdb_backend_shared.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_e5_view_alias_resolution.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_e8_dual_emission.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_e8_temp_chain_key_mismatch.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_empty_propagation_unit.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_extract_select_output_columns.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_file_ignore_defaults.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_find_cmd.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_firstuser_findings.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_freshness_helper.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_gain_coverage.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_gain_ratio.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_gating_join_field_docstrings.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_git_delta.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_git_hooks.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_git_hooks_notify.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_graph_backend.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_graph_completeness_invariant.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_hard_kill_pool.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_has_column_precedence_upsert.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_hook_reindex_detach.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_hygiene_config_warning.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_identity_counters.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_include_working_tree.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_index_cmd.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_index_filter_config.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_index_flags.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_index_progress.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_index_summary_degraded_metric.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_indexer_progress.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_indexer_quality.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_install.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_install_message.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_issue_63_readonly_lock.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_jobs.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_join_col_resolve_marker.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_judgement.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_lineage_conversion.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_literal_column_skip.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_mcp_best_practices.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_mcp_control.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_mcp_stdio_smoke.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_metrics.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_noise_filter.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_normalize_keys.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_parse_failed_classification.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_parse_file_dependency_filter.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_parse_quality.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_parser.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_perf_scaling_guard.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_pr07_observability.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_pr6_execute_immediate_unwrap.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_pr_impact_unit.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_qualify_failed_unit.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_queries_loader.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_read_client.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_repo_relative_cte_namespaces.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_resolvable_write_col_edges_unit.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_resolve_join_columns_sql.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_resolve_pass2_passes_dependency_filter.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_schema_resolver.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_selects_from_completeness_unit.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_selfheal_detector.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_selfheal_pr1_messages.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_selfheal_reexec.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_selfheal_watcher.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_server.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_skip_counts_persistence.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_snowflake_strip_alter_set_tag.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_sprint_06_t04_t05.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_star_resolution_unit.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_star_schema_unit.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_submit_feedback.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_subprocess_isolate.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_t02_expression_name_extraction.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_t03_ddl_skip.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_temp_table_namespacing.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_timeout_cancel.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_tool_version_stamp.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_tools_hints.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_tools_warnings.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_transform_kind_classification.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_uninstall.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_unknown_sentinel_skip.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_unqualified_fallback.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_upsert_batch_invariant.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_use_schema_session_context.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_version_parity.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_view_classification.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_viz_config_schemas.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_viz_facets.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_viz_render_self_contained.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_walker.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_watcher.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/tests/unit/test_worker_error_classification.py +0 -0
- {sql_code_graph-1.35.0 → sql_code_graph-1.35.2}/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.35.
|
|
3
|
+
Version: 1.35.2
|
|
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
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{"total_calls": 1476, "last_7d_calls": 1476, "index_runs": 5, "feedback_tp": 0,
|
|
2
|
+
"feedback_total": 0, "top_tools": [{"name": "execute_sql", "count": 496},
|
|
3
|
+
{"name": "trace_column_lineage", "count": 389}, {"name":
|
|
4
|
+
"list_dialects_and_repos", "count": 127}], "execute_sql_ratio": 0.34,
|
|
5
|
+
"parse_quality": {"sqlglot": 5166, "scripting": 20, "dynamic_sql": 3},
|
|
6
|
+
"coverage": {"catalogued_tables": 5800, "total_tables": 6552, "good_edges":
|
|
7
|
+
52657, "total_edges": 60805, "phantom_edges": 12241, "blindspot_tables": 628,
|
|
8
|
+
"good_edges_strict": 48140, "edge_health_strict_pct": 79.17,
|
|
9
|
+
"good_edges_scoped": 37460, "total_edges_scoped": 38009,
|
|
10
|
+
"edge_health_scoped_pct": 98.56, "phantom_confirmed": 11701,
|
|
11
|
+
"phantom_contradicted": 352, "phantom_unverified": 188, "top_blindspot_tables":
|
|
12
|
+
[{"table": "ba.wtfa_kpi_datum_klant", "bad_edges": 70}, {"table":
|
|
13
|
+
"ba.wtfs_voorraad_dagstand", "bad_edges": 55}, {"table":
|
|
14
|
+
"ba.wtfs_voorraad_zondagstand", "bad_edges": 55}, {"table":
|
|
15
|
+
"da.rtgmd_postnl_customer_usage", "bad_edges": 43}, {"table":
|
|
16
|
+
"da.rtgmd_postnl_athome_3s", "bad_edges": 33}, {"table":
|
|
17
|
+
"wtfe_kpi_voorraad_artikel_voorraadlocatie", "bad_edges": 32}, {"table":
|
|
18
|
+
"da.rtgmd_postnl_facturen", "bad_edges": 30}, {"table": "da.hthyb_pages",
|
|
19
|
+
"bad_edges": 23}, {"table": "da.rtgmd_dhb_extra_kosten", "bad_edges": 19},
|
|
20
|
+
{"table": "da.hthyb_page_brandplacement", "bad_edges": 17}],
|
|
21
|
+
"blindspot_tables_for_80pct": 17, "files_indexed": 1335, "indexed_sha":
|
|
22
|
+
"fdf1b551a34601a6cf3ce1c8b9f76e27ce2753e6", "db_path":
|
|
23
|
+
"/tmp/sqlcg-gain-after.db", "index_timestamp": 1781466521.041257,
|
|
24
|
+
"degraded_parse_total": 5189, "degraded_parse_queries": 20,
|
|
25
|
+
"degraded_parse_by_dir": {"etl": {"degraded": 1, "total": 2776}, "ddl":
|
|
26
|
+
{"degraded": 19, "total": 2413}}, "zero_edge_write_queries": 1034,
|
|
27
|
+
"total_write_queries": 2323, "cte_key_collisions": 0,
|
|
28
|
+
"rescuable_unqualified_edges": 125, "info_schema_has_column_rows": 100193,
|
|
29
|
+
"cte_source_gap_writes": 0, "resolvable_write_col_edges": 36936,
|
|
30
|
+
"transitive_col_edges": 4168, "qualify_failed_statements": 9,
|
|
31
|
+
"tool_version_stale": false, "indexed_tool_version": "1.34.5",
|
|
32
|
+
"running_tool_version": "1.34.5"}}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{"total_calls": 1476, "last_7d_calls": 1476, "index_runs": 5, "feedback_tp": 0,
|
|
2
|
+
"feedback_total": 0, "top_tools": [{"name": "execute_sql", "count": 496},
|
|
3
|
+
{"name": "trace_column_lineage", "count": 389}, {"name":
|
|
4
|
+
"list_dialects_and_repos", "count": 127}], "execute_sql_ratio": 0.34,
|
|
5
|
+
"parse_quality": {"sqlglot": 5166, "scripting": 20, "dynamic_sql": 3},
|
|
6
|
+
"coverage": {"catalogued_tables": 5800, "total_tables": 6581, "good_edges":
|
|
7
|
+
52669, "total_edges": 60817, "phantom_edges": 12241, "blindspot_tables": 628,
|
|
8
|
+
"good_edges_strict": 48140, "edge_health_strict_pct": 79.16,
|
|
9
|
+
"good_edges_scoped": 37460, "total_edges_scoped": 38009,
|
|
10
|
+
"edge_health_scoped_pct": 98.56, "phantom_confirmed": 11701,
|
|
11
|
+
"phantom_contradicted": 352, "phantom_unverified": 188, "top_blindspot_tables":
|
|
12
|
+
[{"table": "ba.wtfa_kpi_datum_klant", "bad_edges": 70}, {"table":
|
|
13
|
+
"ba.wtfs_voorraad_dagstand", "bad_edges": 55}, {"table":
|
|
14
|
+
"ba.wtfs_voorraad_zondagstand", "bad_edges": 55}, {"table":
|
|
15
|
+
"da.rtgmd_postnl_customer_usage", "bad_edges": 43}, {"table":
|
|
16
|
+
"da.rtgmd_postnl_athome_3s", "bad_edges": 33}, {"table":
|
|
17
|
+
"wtfe_kpi_voorraad_artikel_voorraadlocatie", "bad_edges": 32}, {"table":
|
|
18
|
+
"da.rtgmd_postnl_facturen", "bad_edges": 30}, {"table": "da.hthyb_pages",
|
|
19
|
+
"bad_edges": 23}, {"table": "da.rtgmd_dhb_extra_kosten", "bad_edges": 19},
|
|
20
|
+
{"table": "da.hthyb_page_brandplacement", "bad_edges": 17}],
|
|
21
|
+
"blindspot_tables_for_80pct": 17, "files_indexed": 1335, "indexed_sha":
|
|
22
|
+
"fdf1b551a34601a6cf3ce1c8b9f76e27ce2753e6", "db_path":
|
|
23
|
+
"/tmp/sqlcg-gain-before.db", "index_timestamp": 1781466329.8251324,
|
|
24
|
+
"degraded_parse_total": 5189, "degraded_parse_queries": 20,
|
|
25
|
+
"degraded_parse_by_dir": {"etl": {"degraded": 1, "total": 2776}, "ddl":
|
|
26
|
+
{"degraded": 19, "total": 2413}}, "zero_edge_write_queries": 1034,
|
|
27
|
+
"total_write_queries": 2323, "cte_key_collisions": 0,
|
|
28
|
+
"rescuable_unqualified_edges": 125, "info_schema_has_column_rows": 100193,
|
|
29
|
+
"cte_source_gap_writes": 0, "resolvable_write_col_edges": 36936,
|
|
30
|
+
"transitive_col_edges": 4180, "qualify_failed_statements": 9,
|
|
31
|
+
"tool_version_stale": false, "indexed_tool_version": "1.34.4",
|
|
32
|
+
"running_tool_version": "1.34.4"}}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{"total_calls": 1616, "last_7d_calls": 1616, "index_runs": 5, "feedback_tp": 0,
|
|
2
|
+
"feedback_total": 0, "top_tools": [{"name": "execute_sql", "count": 544},
|
|
3
|
+
{"name": "trace_column_lineage", "count": 425}, {"name":
|
|
4
|
+
"list_dialects_and_repos", "count": 139}], "execute_sql_ratio": 0.34,
|
|
5
|
+
"parse_quality": {"sqlglot": 5166, "scripting": 20, "dynamic_sql": 3},
|
|
6
|
+
"coverage": {"catalogued_tables": 5800, "total_tables": 6552, "good_edges":
|
|
7
|
+
52678, "total_edges": 60826, "phantom_edges": 12241, "blindspot_tables": 628,
|
|
8
|
+
"good_edges_strict": 48151, "edge_health_strict_pct": 79.16,
|
|
9
|
+
"good_edges_scoped": 37471, "total_edges_scoped": 38020,
|
|
10
|
+
"edge_health_scoped_pct": 98.56, "phantom_confirmed": 11701,
|
|
11
|
+
"phantom_contradicted": 352, "phantom_unverified": 188, "top_blindspot_tables":
|
|
12
|
+
[{"table": "ba.wtfa_kpi_datum_klant", "bad_edges": 70}, {"table":
|
|
13
|
+
"ba.wtfs_voorraad_dagstand", "bad_edges": 55}, {"table":
|
|
14
|
+
"ba.wtfs_voorraad_zondagstand", "bad_edges": 55}, {"table":
|
|
15
|
+
"da.rtgmd_postnl_customer_usage", "bad_edges": 43}, {"table":
|
|
16
|
+
"da.rtgmd_postnl_athome_3s", "bad_edges": 33}, {"table":
|
|
17
|
+
"wtfe_kpi_voorraad_artikel_voorraadlocatie", "bad_edges": 32}, {"table":
|
|
18
|
+
"da.rtgmd_postnl_facturen", "bad_edges": 30}, {"table": "da.hthyb_pages",
|
|
19
|
+
"bad_edges": 23}, {"table": "da.rtgmd_dhb_extra_kosten", "bad_edges": 19},
|
|
20
|
+
{"table": "da.hthyb_page_brandplacement", "bad_edges": 17}],
|
|
21
|
+
"blindspot_tables_for_80pct": 17, "files_indexed": 1335, "indexed_sha":
|
|
22
|
+
"fdf1b551a34601a6cf3ce1c8b9f76e27ce2753e6", "db_path": "/tmp/mergec_after.db",
|
|
23
|
+
"index_timestamp": 1781470021.8137639, "degraded_parse_total": 5189,
|
|
24
|
+
"degraded_parse_queries": 27, "degraded_parse_by_dir": {"etl": {"degraded": 8,
|
|
25
|
+
"total": 2776}, "ddl": {"degraded": 19, "total": 2413}},
|
|
26
|
+
"zero_edge_write_queries": 1028, "total_write_queries": 2323,
|
|
27
|
+
"cte_key_collisions": 0, "rescuable_unqualified_edges": 125,
|
|
28
|
+
"info_schema_has_column_rows": 100193, "cte_source_gap_writes": 0,
|
|
29
|
+
"resolvable_write_col_edges": 36936, "transitive_col_edges": 4178,
|
|
30
|
+
"qualify_failed_statements": 9, "tool_version_stale": false,
|
|
31
|
+
"indexed_tool_version": "1.35.2", "running_tool_version": "1.35.2"}}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{"total_calls": 1616, "last_7d_calls": 1616, "index_runs": 5, "feedback_tp": 0,
|
|
2
|
+
"feedback_total": 0, "top_tools": [{"name": "execute_sql", "count": 544},
|
|
3
|
+
{"name": "trace_column_lineage", "count": 425}, {"name":
|
|
4
|
+
"list_dialects_and_repos", "count": 139}], "execute_sql_ratio": 0.34,
|
|
5
|
+
"parse_quality": {"sqlglot": 5166, "scripting": 20, "dynamic_sql": 3},
|
|
6
|
+
"coverage": {"catalogued_tables": 5800, "total_tables": 6552, "good_edges":
|
|
7
|
+
52671, "total_edges": 60819, "phantom_edges": 12241, "blindspot_tables": 628,
|
|
8
|
+
"good_edges_strict": 48140, "edge_health_strict_pct": 79.15,
|
|
9
|
+
"good_edges_scoped": 37460, "total_edges_scoped": 38009,
|
|
10
|
+
"edge_health_scoped_pct": 98.56, "phantom_confirmed": 11701,
|
|
11
|
+
"phantom_contradicted": 352, "phantom_unverified": 188, "top_blindspot_tables":
|
|
12
|
+
[{"table": "ba.wtfa_kpi_datum_klant", "bad_edges": 70}, {"table":
|
|
13
|
+
"ba.wtfs_voorraad_dagstand", "bad_edges": 55}, {"table":
|
|
14
|
+
"ba.wtfs_voorraad_zondagstand", "bad_edges": 55}, {"table":
|
|
15
|
+
"da.rtgmd_postnl_customer_usage", "bad_edges": 43}, {"table":
|
|
16
|
+
"da.rtgmd_postnl_athome_3s", "bad_edges": 33}, {"table":
|
|
17
|
+
"wtfe_kpi_voorraad_artikel_voorraadlocatie", "bad_edges": 32}, {"table":
|
|
18
|
+
"da.rtgmd_postnl_facturen", "bad_edges": 30}, {"table": "da.hthyb_pages",
|
|
19
|
+
"bad_edges": 23}, {"table": "da.rtgmd_dhb_extra_kosten", "bad_edges": 19},
|
|
20
|
+
{"table": "da.hthyb_page_brandplacement", "bad_edges": 17}],
|
|
21
|
+
"blindspot_tables_for_80pct": 17, "files_indexed": 1335, "indexed_sha":
|
|
22
|
+
"fdf1b551a34601a6cf3ce1c8b9f76e27ce2753e6", "db_path": "/tmp/mergec_before.db",
|
|
23
|
+
"index_timestamp": 1781469837.2725205, "degraded_parse_total": 5189,
|
|
24
|
+
"degraded_parse_queries": 20, "degraded_parse_by_dir": {"etl": {"degraded": 1,
|
|
25
|
+
"total": 2776}, "ddl": {"degraded": 19, "total": 2413}},
|
|
26
|
+
"zero_edge_write_queries": 1034, "total_write_queries": 2323,
|
|
27
|
+
"cte_key_collisions": 0, "rescuable_unqualified_edges": 125,
|
|
28
|
+
"info_schema_has_column_rows": 100193, "cte_source_gap_writes": 0,
|
|
29
|
+
"resolvable_write_col_edges": 36936, "transitive_col_edges": 4182,
|
|
30
|
+
"qualify_failed_statements": 9, "tool_version_stale": false,
|
|
31
|
+
"indexed_tool_version": "1.35.1", "running_tool_version": "1.35.1"}}
|
|
@@ -551,25 +551,44 @@ class AnsiParser(SqlParser):
|
|
|
551
551
|
# measurement artifact (96.1%/4,544 of 4,727 on the DWH corpus).
|
|
552
552
|
can_have_lineage = self._can_have_column_lineage(stmt)
|
|
553
553
|
|
|
554
|
+
# Phantom source-node gate (#161): a non-table/non-view CREATE
|
|
555
|
+
# (SEQUENCE / STAGE / FILE FORMAT / SCHEMA / INDEX / PROCEDURE / ...) has
|
|
556
|
+
# target=None and no data-flow source. Its only Table node is its own
|
|
557
|
+
# object name, which _fallback_table_scan below would otherwise scoop into
|
|
558
|
+
# `sources`, leaking a phantom SqlTable SOURCE node + SELECTS_FROM edge
|
|
559
|
+
# into the graph. #159 fixed the kind LABEL (-> OTHER); this closes the
|
|
560
|
+
# source-node half. Keying off stmt.kind (the sqlglot AST value, e.g.
|
|
561
|
+
# 'SEQUENCE') keeps the gate independent of the _classify/QueryKind path.
|
|
562
|
+
# CREATE TABLE/VIEW ... AS SELECT keep kind in (TABLE, VIEW) and so retain
|
|
563
|
+
# their real sources. Real procedure lineage comes from the spliced inner
|
|
564
|
+
# DML (a separate node the gate never touches), so gating PROCEDURE is
|
|
565
|
+
# edge-neutral. This single gate feeds all three
|
|
566
|
+
# `referenced_tables.extend(query_node.sources)` sites
|
|
567
|
+
# (ansi_parser.py:246, snowflake_parser.py:784 / :944).
|
|
568
|
+
is_non_table_create = isinstance(stmt, exp.Create) and stmt.kind not in ("TABLE", "VIEW")
|
|
569
|
+
|
|
554
570
|
# Try to extract table references using scope analysis
|
|
555
571
|
try:
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
if root_scope is None:
|
|
559
|
-
from sqlglot.optimizer.scope import build_scope
|
|
560
|
-
|
|
561
|
-
root_scope = build_scope(stmt)
|
|
562
|
-
|
|
563
|
-
if root_scope:
|
|
564
|
-
sources = self._real_tables(root_scope)
|
|
572
|
+
if is_non_table_create:
|
|
573
|
+
sources = []
|
|
565
574
|
else:
|
|
566
|
-
#
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
575
|
+
# Use pre-built scope if provided, otherwise build it here (fallback)
|
|
576
|
+
root_scope = scope
|
|
577
|
+
if root_scope is None:
|
|
578
|
+
from sqlglot.optimizer.scope import build_scope
|
|
579
|
+
|
|
580
|
+
root_scope = build_scope(stmt)
|
|
581
|
+
|
|
582
|
+
if root_scope:
|
|
583
|
+
sources = self._real_tables(root_scope)
|
|
584
|
+
else:
|
|
585
|
+
# Fallback to basic table extraction
|
|
586
|
+
sources = [
|
|
587
|
+
r
|
|
588
|
+
for s in self._fallback_table_scan(stmt)
|
|
589
|
+
if (r := self._apply_table_alias(s)) is not None
|
|
590
|
+
]
|
|
591
|
+
parse_failed = can_have_lineage
|
|
573
592
|
except Exception as exc:
|
|
574
593
|
logger.debug("Failed to build scope for statement %d in %s: %s", stmt_index, path, exc)
|
|
575
594
|
sources = [
|
|
@@ -637,12 +637,14 @@ class SqlParser(ABC):
|
|
|
637
637
|
"""Return True if `_extract_column_lineage` would attempt extraction for `stmt`.
|
|
638
638
|
|
|
639
639
|
Mirrors the type/body checks `_extract_column_lineage` (below, this class)
|
|
640
|
-
already performs: only `exp.Select`, `exp.Insert` with a `SELECT` body,
|
|
641
|
-
`exp.Create` with a `Select`/`Subquery` body (CTAS / CREATE VIEW AS SELECT)
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
640
|
+
already performs: only `exp.Select`, `exp.Insert` with a `SELECT` body,
|
|
641
|
+
`exp.Create` with a `Select`/`Subquery` body (CTAS / CREATE VIEW AS SELECT),
|
|
642
|
+
and `exp.Merge` (column edges extracted structurally from its WHEN clauses —
|
|
643
|
+
see `_extract_merge_lineage`, plan/sprints/sprint_snowflake_lineage_patterns.md
|
|
644
|
+
PR-C) can ever produce column-lineage edges. Everything else (Update, Delete,
|
|
645
|
+
Use, Set, Comment, Drop, Alter, Command, TruncateTable, CREATE ...
|
|
646
|
+
LIKE/CLONE/column-defs, INSERT ... VALUES) is structurally lineage-free
|
|
647
|
+
regardless of `build_scope`'s outcome.
|
|
646
648
|
|
|
647
649
|
Used by `AnsiParser._parse_statement` to avoid marking `parse_failed=True`
|
|
648
650
|
for statement kinds that were never going to produce column lineage in the
|
|
@@ -658,8 +660,185 @@ class SqlParser(ABC):
|
|
|
658
660
|
return isinstance(stmt.expression, exp.Select)
|
|
659
661
|
if isinstance(stmt, exp.Create):
|
|
660
662
|
return isinstance(stmt.expression, (exp.Select, exp.Subquery))
|
|
663
|
+
if isinstance(stmt, exp.Merge):
|
|
664
|
+
return True
|
|
661
665
|
return False
|
|
662
666
|
|
|
667
|
+
def _extract_merge_lineage(
|
|
668
|
+
self,
|
|
669
|
+
stmt: Any,
|
|
670
|
+
dst_table: "TableRef | None",
|
|
671
|
+
query_sources: list["TableRef"] | None,
|
|
672
|
+
out: ParsedFile,
|
|
673
|
+
) -> list[LineageEdge]:
|
|
674
|
+
"""Extract column-level lineage from a MERGE statement's WHEN clauses.
|
|
675
|
+
|
|
676
|
+
MERGE column edges cannot come from sqlglot's ``lineage()`` (it does not model
|
|
677
|
+
MERGE branches), but the ``WHEN MATCHED ... UPDATE SET`` and
|
|
678
|
+
``WHEN NOT MATCHED ... INSERT (cols) VALUES (vals)`` clauses are structurally
|
|
679
|
+
extractable by a direct AST walk. This method performs that walk: it is bounded
|
|
680
|
+
and runs ONCE PER MERGE statement — it NEVER calls ``sg_lineage``, ``qualify``,
|
|
681
|
+
``build_scope`` or ``exp.expand`` (AC-C7,
|
|
682
|
+
plan/sprints/sprint_snowflake_lineage_patterns.md PR-C).
|
|
683
|
+
|
|
684
|
+
Resolution model:
|
|
685
|
+
- The MERGE target (``stmt.this``) and source (``stmt.args['using']``) are both
|
|
686
|
+
captured in ``query_sources`` as already-qualified TableRefs (the table-grain
|
|
687
|
+
path does NOT split them into target/sources for MERGE — ``dst_table`` is
|
|
688
|
+
``None`` here, so AC-C3's shipped table-grain behaviour is preserved). This
|
|
689
|
+
method matches ``stmt.this``/``using`` back to those refs by alias+name to
|
|
690
|
+
identify which is the target and which the source(s), then builds an
|
|
691
|
+
alias -> TableRef map over both.
|
|
692
|
+
- MATCHED UPDATE: each ``exp.EQ`` is ``target_col = source_expr``; the dst is a
|
|
693
|
+
column on the target, the src columns are every ``exp.Column`` in the RHS
|
|
694
|
+
(multi-source expressions emit one edge per source column — AC-C4). A
|
|
695
|
+
pure-literal RHS (no ``exp.Column``) contributes no edge (AC-C5) — mirrors the
|
|
696
|
+
pure-literal skip invariant.
|
|
697
|
+
- NOT MATCHED INSERT: ``then.this`` is the target column tuple, ``then.expression``
|
|
698
|
+
the values tuple; zip positionally and emit per source column. An INSERT with
|
|
699
|
+
no column list (``then.this is None``) is skip-and-logged
|
|
700
|
+
(``col_lineage_skip:merge_no_collist:``) — NO positional DDL fallback (gate
|
|
701
|
+
decision: positional guessing risks wrong edges).
|
|
702
|
+
|
|
703
|
+
Args:
|
|
704
|
+
stmt: the ``exp.Merge`` AST node.
|
|
705
|
+
dst_table: the resolved INSERT/CREATE target TableRef from the caller. For
|
|
706
|
+
MERGE this is ``None`` (the table-grain path leaves the target in
|
|
707
|
+
``query_sources``); the target is recovered here from ``stmt.this``.
|
|
708
|
+
query_sources: resolved table refs for the MERGE (target + ``USING``
|
|
709
|
+
source(s)), each carrying its ``.alias``, fully qualified.
|
|
710
|
+
out: ParsedFile, for skip/unresolved error records.
|
|
711
|
+
|
|
712
|
+
Returns:
|
|
713
|
+
List of LineageEdge (may be empty).
|
|
714
|
+
"""
|
|
715
|
+
import sqlglot.expressions as exp
|
|
716
|
+
|
|
717
|
+
edges: list[LineageEdge] = []
|
|
718
|
+
refs = list(query_sources or [])
|
|
719
|
+
if dst_table is not None:
|
|
720
|
+
refs.append(dst_table)
|
|
721
|
+
|
|
722
|
+
# Identify the MERGE target ref by matching stmt.this against the resolved refs.
|
|
723
|
+
# `_real_tables` does not preserve the AST alias on the TableRef, so match on the
|
|
724
|
+
# AST target's name (and alias, as a fallback) against each ref's name/alias.
|
|
725
|
+
# The remaining refs are the USING source(s).
|
|
726
|
+
target_ast = stmt.this if isinstance(stmt.this, exp.Table) else None
|
|
727
|
+
target_keys: set[str] = set()
|
|
728
|
+
if target_ast is not None:
|
|
729
|
+
if target_ast.name:
|
|
730
|
+
target_keys.add(target_ast.name.lower())
|
|
731
|
+
if target_ast.alias:
|
|
732
|
+
target_keys.add(target_ast.alias.lower())
|
|
733
|
+
|
|
734
|
+
def _ref_keys(ref: TableRef) -> set[str]:
|
|
735
|
+
keys: set[str] = set()
|
|
736
|
+
if ref.alias:
|
|
737
|
+
keys.add(ref.alias.lower())
|
|
738
|
+
if ref.name:
|
|
739
|
+
keys.add(ref.name.lower())
|
|
740
|
+
return keys
|
|
741
|
+
|
|
742
|
+
target_ref: TableRef | None = None
|
|
743
|
+
if target_keys:
|
|
744
|
+
for ref in refs:
|
|
745
|
+
if target_keys & _ref_keys(ref):
|
|
746
|
+
target_ref = ref
|
|
747
|
+
break
|
|
748
|
+
if target_ref is None:
|
|
749
|
+
label = ".".join(sorted(target_keys)) or "<unknown>"
|
|
750
|
+
out.errors.append(f"col_lineage_skip:merge_no_target:{label}")
|
|
751
|
+
return edges
|
|
752
|
+
|
|
753
|
+
source_refs = [r for r in refs if r is not target_ref]
|
|
754
|
+
|
|
755
|
+
# Build an alias/name -> TableRef map over the target + USING source(s).
|
|
756
|
+
# MERGE column references qualify by the table alias (e.g. `target.name`,
|
|
757
|
+
# `s.name`). `_real_tables` strips the alias from the resolved TableRef, so the
|
|
758
|
+
# alias is recovered from the AST nodes (target=stmt.this, source=using) and
|
|
759
|
+
# mapped to its resolved ref. Bare table names are registered as a fallback.
|
|
760
|
+
alias_map: dict[str, TableRef] = {}
|
|
761
|
+
|
|
762
|
+
def _register(ref: TableRef | None, ast_node: Any) -> None:
|
|
763
|
+
if ref is None:
|
|
764
|
+
return
|
|
765
|
+
if isinstance(ast_node, exp.Table) and ast_node.alias:
|
|
766
|
+
alias_map.setdefault(ast_node.alias.lower(), ref)
|
|
767
|
+
if ref.alias:
|
|
768
|
+
alias_map.setdefault(ref.alias.lower(), ref)
|
|
769
|
+
if ref.name:
|
|
770
|
+
alias_map.setdefault(ref.name.lower(), ref)
|
|
771
|
+
|
|
772
|
+
using_ast = stmt.args.get("using")
|
|
773
|
+
_register(target_ref, target_ast)
|
|
774
|
+
for src in source_refs:
|
|
775
|
+
_register(src, using_ast if len(source_refs) == 1 else None)
|
|
776
|
+
|
|
777
|
+
def _resolve_table(col: Any) -> TableRef | None:
|
|
778
|
+
"""Resolve the owning TableRef of a source column reference."""
|
|
779
|
+
tbl_name = col.table
|
|
780
|
+
if tbl_name:
|
|
781
|
+
return alias_map.get(tbl_name.lower())
|
|
782
|
+
# Unqualified RHS column — attribute to the lone source when unambiguous.
|
|
783
|
+
if len(source_refs) == 1:
|
|
784
|
+
return source_refs[0]
|
|
785
|
+
return None
|
|
786
|
+
|
|
787
|
+
def _emit(target_col_name: str, rhs: Any, transform: str) -> None:
|
|
788
|
+
"""Emit one edge per source ``exp.Column`` found in ``rhs``."""
|
|
789
|
+
if not target_col_name:
|
|
790
|
+
return
|
|
791
|
+
cols = list(rhs.find_all(exp.Column)) if rhs is not None else []
|
|
792
|
+
if not cols:
|
|
793
|
+
# Pure-literal / no source column — no edge (AC-C5).
|
|
794
|
+
return
|
|
795
|
+
dst_ref = ColumnRef(table=target_ref, name=target_col_name)
|
|
796
|
+
for col in cols:
|
|
797
|
+
src_table = _resolve_table(col)
|
|
798
|
+
if src_table is None:
|
|
799
|
+
out.errors.append(
|
|
800
|
+
f"col_lineage_skip:merge_unresolved:{col.table or ''}.{col.name}"
|
|
801
|
+
)
|
|
802
|
+
continue
|
|
803
|
+
edges.append(
|
|
804
|
+
LineageEdge(
|
|
805
|
+
src=ColumnRef(table=src_table, name=col.name),
|
|
806
|
+
dst=dst_ref,
|
|
807
|
+
transform=transform,
|
|
808
|
+
)
|
|
809
|
+
)
|
|
810
|
+
|
|
811
|
+
for when in stmt.find_all(exp.When):
|
|
812
|
+
then = when.args.get("then")
|
|
813
|
+
if isinstance(then, exp.Update):
|
|
814
|
+
# WHEN MATCHED THEN UPDATE SET target.a = s.a, target.b = s.x + s.y
|
|
815
|
+
for eq in then.expressions:
|
|
816
|
+
if not isinstance(eq, exp.EQ):
|
|
817
|
+
continue
|
|
818
|
+
lhs = eq.this
|
|
819
|
+
if not isinstance(lhs, exp.Column):
|
|
820
|
+
continue
|
|
821
|
+
_emit(lhs.name, eq.expression, "MERGE_UPDATE")
|
|
822
|
+
elif isinstance(then, exp.Insert):
|
|
823
|
+
# WHEN NOT MATCHED THEN INSERT (cols) VALUES (vals)
|
|
824
|
+
target_cols = then.this
|
|
825
|
+
values = then.expression
|
|
826
|
+
if target_cols is None:
|
|
827
|
+
# INSERT VALUES with no column list — skip-and-log, no positional
|
|
828
|
+
# DDL fallback (gate decision: positional guessing risks wrong edges).
|
|
829
|
+
out.errors.append(f"col_lineage_skip:merge_no_collist:{target_ref.full_id}")
|
|
830
|
+
continue
|
|
831
|
+
col_exprs = list(getattr(target_cols, "expressions", []) or [])
|
|
832
|
+
val_exprs = list(getattr(values, "expressions", []) or [])
|
|
833
|
+
# Positional alignment of (cols) with VALUES (...); a malformed MERGE
|
|
834
|
+
# with mismatched arities zips to the shorter list rather than raising.
|
|
835
|
+
for target_col, value in zip(col_exprs, val_exprs, strict=False):
|
|
836
|
+
if not isinstance(target_col, exp.Column):
|
|
837
|
+
continue
|
|
838
|
+
_emit(target_col.name, value, "MERGE_INSERT")
|
|
839
|
+
|
|
840
|
+
return edges
|
|
841
|
+
|
|
663
842
|
def _real_tables(self, scope: Any) -> list[TableRef]:
|
|
664
843
|
"""Return real (non-CTE) tables referenced in a scope.
|
|
665
844
|
|
|
@@ -1117,19 +1296,15 @@ class SqlParser(ABC):
|
|
|
1117
1296
|
join_col_resolves: list[JoinColResolve] = []
|
|
1118
1297
|
_qualify_failed: bool = False
|
|
1119
1298
|
|
|
1120
|
-
#
|
|
1121
|
-
# sqlglot's lineage()
|
|
1122
|
-
#
|
|
1123
|
-
#
|
|
1299
|
+
# MERGE column lineage (un-defer T-07-06,
|
|
1300
|
+
# plan/sprints/sprint_snowflake_lineage_patterns.md PR-C). sqlglot's lineage()
|
|
1301
|
+
# API does not handle MERGE branches, but the WHEN MATCHED UPDATE SET / WHEN NOT
|
|
1302
|
+
# MATCHED INSERT VALUES clauses are structurally extractable by a direct AST walk.
|
|
1303
|
+
# This is a bounded once-per-statement path that NEVER calls sg_lineage / qualify /
|
|
1304
|
+
# build_scope / exp.expand (AC-C7).
|
|
1124
1305
|
if isinstance(stmt, exp.Merge):
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
try:
|
|
1128
|
-
dst_name = stmt.this.name
|
|
1129
|
-
except Exception:
|
|
1130
|
-
dst_name = None
|
|
1131
|
-
out.errors.append(f"col_lineage_skip:merge_branch:{dst_name or '<unknown>'}")
|
|
1132
|
-
return LineageExtraction(edges=edges, star_sources=star_sources)
|
|
1306
|
+
merge_edges = self._extract_merge_lineage(stmt, dst_table, query_sources, out)
|
|
1307
|
+
return LineageExtraction(edges=merge_edges, star_sources=star_sources)
|
|
1133
1308
|
|
|
1134
1309
|
# Only extract column lineage for certain statement types
|
|
1135
1310
|
if not isinstance(stmt, (exp.Select, exp.Insert, exp.Create)):
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"""Dialect-agnostic bounded constant-fold of dynamic table-name expressions.
|
|
2
|
+
|
|
3
|
+
This is the pure core of the "generic variable-name resolution" feature
|
|
4
|
+
(``plan/sprints/feature_generic_var_name_resolution.md``). It partially folds a
|
|
5
|
+
string-valued expression AST (string literals, ``||`` / ``CONCAT``, and 1-hop
|
|
6
|
+
``$var`` references) into a concrete ``[catalog.]db.name`` table reference,
|
|
7
|
+
recovering the statically-determined trailing identifier components while
|
|
8
|
+
honestly giving up when the name cannot be determined.
|
|
9
|
+
|
|
10
|
+
No parser/indexer state is touched here: ``resolve_dynamic_name`` is a pure
|
|
11
|
+
function, fully unit-testable in isolation. PR-2 wires it into the Snowflake
|
|
12
|
+
parser via a sink predicate; this module ships unwired.
|
|
13
|
+
|
|
14
|
+
Fold classification:
|
|
15
|
+
|
|
16
|
+
* **LIT (resolvable):** ``exp.Literal`` (string), ``exp.DPipe`` / ``exp.Concat``
|
|
17
|
+
over folds, and a 1-hop ``$var`` whose RHS (looked up in ``var_env`` exactly
|
|
18
|
+
once) itself folds to a leading constant prefix.
|
|
19
|
+
* **OPAQUE (unresolvable):** runtime functions (``current_database()``,
|
|
20
|
+
``split_part(...)``, ``current_warehouse()``, any ``exp.Func`` /
|
|
21
|
+
``exp.Anonymous`` that is not a pure string op), scalar subqueries that are not
|
|
22
|
+
a single-projection of folds, bind parameters (``exp.Placeholder``), and any
|
|
23
|
+
``$var`` reference at chain depth >= 2.
|
|
24
|
+
|
|
25
|
+
Name extraction interprets the fold as ``[catalog.]db.name`` (name-last,
|
|
26
|
+
dot-split): it keeps the rightmost statically-determined ``db.name`` tail,
|
|
27
|
+
wildcards (drops) a leading OPAQUE catalog, keeps a static *literal* catalog, and
|
|
28
|
+
returns ``None`` when the whole thing is opaque / the tail is a bare name / the
|
|
29
|
+
tail lacks a resolvable ``db.name``.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
from __future__ import annotations
|
|
33
|
+
|
|
34
|
+
from dataclasses import dataclass
|
|
35
|
+
|
|
36
|
+
import sqlglot.expressions as exp
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass(frozen=True)
|
|
40
|
+
class _Lit:
|
|
41
|
+
"""A statically-known string segment of the folded expression."""
|
|
42
|
+
|
|
43
|
+
text: str
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass(frozen=True)
|
|
47
|
+
class _Opaque:
|
|
48
|
+
"""A runtime-determined segment that cannot be folded statically."""
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
_Part = _Lit | _Opaque
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _fold_parts(
|
|
55
|
+
node: exp.Expression, # type: ignore[attr-defined]
|
|
56
|
+
var_env: dict[str, exp.Expression], # type: ignore[attr-defined]
|
|
57
|
+
*,
|
|
58
|
+
chain_depth: int,
|
|
59
|
+
) -> list[_Part]:
|
|
60
|
+
"""Fold ``node`` into an ordered list of LIT / OPAQUE parts.
|
|
61
|
+
|
|
62
|
+
Descends string-concatenation structure (``||`` / ``CONCAT``), single-
|
|
63
|
+
projection subqueries and parentheses; resolves 1-hop ``$var`` references
|
|
64
|
+
against ``var_env``; classifies everything else OPAQUE.
|
|
65
|
+
"""
|
|
66
|
+
# Unwrap a single-projection (SELECT ...) scalar subquery / paren.
|
|
67
|
+
if isinstance(node, exp.Subquery):
|
|
68
|
+
return _fold_parts(node.this, var_env, chain_depth=chain_depth)
|
|
69
|
+
if isinstance(node, exp.Paren):
|
|
70
|
+
return _fold_parts(node.this, var_env, chain_depth=chain_depth)
|
|
71
|
+
if isinstance(node, exp.Select):
|
|
72
|
+
projections = node.expressions
|
|
73
|
+
if len(projections) != 1:
|
|
74
|
+
return [_Opaque()]
|
|
75
|
+
return _fold_parts(projections[0], var_env, chain_depth=chain_depth)
|
|
76
|
+
|
|
77
|
+
# String concatenation: DPipe is binary (left-nested), Concat is n-ary.
|
|
78
|
+
if isinstance(node, exp.DPipe):
|
|
79
|
+
return _fold_parts(node.this, var_env, chain_depth=chain_depth) + _fold_parts(
|
|
80
|
+
node.expression, var_env, chain_depth=chain_depth
|
|
81
|
+
)
|
|
82
|
+
if isinstance(node, exp.Concat):
|
|
83
|
+
parts: list[_Part] = []
|
|
84
|
+
for child in node.expressions:
|
|
85
|
+
parts.extend(_fold_parts(child, var_env, chain_depth=chain_depth))
|
|
86
|
+
return parts
|
|
87
|
+
|
|
88
|
+
# Concrete string literal.
|
|
89
|
+
if isinstance(node, exp.Literal) and node.is_string:
|
|
90
|
+
return [_Lit(node.this)]
|
|
91
|
+
|
|
92
|
+
# 1-hop $var reference.
|
|
93
|
+
if isinstance(node, exp.Parameter):
|
|
94
|
+
var = node.this
|
|
95
|
+
name = var.name if isinstance(var, exp.Var) else None
|
|
96
|
+
if name is None or chain_depth < 1:
|
|
97
|
+
return [_Opaque()]
|
|
98
|
+
rhs = var_env.get(name.lower())
|
|
99
|
+
if rhs is None:
|
|
100
|
+
return [_Opaque()]
|
|
101
|
+
# Resolve exactly one hop: the looked-up RHS may not itself follow
|
|
102
|
+
# further $vars (depth-2 is OPAQUE because chain_depth drops to 0).
|
|
103
|
+
return _fold_parts(rhs, var_env, chain_depth=chain_depth - 1)
|
|
104
|
+
|
|
105
|
+
# Everything else (runtime funcs, bind params, non-fold subqueries) is opaque.
|
|
106
|
+
return [_Opaque()]
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def resolve_dynamic_name(
|
|
110
|
+
rhs_expr: exp.Expression, # type: ignore[attr-defined]
|
|
111
|
+
var_env: dict[str, exp.Expression], # type: ignore[attr-defined]
|
|
112
|
+
*,
|
|
113
|
+
chain_depth: int = 1,
|
|
114
|
+
) -> exp.Table | None:
|
|
115
|
+
"""Bounded partial constant-fold of a string-expression AST into a TableRef.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
rhs_expr: the RHS expression assigned to the dynamic name (the AST that
|
|
119
|
+
the ``IDENTIFIER($var)`` sink dereferences).
|
|
120
|
+
var_env: lowercased var name -> its RHS AST, for 1-hop chain resolution.
|
|
121
|
+
chain_depth: max var-lookup hops (default 1; corpus max is 1). A var
|
|
122
|
+
whose value references another var resolves only the first hop.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
An ``exp.Table`` for the resolvable trailing identifier components, or
|
|
126
|
+
``None`` to give up honestly (caller leaves the sink dropped).
|
|
127
|
+
"""
|
|
128
|
+
parts = _fold_parts(rhs_expr, var_env, chain_depth=chain_depth)
|
|
129
|
+
|
|
130
|
+
if not parts:
|
|
131
|
+
return None
|
|
132
|
+
|
|
133
|
+
# Take the rightmost contiguous run of LIT parts (the static suffix), noting
|
|
134
|
+
# whether an OPAQUE segment sits immediately before that run (catalog
|
|
135
|
+
# position is then runtime-determined).
|
|
136
|
+
suffix_lits: list[str] = []
|
|
137
|
+
opaque_precedes_suffix = False
|
|
138
|
+
for part in reversed(parts):
|
|
139
|
+
if isinstance(part, _Lit):
|
|
140
|
+
suffix_lits.append(part.text)
|
|
141
|
+
else:
|
|
142
|
+
opaque_precedes_suffix = True
|
|
143
|
+
break
|
|
144
|
+
suffix_lits.reverse()
|
|
145
|
+
|
|
146
|
+
if not suffix_lits:
|
|
147
|
+
# All-opaque (no static tail at all).
|
|
148
|
+
return None
|
|
149
|
+
|
|
150
|
+
suffix = "".join(suffix_lits)
|
|
151
|
+
table = exp.to_table(suffix, dialect="snowflake")
|
|
152
|
+
|
|
153
|
+
# A resolvable object id needs at least db.name (schema.table). A bare name
|
|
154
|
+
# (no db) is a give-up: we never guess the schema/table. A missing name (tail
|
|
155
|
+
# ends on a dot) is likewise unresolvable.
|
|
156
|
+
if table.db == "" or table.name == "":
|
|
157
|
+
return None
|
|
158
|
+
|
|
159
|
+
# Catalog policy:
|
|
160
|
+
# - literal catalog present in the static suffix (3-part name) -> KEEP it.
|
|
161
|
+
# - an OPAQUE segment precedes the suffix (the catalog slot came from a
|
|
162
|
+
# runtime segment) -> wildcard / drop the catalog (emit catalog-less
|
|
163
|
+
# db.name) so the node merges with DDL / plain-SQL refs to the same table.
|
|
164
|
+
# to_table already yields catalog='' when the static suffix had no catalog
|
|
165
|
+
# component (e.g. '.EMP.APPLICATION_FIELDS' or 'DHB.KOSTEN'); the explicit
|
|
166
|
+
# drop only matters when an opaque prefix sits before a literal 3-part tail.
|
|
167
|
+
if opaque_precedes_suffix and table.catalog != "":
|
|
168
|
+
table.set("catalog", None)
|
|
169
|
+
|
|
170
|
+
return table
|