summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/dialects/postgresql/array.py
diff options
context:
space:
mode:
authorFederico Caselli <cfederico87@gmail.com>2022-01-04 20:28:41 +0000
committerGerrit Code Review <gerrit@ci3.zzzcomputing.com>2022-01-04 20:28:41 +0000
commit5a76f52256ca856f245f584869d6b9a4b10d4460 (patch)
tree65160321e458880097d234af46f0335b651fefa9 /lib/sqlalchemy/dialects/postgresql/array.py
parent77fffa930e4d2e5c7097197b82ff5e6b2ca5e9be (diff)
parent94afc4f5fc842160468cf7175552125eebf7a510 (diff)
downloadsqlalchemy-5a76f52256ca856f245f584869d6b9a4b10d4460.tar.gz
Merge "Improve array of enum handling." into main
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