From 7515e50cd7435744fc79c210b2f3aa4c0546ba28 Mon Sep 17 00:00:00 2001 From: RamonWill Date: Wed, 16 Sep 2020 03:33:47 +0100 Subject: [PATCH] support indexing expressions and functions for the MySQL dialect --- doc/build/changelog/unreleased_13/5462.rst | 7 +++++ lib/sqlalchemy/dialects/mysql/base.py | 13 +++++--- test/dialect/mysql/test_compiler.py | 35 +++++++++++++++++++++- 3 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 doc/build/changelog/unreleased_13/5462.rst diff --git a/doc/build/changelog/unreleased_13/5462.rst b/doc/build/changelog/unreleased_13/5462.rst new file mode 100644 index 0000000000..49c633ffd2 --- /dev/null +++ b/doc/build/changelog/unreleased_13/5462.rst @@ -0,0 +1,7 @@ +.. change:: + :tags: mysql, usecase + :tickets: 5462 + + Adjusted the :meth:`MySQLDDLCompiler.visit_create_index` to implement + indexing with expressions and functions on the MySQL dialect. + Pull request courtesy Ramon Williams. diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index 8fb4c3b4b4..2d2f294473 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -1975,12 +1975,17 @@ class MySQLDDLCompiler(compiler.DDLCompiler): self._verify_index_table(index) preparer = self.preparer table = preparer.format_table(index.table) - columns = [ - self.sql_compiler.process( + + columns = [] + for expr in index.expressions: + key_part = self.sql_compiler.process( expr, include_table=False, literal_binds=True ) - for expr in index.expressions - ] + if not isinstance(expr, sa_schema.Column) and not isinstance( + expr, elements.UnaryExpression + ): + key_part = "(%s)" % key_part + columns.append(key_part) name = self._prepared_index_name(index) diff --git a/test/dialect/mysql/test_compiler.py b/test/dialect/mysql/test_compiler.py index b222431ebd..e439c66e33 100644 --- a/test/dialect/mysql/test_compiler.py +++ b/test/dialect/mysql/test_compiler.py @@ -286,7 +286,40 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL): t1 = Table("foo", m, Column("x", Integer)) self.assert_compile( schema.CreateIndex(Index("bar", t1.c.x > 5)), - "CREATE INDEX bar ON foo (x > 5)", + "CREATE INDEX bar ON foo ((x > 5))", + ) + + def test_create_index_expr_two(self): + m = MetaData() + tbl = Table("testtbl", m, Column("x", Integer), Column("y", Integer)) + idx1 = Index("test_idx1", tbl.c.x + tbl.c.y) + idx2 = Index( + "test_idx2", tbl.c.x, tbl.c.x + tbl.c.y, tbl.c.y - tbl.c.x + ) + idx3 = Index("test_idx3", tbl.c.x.desc()) + + self.assert_compile( + schema.CreateIndex(idx1), + "CREATE INDEX test_idx1 ON testtbl ((x + y))", + ) + self.assert_compile( + schema.CreateIndex(idx2), + "CREATE INDEX test_idx2 ON testtbl (x, (x + y), (y - x))", + ) + + self.assert_compile( + schema.CreateIndex(idx3), + "CREATE INDEX test_idx3 ON testtbl (x DESC)", + ) + + def test_create_index_expr_func(self): + m = MetaData() + tbl = Table("testtbl", m, Column("data", Integer)) + idx1 = Index("test_idx1", func.radians(tbl.c.data)) + + self.assert_compile( + schema.CreateIndex(idx1), + "CREATE INDEX test_idx1 ON testtbl ((radians(data)))", ) def test_deferrable_initially_kw_not_ignored(self): -- 2.47.3