From a616c0566d69cc17645c73f3fe51c5d7cceb1e06 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 13 Nov 2017 09:21:48 -0500 Subject: [PATCH] Propagate kwargs for mysql concat, match Fixed bug where the MySQL "concat" and "match" operators failed to propagate kwargs to the left and right expressions, causing compiler options such as "literal_binds" to fail. Also adds non-interpreted **kw for visit_create_index, visit_typeclause Change-Id: Iaf54ac18949cc6a54f50678125f010b4f12c5673 Fixes: #4136 (cherry picked from commit 4f054550b768985f1c3393e46e0fc26bfefeeaf6) --- .../changelog/unreleased_11/ticket_4136.rst | 8 ++++++++ lib/sqlalchemy/dialects/mysql/base.py | 14 +++++++------- test/dialect/mysql/test_compiler.py | 18 +++++++++++++++++- 3 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 doc/build/changelog/unreleased_11/ticket_4136.rst diff --git a/doc/build/changelog/unreleased_11/ticket_4136.rst b/doc/build/changelog/unreleased_11/ticket_4136.rst new file mode 100644 index 0000000000..fa0e084763 --- /dev/null +++ b/doc/build/changelog/unreleased_11/ticket_4136.rst @@ -0,0 +1,8 @@ +.. change:: + :tags: bug, mysql + :tickets: 4136 + :versions: 1.2.0b4 + + Fixed bug where the MySQL "concat" and "match" operators failed to + propagate kwargs to the left and right expressions, causing compiler + options such as "literal_binds" to fail. \ No newline at end of file diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index 2ccdb9599d..73db27b867 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -822,21 +822,21 @@ class MySQLCompiler(compiler.SQLCompiler): self.process(binary.right, **kw)) def visit_concat_op_binary(self, binary, operator, **kw): - return "concat(%s, %s)" % (self.process(binary.left), - self.process(binary.right)) + return "concat(%s, %s)" % (self.process(binary.left, **kw), + self.process(binary.right, **kw)) def visit_match_op_binary(self, binary, operator, **kw): return "MATCH (%s) AGAINST (%s IN BOOLEAN MODE)" % \ - (self.process(binary.left), self.process(binary.right)) + (self.process(binary.left, **kw), self.process(binary.right, **kw)) def get_from_hint_text(self, table, text): return text - def visit_typeclause(self, typeclause, type_=None): + def visit_typeclause(self, typeclause, type_=None, **kw): if type_ is None: type_ = typeclause.type.dialect_impl(self.dialect) if isinstance(type_, sqltypes.TypeDecorator): - return self.visit_typeclause(typeclause, type_.impl) + return self.visit_typeclause(typeclause, type_.impl, **kw) elif isinstance(type_, sqltypes.Integer): if getattr(type_, 'unsigned', False): return 'UNSIGNED INTEGER' @@ -1077,7 +1077,7 @@ class MySQLDDLCompiler(compiler.DDLCompiler): return ' '.join(table_opts) - def visit_create_index(self, create): + def visit_create_index(self, create, **kw): index = create.element self._verify_index_table(index) preparer = self.preparer @@ -1094,7 +1094,7 @@ class MySQLDDLCompiler(compiler.DDLCompiler): index_prefix = index.kwargs.get('mysql_prefix', None) if index_prefix: - text += index_prefix + ' ' + text += index_prefix + ' ' text += "INDEX %s ON %s " % (name, table) diff --git a/test/dialect/mysql/test_compiler.py b/test/dialect/mysql/test_compiler.py index 3c33f540c0..e5c61fd86a 100644 --- a/test/dialect/mysql/test_compiler.py +++ b/test/dialect/mysql/test_compiler.py @@ -8,7 +8,7 @@ from sqlalchemy import Table, MetaData, Column, select, String, \ NUMERIC, DECIMAL, Numeric, Float, FLOAT, TIMESTAMP, DATE, \ DATETIME, TIME, \ DateTime, Time, Date, Interval, NCHAR, CHAR, CLOB, TEXT, Boolean, \ - BOOLEAN, LargeBinary, BLOB, SmallInteger, INT, func, cast + BOOLEAN, LargeBinary, BLOB, SmallInteger, INT, func, cast, literal from sqlalchemy.dialects.mysql import base as mysql from sqlalchemy.testing import fixtures, AssertsCompiledSQL @@ -203,6 +203,22 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL): matchtable.c.title.match('somstr'), "MATCH (matchtable.title) AGAINST (%s IN BOOLEAN MODE)") + def test_match_compile_kw(self): + expr = literal('x').match(literal('y')) + self.assert_compile( + expr, + "MATCH ('x') AGAINST ('y' IN BOOLEAN MODE)", + literal_binds=True + ) + + def test_concat_compile_kw(self): + expr = literal('x', type_=String) + literal('y', type_=String) + self.assert_compile( + expr, + "concat('x', 'y')", + literal_binds=True + ) + def test_for_update(self): table1 = table('mytable', column('myid'), column('name'), column('description')) -- 2.47.3