"""SQL allow-list and Cube query caps. The Phase 8 gate demands zero SQL executed outside the allow-list. That is a property of this module, so it is tested here rather than inferred from the eval run. """ import pytest from guardrails import GuardrailViolation, check_cube_query, check_sql MAX_ROWS = 5000 def test_plain_select_is_allowed_and_capped(): out = check_sql("SELECT tag_id FROM tags", max_rows=MAX_ROWS) assert "LIMIT 5000" in out.upper() def test_smaller_limit_is_honoured(): out = check_sql("SELECT tag_id FROM tags LIMIT 10", max_rows=MAX_ROWS) assert "LIMIT 10" in out.upper() def test_larger_limit_is_capped(): out = check_sql("SELECT tag_id FROM tags LIMIT 999999", max_rows=MAX_ROWS) assert "LIMIT 5000" in out.upper() @pytest.mark.parametrize( "sql", [ "INSERT INTO equipment VALUES ('X')", "UPDATE tags SET display_name = 'x'", "DELETE FROM doc_chunks", "DROP TABLE tags", "CREATE TABLE t (i int)", ], ) def test_writes_are_refused(sql): with pytest.raises(GuardrailViolation): check_sql(sql, max_rows=MAX_ROWS) def test_stacked_statements_are_refused(): with pytest.raises(GuardrailViolation) as caught: check_sql("SELECT 1 FROM tags; DROP TABLE tags", max_rows=MAX_ROWS) assert caught.value.rule in {"multiple_statements", "write_operation"} def test_table_outside_the_allow_list_is_refused(): with pytest.raises(GuardrailViolation) as caught: check_sql("SELECT * FROM pg_shadow", max_rows=MAX_ROWS) assert caught.value.rule == "table_not_allowed" def test_subquery_tables_are_checked_too(): with pytest.raises(GuardrailViolation): check_sql( "SELECT * FROM tags WHERE tag_id IN (SELECT usename FROM pg_shadow)", max_rows=MAX_ROWS, ) def test_cube_query_needs_a_pinned_window(): with pytest.raises(GuardrailViolation) as caught: check_cube_query({"measures": ["alarm_activity.alarm_count"]}, max_rows=MAX_ROWS) assert caught.value.rule == "unpinned_time_window" def test_cube_query_needs_a_date_range(): with pytest.raises(GuardrailViolation): check_cube_query( {"timeDimensions": [{"dimension": "alarm_activity.event_time"}]}, max_rows=MAX_ROWS, ) def test_cube_query_is_capped(): out = check_cube_query( { "timeDimensions": [ {"dimension": "alarm_activity.event_time", "dateRange": ["2026-08-13", "2026-08-20"]} ], "limit": 1_000_000, }, max_rows=MAX_ROWS, ) assert out["limit"] == MAX_ROWS