]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Revert "Use identifier preparer for string type collations"
authorMichael Bayer <mike_mp@zzzcomputing.com>
Tue, 21 Jul 2026 13:19:39 +0000 (13:19 +0000)
committerGerrit Code Review <gerrit@bbpush.zzzcomputing.com>
Tue, 21 Jul 2026 13:19:39 +0000 (13:19 +0000)
This reverts commit 06fd857c553a9e9cc7b4f30d179ee7582655e7e7.

Reason for revert: this first looked like a small place we needed a workaround, but nothing is ever like that.    unfortunately changing it in this way implies that we aren't using `collation_schema` in other places as well, using the awkward quoted_name workaround, which then leads into more awkwardness as we want collation schemas to be reflected, too.  would we be creating hand-quoted quoted_names for reflection also?  obviously not.   I assume I didnt consider these aspects when i tried to do a "less intrusive" change.

I would like to do just one gerrit that adds collation_schema in all places we need it, plus full reflection, at once, rather than the drip-drip that was not making the scope of the problem clear.

Change-Id: I9b21d87f575625188e6c332889c38a4aa7fa787f

doc/build/changelog/unreleased_21/9693.rst [deleted file]
lib/sqlalchemy/dialects/postgresql/base.py
lib/sqlalchemy/sql/compiler.py
lib/sqlalchemy/sql/sqltypes.py
test/sql/test_types.py

diff --git a/doc/build/changelog/unreleased_21/9693.rst b/doc/build/changelog/unreleased_21/9693.rst
deleted file mode 100644 (file)
index dfb2407..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-.. change::
-    :tags: usecase, schema, postgresql
-    :tickets: 9693
-
-    Adjusted string type collation rendering to use the dialect identifier
-    preparer rather than unconditional quoting.  This allows PostgreSQL
-    schema-qualified collation names to be passed using
-    :class:`.quoted_name` with ``quote=False``.  Pull request courtesy
-    cjc0013.
-
-    .. seealso::
-
-        :ref:`postgresql_collation`
index 8d0ac0403501d0d6e32861ca4ab3206b2d39a7fa..5a815bfa7ba646fc2fd760e6067b361fdb9e3a5d 100644 (file)
@@ -1773,46 +1773,6 @@ itself:
 
 .. versionadded:: 1.4.0b2
 
-.. _postgresql_collation:
-
-Schema-Qualified Collation Names
----------------------------------
-
-.. versionchanged:: 2.1  String type collation rendering now uses the
-   dialect's identifier preparer rather than surrounding the collation
-   name with double quotes unconditionally.  Simple lowercase names are
-   rendered unquoted; mixed-case or special-character names are quoted
-   automatically.  :class:`.quoted_name` with ``quote=True`` or
-   ``quote=False`` is now also interpreted.
-
-PostgreSQL supports collations that are qualified by a schema name, such as
-``pg_catalog.default`` or ``myschema.my_collation``.  When passing a
-schema-qualified collation to the :paramref:`.String.collation` parameter,
-use :class:`.quoted_name` with ``quote=False`` so that the dot separator
-is not quoted as part of the identifier::
-
-    from sqlalchemy import Column, Text
-    from sqlalchemy.sql import quoted_name
-
-    Table(
-        "my_table",
-        metadata,
-        Column(
-            "data",
-            Text(collation=quoted_name("pg_catalog.default", False)),
-        ),
-    )
-
-The above will render the column type as
-``TEXT COLLATE pg_catalog.default``.  Without :class:`.quoted_name`, the
-collation string would be quoted as a single identifier, producing
-``TEXT COLLATE "pg_catalog.default"``, which PostgreSQL would reject.
-
-.. seealso::
-
-    :class:`.quoted_name`
-
-    :paramref:`.String.collation`
 
 
 """  # noqa: E501
index e8dd67720507d53e4122dc91c4150174c827b47b..42b64ec726391b238bddfac8e4c804897197d06d 100644 (file)
@@ -7687,9 +7687,7 @@ class GenericTypeCompiler(TypeCompiler):
         if length:
             text += f"({length})"
         if collation:
-            text += (
-                f" COLLATE {self.dialect.identifier_preparer.quote(collation)}"
-            )
+            text += f' COLLATE "{collation}"'
         return text
 
     def visit_CHAR(self, type_: sqltypes.CHAR, **kw: Any) -> str:
index 459d44a650b65c47875b17dfe2e35b53a1d7c6d0..a3ce81da583c5b4fba42dcdf1b270371f722eb23 100644 (file)
@@ -237,11 +237,6 @@ class String(Concatenable, TypeEngine[str]):
             >>> print(select(cast("some string", String(collation="utf8"))))
             {printsql}SELECT CAST(:param_1 AS VARCHAR COLLATE utf8) AS anon_1
 
-          For backends that support qualified collation names, a
-          :class:`.quoted_name` with ``quote=False`` may be used to render the
-          qualified name without applying quotes to the separator.  See
-          :ref:`postgresql_collation` for a PostgreSQL example.
-
           .. note::
 
             In most cases, the :class:`.Unicode` or :class:`.UnicodeText`
index 2568417629073953d8872b1bb394a5dcca89d81a..fd82a34ea0423907bf71adc6fee210903ebd028c 100644 (file)
@@ -78,7 +78,6 @@ from sqlalchemy.sql import ddl
 from sqlalchemy.sql import elements
 from sqlalchemy.sql import null
 from sqlalchemy.sql import operators
-from sqlalchemy.sql import quoted_name
 from sqlalchemy.sql import sqltypes
 from sqlalchemy.sql import table
 from sqlalchemy.sql import type_api
@@ -3493,7 +3492,7 @@ class ExpressionTest(
         (lambda c1: c1.like("qpr"), "q LIKE :q_1->BINDCAST->[TEXT]"),
         (
             lambda c2: c2.like("qpr"),
-            "q LIKE :q_1->BINDCAST->[TEXT COLLATE xyz]",
+            'q LIKE :q_1->BINDCAST->[TEXT COLLATE "xyz"]',
         ),
         (
             # new behavior, a type with no collation passed into collate()
@@ -3501,11 +3500,11 @@ class ExpressionTest(
             # on the right side bind-cast. previous to #11576 we'd only
             # get TEXT for the bindcast.
             lambda c1: collate(c1, "abc").like("qpr"),
-            "(q COLLATE abc) LIKE :param_1->BINDCAST->[TEXT COLLATE abc]",
+            '(q COLLATE abc) LIKE :param_1->BINDCAST->[TEXT COLLATE "abc"]',
         ),
         (
             lambda c2: collate(c2, "abc").like("qpr"),
-            "(q COLLATE abc) LIKE :param_1->BINDCAST->[TEXT COLLATE abc]",
+            '(q COLLATE abc) LIKE :param_1->BINDCAST->[TEXT COLLATE "abc"]',
         ),
         argnames="testcase,expected",
     )
@@ -3550,7 +3549,7 @@ class ExpressionTest(
         )
         self.assert_compile(
             c2.like("qpr"),
-            "q LIKE :q_1->BINDCAST->[TEXT COLLATE xyz]",
+            'q LIKE :q_1->BINDCAST->[TEXT COLLATE "xyz"]',
             dialect=renders_bind_cast,
         )
 
@@ -4034,20 +4033,6 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
     def test_text_collation(self):
         self.assert_compile(Text(collation="FOO"), 'TEXT COLLATE "FOO"')
 
-    @testing.combinations(
-        ("foo", "TEXT COLLATE foo"),
-        ("FooIdentifier", 'TEXT COLLATE "FooIdentifier"'),
-        ("foo identifier", 'TEXT COLLATE "foo identifier"'),
-        (quoted_name("foo", True), 'TEXT COLLATE "foo"'),
-        (
-            quoted_name("schema_name.collation_name", False),
-            "TEXT COLLATE schema_name.collation_name",
-        ),
-        argnames="collation,expected",
-    )
-    def test_text_collation_identifier_preparer(self, collation, expected):
-        self.assert_compile(Text(collation=collation), expected)
-
     def test_default_compile_pg_inet(self):
         self.assert_compile(
             dialects.postgresql.INET(), "INET", allow_dialect_select=True