diff options
| author | Dobes Vandermeer <dvandermeer@roovy.com> | 2014-04-24 15:20:57 -0700 |
|---|---|---|
| committer | Dobes Vandermeer <dvandermeer@roovy.com> | 2014-04-24 15:20:57 -0700 |
| commit | 338ca8e48827840ad5db4ee4f677e4d3fcd315c9 (patch) | |
| tree | 483e7092969c364fff255b6ed24d1845c2e45c5f /lib | |
| parent | 5016b581b6a0099b5d4babf885ae1f2c05a9589f (diff) | |
| download | sqlalchemy-338ca8e48827840ad5db4ee4f677e4d3fcd315c9.tar.gz | |
Proof-of-concept implementation of supporting bindparam for offset and limit on a query.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/sqlalchemy/dialects/firebird/base.py | 6 | ||||
| -rw-r--r-- | lib/sqlalchemy/dialects/postgresql/base.py | 5 | ||||
| -rw-r--r-- | lib/sqlalchemy/dialects/sqlite/base.py | 5 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 5 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/selectable.py | 16 |
5 files changed, 24 insertions, 13 deletions
diff --git a/lib/sqlalchemy/dialects/firebird/base.py b/lib/sqlalchemy/dialects/firebird/base.py index 21db57b68..fdadb61c1 100644 --- a/lib/sqlalchemy/dialects/firebird/base.py +++ b/lib/sqlalchemy/dialects/firebird/base.py @@ -76,7 +76,7 @@ from sqlalchemy import exc, types as sqltypes, sql, util from sqlalchemy.sql import expression from sqlalchemy.engine import base, default, reflection from sqlalchemy.sql import compiler - +from sqlalchemy.sql.elements import _literal_as_binds from sqlalchemy.types import (BIGINT, BLOB, DATE, FLOAT, INTEGER, NUMERIC, SMALLINT, TEXT, TIME, TIMESTAMP, Integer) @@ -301,9 +301,9 @@ class FBCompiler(sql.compiler.SQLCompiler): result = "" if select._limit: - result += "FIRST %s " % self.process(sql.literal(select._limit)) + result += "FIRST %s " % self.process(_literal_as_binds(select._limit)) if select._offset: - result += "SKIP %s " % self.process(sql.literal(select._offset)) + result += "SKIP %s " % self.process(_literal_as_binds(select._offset)) if select._distinct: result += "DISTINCT " return result diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index f69a6e010..d63e3ed87 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -346,6 +346,7 @@ from ... import sql, schema, exc, util from ...engine import default, reflection from ...sql import compiler, expression, operators from ... import types as sqltypes +from sqlalchemy.sql.elements import _literal_as_binds try: from uuid import UUID as _python_UUID @@ -1144,11 +1145,11 @@ class PGCompiler(compiler.SQLCompiler): def limit_clause(self, select): text = "" if select._limit is not None: - text += " \n LIMIT " + self.process(sql.literal(select._limit)) + text += " \n LIMIT " + self.process(_literal_as_binds(select._limit)) if select._offset is not None: if select._limit is None: text += " \n LIMIT ALL" - text += " OFFSET " + self.process(sql.literal(select._offset)) + text += " OFFSET " + self.process(_literal_as_binds(select._offset)) return text def format_from_hint_text(self, sqltext, table, hint, iscrud): diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index 90df9c192..1ae565232 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -185,6 +185,7 @@ from ... import types as sqltypes, schema as sa_schema from ... import util from ...engine import default, reflection from ...sql import compiler +from sqlalchemy.sql.elements import _literal_as_binds from ...types import (BLOB, BOOLEAN, CHAR, DATE, DECIMAL, FLOAT, INTEGER, REAL, NUMERIC, SMALLINT, TEXT, TIMESTAMP, VARCHAR) @@ -520,11 +521,11 @@ class SQLiteCompiler(compiler.SQLCompiler): def limit_clause(self, select): text = "" if select._limit is not None: - text += "\n LIMIT " + self.process(sql.literal(select._limit)) + text += "\n LIMIT " + self.process(_literal_as_binds(select._limit)) if select._offset is not None: if select._limit is None: text += "\n LIMIT " + self.process(sql.literal(-1)) - text += " OFFSET " + self.process(sql.literal(select._offset)) + text += " OFFSET " + self.process(_literal_as_binds(select._offset)) else: text += " OFFSET " + self.process(sql.literal(0)) return text diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 31193ab17..b59e8a941 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -29,6 +29,7 @@ from .. import util, exc import decimal import itertools import operator +from sqlalchemy.sql.elements import _literal_as_binds RESERVED_WORDS = set([ 'all', 'analyse', 'analyze', 'and', 'any', 'array', @@ -1625,11 +1626,11 @@ class SQLCompiler(Compiled): def limit_clause(self, select): text = "" if select._limit is not None: - text += "\n LIMIT " + self.process(elements.literal(select._limit)) + text += "\n LIMIT " + self.process(_literal_as_binds(select._limit)) if select._offset is not None: if select._limit is None: text += "\n LIMIT -1" - text += " OFFSET " + self.process(elements.literal(select._offset)) + text += " OFFSET " + self.process(_literal_as_binds(select._offset)) return text def visit_table(self, table, asfrom=False, iscrud=False, ashint=False, diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index afcf437e9..5995c1f8a 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -1562,9 +1562,9 @@ class GenerativeSelect(SelectBase): self._execution_options.union( {'autocommit': autocommit}) if limit is not None: - self._limit = util.asint(limit) + self._limit = limit if offset is not None: - self._offset = util.asint(offset) + self._offset = offset self._bind = bind if order_by is not None: @@ -1644,14 +1644,14 @@ class GenerativeSelect(SelectBase): """return a new selectable with the given LIMIT criterion applied.""" - self._limit = util.asint(limit) + self._limit = limit @_generative def offset(self, offset): """return a new selectable with the given OFFSET criterion applied.""" - self._offset = util.asint(offset) + self._offset = offset @_generative def order_by(self, *clauses): @@ -1712,6 +1712,12 @@ class GenerativeSelect(SelectBase): self._group_by_clause = ClauseList(*clauses) + def _copy_internals(self, clone=_clone, **kw): + if isinstance(self._limit, ClauseElement): + self._limit = clone(self._limit) + if isinstance(self._offset, ClauseElement): + self._offset = clone(self._offset) + class CompoundSelect(GenerativeSelect): """Forms the basis of ``UNION``, ``UNION ALL``, and other SELECT-based set operations. @@ -1930,6 +1936,7 @@ class CompoundSelect(GenerativeSelect): "addition of columns to underlying selectables") def _copy_internals(self, clone=_clone, **kw): + super(CompoundSelect, self)._copy_internals(clone, **kw) self._reset_exported() self.selects = [clone(s, **kw) for s in self.selects] if hasattr(self, '_col_map'): @@ -2380,6 +2387,7 @@ class Select(HasPrefixes, GenerativeSelect): return False def _copy_internals(self, clone=_clone, **kw): + super(Select, self)._copy_internals(clone, **kw) # Select() object has been cloned and probably adapted by the # given clone function. Apply the cloning function to internal |
