sql-dialect-master 1.6.0__tar.gz → 1.7.0__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.
Files changed (70) hide show
  1. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/PKG-INFO +2 -2
  2. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/README.md +1 -1
  3. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/metadata.py +2 -2
  4. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_pipeline/orchestrator.py +150 -1
  5. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/pyproject.toml +1 -1
  6. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/sql_dialect_master.egg-info/PKG-INFO +2 -2
  7. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/LICENSE +0 -0
  8. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/__init__.py +0 -0
  9. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/api/__init__.py +0 -0
  10. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/api/auth.py +0 -0
  11. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/api/client_identity.py +0 -0
  12. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/api/main.py +0 -0
  13. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/api/metrics.py +0 -0
  14. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/api/middleware.py +0 -0
  15. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/api/rate_limit_store.py +0 -0
  16. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/api/readiness.py +0 -0
  17. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/api/workers.py +0 -0
  18. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/__init__.py +0 -0
  19. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/cache.py +0 -0
  20. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/column_hint_validation.py +0 -0
  21. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/config.py +0 -0
  22. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/constants.py +0 -0
  23. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/exceptions.py +0 -0
  24. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/function_call_scanner.py +0 -0
  25. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/function_semantics.py +0 -0
  26. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/functions_db.json +0 -0
  27. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/functions_lookup.py +0 -0
  28. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql.py +0 -0
  29. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_components/__init__.py +0 -0
  30. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_components/aggregations.py +0 -0
  31. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_components/boolean_conditions.py +0 -0
  32. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_components/core_extract.py +0 -0
  33. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_components/evidence.py +0 -0
  34. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_components/mappings.py +0 -0
  35. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_components/relations.py +0 -0
  36. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_components/templates.py +0 -0
  37. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_components/tokenizer.py +0 -0
  38. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_legacy.py +0 -0
  39. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_llm.py +0 -0
  40. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_pipeline/__init__.py +0 -0
  41. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_pipeline/aggregations.py +0 -0
  42. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_pipeline/clause_extract.py +0 -0
  43. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_pipeline/dialect.py +0 -0
  44. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_pipeline/intent.py +0 -0
  45. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_pipeline/ir.py +0 -0
  46. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_pipeline/models.py +0 -0
  47. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_pipeline/predicates.py +0 -0
  48. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_pipeline/renderer.py +0 -0
  49. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_pipeline/resolution.py +0 -0
  50. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_pipeline/suggestions.py +0 -0
  51. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_pipeline/templates.py +0 -0
  52. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_pipeline/validation.py +0 -0
  53. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/nl2sql_schema.py +0 -0
  54. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/p1_sql_scanner.py +0 -0
  55. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/p2_data_validation.py +0 -0
  56. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/parser.py +0 -0
  57. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/post_processor.py +0 -0
  58. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/rules.py +0 -0
  59. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/semantic_diff.py +0 -0
  60. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/sql_statements.py +0 -0
  61. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/transpiler.py +0 -0
  62. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/type_mapping.json +0 -0
  63. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/core/type_mapping.py +0 -0
  64. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/utils/__init__.py +0 -0
  65. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/backend/utils/validators.py +0 -0
  66. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/setup.cfg +0 -0
  67. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/sql_dialect_master.egg-info/SOURCES.txt +0 -0
  68. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/sql_dialect_master.egg-info/dependency_links.txt +0 -0
  69. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/sql_dialect_master.egg-info/requires.txt +0 -0
  70. {sql_dialect_master-1.6.0 → sql_dialect_master-1.7.0}/sql_dialect_master.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sql-dialect-master
3
- Version: 1.6.0
3
+ Version: 1.7.0
4
4
  Summary: SQL Dialect Master - Multi-database SQL conversion engine
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -38,7 +38,7 @@ Dynamic: license-file
38
38
 
39
39
  Enterprise-grade multi-database SQL conversion engine supporting 12 database dialects.
40
40
 
41
- Current release: 1.6.0
41
+ Current release: 1.7.0
42
42
 
43
43
  [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
44
44
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -2,7 +2,7 @@
2
2
 
3
3
  Enterprise-grade multi-database SQL conversion engine supporting 12 database dialects.
4
4
 
5
- Current release: 1.6.0
5
+ Current release: 1.7.0
6
6
 
7
7
  [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -17,8 +17,8 @@ Design rules:
17
17
  from __future__ import annotations
18
18
 
19
19
  # ── Release version facts (sole source of truth) ────────────────────────
20
- PROJECT_VERSION = "1.6.0"
21
- API_VERSION = "1.6.0"
20
+ PROJECT_VERSION = "1.7.0"
21
+ API_VERSION = "1.7.0"
22
22
  # Frontend v2 architecture — independent of the product release version.
23
23
  FRONTEND_ARCHITECTURE_VERSION = 2
24
24
 
@@ -125,6 +125,18 @@ _SCHEMA_JOINED_WITH_PREFIX = re.compile(
125
125
  r"([A-Za-z_][A-Za-z0-9_$]*(?:\.[A-Za-z_][A-Za-z0-9_$]*)?)\b",
126
126
  re.IGNORECASE,
127
127
  )
128
+ _SCHEMA_DIAGNOSTIC_VALUES = {
129
+ "active", "inactive", "enabled", "disabled", "valid", "invalid",
130
+ "completed", "pending", "paid", "unpaid", "done", "true", "false",
131
+ }
132
+ _SCHEMA_DIAGNOSTIC_KEYWORDS = {
133
+ "and", "or", "not", "is", "where", "with", "by", "group", "grouped",
134
+ "order", "ordered", "sort", "sorted", "asc", "desc", "ascending",
135
+ "descending", "users", "user", "show", "list", "find", "display",
136
+ }
137
+ _SCHEMA_DIAGNOSTIC_COLUMN_ALLOWLIST = {
138
+ "password", "nickname", "token", "hash", "bio", "avatar",
139
+ }
128
140
  _SCHEMA_GROUP_LABEL_COLUMNS = {
129
141
  "部门": ("department", "dept"),
130
142
  "状态": ("status",),
@@ -1481,6 +1493,134 @@ class PipelineNL2SQLGenerator:
1481
1493
  "join_spec": JoinSpec(kind=kind, matched_text="joined with"),
1482
1494
  }], span
1483
1495
 
1496
+ def _schema_diagnostic_suggestions(
1497
+ self,
1498
+ text: str,
1499
+ table: SchemaTableContext,
1500
+ schema: SchemaContext,
1501
+ columns: list[str],
1502
+ existing: list,
1503
+ ) -> list:
1504
+ """Return high-confidence unmapped-column suggestions for schema success."""
1505
+ if not table.has_column_metadata:
1506
+ return list(existing)
1507
+ masked = mask_non_executable(text)
1508
+ schema_tables = {candidate.key for candidate in schema.tables}
1509
+ table_aliases = {
1510
+ pattern.casefold() for pattern in self.TABLE_PATTERNS
1511
+ } | {
1512
+ mapped.casefold() for mapped in self.TABLE_PATTERNS.values()
1513
+ }
1514
+ schema_columns = {column.casefold() for column in table.columns}
1515
+ mapped_aliases = {
1516
+ alias.casefold(): canonical
1517
+ for alias, canonical in self.COLUMN_PATTERNS.items()
1518
+ }
1519
+ warnings: list[tuple[int, str]] = []
1520
+ seen: set[str] = set()
1521
+
1522
+ def add_warning(position: int, token: str, *, projection: bool = False) -> None:
1523
+ key = token.casefold()
1524
+ if key in seen or key in schema_columns:
1525
+ return
1526
+ canonical = mapped_aliases.get(key)
1527
+ if canonical is not None and canonical.casefold() in schema_columns:
1528
+ return
1529
+ message = (
1530
+ f'Possible projection term "{token}" was not resolved against the selected schema table.'
1531
+ if projection else
1532
+ f'Possible unmapped column reference: "{token}". '
1533
+ "Provide it in column_hints if it is a schema column."
1534
+ )
1535
+ seen.add(key)
1536
+ warnings.append((position, message))
1537
+
1538
+ # Strong identifier contexts: `with token` and `by snake_case`.
1539
+ for match in re.finditer(
1540
+ r"\b(?:with|by)\s+([A-Za-z_][A-Za-z0-9_$]*)",
1541
+ masked,
1542
+ re.IGNORECASE,
1543
+ ):
1544
+ token = match.group(1)
1545
+ lowered = token.casefold()
1546
+ if lowered in _SCHEMA_DIAGNOSTIC_KEYWORDS | _SCHEMA_DIAGNOSTIC_VALUES:
1547
+ continue
1548
+ if schema.table_candidates(token) or lowered in schema_tables:
1549
+ continue
1550
+ if lowered in table_aliases:
1551
+ continue
1552
+ if schema.canonical_column(table, token) is not None:
1553
+ continue
1554
+ if lowered in mapped_aliases and mapped_aliases[lowered].casefold() in schema_columns:
1555
+ continue
1556
+ if match.group(0).casefold().startswith("by ") and "_" not in token:
1557
+ continue
1558
+ add_warning(match.start(1), token)
1559
+
1560
+ # Explicit projection conjunctions: only mapped aliases after a
1561
+ # show/list/display marker, before any predicate/clause boundary.
1562
+ projection_marker = re.search(r"\b(?:show|list|display|select)\b", masked, re.IGNORECASE)
1563
+ if projection_marker:
1564
+ boundary = re.search(
1565
+ r"\b(?:where|whose|order(?:ed)?\s+by|sort(?:ed)?\s+by|group(?:ed)?\s+by)\b",
1566
+ masked[projection_marker.end():],
1567
+ re.IGNORECASE,
1568
+ )
1569
+ projection_end = (
1570
+ projection_marker.end() + boundary.start()
1571
+ if boundary is not None else len(masked)
1572
+ )
1573
+ for alias, canonical in sorted(self.COLUMN_PATTERNS.items(), key=lambda item: -len(item[0])):
1574
+ if canonical.casefold() in schema_columns:
1575
+ continue
1576
+ aliases = [alias]
1577
+ if alias.isascii() and not alias.casefold().endswith("s"):
1578
+ aliases.append(alias + "s")
1579
+ for candidate_alias in aliases:
1580
+ expression = re.escape(candidate_alias)
1581
+ if not re.search(r"[\u4e00-\u9fff]", candidate_alias):
1582
+ expression = rf"(?<![\w$]){expression}(?![\w$])"
1583
+ for match in re.finditer(expression, masked[projection_marker.end():projection_end], re.IGNORECASE):
1584
+ add_warning(
1585
+ projection_marker.end() + match.start(),
1586
+ alias,
1587
+ projection=True,
1588
+ )
1589
+ projection_slice = masked[projection_marker.end():projection_end]
1590
+ for token_match in re.finditer(
1591
+ r"[A-Za-z_][A-Za-z0-9_$]*", projection_slice
1592
+ ):
1593
+ token = token_match.group(0)
1594
+ lowered = token.casefold()
1595
+ if (
1596
+ lowered in _SCHEMA_DIAGNOSTIC_KEYWORDS
1597
+ or lowered in _SCHEMA_DIAGNOSTIC_VALUES
1598
+ or lowered in table_aliases
1599
+ or lowered in schema_tables
1600
+ or lowered in schema_columns
1601
+ ):
1602
+ continue
1603
+ canonical = mapped_aliases.get(lowered)
1604
+ if canonical is not None and canonical.casefold() in schema_columns:
1605
+ continue
1606
+ if canonical is None and (
1607
+ "_" not in token and lowered not in _SCHEMA_DIAGNOSTIC_COLUMN_ALLOWLIST
1608
+ ):
1609
+ continue
1610
+ add_warning(
1611
+ projection_marker.end() + token_match.start(),
1612
+ canonical or token,
1613
+ projection=True,
1614
+ )
1615
+
1616
+ warnings.sort(key=lambda item: item[0])
1617
+ diagnostic_messages = [message for _, message in warnings[:3]]
1618
+ combined: list = []
1619
+ for suggestion in [*existing, *diagnostic_messages]:
1620
+ if suggestion not in combined:
1621
+ combined.append(suggestion)
1622
+ return combined[:3]
1623
+
1484
1624
  def _schema_resolve_joins(
1485
1625
  self,
1486
1626
  text: str,
@@ -1734,7 +1874,16 @@ class PipelineNL2SQLGenerator:
1734
1874
  ),
1735
1875
  parsed_elements=parsed,
1736
1876
  ))
1737
- return self._schema_finalize(result, schema)
1877
+ finalized = self._schema_finalize(result, schema)
1878
+ if finalized.success and finalized.schema_used:
1879
+ finalized.suggestions = self._schema_diagnostic_suggestions(
1880
+ text,
1881
+ table_context,
1882
+ schema,
1883
+ columns,
1884
+ list(finalized.suggestions),
1885
+ )
1886
+ return finalized
1738
1887
  except (SchemaValidationError, ValueError):
1739
1888
  return self._schema_failure(
1740
1889
  text,
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sql-dialect-master"
3
- version = "1.6.0"
3
+ version = "1.7.0"
4
4
  description = "SQL Dialect Master - Multi-database SQL conversion engine"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sql-dialect-master
3
- Version: 1.6.0
3
+ Version: 1.7.0
4
4
  Summary: SQL Dialect Master - Multi-database SQL conversion engine
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -38,7 +38,7 @@ Dynamic: license-file
38
38
 
39
39
  Enterprise-grade multi-database SQL conversion engine supporting 12 database dialects.
40
40
 
41
- Current release: 1.6.0
41
+ Current release: 1.7.0
42
42
 
43
43
  [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
44
44
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)