here is fully backwards compatible with existing third party dialects,
however those dialects which implement special LIMIT/OFFSET systems
will need modification in order to take advantage of the new
- capabilities. Work on this feature is courtesy of Dobes Vandermeer.
+ capabilities. Limit and offset also support "literal_binds" mode,
+ where bound parameters are rendered inline as strings based on
+ a compile-time option.
+ Work on this feature is courtesy of Dobes Vandermeer.
+
.. seealso::
def get_crud_hint_text(self, table, text):
return text
- def limit_clause(self, select):
+ def limit_clause(self, select, **kw):
# Limit in mssql is after the select keyword
return ""
" ON ",
self.process(join.onclause, **kwargs)))
- def for_update_clause(self, select):
+ def for_update_clause(self, select, **kw):
if select._for_update_arg.read:
return " LOCK IN SHARE MODE"
else:
return " FOR UPDATE"
- def limit_clause(self, select):
+ def limit_clause(self, select, **kw):
# MySQL supports:
# LIMIT <limit>
# LIMIT <offset>, <limit>
# bound as part of MySQL's "syntax" for OFFSET with
# no LIMIT
return ' \n LIMIT %s, %s' % (
- self.process(offset_clause),
+ self.process(offset_clause, **kw),
"18446744073709551615")
else:
return ' \n LIMIT %s, %s' % (
- self.process(offset_clause),
- self.process(limit_clause))
+ self.process(offset_clause, **kw),
+ self.process(limit_clause, **kw))
else:
# No offset provided, so just use the limit
- return ' \n LIMIT %s' % (self.process(limit_clause),)
+ return ' \n LIMIT %s' % (self.process(limit_clause, **kw),)
def update_limit_clause(self, update_stmt):
limit = update_stmt.kwargs.get('%s_limit' % self.dialect.name, None)
kwargs['iswrapper'] = getattr(select, '_is_wrapper', False)
return compiler.SQLCompiler.visit_select(self, select, **kwargs)
- def limit_clause(self, select):
+ def limit_clause(self, select, **kw):
return ""
- def for_update_clause(self, select):
+ def for_update_clause(self, select, **kw):
if self.is_subquery():
return ""
if select._for_update_arg.of:
tmp += ' OF ' + ', '.join(
- self.process(elem) for elem in
+ self.process(elem, **kw) for elem in
select._for_update_arg.of
)
def visit_sequence(self, seq):
return "nextval('%s')" % self.preparer.format_sequence(seq)
- def limit_clause(self, select):
+ def limit_clause(self, select, **kw):
text = ""
if select._limit_clause is not None:
- text += " \n LIMIT " + self.process(select._limit_clause)
+ text += " \n LIMIT " + self.process(select._limit_clause, **kw)
if select._offset_clause is not None:
if select._limit_clause is None:
text += " \n LIMIT ALL"
- text += " OFFSET " + self.process(select._offset_clause)
+ text += " OFFSET " + self.process(select._offset_clause, **kw)
return text
def format_from_hint_text(self, sqltext, table, hint, iscrud):
else:
return ""
- def for_update_clause(self, select):
+ def for_update_clause(self, select, **kw):
if select._for_update_arg.read:
tmp = " FOR SHARE"
c.table if isinstance(c, expression.ColumnClause)
else c for c in select._for_update_arg.of)
tmp += " OF " + ", ".join(
- self.process(table, ashint=True)
+ self.process(table, ashint=True, **kw)
for table in tables
)
raise exc.CompileError(
"%s is not a valid extract argument." % extract.field)
- def limit_clause(self, select):
+ def limit_clause(self, select, **kw):
text = ""
if select._limit_clause is not None:
- text += "\n LIMIT " + self.process(select._limit_clause)
+ text += "\n LIMIT " + self.process(select._limit_clause, **kw)
if select._offset_clause is not None:
if select._limit_clause is None:
text += "\n LIMIT " + self.process(sql.literal(-1))
- text += " OFFSET " + self.process(select._offset_clause)
+ text += " OFFSET " + self.process(select._offset_clause, **kw)
else:
- text += " OFFSET " + self.process(sql.literal(0))
+ text += " OFFSET " + self.process(sql.literal(0), **kw)
return text
- def for_update_clause(self, select):
+ def for_update_clause(self, select, **kw):
# sqlite has no "FOR UPDATE" AFAICT
return ''
def get_from_hint_text(self, table, text):
return text
- def limit_clause(self, select):
+ def limit_clause(self, select, **kw):
# Limit in sybase is after the select keyword
return ""
if (select._limit_clause is not None or
select._offset_clause is not None):
- text += self.limit_clause(select)
+ text += self.limit_clause(select, **kwargs)
if select._for_update_arg is not None:
- text += self.for_update_clause(select)
+ text += self.for_update_clause(select, **kwargs)
if self.ctes and \
compound_index == 0 and toplevel:
else:
return ""
- def for_update_clause(self, select):
+ def for_update_clause(self, select, **kw):
return " FOR UPDATE"
def returning_clause(self, stmt, returning_cols):
"RETURNING is not supported by this "
"dialect's statement compiler.")
- def limit_clause(self, select):
+ def limit_clause(self, select, **kw):
text = ""
if select._limit_clause is not None:
- text += "\n LIMIT " + self.process(select._limit_clause)
+ text += "\n LIMIT " + self.process(select._limit_clause, **kw)
if select._offset_clause is not None:
if select._limit_clause is None:
text += "\n LIMIT -1"
- text += " OFFSET " + self.process(select._offset_clause)
+ text += " OFFSET " + self.process(select._offset_clause, **kw)
return text
def visit_table(self, table, asfrom=False, iscrud=False, ashint=False,
[(2, 2, 3), (3, 3, 4)]
)
+ def test_limit_offset_nobinds(self):
+ """test that 'literal binds' mode works - no bound params."""
+
+ table = self.tables.some_table
+ stmt = select([table]).order_by(table.c.id).limit(2).offset(1)
+ sql = stmt.compile(
+ dialect=config.db.dialect,
+ compile_kwargs={"literal_binds": True})
+ sql = str(sql)
+
+ self._assert_result(
+ sql,
+ [(2, 2, 3), (3, 3, 4)]
+ )
+
@testing.requires.bound_limit_offset
def test_bound_limit(self):
table = self.tables.some_table
select._offset))
return result
- def limit_clause(self, select):
+ def limit_clause(self, select, **kw):
return ""
dialect = default.DefaultDialect()