sql-dialect-master 1.1.1__py3-none-any.whl

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.
Files changed (86) hide show
  1. backend/__init__.py +1 -0
  2. backend/api/__init__.py +1 -0
  3. backend/api/main.py +732 -0
  4. backend/api/middleware.py +274 -0
  5. backend/api/rate_limit_store.py +105 -0
  6. backend/api/readiness.py +178 -0
  7. backend/core/__init__.py +57 -0
  8. backend/core/cache.py +261 -0
  9. backend/core/column_hint_validation.py +22 -0
  10. backend/core/config.py +546 -0
  11. backend/core/constants.py +84 -0
  12. backend/core/exceptions.py +124 -0
  13. backend/core/function_call_scanner.py +64 -0
  14. backend/core/function_semantics.py +148 -0
  15. backend/core/functions_db.json +601 -0
  16. backend/core/functions_lookup.py +332 -0
  17. backend/core/metadata.py +71 -0
  18. backend/core/nl2sql.py +85 -0
  19. backend/core/nl2sql_components/__init__.py +72 -0
  20. backend/core/nl2sql_components/aggregations.py +35 -0
  21. backend/core/nl2sql_components/boolean_conditions.py +279 -0
  22. backend/core/nl2sql_components/core_extract.py +106 -0
  23. backend/core/nl2sql_components/evidence.py +122 -0
  24. backend/core/nl2sql_components/mappings.py +185 -0
  25. backend/core/nl2sql_components/relations.py +180 -0
  26. backend/core/nl2sql_components/templates.py +130 -0
  27. backend/core/nl2sql_components/tokenizer.py +187 -0
  28. backend/core/nl2sql_legacy.py +22 -0
  29. backend/core/nl2sql_pipeline/__init__.py +13 -0
  30. backend/core/nl2sql_pipeline/aggregations.py +26 -0
  31. backend/core/nl2sql_pipeline/clause_extract.py +97 -0
  32. backend/core/nl2sql_pipeline/dialect.py +139 -0
  33. backend/core/nl2sql_pipeline/intent.py +85 -0
  34. backend/core/nl2sql_pipeline/ir.py +70 -0
  35. backend/core/nl2sql_pipeline/models.py +30 -0
  36. backend/core/nl2sql_pipeline/orchestrator.py +576 -0
  37. backend/core/nl2sql_pipeline/predicates.py +182 -0
  38. backend/core/nl2sql_pipeline/renderer.py +248 -0
  39. backend/core/nl2sql_pipeline/resolution.py +69 -0
  40. backend/core/nl2sql_pipeline/suggestions.py +30 -0
  41. backend/core/nl2sql_pipeline/templates.py +371 -0
  42. backend/core/nl2sql_pipeline/validation.py +28 -0
  43. backend/core/p1_sql_scanner.py +196 -0
  44. backend/core/p2_data_validation.py +72 -0
  45. backend/core/parser.py +280 -0
  46. backend/core/post_processor.py +129 -0
  47. backend/core/rules.py +808 -0
  48. backend/core/semantic_diff.py +385 -0
  49. backend/core/transpiler.py +791 -0
  50. backend/core/type_mapping.json +593 -0
  51. backend/core/type_mapping.py +765 -0
  52. backend/utils/__init__.py +2 -0
  53. backend/utils/validators.py +407 -0
  54. frontend/__init__.py +10 -0
  55. frontend/app_context_v2.py +201 -0
  56. frontend/core/__init__.py +33 -0
  57. frontend/core/design_tokens.py +127 -0
  58. frontend/core/escaping.py +13 -0
  59. frontend/core/navigation.py +135 -0
  60. frontend/core/state.py +612 -0
  61. frontend/core/styles.py +523 -0
  62. frontend/core/themes.py +69 -0
  63. frontend/core/viewmodels.py +499 -0
  64. frontend/pages/__init__.py +0 -0
  65. frontend/pages/convert.py +283 -0
  66. frontend/pages/diff.py +157 -0
  67. frontend/pages/functions.py +100 -0
  68. frontend/pages/history.py +144 -0
  69. frontend/pages/lineage.py +168 -0
  70. frontend/pages/nl2sql.py +305 -0
  71. frontend/pages/query_analysis.py +120 -0
  72. frontend/pages/runtime.py +66 -0
  73. frontend/pages/settings.py +60 -0
  74. frontend/pages/templates.py +67 -0
  75. frontend/pages/types.py +110 -0
  76. frontend/templates_v2.py +53 -0
  77. frontend/ui/__init__.py +0 -0
  78. frontend/ui/command_palette.py +153 -0
  79. frontend/ui/diff.py +275 -0
  80. frontend/ui/editor.py +102 -0
  81. frontend/ui/status.py +255 -0
  82. sql_dialect_master-1.1.1.dist-info/METADATA +360 -0
  83. sql_dialect_master-1.1.1.dist-info/RECORD +86 -0
  84. sql_dialect_master-1.1.1.dist-info/WHEEL +5 -0
  85. sql_dialect_master-1.1.1.dist-info/licenses/LICENSE +21 -0
  86. sql_dialect_master-1.1.1.dist-info/top_level.txt +2 -0
@@ -0,0 +1,127 @@
1
+ """Design tokens for SQL Dialect Master v2.
2
+
3
+ Defines a single source of truth for colors, typography, spacing, and
4
+ semantic status values used across the entire frontend.
5
+
6
+ Two themes only: Dark (default) and Light.
7
+ """
8
+ from dataclasses import dataclass
9
+ from typing import Literal
10
+
11
+ ThemeName = Literal["dark", "light"]
12
+
13
+
14
+ @dataclass(frozen=True)
15
+ class ColorTokens:
16
+ """Complete color palette for one theme."""
17
+
18
+ # Background layers
19
+ bg: str
20
+ surface: str
21
+ surface_elevated: str
22
+
23
+ # Borders and dividers
24
+ border: str
25
+ border_subtle: str
26
+
27
+ # Text
28
+ text_primary: str
29
+ text_secondary: str
30
+ text_muted: str
31
+ text_on_accent: str
32
+
33
+ # Semantic colors
34
+ accent: str
35
+ success: str
36
+ warning: str
37
+ danger: str
38
+ info: str
39
+
40
+ # Component states
41
+ input_bg: str
42
+ input_border: str
43
+ input_border_focus: str
44
+ hover_bg: str
45
+ selected_bg: str
46
+
47
+
48
+ # ---------------------------------------------------------------------------
49
+ # Theme definitions
50
+ # ---------------------------------------------------------------------------
51
+
52
+ DARK: ColorTokens = ColorTokens(
53
+ bg="#0B0D10",
54
+ surface="#111418",
55
+ surface_elevated="#171B21",
56
+ border="#262B33",
57
+ border_subtle="#1E2229",
58
+ text_primary="#E6EAF0",
59
+ text_secondary="#9AA4B2",
60
+ text_muted="#667085",
61
+ text_on_accent="#0B0D10",
62
+ accent="#4F8CFF",
63
+ success="#2FBF71",
64
+ warning="#D9A441",
65
+ danger="#E25555",
66
+ info="#5B9CFF",
67
+ input_bg="#171B21",
68
+ input_border="#262B33",
69
+ input_border_focus="#4F8CFF",
70
+ hover_bg="#1E2229",
71
+ selected_bg="#4F8CFF18",
72
+ )
73
+
74
+ LIGHT: ColorTokens = ColorTokens(
75
+ bg="#F7F8FA",
76
+ surface="#FFFFFF",
77
+ surface_elevated="#FFFFFF",
78
+ border="#E4E7EC",
79
+ border_subtle="#EEF0F4",
80
+ text_primary="#101828",
81
+ text_secondary="#475467",
82
+ text_muted="#667085",
83
+ text_on_accent="#FFFFFF",
84
+ accent="#2563EB",
85
+ success="#15803D",
86
+ warning="#B45309",
87
+ danger="#DC2626",
88
+ info="#2563EB",
89
+ input_bg="#FFFFFF",
90
+ input_border="#E4E7EC",
91
+ input_border_focus="#2563EB",
92
+ hover_bg="#F4F5F7",
93
+ selected_bg="#2563EB18",
94
+ )
95
+
96
+ THEMES: dict[ThemeName, ColorTokens] = {
97
+ "dark": DARK,
98
+ "light": LIGHT,
99
+ }
100
+
101
+ # ---------------------------------------------------------------------------
102
+ # Semantic status constants
103
+ # ---------------------------------------------------------------------------
104
+
105
+ STATUS_VALID = "valid"
106
+ STATUS_WARNING = "warning"
107
+ STATUS_ERROR = "error"
108
+ STATUS_INFO = "info"
109
+ STATUS_NEUTRAL = "neutral"
110
+
111
+ SEMANTIC_STATUS_LABELS: dict[str, str] = {
112
+ "equivalent": "Equivalent",
113
+ "structurally_equivalent": "Structurally Equivalent",
114
+ "potentially_different": "Potentially Different",
115
+ "definitely_different": "Definitely Different",
116
+ "unknown": "Unknown",
117
+ "parse_error": "Parse Error",
118
+ }
119
+
120
+ SEMANTIC_STATUS_COLOR: dict[str, str] = {
121
+ "equivalent": "success",
122
+ "structurally_equivalent": "success",
123
+ "potentially_different": "warning",
124
+ "definitely_different": "danger",
125
+ "unknown": "warning",
126
+ "parse_error": "error",
127
+ }
@@ -0,0 +1,13 @@
1
+ """Shared HTML-safe escaping utilities.
2
+
3
+ Replaces the ad-hoc `_esc()` function that lived in app_context.py.
4
+ Uses markupsafe.escape which is already a transitive dependency of
5
+ Streamlit and handles all HTML entity encoding correctly including
6
+ attribute contexts.
7
+ """
8
+ from markupsafe import escape as html_escape
9
+
10
+ # Re-export under a project-specific name for clarity
11
+ esc = html_escape
12
+
13
+ __all__ = ["esc"]
@@ -0,0 +1,135 @@
1
+ """Unified navigation intent system for SQL Dialect Master v2.
2
+
3
+ Replaces scattered sdm_pending_* session state keys with a single
4
+ NavigationIntent dataclass. All cross-page handoffs flow through this
5
+ contract:
6
+
7
+ Producer → NavigationIntent → session state
8
+ ↓
9
+ Consumer reads once, clears immediately
10
+
11
+ Supported actions:
12
+ open_conversion — NL2SQL / History → Convert
13
+ open_diff — Convert / NL2SQL → Diff
14
+ select_finding — Diff internal (finding selection)
15
+ new_conversion — Command Palette → Convert
16
+ open_lineage — Command Palette → Lineage
17
+ open_query_analysis — Command Palette → Query Analysis
18
+ open_history — Command Palette → History
19
+ open_settings — Command Palette → Settings
20
+ """
21
+ from __future__ import annotations
22
+
23
+ from dataclasses import dataclass, field
24
+ from typing import Any, Literal
25
+
26
+ ActionKind = Literal[
27
+ "open_conversion",
28
+ "open_diff",
29
+ "select_finding",
30
+ "new_conversion",
31
+ "open_lineage",
32
+ "open_query_analysis",
33
+ "open_history",
34
+ "open_settings",
35
+ "open_functions",
36
+ "open_types",
37
+ "open_templates",
38
+ "open_runtime",
39
+ ]
40
+
41
+
42
+ @dataclass
43
+ class NavigationIntent:
44
+ """Single source of truth for cross-page navigation."""
45
+
46
+ target_page: str = ""
47
+ action: ActionKind | None = None
48
+ payload: dict[str, Any] = field(default_factory=dict)
49
+
50
+ # Validation
51
+ @property
52
+ def is_valid(self) -> bool:
53
+ return bool(self.target_page)
54
+
55
+ def has_payload(self, key: str) -> bool:
56
+ return key in self.payload
57
+
58
+ def get_payload(self, key: str, default: Any = None) -> Any:
59
+ return self.payload.get(key, default)
60
+
61
+ def __bool__(self) -> bool:
62
+ return self.is_valid
63
+
64
+
65
+ def create_navigation_intent(
66
+ target_page: str,
67
+ action: ActionKind | None = None,
68
+ **payload: Any,
69
+ ) -> NavigationIntent:
70
+ """Factory for NavigationIntent."""
71
+ return NavigationIntent(
72
+ target_page=target_page,
73
+ action=action,
74
+ payload=payload,
75
+ )
76
+
77
+
78
+ # ── Known actions per page ─────────────────────────────────────────────
79
+
80
+ PAGE_ACTIONS: dict[str, list[ActionKind]] = {
81
+ "convert": ["open_conversion", "new_conversion"],
82
+ "diff": ["open_diff", "select_finding"],
83
+ "lineage": ["open_lineage"],
84
+ "query_analysis": ["open_query_analysis"],
85
+ "history": ["open_history"],
86
+ "settings": ["open_settings"],
87
+ "functions": ["open_functions"],
88
+ "types": ["open_types"],
89
+ "templates": [],
90
+ "runtime": ["open_runtime"],
91
+ "nl2sql": [],
92
+ }
93
+
94
+
95
+ def is_valid_action(target_page: str, action: str | None) -> bool:
96
+ """Check if an action is valid for a given page."""
97
+ if action is None:
98
+ return True
99
+ allowed = PAGE_ACTIONS.get(target_page, [])
100
+ return action in allowed or target_page == "convert" # open_conversion goes to convert
101
+
102
+
103
+ # ── Session state helpers ──────────────────────────────────────────────
104
+
105
+ _NAV_KEY = "sdm_navigation_intent"
106
+ _FINDING_KEY = "sdm_selected_finding_index"
107
+
108
+
109
+ def get_pending_intent() -> NavigationIntent:
110
+ """Read the current pending navigation intent from session state."""
111
+ import streamlit as st
112
+ raw = st.session_state.get(_NAV_KEY)
113
+ if isinstance(raw, NavigationIntent):
114
+ return raw
115
+ return NavigationIntent()
116
+
117
+
118
+ def consume_navigation_intent() -> NavigationIntent | None:
119
+ """Atomically read and clear the pending navigation intent.
120
+
121
+ Returns:
122
+ The consumed NavigationIntent, or None if there was no pending intent.
123
+ """
124
+ import streamlit as st
125
+ intent = get_pending_intent()
126
+ if not intent:
127
+ return None
128
+ st.session_state[_NAV_KEY] = NavigationIntent()
129
+ return intent
130
+
131
+
132
+ def clear_finding_selection() -> None:
133
+ """Clear the selected finding index from session state."""
134
+ import streamlit as st
135
+ st.session_state[_FINDING_KEY] = None