Multi-way conditional (searched or simple form).
CASE [<operand>]
WHEN <expr> THEN <statements>
[WHEN ...]
[ELSE <statements>]
END CASE;
## Overview The CASE statement provides multi-way branching in PL/pgSQL blocks. It supports two forms: the simple form (CASE operand WHEN value THEN ...) that compares a single expression against multiple values, and the searched form (CASE WHEN condition THEN ...) that evaluates independent boolean conditions. ## Behavior - In the simple form, the operand expression is evaluated once. Each WHEN clause value is then compared against it using equality. Multiple comma-separated values in a single WHEN clause are tested as alternatives (OR semantics). - In the searched form (no operand), each WHEN clause is a standalone boolean expression evaluated in order. - The first matching WHEN branch executes. Subsequent branches are skipped entirely. - If no WHEN branch matches and no ELSE clause is present, execution continues silently past the END CASE (no error is raised). - All expressions are evaluated via the DataFusion expression evaluator, so the full range of SQL operators and functions is available in conditions. ## Differences from PostgreSQL - PostgreSQL raises a CASE_NOT_FOUND error when no branch matches and ELSE is absent. DeltaForge does not raise this error; it silently falls through. Add an explicit ELSE clause to guarantee coverage. - Comparison in the simple form uses DataFusion equality, which follows SQL NULL semantics: NULL = NULL evaluates to NULL (not true). Use the searched form with IS NULL checks when NULL values are possible.
DO $$
DECLARE
status TEXT := 'active';
BEGIN
CASE status
WHEN 'active' THEN PRINT 'Active';
WHEN 'inactive' THEN PRINT 'Inactive';
ELSE PRINT 'Unknown';
END CASE;
END;
$$;
DO $$
DECLARE
score INT := 85;
BEGIN
CASE
WHEN score >= 90 THEN PRINT 'Grade: A';
WHEN score >= 80 THEN PRINT 'Grade: B';
WHEN score >= 70 THEN PRINT 'Grade: C';
ELSE PRINT 'Grade: F';
END CASE;
END;
$$;
DO $$
DECLARE
rec RECORD;
BEGIN
FOR rec IN SELECT id, status FROM pipelines LOOP
CASE rec.status
WHEN 'running' THEN
PRINT 'Pipeline', rec.id, 'is running';
WHEN 'failed' THEN
RAISE WARNING 'Pipeline % failed', rec.id;
WHEN 'success' THEN
NULL;
END CASE;
END LOOP;
END;
$$;
DO $$
DECLARE
day_of_week INT;
BEGIN
day_of_week := EXTRACT(DOW FROM CURRENT_DATE)::INT;
CASE day_of_week
WHEN 0, 6 THEN PRINT 'Weekend: skip pipeline';
WHEN 1 THEN PRINT 'Monday: full refresh';
ELSE PRINT 'Weekday: incremental load';
END CASE;
END;
$$;