diff options
Diffstat (limited to 'lib/sqlalchemy/sql')
| -rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 6 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/elements.py | 21 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/operators.py | 6 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/selectable.py | 1 |
4 files changed, 32 insertions, 2 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 5fbc7d87f..e45db428a 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -1019,13 +1019,15 @@ class SQLCompiler(Compiled): "Unary expression has no operator or modifier") def visit_istrue_unary_operator(self, element, operator, **kw): - if self.dialect.supports_native_boolean: + if element._is_implicitly_boolean or \ + self.dialect.supports_native_boolean: return self.process(element.element, **kw) else: return "%s = 1" % self.process(element.element, **kw) def visit_isfalse_unary_operator(self, element, operator, **kw): - if self.dialect.supports_native_boolean: + if element._is_implicitly_boolean or \ + self.dialect.supports_native_boolean: return "NOT %s" % self.process(element.element, **kw) else: return "%s = 0" % self.process(element.element, **kw) diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index 2e8c39f3b..2a6fa323c 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -641,6 +641,8 @@ class ColumnElement(operators.ColumnOperators, ClauseElement): """A flag that can be flipped to prevent a column from being resolvable by string label name.""" + _is_implicitly_boolean = False + _alt_names = () def self_group(self, against=None): @@ -1229,6 +1231,7 @@ class TextClause(Executable, ClauseElement): _execution_options = \ Executable._execution_options.union( {'autocommit': PARSE_AUTOCOMMIT}) + _is_implicitly_boolean = False @property def _select_iterable(self): @@ -1813,6 +1816,7 @@ class ClauseList(ClauseElement): self.clauses = [ text_converter(clause) for clause in clauses] + self._is_implicitly_boolean = operators.is_boolean(self.operator) def __iter__(self): return iter(self.clauses) @@ -1915,6 +1919,7 @@ class BooleanClauseList(ClauseList, ColumnElement): self.operator = operator self.group_contents = True self.type = type_api.BOOLEANTYPE + self._is_implicitly_boolean = True return self @classmethod @@ -2923,6 +2928,7 @@ class AsBoolean(UnaryExpression): self.negate = negate self.modifier = None self.wraps_column_expression = True + self._is_implicitly_boolean = element._is_implicitly_boolean def self_group(self, against=None): return self @@ -2950,6 +2956,12 @@ class BinaryExpression(ColumnElement): __visit_name__ = 'binary' + _is_implicitly_boolean = True + """Indicates that any database will know this is a boolean expression + even if the database does not have an explicit boolean datatype. + + """ + def __init__(self, left, right, operator, type_=None, negate=None, modifiers=None): # allow compatibility with libraries that @@ -2962,6 +2974,7 @@ class BinaryExpression(ColumnElement): self.operator = operator self.type = type_api.to_instance(type_) self.negate = negate + self._is_implicitly_boolean = operators.is_boolean(operator) if modifiers is None: self.modifiers = {} @@ -3066,6 +3079,10 @@ class Grouping(ColumnElement): def self_group(self, against=None): return self + @util.memoized_property + def _is_implicitly_boolean(self): + return self.element._is_implicitly_boolean + @property def _key_label(self): return self._label @@ -3551,6 +3568,10 @@ class Label(ColumnElement): return self.__class__, (self.name, self._element, self._type) @util.memoized_property + def _is_implicitly_boolean(self): + return self.element._is_implicitly_boolean + + @util.memoized_property def _allow_label_resolve(self): return self.element._allow_label_resolve diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py index fd65979c5..a9f4e3e3e 100644 --- a/lib/sqlalchemy/sql/operators.py +++ b/lib/sqlalchemy/sql/operators.py @@ -1315,6 +1315,12 @@ def is_natural_self_precedent(op): return op in _natural_self_precedent or \ isinstance(op, custom_op) and op.natural_self_precedent +_booleans = (inv, istrue, isfalse, and_, or_) + + +def is_boolean(op): + return is_comparison(op) or op in _booleans + _mirror = { gt: lt, ge: le, diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index 04f6c086d..5b665829b 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -3576,6 +3576,7 @@ class Select(HasPrefixes, HasSuffixes, GenerativeSelect): class ScalarSelect(Generative, Grouping): _from_objects = [] _is_from_container = True + _is_implicitly_boolean = False def __init__(self, element): self.element = element |
