summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES4
-rw-r--r--lib/sqlalchemy/sql/compiler.py1
-rw-r--r--lib/sqlalchemy/sql/expression.py6
-rw-r--r--lib/sqlalchemy/sql/operators.py3
-rw-r--r--test/orm/test_query.py4
-rw-r--r--test/sql/test_select.py15
6 files changed, 31 insertions, 2 deletions
diff --git a/CHANGES b/CHANGES
index dc69c7dac..fe0be1d4b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,10 @@
=======
CHANGES
=======
+0.6beta2
+- sql
+ - Added math negation operator support, -x.
+
0.6beta1
========
- Major Release
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index e635e20e1..4486c24db 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -73,6 +73,7 @@ OPERATORS = {
# end Py2K
operators.mod : ' % ',
operators.truediv : ' / ',
+ operators.neg : '-',
operators.lt : ' < ',
operators.le : ' <= ',
operators.ne : ' != ',
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py
index 5c61777fe..89137d2ce 100644
--- a/lib/sqlalchemy/sql/expression.py
+++ b/lib/sqlalchemy/sql/expression.py
@@ -1363,6 +1363,9 @@ class ColumnOperators(Operators):
def __ge__(self, other):
return self.operate(operators.ge, other)
+ def __neg__(self):
+ return self.operate(operators.neg)
+
def concat(self, other):
return self.operate(operators.concat_op, other)
@@ -1537,6 +1540,9 @@ class _CompareMixin(ColumnOperators):
return self.__compare(op, ClauseList(*args).self_group(against=op), negate=negate_op)
+ def __neg__(self):
+ return _UnaryExpression(self, operator=operators.neg)
+
def startswith(self, other, escape=None):
"""Produce the clause ``LIKE '<other>%'``"""
diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py
index 879f0f3e5..6f70b1778 100644
--- a/lib/sqlalchemy/sql/operators.py
+++ b/lib/sqlalchemy/sql/operators.py
@@ -4,7 +4,7 @@
"""Defines operators used in SQL expressions."""
from operator import (
- and_, or_, inv, add, mul, sub, mod, truediv, lt, le, ne, gt, ge, eq
+ and_, or_, inv, add, mul, sub, mod, truediv, lt, le, ne, gt, ge, eq, neg
)
# Py2K
@@ -98,6 +98,7 @@ _PRECEDENCE = {
div: 7,
# end Py2K
mod: 7,
+ neg: 7,
add: 6,
sub: 6,
concat_op: 6,
diff --git a/test/orm/test_query.py b/test/orm/test_query.py
index c0835e74a..0d71b3025 100644
--- a/test/orm/test_query.py
+++ b/test/orm/test_query.py
@@ -480,6 +480,10 @@ class OperatorTest(QueryTest, AssertsCompiledSQL):
def test_in_on_relation_not_supported(self):
assert_raises(NotImplementedError, Address.user.in_, [User(id=5)])
+
+ def test_neg(self):
+ self._test(-User.id, "-users.id")
+ self._test(User.id + -User.id, "users.id + -users.id")
def test_between(self):
self._test(User.id.between('a', 'b'),
diff --git a/test/sql/test_select.py b/test/sql/test_select.py
index 8390c7342..766ce8e9b 100644
--- a/test/sql/test_select.py
+++ b/test/sql/test_select.py
@@ -568,7 +568,20 @@ sq.myothertable_othername AS sq_myothertable_othername FROM (" + sqstring + ") A
self.assert_(compiled == fwd_sql or compiled == rev_sql,
"\n'" + compiled + "'\n does not match\n'" +
fwd_sql + "'\n or\n'" + rev_sql + "'")
-
+
+ for (py_op, op) in (
+ (operator.neg, '-'),
+ (operator.inv, 'NOT '),
+ ):
+ for expr, sql in (
+ (table1.c.myid, "mytable.myid"),
+ (literal("foo"), ":param_1"),
+ ):
+
+ compiled = str(py_op(expr))
+ sql = "%s%s" % (op, sql)
+ eq_(compiled, sql)
+
self.assert_compile(
table1.select((table1.c.myid != 12) & ~(table1.c.name=='john')),
"SELECT mytable.myid, mytable.name, mytable.description FROM mytable WHERE mytable.myid != :myid_1 AND mytable.name != :name_1"