You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by be...@apache.org on 2025/07/15 21:42:52 UTC

(superset) branch databricks-string-escape created (now 595ec937d3)

This is an automated email from the ASF dual-hosted git repository.

beto pushed a change to branch databricks-string-escape
in repository https://gitbox.apache.org/repos/asf/superset.git


      at 595ec937d3 fix(databricks): string escaper

This branch includes the following new commits:

     new 595ec937d3 fix(databricks): string escaper

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(superset) 01/01: fix(databricks): string escaper

Posted by be...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

beto pushed a commit to branch databricks-string-escape
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 595ec937d37f859a674fa886afae16ee3147c656
Author: Beto Dealmeida <ro...@dealmeida.net>
AuthorDate: Tue Jul 15 17:42:41 2025 -0400

    fix(databricks): string escaper
---
 superset/db_engine_specs/databricks.py | 52 ++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/superset/db_engine_specs/databricks.py b/superset/db_engine_specs/databricks.py
index 66e9078bee..758434e1fe 100644
--- a/superset/db_engine_specs/databricks.py
+++ b/superset/db_engine_specs/databricks.py
@@ -24,6 +24,7 @@ from apispec.ext.marshmallow import MarshmallowPlugin
 from flask_babel import gettext as __
 from marshmallow import fields, Schema
 from marshmallow.validate import Range
+from sqlalchemy import types
 from sqlalchemy.engine.reflection import Inspector
 from sqlalchemy.engine.url import URL
 
@@ -40,6 +41,53 @@ if TYPE_CHECKING:
     from superset.models.core import Database
 
 
+try:
+    from databricks.sql.utils import ParamEscaper
+except ImportError:
+
+    class ParamEscaper:
+        """Dummy class."""
+
+
+class DatabricksStringType(types.TypeDecorator):
+    impl = types.String
+    cache_ok = True
+    pe = ParamEscaper()
+
+    def process_literal_param(self, value, dialect) -> str:
+        return self.pe.escape_string(value)
+
+    def literal_processor(self, dialect):
+        def process(value):
+            _step1 = self.process_literal_param(value, dialect="databricks")
+            if dialect.identifier_preparer._double_percents:
+                _step2 = _step1.replace("%", "%%")
+            else:
+                _step2 = _step1
+
+            return "%s" % _step2
+
+        return process
+
+
+def monkeypatch_dialect() -> None:
+    """
+    Monkeypatch dialect to correctly escape single quotes.
+
+    The Databricks SQLAlchemy dialect we currently use does not escape single quotes
+    correctly -- it doubles the single quotes, instead of adding a backslash. The fixed
+    version requires SQLAlchemy 2.0, which is not yet available in Superset.
+    """
+    try:
+        from sqlalchemy_databricks._dialect import DatabricksDialect
+    except ImportError:
+        return
+
+    DatabricksDialect.colspecs[types.String] = DatabricksStringType
+
+    return
+
+
 class DatabricksBaseSchema(Schema):
     """
     Fields that are required for both Databricks drivers that uses a
@@ -595,3 +643,7 @@ class DatabricksPythonConnectorEngineSpec(DatabricksDynamicBaseEngineSpec):
             uri = uri.update_query_dict({"schema": schema})
 
         return uri, connect_args
+
+
+# remove once we've upgraded to SQLAlchemy 2.0 and the 2.x databricks-sqlalchemy lib
+monkeypatch_dialect()