diff --git a/sqlglot-integration-tests b/sqlglot-integration-tests index b4603785d5..54d8263cc1 160000 --- a/sqlglot-integration-tests +++ b/sqlglot-integration-tests @@ -1 +1 @@ -Subproject commit b4603785d5871f30f7aef44b79f7d2a70489d95c +Subproject commit 54d8263cc1b318f2aad9a9c22b1ee6c7f247e1e6 diff --git a/sqlglot/dialects/dialect.py b/sqlglot/dialects/dialect.py index d77b6d396d..a45ec3d952 100644 --- a/sqlglot/dialects/dialect.py +++ b/sqlglot/dialects/dialect.py @@ -2285,15 +2285,12 @@ def _json_extract_segments(self: Generator, expression: JSON_EXTRACT_TYPE) -> st segments = [] for segment in path.expressions: - escape = segment.args.get("quoted") path = self.sql(segment) if path: if isinstance(segment, exp.JSONPathPart) and ( quoted_index or not isinstance(segment, exp.JSONPathSubscript) ): - if escape: - path = self.escape_str(path) - + path = self.escape_str(path) path = f"{self.dialect.QUOTE_START}{path}{self.dialect.QUOTE_END}" segments.append(path) diff --git a/sqlglot/generator.py b/sqlglot/generator.py index 8dde498c7a..869a81e34b 100644 --- a/sqlglot/generator.py +++ b/sqlglot/generator.py @@ -3822,6 +3822,7 @@ def jsonpath_sql(self, expression: exp.JSONPath) -> str: path = self.expressions(expression, sep="", flat=True).lstrip(".") if self.QUOTE_JSON_PATH: + path = self.escape_str(path) path = f"{self.dialect.QUOTE_START}{path}{self.dialect.QUOTE_END}" return path @@ -3840,7 +3841,7 @@ def json_path_part(self, expression: int | str | exp.JSONPathPart) -> str: if self._quote_json_path_key_using_brackets and self.JSON_PATH_SINGLE_QUOTE_ESCAPE: escaped = expression.replace("'", "\\'") - escaped = f"\\'{expression}\\'" + escaped = f"'{escaped}'" else: escaped = expression.replace('"', '\\"') escaped = f'"{escaped}"' @@ -5401,12 +5402,6 @@ def _jsonpathkey_sql(self, expression: exp.JSONPathKey) -> str: this = self.json_path_part(this) - if quoted and self.QUOTE_JSON_PATH: - # The whole path is rendered as a single quoted string literal, so the bracketed key - # (which may itself contain backslash-escaped quotes, e.g. ["x \"y\"z"]) must be - # escaped again for the outer string literal (-> ["x \\"y\\"z"]). - this = self.escape_str(this) - return ( f"[{this}]" if self._quote_json_path_key_using_brackets and self.JSON_PATH_BRACKETED_KEY_SUPPORTED diff --git a/sqlglot/generators/databricks.py b/sqlglot/generators/databricks.py index 98319538ce..7611d29dd3 100644 --- a/sqlglot/generators/databricks.py +++ b/sqlglot/generators/databricks.py @@ -97,10 +97,10 @@ def timeserieskey_sql(self, expression: exp.TimeseriesKey) -> str: return f"{self.sql(expression, 'this')} TIMESERIES" def jsonpath_sql(self, expression: exp.JSONPath) -> str: - expression.set("escape", None) path = super().jsonpath_sql(expression) if isinstance(expression.parent, exp.JSONExtractScalar): + path = self.escape_str(path) return f"{self.dialect.QUOTE_START}{path}{self.dialect.QUOTE_END}" return path diff --git a/tests/test_jsonpath.py b/tests/test_jsonpath.py index 7e846e886c..d37f89d123 100644 --- a/tests/test_jsonpath.py +++ b/tests/test_jsonpath.py @@ -156,4 +156,5 @@ def test_cts_file(self): pass else: path = parse(selector) - self.assertEqual(path.sql(), f"'{overrides.get(selector, selector)}'") + expected = overrides.get(selector, selector).replace("'", "''") + self.assertEqual(path.sql(), f"'{expected}'")