diff options
| author | Federico Caselli <cfederico87@gmail.com> | 2021-12-10 14:18:34 +0100 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-01-04 14:33:46 -0500 |
| commit | 94afc4f5fc842160468cf7175552125eebf7a510 (patch) | |
| tree | 37413d3e57a71cb128cd8a61edacc66692bb30b0 /lib/sqlalchemy/dialects/postgresql/array.py | |
| parent | e913ec8155b64e055f3a88ca9c1bb7f112202c76 (diff) | |
| download | sqlalchemy-94afc4f5fc842160468cf7175552125eebf7a510.tar.gz | |
Improve array of enum handling.
Fixed handling of array of enum values which require escape characters.
Fixes: #7418
Change-Id: I50525846f6029dfea9a8ad1cb913424d168d5f62
Diffstat (limited to 'lib/sqlalchemy/dialects/postgresql/array.py')
| -rw-r--r-- | lib/sqlalchemy/dialects/postgresql/array.py | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/lib/sqlalchemy/dialects/postgresql/array.py b/lib/sqlalchemy/dialects/postgresql/array.py index a8010c0fa..f3e82c935 100644 --- a/lib/sqlalchemy/dialects/postgresql/array.py +++ b/lib/sqlalchemy/dialects/postgresql/array.py @@ -364,10 +364,11 @@ class ARRAY(sqltypes.ARRAY): if self._against_native_enum: super_rp = process + pattern = re.compile(r"^{(.*)}$") def handle_raw_string(value): - inner = re.match(r"^{(.*)}$", value).group(1) - return inner.split(",") if inner else [] + inner = pattern.match(value).group(1) + return _split_enum_values(inner) def process(value): if value is None: @@ -382,3 +383,27 @@ class ARRAY(sqltypes.ARRAY): ) return process + + +def _split_enum_values(array_string): + if '"' not in array_string: + # no escape char is present so it can just split on the comma + return array_string.split(",") + + # handles quoted strings from: + # r'abc,"quoted","also\\\\quoted", "quoted, comma", "esc \" quot", qpr' + # returns + # ['abc', 'quoted', 'also\\quoted', 'quoted, comma', 'esc " quot', 'qpr'] + text = array_string.replace(r"\"", "_$ESC_QUOTE$_") + text = text.replace(r"\\", "\\") + result = [] + on_quotes = re.split(r'(")', text) + in_quotes = False + for tok in on_quotes: + if tok == '"': + in_quotes = not in_quotes + elif in_quotes: + result.append(tok.replace("_$ESC_QUOTE$_", '"')) + else: + result.extend(re.findall(r"([^\s,]+),?", tok)) + return result |
