diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-08-20 17:04:25 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-08-20 17:04:25 -0400 |
| commit | aef0c7a903464f4e05496c69ff4e78d41239c220 (patch) | |
| tree | 716afd20faf81a90ca734b946be619549f8d4384 /test/sql/test_operators.py | |
| parent | ce1b80ad08f58ea18914a93805754a5e19a85abb (diff) | |
| download | sqlalchemy-aef0c7a903464f4e05496c69ff4e78d41239c220.tar.gz | |
- [feature] The Core oeprator system now includes
the `getitem` operator, i.e. the bracket
operator in Python. This is used at first
to provide index and slice behavior to the
Postgresql ARRAY type, and also provides a hook
for end-user definition of custom __getitem__
schemes which can be applied at the type
level as well as within ORM-level custom
operator schemes.
Note that this change has the effect that
descriptor-based __getitem__ schemes used by
the ORM in conjunction with synonym() or other
"descriptor-wrapped" schemes will need
to start using a custom comparator in order
to maintain this behavior.
- [feature] postgresql.ARRAY now supports
indexing and slicing. The Python [] operator
is available on all SQL expressions that are
of type ARRAY; integer or simple slices can be
passed. The slices can also be used on the
assignment side in the SET clause of an UPDATE
statement by passing them into Update.values();
see the docs for examples.
- [feature] Added new "array literal" construct
postgresql.array(). Basically a "tuple" that
renders as ARRAY[1,2,3].
Diffstat (limited to 'test/sql/test_operators.py')
| -rw-r--r-- | test/sql/test_operators.py | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/test/sql/test_operators.py b/test/sql/test_operators.py index 05de8c9ef..26a36fd34 100644 --- a/test/sql/test_operators.py +++ b/test/sql/test_operators.py @@ -34,6 +34,18 @@ class DefaultColumnComparatorTest(fixtures.TestBase): def test_plus(self): self._do_operate_test(operators.add) + def test_no_getitem(self): + assert_raises_message( + NotImplementedError, + "Operator 'getitem' is not supported on this expression", + self._do_operate_test, operators.getitem + ) + assert_raises_message( + NotImplementedError, + "Operator 'getitem' is not supported on this expression", + lambda: column('left')[3] + ) + def test_in(self): left = column('left') assert left.comparator.operate(operators.in_op, [1, 2, 3]).compare( @@ -224,3 +236,87 @@ class NewOperatorTest(_CustomComparatorTests, fixtures.TestBase): def _assert_not_add_override(self, expr): assert not hasattr(expr, "foob") +from sqlalchemy import and_, not_, between + +class OperatorPrecedenceTest(fixtures.TestBase, testing.AssertsCompiledSQL): + __dialect__ = 'default' + + def test_operator_precedence(self): + # TODO: clean up /break up + metadata = MetaData() + table = Table('op', metadata, + Column('field', Integer)) + self.assert_compile(table.select((table.c.field == 5) == None), + "SELECT op.field FROM op WHERE (op.field = :field_1) IS NULL") + self.assert_compile(table.select((table.c.field + 5) == table.c.field), + "SELECT op.field FROM op WHERE op.field + :field_1 = op.field") + self.assert_compile(table.select((table.c.field + 5) * 6), + "SELECT op.field FROM op WHERE (op.field + :field_1) * :param_1") + self.assert_compile(table.select((table.c.field * 5) + 6), + "SELECT op.field FROM op WHERE op.field * :field_1 + :param_1") + self.assert_compile(table.select(5 + table.c.field.in_([5, 6])), + "SELECT op.field FROM op WHERE :param_1 + " + "(op.field IN (:field_1, :field_2))") + self.assert_compile(table.select((5 + table.c.field).in_([5, 6])), + "SELECT op.field FROM op WHERE :field_1 + op.field " + "IN (:param_1, :param_2)") + self.assert_compile(table.select(not_(and_(table.c.field == 5, + table.c.field == 7))), + "SELECT op.field FROM op WHERE NOT " + "(op.field = :field_1 AND op.field = :field_2)") + self.assert_compile(table.select(not_(table.c.field == 5)), + "SELECT op.field FROM op WHERE op.field != :field_1") + self.assert_compile(table.select(not_(table.c.field.between(5, 6))), + "SELECT op.field FROM op WHERE NOT " + "(op.field BETWEEN :field_1 AND :field_2)") + self.assert_compile(table.select(not_(table.c.field) == 5), + "SELECT op.field FROM op WHERE (NOT op.field) = :param_1") + self.assert_compile(table.select((table.c.field == table.c.field).\ + between(False, True)), + "SELECT op.field FROM op WHERE (op.field = op.field) " + "BETWEEN :param_1 AND :param_2") + self.assert_compile(table.select( + between((table.c.field == table.c.field), False, True)), + "SELECT op.field FROM op WHERE (op.field = op.field) " + "BETWEEN :param_1 AND :param_2") + +class OperatorAssociativityTest(fixtures.TestBase, testing.AssertsCompiledSQL): + __dialect__ = 'default' + + def test_associativity(self): + # TODO: clean up /break up + f = column('f') + self.assert_compile(f - f, "f - f") + self.assert_compile(f - f - f, "(f - f) - f") + + self.assert_compile((f - f) - f, "(f - f) - f") + self.assert_compile((f - f).label('foo') - f, "(f - f) - f") + + self.assert_compile(f - (f - f), "f - (f - f)") + self.assert_compile(f - (f - f).label('foo'), "f - (f - f)") + + # because - less precedent than / + self.assert_compile(f / (f - f), "f / (f - f)") + self.assert_compile(f / (f - f).label('foo'), "f / (f - f)") + + self.assert_compile(f / f - f, "f / f - f") + self.assert_compile((f / f) - f, "f / f - f") + self.assert_compile((f / f).label('foo') - f, "f / f - f") + + # because / more precedent than - + self.assert_compile(f - (f / f), "f - f / f") + self.assert_compile(f - (f / f).label('foo'), "f - f / f") + self.assert_compile(f - f / f, "f - f / f") + self.assert_compile((f - f) / f, "(f - f) / f") + + self.assert_compile(((f - f) / f) - f, "(f - f) / f - f") + self.assert_compile((f - f) / (f - f), "(f - f) / (f - f)") + + # higher precedence + self.assert_compile((f / f) - (f / f), "f / f - f / f") + + self.assert_compile((f / f) - (f - f), "f / f - (f - f)") + self.assert_compile((f / f) / (f - f), "(f / f) / (f - f)") + self.assert_compile(f / (f / (f - f)), "f / (f / (f - f))") + + |
