fix(translate): normalize backend dialect detection with explicit mapping
- Replace fragile substring check (any(kw in backend for kw in ('clickhouse', 'ch')))
with a proper _backend_normalize mapping + exact comparison.
Fixes misdetection of Greenplum (postgresql) and other backends.
- Add 'clickhousedb' to CLICKHOUSE_DIALECTS so SQL generator uses
backtick quoting and correct INSERT strategy for ClickHouse.
- Normalize _extract_dialect to map 'clickhousedb' -> 'clickhouse'
and 'greenplum' -> 'postgresql'.
This commit is contained in:
@@ -241,8 +241,31 @@ def validate_target_table_schema(
|
||||
safe_schema = (req.target_schema or "public").replace("'", "''")
|
||||
safe_table = req.target_table.replace("'", "''")
|
||||
|
||||
# Нормализуем backend через маппинг (как в get_dialect_from_database)
|
||||
# чтобы правильно обработать "clickhousedb" → "clickhouse",
|
||||
# "greenplum" → "postgresql" и другие варианты
|
||||
_backend_normalize = {
|
||||
"clickhouse": "clickhouse",
|
||||
"clickhousedb": "clickhouse",
|
||||
"postgresql": "postgresql",
|
||||
"greenplum": "postgresql",
|
||||
"mysql": "mysql",
|
||||
"mssql": "mssql",
|
||||
"sqlite": "sqlite",
|
||||
"oracle": "oracle",
|
||||
"snowflake": "snowflake",
|
||||
"bigquery": "bigquery",
|
||||
"redshift": "redshift",
|
||||
"presto": "presto",
|
||||
"trino": "trino",
|
||||
"druid": "druid",
|
||||
"hive": "hive",
|
||||
"spark": "spark",
|
||||
"databricks": "databricks",
|
||||
}
|
||||
normalized_backend = _backend_normalize.get(backend.lower().strip(), backend.lower().strip())
|
||||
# ClickHouse использует system.columns, всё остальное — information_schema.columns
|
||||
is_clickhouse = any(kw in backend.lower() for kw in ("clickhouse", "ch"))
|
||||
is_clickhouse = normalized_backend == "clickhouse"
|
||||
if is_clickhouse:
|
||||
sql = (
|
||||
f"SELECT name, type, default_expression AS data_default "
|
||||
|
||||
@@ -7,15 +7,27 @@ from ...schemas.translate import TranslateJobResponse
|
||||
|
||||
|
||||
# #region _extract_dialect [TYPE Function]
|
||||
# @BRIEF Extract database dialect from Superset backend URI.
|
||||
# @BRIEF Extract database dialect from Superset backend URI or engine name.
|
||||
def _extract_dialect(backend: str) -> str:
|
||||
"""Extract dialect name from a Superset database backend URI."""
|
||||
"""Extract dialect name from a Superset database backend URI or engine name.
|
||||
|
||||
Handles both URI formats (e.g. 'postgresql://...', 'clickhousedb://...')
|
||||
and plain engine names (e.g. 'postgresql', 'clickhousedb') returned by Superset.
|
||||
Normalises known variants like 'clickhousedb' → 'clickhouse'.
|
||||
"""
|
||||
if not backend:
|
||||
return "unknown"
|
||||
try:
|
||||
# Extract scheme from URI or use plain name
|
||||
scheme = backend.split("://")[0]
|
||||
dialect = scheme.split("+")[0]
|
||||
return dialect.lower()
|
||||
raw = dialect.lower()
|
||||
# Normalise known Superset backend variants
|
||||
dialect_map = {
|
||||
"clickhousedb": "clickhouse",
|
||||
"greenplum": "postgresql",
|
||||
}
|
||||
return dialect_map.get(raw, raw)
|
||||
except Exception:
|
||||
return "unknown"
|
||||
# #endregion _extract_dialect
|
||||
|
||||
@@ -18,7 +18,7 @@ from ...core.logger import belief_scope, logger
|
||||
# PostgreSQL/Greenplum dialects that support ON CONFLICT
|
||||
POSTGRESQL_DIALECTS = {"postgresql", "redshift", "greenplum"}
|
||||
# Dialects that use backtick or no quoting
|
||||
CLICKHOUSE_DIALECTS = {"clickhouse"}
|
||||
CLICKHOUSE_DIALECTS = {"clickhouse", "clickhousedb"}
|
||||
|
||||
|
||||
# #region _normalize_timestamp_value [C:2] [TYPE Function] [SEMANTICS translate,sql,timestamp]
|
||||
|
||||
Reference in New Issue
Block a user