From d2989013a6ee11339e1837b74787cd72ee052654 Mon Sep 17 00:00:00 2001 From: chuenchen309 <48723787+chuenchen309@users.noreply.github.com> Date: Sun, 19 Jul 2026 21:23:28 +0800 Subject: [PATCH] Cast REAL to numeric before ROUND in Postgres [CLAUDE] Postgres has no ROUND(real, integer) any more than ROUND(double precision, integer), but the generator only cast double-typed arguments to numeric before rounding, so a REAL argument produced ROUND(real, integer), which Postgres rejects. Widen the guard from DOUBLE to FLOAT_TYPES (which covers REAL) so REAL is cast too; decimal, numeric and integer arguments are unaffected. Co-authored-by AI: Claude (Claude Code). [CLAUDE] --- sqlglot/generators/postgres.py | 2 +- tests/dialects/test_postgres.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/sqlglot/generators/postgres.py b/sqlglot/generators/postgres.py index 37fd98e2b3..ca1988aa0f 100644 --- a/sqlglot/generators/postgres.py +++ b/sqlglot/generators/postgres.py @@ -222,7 +222,7 @@ def _round_sql(self: PostgresGenerator, expression: exp.Round) -> str: # ROUND(double precision, integer) is not permitted in Postgres # so it's necessary to cast to decimal before rounding. - if expression.this.is_type(exp.DType.DOUBLE): + if expression.this.is_type(*exp.DataType.FLOAT_TYPES): decimal_type = exp.DType.DECIMAL.into_expr(expressions=expression.expressions) this = self.sql(exp.Cast(this=this, to=decimal_type)) diff --git a/tests/dialects/test_postgres.py b/tests/dialects/test_postgres.py index f30906bee7..0513fa543c 100644 --- a/tests/dialects/test_postgres.py +++ b/tests/dialects/test_postgres.py @@ -1798,6 +1798,11 @@ def test_round(self): "bigquery": "ROUND(x::DOUBLE, 4)", }, ) + # ROUND(real, integer) is not permitted in Postgres either, so REAL must be cast too. + self.validate_all( + "ROUND(CAST(CAST(x AS REAL) AS DECIMAL), 4)", + read={"postgres": "ROUND(x::REAL, 4)"}, + ) self.validate_all( "ROUND(CAST(x AS DECIMAL(18, 3)), 4)", read={"duckdb": "ROUND(x::DECIMAL, 4)"} )