diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-08-27 19:40:12 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-08-27 19:40:12 -0400 |
commit | 7d6c1c4a95596d5d83d9187d823f88fdc46f35b6 (patch) | |
tree | 1899e61ed65a2e5e44698bf06a3342aa1e89b422 /lib/sqlalchemy/sql/compiler.py | |
parent | 3a2d617f7f4232ae6f0e256e6b4327e48118ffbf (diff) | |
download | sqlalchemy-7d6c1c4a95596d5d83d9187d823f88fdc46f35b6.tar.gz |
- [feature] Reworked the startswith(), endswith(),
contains() operators to do a better job with
negation (NOT LIKE), and also to assemble them
at compilation time so that their rendered SQL
can be altered, such as in the case for Firebird
STARTING WITH [ticket:2470]
- [feature] firebird - The "startswith()" operator renders
as "STARTING WITH", "~startswith()" renders
as "NOT STARTING WITH", using FB's more efficient
operator. [ticket:2470]
Diffstat (limited to 'lib/sqlalchemy/sql/compiler.py')
-rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 8e4f0288f..297cd9adb 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -24,7 +24,7 @@ To generate user-defined SQL strings, see import re import sys -from .. import schema, engine, util, exc +from .. import schema, engine, util, exc, types from . import ( operators, functions, util as sql_util, visitors, expression as sql ) @@ -670,6 +670,50 @@ class SQLCompiler(engine.Compiled): def _generate_generic_unary_modifier(self, unary, opstring, **kw): return unary.element._compiler_dispatch(self, **kw) + opstring + @util.memoized_property + def _like_percent_literal(self): + return sql.literal_column("'%'", type_=types.String()) + + def visit_contains_op_binary(self, binary, operator, **kw): + binary = binary._clone() + percent = self._like_percent_literal + binary.right = percent.__add__(binary.right).__add__(percent) + return self.visit_like_op_binary(binary, operator, **kw) + + def visit_notcontains_op_binary(self, binary, operator, **kw): + binary = binary._clone() + percent = self._like_percent_literal + binary.right = percent.__add__(binary.right).__add__(percent) + return self.visit_notlike_op_binary(binary, operator, **kw) + + def visit_startswith_op_binary(self, binary, operator, **kw): + binary = binary._clone() + percent = self._like_percent_literal + binary.right = percent.__radd__( + binary.right + ) + return self.visit_like_op_binary(binary, operator, **kw) + + def visit_notstartswith_op_binary(self, binary, operator, **kw): + binary = binary._clone() + percent = self._like_percent_literal + binary.right = percent.__radd__( + binary.right + ) + return self.visit_notlike_op_binary(binary, operator, **kw) + + def visit_endswith_op_binary(self, binary, operator, **kw): + binary = binary._clone() + percent = self._like_percent_literal + binary.right = percent.__add__(binary.right) + return self.visit_like_op_binary(binary, operator, **kw) + + def visit_notendswith_op_binary(self, binary, operator, **kw): + binary = binary._clone() + percent = self._like_percent_literal + binary.right = percent.__add__(binary.right) + return self.visit_notlike_op_binary(binary, operator, **kw) + def visit_like_op_binary(self, binary, operator, **kw): escape = binary.modifiers.get("escape", None) return '%s LIKE %s' % ( |