Extract line and column position from SQL exception message.
(
exception_msg: str,
)
| 103 | |
| 104 | |
| 105 | def _extract_sql_position( |
| 106 | exception_msg: str, |
| 107 | ) -> tuple[int | None, int | None]: |
| 108 | """Extract line and column position from SQL exception message.""" |
| 109 | # SqlGlot format: "Line 1, Col: 15" |
| 110 | line_col_match = re.search(r"Line (\d+), Col: (\d+)", exception_msg) |
| 111 | if line_col_match: |
| 112 | return ( |
| 113 | int(line_col_match.group(1)) - 1, # Convert to 0-based |
| 114 | int(line_col_match.group(2)) - 1, |
| 115 | ) |
| 116 | |
| 117 | # DuckDB format: "LINE 4:" (line only) |
| 118 | line_only_match = re.search(r"LINE (\d+):", exception_msg) |
| 119 | if line_only_match: |
| 120 | return ( |
| 121 | int(line_only_match.group(1)) - 1, # Convert to 0-based |
| 122 | None, # No column information |
| 123 | ) |
| 124 | |
| 125 | # SQLGlot format variations |
| 126 | sqlglot_match = re.search( |
| 127 | r"line (\d+), col (\d+)", exception_msg, re.IGNORECASE |
| 128 | ) |
| 129 | if sqlglot_match: |
| 130 | return ( |
| 131 | int(sqlglot_match.group(1)) - 1, |
| 132 | int(sqlglot_match.group(2)) - 1, |
| 133 | ) |
| 134 | |
| 135 | return None, None |
| 136 | |
| 137 | |
| 138 | def create_sql_error_metadata( |
searching dependent graphs…