diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-12-16 12:56:21 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-12-16 13:37:40 -0500 |
| commit | d7107641c309e0b7db9b0876ac048dbb38316ba6 (patch) | |
| tree | 747b5ced1c33b1f8eb2da82b534e7159aa979270 /lib/sqlalchemy/dialects | |
| parent | 5bb48511a126b66ed06abf76d706ab707afafbf1 (diff) | |
| download | sqlalchemy-d7107641c309e0b7db9b0876ac048dbb38316ba6.tar.gz | |
make bind escape lookup extensible
To accommodate for third party dialects with different character escaping
needs regarding bound parameters, the system by which SQLAlchemy "escapes"
(i.e., replaces with another character in its place) special characters in
bound parameter names has been made extensible for third party dialects,
using the :attr:`.SQLCompiler.bindname_escape_chars` dictionary which can
be overridden at the class declaration level on any :class:`.SQLCompiler`
subclass. As part of this change, also added the dot ``"."`` as a default
"escaped" character.
Fixes: #8994
Change-Id: I52fbbfa8c64497b123f57327113df3f022bd1419
Diffstat (limited to 'lib/sqlalchemy/dialects')
| -rw-r--r-- | lib/sqlalchemy/dialects/oracle/cx_oracle.py | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py index 8f80aed65..c45aafae6 100644 --- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py +++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py @@ -445,15 +445,6 @@ from ...sql._typing import is_sql_compiler _CX_ORACLE_MAGIC_LOB_SIZE = 131072 -_ORACLE_BIND_TRANSLATE_RE = re.compile(r"[%\(\):\[\]\.\/\? ]") - -# Oracle bind names can't start with digits or underscores. -# currently we rely upon Oracle-specific quoting of bind names in most cases. -# however for expanding params, the escape chars are used. -# see #8708 -_ORACLE_BIND_TRANSLATE_CHARS = dict(zip("%():[]./? ", "PAZCCCCCCCC")) - - class _OracleInteger(sqltypes.Integer): def get_dbapi_type(self, dbapi): # see https://github.com/oracle/python-cx_Oracle/issues/ @@ -694,6 +685,26 @@ class OracleCompiler_cx_oracle(OracleCompiler): _oracle_returning = False + # Oracle bind names can't start with digits or underscores. + # currently we rely upon Oracle-specific quoting of bind names in most + # cases. however for expanding params, the escape chars are used. + # see #8708 + bindname_escape_characters = util.immutabledict( + { + "%": "P", + "(": "A", + ")": "Z", + ":": "C", + ".": "C", + "[": "C", + "]": "C", + " ": "C", + "\\": "C", + "/": "C", + "?": "C", + } + ) + def bindparam_string(self, name, **kw): quote = getattr(name, "quote", None) if ( @@ -721,12 +732,12 @@ class OracleCompiler_cx_oracle(OracleCompiler): escaped_from = kw.get("escaped_from", None) if not escaped_from: - if _ORACLE_BIND_TRANSLATE_RE.search(name): + if self._bind_translate_re.search(name): # not quite the translate use case as we want to # also get a quick boolean if we even found # unusual characters in the name - new_name = _ORACLE_BIND_TRANSLATE_RE.sub( - lambda m: _ORACLE_BIND_TRANSLATE_CHARS[m.group(0)], + new_name = self._bind_translate_re.sub( + lambda m: self._bind_translate_chars[m.group(0)], name, ) if new_name[0].isdigit() or new_name[0] == "_": |
