From c3aeca6084ec780dc2fe6d7b29d2221d2c0e55d8 Mon Sep 17 00:00:00 2001 From: tkaunlaky-e6 Date: Thu, 26 Feb 2026 15:02:56 +0530 Subject: [PATCH] Preserve map[] bracket syntax in VALUES clause for E6 dialect When transpiling from Databricks to E6, map[...] with multiple expressions inside a VALUES clause was incorrectly converted to ELEMENT_AT(), dropping all but the first expression. Databricks uses MAP() with parens for map construction, so map[...] in INSERT VALUES is column access that should be preserved as-is. --- sqlglot/dialects/e6.py | 19 +++++++++++++++++-- tests/dialects/test_e6.py | 25 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/sqlglot/dialects/e6.py b/sqlglot/dialects/e6.py index e8999a861c..1808dde305 100644 --- a/sqlglot/dialects/e6.py +++ b/sqlglot/dialects/e6.py @@ -2139,9 +2139,24 @@ def bracket_sql(self, expression: exp.Bracket) -> str: Convert bracket access to ELEMENT_AT function for E6 dialect. In E6: - - Map access: map['key'] -> ELEMENT_AT(map, 'key') - - Array access: arr[0] -> ELEMENT_AT(arr, 1) (1-indexed in E6) + - col['key'] -> ELEMENT_AT(col, 'key') + - arr[0] -> ELEMENT_AT(arr, 1) (1-indexed in E6) + - Inside VALUES: map[...] preserved as-is (Databricks uses MAP() with + parens for constructors, so map[...] in INSERT VALUES is not ELEMENT_AT) """ + # Inside a VALUES clause, map[...] bracket syntax should be preserved + # as-is. In Databricks MAP() with parens is the constructor; map[...] + # in VALUES is a literal value that must not be rewritten to ELEMENT_AT. + this = expression.this + col_name = this.name if isinstance(this, exp.Column) else "" + if col_name.upper() == "MAP" and len(expression.expressions) > 1: + parent = expression.parent + while parent: + if isinstance(parent, exp.Values): + expressions_sql = ", ".join(self.sql(e) for e in expression.expressions) + return f"{self.sql(expression, 'this')}[{expressions_sql}]" + parent = parent.parent + func_name = ( "TRY_ELEMENT_AT" if expression._meta and expression._meta.get("name", "").upper() == "TRY_ELEMENT_AT" diff --git a/tests/dialects/test_e6.py b/tests/dialects/test_e6.py index 5f4eaffe11..fbafe2051d 100644 --- a/tests/dialects/test_e6.py +++ b/tests/dialects/test_e6.py @@ -585,6 +585,31 @@ def test_E6(self): }, ) + # map[...] bracket syntax inside VALUES should be preserved as-is. + # Databricks uses MAP() with parens for map construction, so map[...] + # in INSERT VALUES is not an ELEMENT_AT operation. + self.validate_all( + "INSERT INTO t1 (selection) VALUES (map['report_id', '221be455', 'name', 'ED SHEERAN'])", + read={ + "databricks": "INSERT INTO t1 (selection) VALUES (map['report_id', '221be455', 'name', 'ED SHEERAN'])", + }, + ) + + self.validate_all( + "INSERT INTO t1 (selection, report_id) VALUES (map['k1', 'v1', 'k2', 'v2'], '123')", + read={ + "databricks": "INSERT INTO t1 (selection, report_id) VALUES (map['k1', 'v1', 'k2', 'v2'], '123')", + }, + ) + + # map['key'] in SELECT (not inside VALUES) should still convert to ELEMENT_AT + self.validate_all( + "SELECT ELEMENT_AT(map, 'key') FROM t1", + read={ + "databricks": "SELECT map['key'] FROM t1", + }, + ) + self.validate_all( "SELECT CONVERT_TIMEZONE('Asia/Seoul', 'UTC', CAST('2016-08-31' AS TIMESTAMP))", read={"databricks": "SELECT to_utc_timestamp('2016-08-31', 'Asia/Seoul')"},