Skip to content

Commit 3ebc4e8

Browse files
committed
feat: support return values in autonomous transaction functions
- Detect function vs procedure (VOID vs non-VOID return type) - Functions use SELECT via dblink() with SPI to capture return value - Procedures use CALL via dblink_exec() (no return value) - Add test cases for function return values (Test 10, 11) - Document COMMIT/ROLLBACK limitation (issue IvorySQL#985) All 17 tests pass. Matches Oracle behavior for function returns.
1 parent 33bab6f commit 3ebc4e8

File tree

3 files changed

+402
-39
lines changed

3 files changed

+402
-39
lines changed

src/pl/plisql/src/expected/plisql_autonomous.out

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,122 @@ SELECT id, msg FROM autonomous_test WHERE id IN (9, 10) ORDER BY id;
211211
10 | oid test
212212
(2 rows)
213213

214+
--
215+
-- Test 10: Autonomous function with return value
216+
--
217+
CREATE OR REPLACE FUNCTION test_function_return(p_input INT) RETURN INT AS $$
218+
DECLARE
219+
PRAGMA AUTONOMOUS_TRANSACTION;
220+
v_result INT;
221+
BEGIN
222+
v_result := p_input * 2;
223+
INSERT INTO autonomous_test VALUES (p_input, 'function test', 'committed');
224+
RETURN v_result;
225+
END;
226+
$$ LANGUAGE plisql;
227+
/
228+
COMMIT;
229+
WARNING: there is no transaction in progress
230+
-- Call function and verify return value
231+
SELECT test_function_return(50) AS doubled_value;
232+
doubled_value
233+
---------------
234+
100
235+
(1 row)
236+
237+
-- Verify the function also did the insert
238+
SELECT id, msg FROM autonomous_test WHERE id = 50;
239+
id | msg
240+
----+---------------
241+
50 | function test
242+
(1 row)
243+
244+
--
245+
-- Test 11: Autonomous function with NULL return
246+
--
247+
CREATE OR REPLACE FUNCTION test_function_null() RETURN TEXT AS $$
248+
DECLARE
249+
PRAGMA AUTONOMOUS_TRANSACTION;
250+
BEGIN
251+
INSERT INTO autonomous_test VALUES (51, 'null return test', 'committed');
252+
RETURN NULL;
253+
END;
254+
$$ LANGUAGE plisql;
255+
/
256+
COMMIT;
257+
WARNING: there is no transaction in progress
258+
SELECT test_function_null() AS null_result;
259+
null_result
260+
-------------
261+
262+
(1 row)
263+
264+
SELECT id, msg FROM autonomous_test WHERE id = 51;
265+
id | msg
266+
----+------------------
267+
51 | null return test
268+
(1 row)
269+
270+
--
271+
-- Test 12: Explicit COMMIT in autonomous transaction (EXPECTED TO FAIL)
272+
-- Reference: https://github.com/IvorySQL/IvorySQL/issues/985
273+
-- PL/iSQL does not support COMMIT/ROLLBACK in procedures
274+
--
275+
/*
276+
CREATE OR REPLACE PROCEDURE test_explicit_commit(p_id INT) AS
277+
DECLARE
278+
PRAGMA AUTONOMOUS_TRANSACTION;
279+
BEGIN
280+
INSERT INTO autonomous_test VALUES (p_id, 'explicit commit', 'committed');
281+
COMMIT; -- Would fail: ERROR: invalid transaction termination
282+
END;
283+
/
284+
285+
CALL test_explicit_commit(60);
286+
*/
287+
--
288+
-- Test 13: Explicit ROLLBACK in autonomous transaction (EXPECTED TO FAIL)
289+
-- Reference: https://github.com/IvorySQL/IvorySQL/issues/985
290+
-- PL/iSQL does not support COMMIT/ROLLBACK in procedures
291+
--
292+
/*
293+
CREATE OR REPLACE PROCEDURE test_explicit_rollback(p_id INT) AS
294+
DECLARE
295+
PRAGMA AUTONOMOUS_TRANSACTION;
296+
BEGIN
297+
INSERT INTO autonomous_test VALUES (p_id, 'should rollback', 'rolled back');
298+
ROLLBACK; -- Would fail: ERROR: invalid transaction termination
299+
INSERT INTO autonomous_test VALUES (p_id + 1, 'after rollback', 'committed');
300+
END;
301+
/
302+
303+
CALL test_explicit_rollback(70);
304+
-- Expected: id=71 survives, id=70 rolled back (if it worked)
305+
-- Actual: ERROR: invalid transaction termination
306+
*/
307+
--
308+
-- Test 14: Conditional transaction control (EXPECTED TO FAIL)
309+
-- Reference: https://github.com/IvorySQL/IvorySQL/issues/985
310+
-- This pattern is common in Oracle but not supported in PL/iSQL
311+
--
312+
/*
313+
CREATE OR REPLACE PROCEDURE test_conditional_tx(p_id INT, p_should_commit BOOLEAN) AS
314+
DECLARE
315+
PRAGMA AUTONOMOUS_TRANSACTION;
316+
BEGIN
317+
INSERT INTO autonomous_test VALUES (p_id, 'conditional', 'unknown');
318+
319+
IF p_should_commit THEN
320+
COMMIT; -- Would fail: ERROR: invalid transaction termination
321+
ELSE
322+
ROLLBACK; -- Would fail: ERROR: invalid transaction termination
323+
END IF;
324+
END;
325+
/
326+
327+
CALL test_conditional_tx(80, true);
328+
CALL test_conditional_tx(81, false);
329+
*/
214330
--
215331
-- Summary: Show all test results
216332
--
@@ -229,4 +345,6 @@ DROP PROCEDURE test_nulls(INT, TEXT);
229345
DROP PROCEDURE test_sequential(INT);
230346
DROP PROCEDURE test_persist(INT);
231347
DROP PROCEDURE test_oid_invalidation(INT);
348+
DROP FUNCTION test_function_return(INT);
349+
DROP FUNCTION test_function_null();
232350
DROP TABLE autonomous_test;

0 commit comments

Comments
 (0)