Source code for sqlspec.dialects.spanner._spangres

r"""Google Cloud Spanner PostgreSQL-interface dialect ("Spangres")."""

from typing import cast

from sqlglot import exp
from sqlglot.dialects.postgres import Postgres
from sqlglot.tokenizer_core import TokenType

__all__ = ("Spangres",)


_ROW_DELETION_NAME = "ROW_DELETION_POLICY"
_TTL_MIN_COMPONENTS = 2


class SpangresParser(Postgres.Parser):
    """Parse Spanner row deletion policies."""

    def _parse_property(self) -> exp.Expression:
        if self._match_text_seq("ROW", "DELETION", "POLICY"):
            self._match(TokenType.L_PAREN)
            self._match_text_seq("OLDER_THAN")
            self._match(TokenType.L_PAREN)
            column = cast("exp.Expression", self._parse_id_var())
            self._match(TokenType.COMMA)
            self._match_text_seq("INTERVAL")
            interval = cast("exp.Expression", self._parse_expression())
            self._match(TokenType.R_PAREN)
            self._match(TokenType.R_PAREN)

            return exp.Property(
                this=exp.Literal.string(_ROW_DELETION_NAME), value=exp.Tuple(expressions=[column, interval])
            )

        return cast("exp.Expression", super()._parse_property())


class SpangresGenerator(Postgres.Generator):
    """Generate Spanner row deletion policies."""

    def property_sql(self, expression: exp.Property) -> str:
        if isinstance(expression.this, exp.Literal) and expression.this.name.upper() == _ROW_DELETION_NAME:
            values = expression.args.get("value")
            if isinstance(values, exp.Tuple) and len(values.expressions) >= _TTL_MIN_COMPONENTS:
                column = self.sql(values.expressions[0])
                interval_sql = self.sql(values.expressions[1])
                if not interval_sql.upper().startswith("INTERVAL"):
                    interval_sql = f"INTERVAL {interval_sql}"
                return f"ROW DELETION POLICY (OLDER_THAN({column}, {interval_sql}))"

        return super().property_sql(expression)


[docs] class Spangres(Postgres): """Spanner PostgreSQL-compatible dialect.""" Parser = SpangresParser Generator = SpangresGenerator