From 735b26fd5935ea23d7d8d56fed96387602bcc028 Mon Sep 17 00:00:00 2001 From: Dhruv Gupta Date: Fri, 6 Nov 2026 06:31:39 -0500 Subject: [PATCH] fix(audits): fail at_least_one when no row has a non-NULL value The at_least_one audit grouped by the constant 1, so an empty table, or a condition that filters out every row, produced no groups at all and the audit passed even though no row has a non-NULL value in the column. Aggregate over the whole table instead and keep the HAVING check, which returns a single row whenever the non-NULL count is zero. Signed-off-by: Dhruv Gupta --- sqlmesh/core/audit/builtin.py | 6 ++++-- tests/core/test_audit.py | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/sqlmesh/core/audit/builtin.py b/sqlmesh/core/audit/builtin.py index f20ce24dc0..e2a5eccb22 100644 --- a/sqlmesh/core/audit/builtin.py +++ b/sqlmesh/core/audit/builtin.py @@ -137,14 +137,16 @@ def create_non_blocking_copy(audit: Audit) -> Audit: ) # at_least_one(column=column_name) +# The aggregate is computed over the whole table rather than per group: grouping by the constant +# produces no groups at all when the table is empty or @condition filters out every row, which +# would make the audit pass even though no row has a non-NULL value. at_least_one_audit = ModelAudit( name="at_least_one", defaults={"condition": exp.true()}, query=""" -SELECT 1 +SELECT COUNT(@column) AS cnt_not_null FROM @this_model WHERE @condition -GROUP BY 1 HAVING COUNT(@column) = 0 """, ) diff --git a/tests/core/test_audit.py b/tests/core/test_audit.py index d579064a07..4ac44da664 100644 --- a/tests/core/test_audit.py +++ b/tests/core/test_audit.py @@ -1,4 +1,6 @@ import json +import typing as t + import pytest from sqlglot import exp, parse_one @@ -712,8 +714,38 @@ def test_at_least_one_audit(model: Model): ) assert ( rendered_query.sql() - == 'SELECT 1 AS "1" FROM (SELECT * FROM "db"."test_model" AS "test_model" WHERE "ds" BETWEEN \'1970-01-01\' AND \'1970-01-01\') AS "_0" WHERE TRUE GROUP BY 1 HAVING COUNT("a") = 0' + == 'SELECT COUNT("a") AS "cnt_not_null" FROM (SELECT * FROM "db"."test_model" AS "test_model" WHERE "ds" BETWEEN \'1970-01-01\' AND \'1970-01-01\') AS "_0" WHERE TRUE HAVING COUNT("a") = 0' + ) + + +def test_at_least_one_audit_fails_when_no_row_has_a_value(): + import duckdb + + model = load_sql_based_model( + parse("MODEL (name db.t, kind FULL); SELECT 1 AS a, TRUE AS flag", default_dialect="duckdb") ) + conn = duckdb.connect() + conn.execute("CREATE SCHEMA db") + conn.execute("CREATE TABLE db.t (a INT, flag BOOLEAN)") + + def audit_rows(**kwargs: exp.Expr) -> t.List[t.Tuple[int]]: + query = model.render_audit_query( + builtin.at_least_one_audit, column=exp.to_column("a"), **kwargs + ) + return conn.execute(query.sql("duckdb")).fetchall() + + # An empty table has no row with a non-NULL value, so the audit must fail + assert audit_rows() == [(0,)] + + conn.execute("INSERT INTO db.t VALUES (NULL, TRUE), (NULL, FALSE)") + assert audit_rows() == [(0,)] + + conn.execute("INSERT INTO db.t VALUES (1, FALSE)") + assert audit_rows() == [] + + # The only non-NULL value is excluded by the condition, so the audit must fail + assert audit_rows(condition=exp.column("flag")) == [(0,)] + assert audit_rows(condition=exp.not_(exp.column("flag"))) == [] def test_mutually_exclusive_ranges_audit(model: Model):