diff --git a/sqlglot/dialects/e6.py b/sqlglot/dialects/e6.py index 9e5ba190a6..016d102d7e 100644 --- a/sqlglot/dialects/e6.py +++ b/sqlglot/dialects/e6.py @@ -3010,7 +3010,14 @@ def _render_variant_colon(self, root, segments) -> str: sql += f":[{seg.this}]" elif isinstance(seg, exp.JSONPathKey): key = seg.this - if key in self.RESERVED_DATATYPE_KEYWORDS or seg.args.get("escape"): + # E6's colon-path grammar rejects a bare reserved word after ':', so any + # E6 reserved word (not just a datatype keyword, e.g. LIMIT/FROM/ORDER) + # must be double-quoted: col:"limit". + if ( + key in self.RESERVED_DATATYPE_KEYWORDS + or (isinstance(key, str) and key.lower() in self.RESERVED_KEYWORDS) + or seg.args.get("escape") + ): sql += f':"{key}"' else: sql += f":{key}" @@ -3041,12 +3048,19 @@ def json_extract_sql(self, e: exp.JSONExtract | exp.JSONExtractScalar): and isinstance(path_expressions[1], exp.JSONPathKey) ): path_key = path_expressions[1].this - if path_key in self.RESERVED_DATATYPE_KEYWORDS: + # E6's colon-path grammar rejects a bare reserved word after ':', so + # any E6 reserved word (not just a datatype keyword, e.g. + # LIMIT/FROM/ORDER) must be double-quoted: col:"limit". + if ( + path_key in self.RESERVED_DATATYPE_KEYWORDS + or ( + isinstance(path_key, str) + and path_key.lower() in self.RESERVED_KEYWORDS + ) + or e.expression.args.get("escape") + ): return f'{self.sql(e.this)}:"{path_key}"' - else: - if e.expression.args.get("escape"): - return f'{self.sql(e.this)}:"{path_key}"' - return f"{self.sql(e.this)}:{path_key}" + return f"{self.sql(e.this)}:{path_key}" # Fallback if not JSONPath format elif isinstance(e.expression, exp.Literal): return f"{self.sql(e.this)}:{e.expression.this}" diff --git a/tests/dialects/test_e6.py b/tests/dialects/test_e6.py index 5d42331710..239ed92782 100644 --- a/tests/dialects/test_e6.py +++ b/tests/dialects/test_e6.py @@ -16,6 +16,21 @@ def test_E6(self): }, ) + # E6's colon-path grammar rejects a bare reserved word after ':' (e.g. LIMIT / ORDER / + # FROM), so those keys must be double-quoted; non-reserved keys stay bare. + self.validate_all( + 'SELECT properties:"limit" FROM source', + read={"databricks": "SELECT properties:limit FROM source"}, + ) + self.validate_all( + 'SELECT properties:"order" FROM source', + read={"databricks": "SELECT properties:order FROM source"}, + ) + self.validate_all( + "SELECT properties:geojson FROM source", + read={"databricks": "SELECT properties:geojson FROM source"}, + ) + self.validate_all( "SELECT FIRST_VALUE(zone) AS zone FROM filtered_zones", read={"databricks": "SELECT FIRST(zone) AS zone FROM filtered_zones"},