Skip to content

Commit 688855f

Browse files
Merge pre/v2.0: Fix nested parentheses in index parsing
2 parents 33abfeb + bf12aba commit 688855f

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

src/datajoint/declare.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,45 @@ def alter(definition: str, old_definition: str, context: dict, adapter) -> tuple
634634
return sql, [e for e in external_stores if e not in external_stores_]
635635

636636

637+
def _parse_index_args(args: str) -> list[str]:
638+
"""
639+
Parse comma-separated index arguments, handling nested parentheses.
640+
641+
Parameters
642+
----------
643+
args : str
644+
The arguments string from an index declaration (e.g., ``"a, b, (func(x, y))"``)
645+
646+
Returns
647+
-------
648+
list[str]
649+
List of individual arguments with surrounding whitespace stripped.
650+
651+
Notes
652+
-----
653+
This parser correctly handles nested parentheses in expressions like
654+
``(json_value(`col`, '$.path' returning char(20)))``.
655+
"""
656+
result = []
657+
current = []
658+
depth = 0
659+
for char in args:
660+
if char == "(":
661+
depth += 1
662+
current.append(char)
663+
elif char == ")":
664+
depth -= 1
665+
current.append(char)
666+
elif char == "," and depth == 0:
667+
result.append("".join(current).strip())
668+
current = []
669+
else:
670+
current.append(char)
671+
if current:
672+
result.append("".join(current).strip())
673+
return [arg for arg in result if arg] # Filter empty strings
674+
675+
637676
def compile_index(line: str, index_sql: list[str], adapter) -> None:
638677
"""
639678
Parse an index declaration and append SQL to index_sql.
@@ -667,7 +706,7 @@ def format_attribute(attr):
667706
raise DataJointError(f'Table definition syntax error in line "{line}"')
668707
match = match.groupdict()
669708

670-
attr_list = re.findall(r"(?:[^,(]|\([^)]*\))+", match["args"])
709+
attr_list = _parse_index_args(match["args"])
671710
index_sql.append(
672711
"{unique}index ({attrs})".format(
673712
unique="unique " if match["unique"] else "",

0 commit comments

Comments
 (0)