Skip to content

Commit 2032e34

Browse files
committed
Changes
1 parent e92f134 commit 2032e34

File tree

2 files changed

+59
-38
lines changed

2 files changed

+59
-38
lines changed

mysql_ch_replicator/converter.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,16 @@ def convert_type(self, mysql_type, parameters):
370370
if "varchar" in mysql_type:
371371
return "String"
372372
if mysql_type.startswith("enum"):
373-
enum_values = parse_mysql_enum(mysql_type)
373+
try:
374+
enum_values = parse_mysql_enum(mysql_type)
375+
except ValueError as e:
376+
# Enhanced error reporting - show both mysql_type and parameters
377+
raise ValueError(
378+
f"Failed to parse enum type. "
379+
f"mysql_type={mysql_type!r}, "
380+
f"parameters={parameters!r}, "
381+
f"Original error: {e}"
382+
) from e
374383
ch_enum_values = []
375384
for idx, value_name in enumerate(enum_values):
376385
ch_enum_values.append(f"'{value_name.lower()}' = {idx + 1}")

mysql_ch_replicator/enum/ddl_parser.py

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
def find_enum_or_set_definition_end(line: str) -> Tuple[int, str, str]:
44
"""
55
Find the end of an enum or set definition in a DDL line
6-
6+
77
Args:
88
line: The DDL line containing an enum or set definition
9-
9+
1010
Returns:
1111
Tuple containing (end_position, field_type, field_parameters)
1212
"""
@@ -34,56 +34,68 @@ def find_enum_or_set_definition_end(line: str) -> Tuple[int, str, str]:
3434
field_type = line[:end_pos]
3535
field_parameters = line[end_pos:].strip()
3636
return end_pos, field_type, field_parameters
37-
38-
# Fallback to splitting by space if we can't find the end
39-
# Use split() instead of split(' ') to handle multiple consecutive spaces
40-
definition = line.split()
41-
field_type = definition[0] if definition else ""
42-
field_parameters = ' '.join(definition[1:]) if len(definition) > 1 else ''
43-
44-
return -1, field_type, field_parameters
37+
38+
# If we couldn't find the end, raise an error with detailed information
39+
# instead of silently falling back to incorrect parsing
40+
raise ValueError(
41+
f"Could not find end of enum/set definition in line. "
42+
f"Input line: {line!r}, "
43+
f"open_parens={open_parens}, "
44+
f"in_quotes={in_quotes}, "
45+
f"quote_char={quote_char!r}"
46+
)
4547

4648

4749
def parse_enum_or_set_field(line: str, field_name: str, is_backtick_quoted: bool = False) -> Tuple[str, str, str]:
4850
"""
4951
Parse a field definition line containing an enum or set type
50-
52+
5153
Args:
5254
line: The line to parse
5355
field_name: The name of the field (already extracted)
5456
is_backtick_quoted: Whether the field name was backtick quoted
55-
57+
5658
Returns:
5759
Tuple containing (field_name, field_type, field_parameters)
5860
"""
59-
# If the field name was backtick quoted, it's already been extracted
60-
if is_backtick_quoted:
61-
line = line.strip()
62-
# Don't split by space for enum and set types that might contain spaces
63-
if line.lower().startswith('enum(') or line.lower().startswith('set('):
64-
end_pos, field_type, field_parameters = find_enum_or_set_definition_end(line)
61+
try:
62+
# If the field name was backtick quoted, it's already been extracted
63+
if is_backtick_quoted:
64+
line = line.strip()
65+
# Don't split by space for enum and set types that might contain spaces
66+
if line.lower().startswith('enum(') or line.lower().startswith('set('):
67+
end_pos, field_type, field_parameters = find_enum_or_set_definition_end(line)
68+
else:
69+
# Use split() instead of split(' ') to handle multiple consecutive spaces
70+
definition = line.split()
71+
field_type = definition[0] if definition else ""
72+
field_parameters = ' '.join(definition[1:]) if len(definition) > 1 else ''
6573
else:
74+
# For non-backtick quoted fields
6675
# Use split() instead of split(' ') to handle multiple consecutive spaces
6776
definition = line.split()
68-
field_type = definition[0] if definition else ""
69-
field_parameters = ' '.join(definition[1:]) if len(definition) > 1 else ''
70-
else:
71-
# For non-backtick quoted fields
72-
# Use split() instead of split(' ') to handle multiple consecutive spaces
73-
definition = line.split()
74-
definition = definition[1:] # Skip the field name which was already extracted
75-
76-
if definition and (
77-
definition[0].lower().startswith('enum(')
78-
or definition[0].lower().startswith('set(')
79-
):
80-
line = ' '.join(definition)
81-
end_pos, field_type, field_parameters = find_enum_or_set_definition_end(line)
82-
else:
83-
field_type = definition[0] if definition else ""
84-
field_parameters = ' '.join(definition[1:]) if len(definition) > 1 else ''
85-
86-
return field_name, field_type, field_parameters
77+
definition = definition[1:] # Skip the field name which was already extracted
78+
79+
if definition and (
80+
definition[0].lower().startswith('enum(')
81+
or definition[0].lower().startswith('set(')
82+
):
83+
line = ' '.join(definition)
84+
end_pos, field_type, field_parameters = find_enum_or_set_definition_end(line)
85+
else:
86+
field_type = definition[0] if definition else ""
87+
field_parameters = ' '.join(definition[1:]) if len(definition) > 1 else ''
88+
89+
return field_name, field_type, field_parameters
90+
except ValueError as e:
91+
# Enhanced error reporting with full context
92+
raise ValueError(
93+
f"Failed to parse field definition. "
94+
f"field_name={field_name!r}, "
95+
f"line={line!r}, "
96+
f"is_backtick_quoted={is_backtick_quoted}, "
97+
f"Original error: {e}"
98+
) from e
8799

88100

89101
def extract_enum_or_set_values(field_type: str, from_parser_func=None) -> Optional[List[str]]:

0 commit comments

Comments
 (0)