From: Mike Bayer Date: Thu, 4 Aug 2016 16:34:55 +0000 (-0400) Subject: Propagate kwargs to all MySQL CAST paths X-Git-Tag: rel_1_1_0~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=af6f4ab938f1ef66491cf239c91ffff393275d95;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Propagate kwargs to all MySQL CAST paths Change-Id: I23a6abb26bbbe3d118887d043ce761fc4572d8d2 Fixes: #3766 --- diff --git a/doc/build/changelog/changelog_11.rst b/doc/build/changelog/changelog_11.rst index 5693735297..fe6be3b17e 100644 --- a/doc/build/changelog/changelog_11.rst +++ b/doc/build/changelog/changelog_11.rst @@ -21,6 +21,13 @@ .. changelog:: :version: 1.1.0 + .. change:: + :tags: bug, mysql + :tickets: 3766 + + Fixed bug where the "literal_binds" flag would not be propagated + to a CAST expression under MySQL. + .. change:: :tags: change, orm diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index 5abb1f3d6f..7ab9fad69f 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -811,13 +811,13 @@ class MySQLCompiler(compiler.SQLCompiler): else: return None - def visit_cast(self, cast, **kwargs): + def visit_cast(self, cast, **kw): # No cast until 4, no decimals until 5. if not self.dialect._supports_cast: util.warn( "Current MySQL version does not support " "CAST; the CAST will be skipped.") - return self.process(cast.clause.self_group()) + return self.process(cast.clause.self_group(), **kw) type_ = self.process(cast.typeclause) if type_ is None: @@ -825,9 +825,9 @@ class MySQLCompiler(compiler.SQLCompiler): "Datatype %s does not support CAST on MySQL; " "the CAST will be skipped." % self.dialect.type_compiler.process(cast.typeclause.type)) - return self.process(cast.clause.self_group()) + return self.process(cast.clause.self_group(), **kw) - return 'CAST(%s AS %s)' % (self.process(cast.clause), type_) + return 'CAST(%s AS %s)' % (self.process(cast.clause, **kw), type_) def render_literal_value(self, value, type_): value = super(MySQLCompiler, self).render_literal_value(value, type_) diff --git a/test/dialect/mysql/test_compiler.py b/test/dialect/mysql/test_compiler.py index 8a78934454..88f9235e11 100644 --- a/test/dialect/mysql/test_compiler.py +++ b/test/dialect/mysql/test_compiler.py @@ -12,6 +12,8 @@ from sqlalchemy import Table, MetaData, Column, select, String, \ from sqlalchemy.dialects.mysql import base as mysql from sqlalchemy.testing import fixtures, AssertsCompiledSQL +from sqlalchemy.testing import mock +from sqlalchemy import testing from sqlalchemy.sql import table, column import re @@ -414,6 +416,39 @@ class SQLTest(fixtures.TestBase, AssertsCompiledSQL): self.assert_compile( cast(t.c.col, type_), "CAST(t.col AS SIGNED INTEGER)") + def test_cast_literal_bind(self): + expr = cast(column('foo', Integer) + 5, Integer()) + + self.assert_compile( + expr, + "CAST(foo + 5 AS SIGNED INTEGER)", + literal_binds=True + ) + + def test_unsupported_cast_literal_bind(self): + expr = cast(column('foo', Integer) + 5, Float) + + with expect_warnings( + "Datatype FLOAT does not support CAST on MySQL;" + ): + self.assert_compile( + expr, + "(foo + 5)", + literal_binds=True + ) + + dialect = mysql.MySQLDialect() + dialect.server_version_info = (3, 9, 8) + with expect_warnings( + "Current MySQL version does not support CAST" + ): + eq_( + str(expr.compile( + dialect=dialect, + compile_kwargs={"literal_binds": True})), + "(foo + 5)" + ) + def test_unsupported_casts(self): t = sql.table('t', sql.column('col'))