From 90335a89a98df23db7a3ae1233eb4fbb5743d2e8 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 20 Mar 2011 12:49:28 -0400 Subject: - Added new generic function "next_value()", accepts a Sequence object as its argument and renders the appropriate "next value" generation string on the target platform, if supported. Also provides ".next_value()" method on Sequence itself. [ticket:2085] - added tests for all the conditions described in [ticket:2085] - postgresql dialect will exec/compile a Sequence that has "optional=True". the optional flag is now only checked specifically in the context of a Table primary key evaulation. - func.next_value() or other SQL expression can be embedded directly into an insert() construct, and if implicit or explicit "returning" is used in conjunction with a primary key column, the newly generated value will be present in result.inserted_primary_key. [ticket:2084] --- lib/sqlalchemy/sql/compiler.py | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'lib/sqlalchemy/sql/compiler.py') 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) -- cgit v1.2.1