diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-09-30 10:09:56 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-10-01 09:46:11 -0400 |
commit | 333414fe94941a6a58e7d8e45042548eb2d58119 (patch) | |
tree | d4e82336605dbfbeda0afb5735b3c56449db9b56 /lib/sqlalchemy/sql/compiler.py | |
parent | 9bfd0289383bfcaf650fe516862df545dcf95c2e (diff) | |
download | sqlalchemy-333414fe94941a6a58e7d8e45042548eb2d58119.tar.gz |
Add "eager_parenthesis" late-compilation rule, use w/ PG JSON/HSTORE
Added compiler-level flags used by Postgresql to place additional
parenthesis than would normally be generated by precedence rules
around operations involving JSON, HSTORE indexing operators as well as
within their operands since it has been observed that Postgresql's
precedence rules for at least the HSTORE indexing operator is not
consistent between 9.4 and 9.5.
Fixes: #3806
Change-Id: I5899677b330595264543b055abd54f3c76bfabf2
Diffstat (limited to 'lib/sqlalchemy/sql/compiler.py')
-rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index a2dbcee5c..6527eb8c6 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -994,7 +994,9 @@ class SQLCompiler(Compiled): return "NOT %s" % self.visit_binary( binary, override_operator=operators.match_op) - def visit_binary(self, binary, override_operator=None, **kw): + def visit_binary(self, binary, override_operator=None, + eager_grouping=False, **kw): + # don't allow "? = ?" to render if self.ansi_bind_rules and \ isinstance(binary.left, elements.BindParameter) and \ @@ -1014,6 +1016,7 @@ class SQLCompiler(Compiled): return self._generate_generic_binary(binary, opstring, **kw) def visit_custom_op_binary(self, element, operator, **kw): + kw['eager_grouping'] = operator.eager_grouping return self._generate_generic_binary( element, " " + operator.opstring + " ", **kw) @@ -1025,10 +1028,21 @@ class SQLCompiler(Compiled): return self._generate_generic_unary_modifier( element, " " + operator.opstring, **kw) - def _generate_generic_binary(self, binary, opstring, **kw): - return binary.left._compiler_dispatch(self, **kw) + \ + def _generate_generic_binary( + self, binary, opstring, eager_grouping=False, **kw): + + _in_binary = kw.get('_in_binary', False) + + kw['_in_binary'] = True + text = binary.left._compiler_dispatch( + self, eager_grouping=eager_grouping, **kw) + \ opstring + \ - binary.right._compiler_dispatch(self, **kw) + binary.right._compiler_dispatch( + self, eager_grouping=eager_grouping, **kw) + + if _in_binary and eager_grouping: + text = "(%s)" % text + return text def _generate_generic_unary_operator(self, unary, opstring, **kw): return opstring + unary.element._compiler_dispatch(self, **kw) @@ -2215,6 +2229,12 @@ class StrSQLCompiler(SQLCompiler): self.process(binary.right, **kw) ) + def visit_json_getitem_op_binary(self, binary, operator, **kw): + return self.visit_getitem_binary(binary, operator, **kw) + + def visit_json_path_getitem_op_binary(self, binary, operator, **kw): + return self.visit_getitem_binary(binary, operator, **kw) + def returning_clause(self, stmt, returning_cols): columns = [ self._label_select_column(None, c, True, False, {}) |