@@ -57,6 +57,80 @@ END $$;
5757
5858DROP TABLE _test_state;
5959
60+ -- Regression: rolled-back df.start() should not inflate failed_instances in df.metrics()
61+ DO $$
62+ DECLARE
63+ total_metrics BIGINT ;
64+ running_metrics BIGINT ;
65+ completed_metrics BIGINT ;
66+ failed_metrics BIGINT ;
67+ previous_failed_metrics BIGINT := - 1 ;
68+ stable_checks INT := 0 ;
69+ attempts INT := 0 ;
70+ total_instances BIGINT ;
71+ running_instances BIGINT ;
72+ completed_instances BIGINT ;
73+ failed_instances BIGINT ;
74+ BEGIN
75+ BEGIN
76+ PERFORM df .start (' SELECT 1' , ' rollback-metrics-probe' );
77+ RAISE EXCEPTION ' force rollback' ;
78+ EXCEPTION
79+ WHEN OTHERS THEN NULL ;
80+ END;
81+
82+ -- Worker waits up to 5s for an instance row after dequeue. Poll until
83+ -- failed_instances stabilizes for 3 checks after at least ~6s.
84+ LOOP
85+ SELECT m .failed_instances INTO failed_metrics FROM df .metrics () m;
86+
87+ IF failed_metrics = previous_failed_metrics THEN
88+ stable_checks := stable_checks + 1 ;
89+ ELSE
90+ stable_checks := 0 ;
91+ previous_failed_metrics := failed_metrics;
92+ END IF;
93+
94+ EXIT WHEN (attempts >= 12 AND stable_checks >= 3 ) OR attempts >= 60 ;
95+ PERFORM pg_sleep(0 .5 );
96+ attempts := attempts + 1 ;
97+ END LOOP;
98+
99+ SELECT m .total_instances , m .running_instances , m .completed_instances , m .failed_instances
100+ INTO total_metrics, running_metrics, completed_metrics, failed_metrics
101+ FROM df .metrics () m;
102+
103+ SELECT
104+ COUNT (* )::BIGINT ,
105+ COUNT (* ) FILTER (WHERE lower (status) = ' running' )::BIGINT ,
106+ COUNT (* ) FILTER (WHERE lower (status) = ' completed' )::BIGINT ,
107+ COUNT (* ) FILTER (WHERE lower (status) = ' failed' )::BIGINT
108+ INTO total_instances, running_instances, completed_instances, failed_instances
109+ FROM df .instances ;
110+
111+ IF total_metrics != total_instances THEN
112+ RAISE EXCEPTION ' TEST FAILED: metrics total_instances=% does not match df.instances=%' ,
113+ total_metrics, total_instances;
114+ END IF;
115+
116+ IF running_metrics != running_instances THEN
117+ RAISE EXCEPTION ' TEST FAILED: metrics running_instances=% does not match df.instances=%' ,
118+ running_metrics, running_instances;
119+ END IF;
120+
121+ IF completed_metrics != completed_instances THEN
122+ RAISE EXCEPTION ' TEST FAILED: metrics completed_instances=% does not match df.instances=%' ,
123+ completed_metrics, completed_instances;
124+ END IF;
125+
126+ IF failed_metrics != failed_instances THEN
127+ RAISE EXCEPTION ' TEST FAILED: metrics failed_instances=% does not match df.instances=%' ,
128+ failed_metrics, failed_instances;
129+ END IF;
130+
131+ RAISE NOTICE ' TEST PASSED: rollback metrics consistency' ;
132+ END $$;
133+
60134-- === Test: 10_explain ===
61135
62136-- Test dry-run explain (use $body$ to avoid conflict with inner $$)
0 commit comments