2025-02-13 14:53:05 +01:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
import typing as t
|
2025-02-13 06:15:54 +01:00
|
|
|
from enum import auto
|
|
|
|
|
|
|
|
from sqlglot.helper import AutoName
|
|
|
|
|
|
|
|
|
|
|
|
class ErrorLevel(AutoName):
|
2025-02-13 15:23:26 +01:00
|
|
|
IGNORE = auto()
|
|
|
|
"""Ignore all errors."""
|
|
|
|
|
|
|
|
WARN = auto()
|
|
|
|
"""Log all errors."""
|
|
|
|
|
|
|
|
RAISE = auto()
|
|
|
|
"""Collect all errors and raise a single exception."""
|
|
|
|
|
|
|
|
IMMEDIATE = auto()
|
|
|
|
"""Immediately raise an exception on the first error found."""
|
2025-02-13 06:15:54 +01:00
|
|
|
|
|
|
|
|
|
|
|
class SqlglotError(Exception):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class UnsupportedError(SqlglotError):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class ParseError(SqlglotError):
|
2025-02-13 14:56:25 +01:00
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
message: str,
|
|
|
|
errors: t.Optional[t.List[t.Dict[str, t.Any]]] = None,
|
|
|
|
):
|
|
|
|
super().__init__(message)
|
|
|
|
self.errors = errors or []
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def new(
|
|
|
|
cls,
|
|
|
|
message: str,
|
|
|
|
description: t.Optional[str] = None,
|
|
|
|
line: t.Optional[int] = None,
|
|
|
|
col: t.Optional[int] = None,
|
|
|
|
start_context: t.Optional[str] = None,
|
|
|
|
highlight: t.Optional[str] = None,
|
|
|
|
end_context: t.Optional[str] = None,
|
|
|
|
into_expression: t.Optional[str] = None,
|
|
|
|
) -> ParseError:
|
|
|
|
return cls(
|
|
|
|
message,
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"description": description,
|
|
|
|
"line": line,
|
|
|
|
"col": col,
|
|
|
|
"start_context": start_context,
|
|
|
|
"highlight": highlight,
|
|
|
|
"end_context": end_context,
|
|
|
|
"into_expression": into_expression,
|
|
|
|
}
|
|
|
|
],
|
|
|
|
)
|
2025-02-13 06:15:54 +01:00
|
|
|
|
|
|
|
|
|
|
|
class TokenError(SqlglotError):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class OptimizeError(SqlglotError):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2025-02-13 14:53:05 +01:00
|
|
|
class SchemaError(SqlglotError):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2025-02-13 14:54:32 +01:00
|
|
|
class ExecuteError(SqlglotError):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2025-02-13 14:56:25 +01:00
|
|
|
def concat_messages(errors: t.Sequence[t.Any], maximum: int) -> str:
|
2025-02-13 06:15:54 +01:00
|
|
|
msg = [str(e) for e in errors[:maximum]]
|
|
|
|
remaining = len(errors) - maximum
|
|
|
|
if remaining > 0:
|
|
|
|
msg.append(f"... and {remaining} more")
|
|
|
|
return "\n\n".join(msg)
|
2025-02-13 14:56:25 +01:00
|
|
|
|
|
|
|
|
|
|
|
def merge_errors(errors: t.Sequence[ParseError]) -> t.List[t.Dict[str, t.Any]]:
|
|
|
|
return [e_dict for error in errors for e_dict in error.errors]
|