From 9d9fc93b7065d25a088e244961cf54606ad80b31 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 26 Jan 2016 15:41:56 -0500 Subject: - The workaround for right-nested joins on SQLite, where they are rewritten as subqueries in order to work around SQLite's lack of support for this syntax, is lifted when SQLite version 3.7.16 or greater is detected. fixes #3634 - The workaround for SQLite's unexpected delivery of column names as ``tablename.columnname`` for some kinds of queries is now disabled when SQLite version 3.10.0 or greater is detected. fixes #3633 --- lib/sqlalchemy/dialects/sqlite/base.py | 19 +++++++++++++------ lib/sqlalchemy/sql/compiler.py | 2 +- 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index c78723ee5..0e048aeff 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -352,6 +352,8 @@ The index will be rendered at create time as:: .. versionadded:: 0.9.9 +.. _sqlite_dotted_column_names: + Dotted Column Names ------------------- @@ -361,7 +363,7 @@ databases in general, as the dot is a syntactically significant character, the SQLite driver up until version **3.10.0** of SQLite has a bug which requires that SQLAlchemy filter out these dots in result sets. -.. note:: +.. versionchanged:: 1.1 The following SQLite issue has been resolved as of version 3.10.0 of SQLite. SQLAlchemy as of **1.1** automatically disables its internal @@ -371,6 +373,8 @@ The bug, entirely outside of SQLAlchemy, can be illustrated thusly:: import sqlite3 + assert sqlite3.sqlite_version_info < (3, 10, 0), "bug is fixed in this version" + conn = sqlite3.connect(":memory:") cursor = conn.cursor() @@ -1003,7 +1007,8 @@ class SQLiteIdentifierPreparer(compiler.IdentifierPreparer): class SQLiteExecutionContext(default.DefaultExecutionContext): @util.memoized_property def _preserve_raw_colnames(self): - return self.execution_options.get("sqlite_raw_colnames", False) + return not self.dialect._broken_dotted_colnames or \ + self.execution_options.get("sqlite_raw_colnames", False) def _translate_colname(self, colname): # TODO: detect SQLite version 3.10.0 or greater; @@ -1029,10 +1034,6 @@ class SQLiteDialect(default.DefaultDialect): supports_cast = True supports_multivalues_insert = True - # TODO: detect version 3.7.16 or greater; - # see [ticket:3634] - supports_right_nested_joins = False - default_paramstyle = 'qmark' execution_ctx_cls = SQLiteExecutionContext statement_compiler = SQLiteCompiler @@ -1056,6 +1057,7 @@ class SQLiteDialect(default.DefaultDialect): ] _broken_fk_pragma_quotes = False + _broken_dotted_colnames = False def __init__(self, isolation_level=None, native_datetime=False, **kwargs): default.DefaultDialect.__init__(self, **kwargs) @@ -1068,6 +1070,11 @@ class SQLiteDialect(default.DefaultDialect): self.native_datetime = native_datetime if self.dbapi is not None: + self.supports_right_nested_joins = ( + self.dbapi.sqlite_version_info >= (3, 7, 16)) + self._broken_dotted_colnames = ( + self.dbapi.sqlite_version_info < (3, 10, 0) + ) self.supports_default_values = ( self.dbapi.sqlite_version_info >= (3, 3, 8)) self.supports_cast = ( diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 076ae53b2..492999d16 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -1422,7 +1422,7 @@ class SQLCompiler(Compiled): """Rewrite any "a JOIN (b JOIN c)" expression as "a JOIN (select * from b JOIN c) AS anon", to support databases that can't parse a parenthesized join correctly - (i.e. sqlite the main one). + (i.e. sqlite < 3.7.16). """ cloned = {} -- cgit v1.2.1