summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r--lib/sqlalchemy/sql/compiler.py26
-rw-r--r--lib/sqlalchemy/sql/expression.py10
-rw-r--r--lib/sqlalchemy/sql/functions.py26
3 files changed, 50 insertions, 12 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index d6a020bdc..7547e1662 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -492,6 +492,14 @@ class SQLCompiler(engine.Compiled):
return ".".join(func.packagenames + [name]) % \
{'expr':self.function_argspec(func, **kwargs)}
+ def visit_next_value_func(self, next_value, **kw):
+ return self.visit_sequence(next_value.sequence)
+
+ def visit_sequence(self, sequence):
+ raise NotImplementedError(
+ "Dialect '%s' does not support sequence increments." % self.dialect.name
+ )
+
def function_argspec(self, func, **kwargs):
return func.clause_expr._compiler_dispatch(self, **kwargs)
@@ -926,9 +934,6 @@ class SQLCompiler(engine.Compiled):
join.onclause._compiler_dispatch(self, **kwargs)
)
- def visit_sequence(self, seq):
- return None
-
def visit_insert(self, insert_stmt):
self.isinsert = True
colparams = self._get_colparams(insert_stmt)
@@ -1075,6 +1080,9 @@ class SQLCompiler(engine.Compiled):
if sql._is_literal(value):
value = self._create_crud_bind_param(
c, value, required=value is required)
+ elif c.primary_key and implicit_returning:
+ self.returning.append(c)
+ value = self.process(value.self_group())
else:
self.postfetch.append(c)
value = self.process(value.self_group())
@@ -1092,8 +1100,10 @@ class SQLCompiler(engine.Compiled):
if implicit_returning:
if c.default is not None:
if c.default.is_sequence:
- proc = self.process(c.default)
- if proc is not None:
+ if self.dialect.supports_sequences and \
+ (not c.default.optional or \
+ not self.dialect.sequences_optional):
+ proc = self.process(c.default)
values.append((c, proc))
self.returning.append(c)
elif c.default.is_clause_element:
@@ -1124,8 +1134,10 @@ class SQLCompiler(engine.Compiled):
elif c.default is not None:
if c.default.is_sequence:
- proc = self.process(c.default)
- if proc is not None:
+ if self.dialect.supports_sequences and \
+ (not c.default.optional or \
+ not self.dialect.sequences_optional):
+ proc = self.process(c.default)
values.append((c, proc))
if not c.primary_key:
self.postfetch.append(c)
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py
index 9aed957d2..d49f12150 100644
--- a/lib/sqlalchemy/sql/expression.py
+++ b/lib/sqlalchemy/sql/expression.py
@@ -1178,14 +1178,16 @@ def _column_as_key(element):
return element.key
def _literal_as_text(element):
- if hasattr(element, '__clause_element__'):
+ if isinstance(element, Visitable):
+ return element
+ elif hasattr(element, '__clause_element__'):
return element.__clause_element__()
elif isinstance(element, basestring):
return _TextClause(unicode(element))
- elif not isinstance(element, Visitable):
- raise exc.ArgumentError("SQL expression object or string expected.")
else:
- return element
+ raise exc.ArgumentError(
+ "SQL expression object or string expected."
+ )
def _clause_element_as_expr(element):
if hasattr(element, '__clause_element__'):
diff --git a/lib/sqlalchemy/sql/functions.py b/lib/sqlalchemy/sql/functions.py
index 10eaa577b..717816656 100644
--- a/lib/sqlalchemy/sql/functions.py
+++ b/lib/sqlalchemy/sql/functions.py
@@ -4,7 +4,7 @@
# This module is part of SQLAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
-from sqlalchemy import types as sqltypes
+from sqlalchemy import types as sqltypes, schema
from sqlalchemy.sql.expression import (
ClauseList, Function, _literal_as_binds, text, _type_from_args
)
@@ -29,6 +29,29 @@ class GenericFunction(Function):
self.type = sqltypes.to_instance(
type_ or getattr(self, '__return_type__', None))
+
+class next_value(Function):
+ """Represent the 'next value', given a :class:`.Sequence`
+ as it's single argument.
+
+ Compiles into the appropriate function on each backend,
+ or will raise NotImplementedError if used on a backend
+ that does not provide support for sequences.
+
+ """
+ type = sqltypes.Integer()
+ name = "next_value"
+
+ def __init__(self, seq, **kw):
+ assert isinstance(seq, schema.Sequence), \
+ "next_value() accepts a Sequence object as input."
+ self._bind = kw.get('bind', None)
+ self.sequence = seq
+
+ @property
+ def _from_objects(self):
+ return []
+
class AnsiFunction(GenericFunction):
def __init__(self, **kwargs):
GenericFunction.__init__(self, **kwargs)
@@ -52,6 +75,7 @@ class min(ReturnTypeFromArgs):
class sum(ReturnTypeFromArgs):
pass
+
class now(GenericFunction):
__return_type__ = sqltypes.DateTime