-- Copyright (c) Microsoft Corporation. -- Licensed under the PostgreSQL License. -- A loop running directly as a JOIN branch must propagate its body failure -- through the child boundary while leaving both the loop node and parent -- instance terminal. The sibling branch is allowed to finish independently. SET SESSION AUTHORIZATION df_e2e_user; DROP TABLE IF EXISTS test_loop_branch_failure_iterations; DROP TABLE IF EXISTS test_loop_branch_failure_sibling; CREATE TABLE test_loop_branch_failure_iterations (iteration INT PRIMARY KEY); CREATE TABLE test_loop_branch_failure_sibling (marker INT); CREATE TEMP TABLE _loop_branch_failure_instance AS SELECT df.start( df.loop( $$INSERT INTO test_loop_branch_failure_iterations SELECT COUNT(*) + 1 FROM test_loop_branch_failure_iterations$$ ~> df.if( 'SELECT COUNT(*) >= 2 FROM test_loop_branch_failure_iterations', 'SELECT 1/0', df.sleep(1) ) ) & 'INSERT INTO test_loop_branch_failure_sibling VALUES (1)', 'test-loop-branch-failure' ) AS instance_id; DO $$ DECLARE instance_id TEXT; final_status TEXT; instance_output TEXT; loop_status TEXT; loop_inferred_status TEXT; loop_result TEXT; iteration_count INT; sibling_count INT; BEGIN SELECT i.instance_id INTO instance_id FROM _loop_branch_failure_instance i; SELECT df.await_instance(instance_id, 60) INTO final_status; IF final_status IS DISTINCT FROM 'failed' THEN RAISE EXCEPTION 'TEST FAILED [loop-branch-failure]: expected failed instance, got %', final_status; END IF; SELECT count(*) INTO iteration_count FROM test_loop_branch_failure_iterations; SELECT count(*) INTO sibling_count FROM test_loop_branch_failure_sibling; IF iteration_count != 2 OR sibling_count != 1 THEN RAISE EXCEPTION 'TEST FAILED [loop-branch-failure]: expected 2 loop iterations and 1 sibling write, got % / %', iteration_count, sibling_count; END IF; SELECT n.status, n.inferred_status, n.result INTO loop_status, loop_inferred_status, loop_result FROM df.instance_nodes(instance_id) n WHERE n.node_type = 'LOOP'; IF loop_status IS DISTINCT FROM 'failed' OR loop_inferred_status IS DISTINCT FROM 'failed' THEN RAISE EXCEPTION 'TEST FAILED [loop-branch-failure]: LOOP node physical/inferred status = % / %', loop_status, loop_inferred_status; END IF; SELECT output INTO instance_output FROM df.instance_info(instance_id); IF COALESCE(instance_output, loop_result, '') NOT LIKE '%division by zero%' THEN RAISE EXCEPTION 'TEST FAILED [loop-branch-failure]: original SQL error did not surface: instance %, loop %', instance_output, loop_result; END IF; END $$; DROP TABLE _loop_branch_failure_instance; DROP TABLE test_loop_branch_failure_iterations; DROP TABLE test_loop_branch_failure_sibling; RESET SESSION AUTHORIZATION; SELECT 'TEST PASSED' AS result;