"""SQL compilation and caching.
Components:
- CompiledSQL: Immutable compilation result
- SQLProcessor: SQL compiler with caching
- Parameter processing via ParameterProcessor
"""
import logging
from collections import OrderedDict
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, Literal, final
import sqlglot
from mypy_extensions import mypyc_attr
from sqlglot import expressions as exp
from sqlglot.errors import ParseError
import sqlspec.exceptions
from sqlspec.core.parameters import (
ParameterProcessor,
ParameterProfile,
structural_fingerprint,
validate_parameter_alignment,
value_fingerprint,
)
from sqlspec.core.parameters._processor import _make_cache_key_tuple
from sqlspec.utils.logging import get_logger, log_with_context
from sqlspec.utils.type_guards import get_value_attribute
if TYPE_CHECKING:
from sqlspec.core.statement import StatementConfig
__all__ = (
"CompiledSQL",
"OperationProfile",
"OperationType",
"SQLProcessor",
"is_copy_from_operation",
"is_copy_operation",
"is_copy_to_operation",
)
logger: "logging.Logger" = get_logger("sqlspec.core.compiler")
OperationType = Literal[
"SELECT",
"INSERT",
"UPDATE",
"DELETE",
"COPY",
"COPY_FROM",
"COPY_TO",
"EXECUTE",
"SCRIPT",
"DDL",
"PRAGMA",
"MERGE",
"COMMAND",
]
OPERATION_TYPE_MAP: "dict[type[exp.Expr], OperationType]" = {
# Queries
exp.Select: "SELECT",
exp.Union: "SELECT",
exp.Except: "SELECT",
exp.Intersect: "SELECT",
exp.Summarize: "SELECT", # DuckDB SUMMARIZE — returns rows
# DML
exp.Insert: "INSERT",
exp.Update: "UPDATE",
exp.Delete: "DELETE",
exp.Merge: "MERGE",
exp.LoadData: "INSERT", # Hive LOAD DATA — ingests data into a table
# DDL
exp.Create: "DDL",
exp.Drop: "DDL",
exp.Alter: "DDL",
exp.TruncateTable: "DDL",
exp.Grant: "DDL",
exp.Revoke: "DDL",
exp.Comment: "DDL",
# Procedure execution
exp.Execute: "EXECUTE", # TSQL EXEC/EXECUTE
# Session / Admin
exp.Pragma: "PRAGMA",
exp.Command: "COMMAND",
exp.Set: "COMMAND",
exp.Show: "COMMAND", # MySQL dialect
exp.Describe: "COMMAND",
exp.Use: "COMMAND",
exp.Kill: "COMMAND",
exp.Analyze: "COMMAND",
exp.Install: "COMMAND", # DuckDB
exp.Attach: "COMMAND", # DuckDB / SQLite
# Transaction control — mapped to COMMAND for now; a dedicated "TRANSACTION"
# OperationType could be added if downstream code needs to distinguish these.
exp.Transaction: "COMMAND",
exp.Commit: "COMMAND",
exp.Rollback: "COMMAND",
}
COPY_OPERATION_TYPES: "tuple[OperationType, ...]" = ("COPY", "COPY_FROM", "COPY_TO")
COPY_FROM_OPERATION_TYPES: "tuple[OperationType, ...]" = ("COPY", "COPY_FROM")
COPY_TO_OPERATION_TYPES: "tuple[OperationType, ...]" = ("COPY_TO",)
ParseCacheEntry = tuple[exp.Expr | None, OperationType, tuple[bool, bool]]
def is_copy_operation(operation_type: "OperationType") -> bool:
"""Determine if the operation corresponds to any PostgreSQL COPY variant.
Args:
operation_type: Operation type detected by the compiler.
Returns:
True when the operation type represents COPY, COPY FROM, or COPY TO.
"""
return operation_type in COPY_OPERATION_TYPES