summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/dialects/postgresql/array.py
diff options
context:
space:
mode:
authorFederico Caselli <cfederico87@gmail.com>2021-12-10 14:18:34 +0100
committerMike Bayer <mike_mp@zzzcomputing.com>2022-01-04 14:33:46 -0500
commit94afc4f5fc842160468cf7175552125eebf7a510 (patch)
tree37413d3e57a71cb128cd8a61edacc66692bb30b0 /lib/sqlalchemy/dialects/postgresql/array.py
parente913ec8155b64e055f3a88ca9c1bb7f112202c76 (diff)
downloadsqlalchemy-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.py29
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