Skip to content

Commit 2b5e118

Browse files
committed
feat: add DBMS_UTILITY.FORMAT_ERROR_BACKTRACE
Implements Oracle-compatible DBMS_UTILITY package with FORMAT_ERROR_BACKTRACE function. Adds PL/iSQL exception context tracking and comprehensive test suite.
1 parent c51d958 commit 2b5e118

File tree

9 files changed

+843
-0
lines changed

9 files changed

+843
-0
lines changed

contrib/ivorysql_ora/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ OBJS = \
2525
src/builtin_functions/datetime_datatype_functions.o \
2626
src/builtin_functions/numeric_datatype_functions.o \
2727
src/builtin_functions/misc_functions.o \
28+
src/builtin_functions/dbms_utility.o \
2829
src/merge/ora_merge.o \
2930
src/sysview/sysview_functions.o \
3031
src/xml_functions/ora_xml_functions.o
@@ -65,6 +66,7 @@ ORA_REGRESS = \
6566
ora_character_datatype_functions \
6667
ora_datetime_datatype_functions \
6768
ora_misc_functions \
69+
dbms_utility \
6870
ora_merge \
6971
datatype_and_func_bugs \
7072
ora_sysview \
@@ -73,6 +75,9 @@ ORA_REGRESS = \
7375

7476
SHLIB_LINK += -lxml2
7577

78+
# Add plisql include path for dbms_utility.c
79+
PG_CPPFLAGS += -I$(top_srcdir)/src/pl/plisql/src
80+
7681
ifdef USE_PGXS
7782
PG_CONFIG = pg_config
7883
PGXS := $(shell $(PG_CONFIG) --pgxs)
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
--
2+
-- Tests for DBMS_UTILITY package
3+
--
4+
-- Test 1: FORMAT_ERROR_BACKTRACE - Basic exception in procedure
5+
CREATE OR REPLACE PROCEDURE test_basic_error AS
6+
v_backtrace VARCHAR2(4000);
7+
BEGIN
8+
RAISE EXCEPTION 'Test error';
9+
EXCEPTION
10+
WHEN OTHERS THEN
11+
v_backtrace := DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
12+
RAISE INFO 'Backtrace: %', v_backtrace;
13+
END;
14+
/
15+
CALL test_basic_error();
16+
INFO: Backtrace: ORA-06512: at "PUBLIC.TEST_BASIC_ERROR", line 3
17+
18+
DROP PROCEDURE test_basic_error;
19+
-- Test 2: FORMAT_ERROR_BACKTRACE - Nested procedure calls
20+
CREATE OR REPLACE PROCEDURE test_level3 AS
21+
BEGIN
22+
RAISE EXCEPTION 'Error at level 3';
23+
END;
24+
/
25+
CREATE OR REPLACE PROCEDURE test_level2 AS
26+
BEGIN
27+
test_level3();
28+
END;
29+
/
30+
CREATE OR REPLACE PROCEDURE test_level1 AS
31+
v_backtrace VARCHAR2(4000);
32+
BEGIN
33+
test_level2();
34+
EXCEPTION
35+
WHEN OTHERS THEN
36+
v_backtrace := DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
37+
RAISE INFO 'Backtrace: %', v_backtrace;
38+
END;
39+
/
40+
CALL test_level1();
41+
INFO: Backtrace: ORA-06512: at "PUBLIC.TEST_LEVEL3", line 2
42+
ORA-06512: at "PUBLIC.TEST_LEVEL2", line 2
43+
ORA-06512: at "PUBLIC.TEST_LEVEL1", line 3
44+
45+
DROP PROCEDURE test_level1;
46+
DROP PROCEDURE test_level2;
47+
DROP PROCEDURE test_level3;
48+
-- Test 3: FORMAT_ERROR_BACKTRACE - Deeply nested calls
49+
CREATE OR REPLACE PROCEDURE test_deep5 AS
50+
BEGIN
51+
RAISE EXCEPTION 'Error at deepest level';
52+
END;
53+
/
54+
CREATE OR REPLACE PROCEDURE test_deep4 AS
55+
BEGIN
56+
test_deep5();
57+
END;
58+
/
59+
CREATE OR REPLACE PROCEDURE test_deep3 AS
60+
BEGIN
61+
test_deep4();
62+
END;
63+
/
64+
CREATE OR REPLACE PROCEDURE test_deep2 AS
65+
BEGIN
66+
test_deep3();
67+
END;
68+
/
69+
CREATE OR REPLACE PROCEDURE test_deep1 AS
70+
v_backtrace VARCHAR2(4000);
71+
BEGIN
72+
test_deep2();
73+
EXCEPTION
74+
WHEN OTHERS THEN
75+
v_backtrace := DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
76+
RAISE INFO 'Deep backtrace: %', v_backtrace;
77+
END;
78+
/
79+
CALL test_deep1();
80+
INFO: Deep backtrace: ORA-06512: at "PUBLIC.TEST_DEEP5", line 2
81+
ORA-06512: at "PUBLIC.TEST_DEEP4", line 2
82+
ORA-06512: at "PUBLIC.TEST_DEEP3", line 2
83+
ORA-06512: at "PUBLIC.TEST_DEEP2", line 2
84+
ORA-06512: at "PUBLIC.TEST_DEEP1", line 3
85+
86+
DROP PROCEDURE test_deep1;
87+
DROP PROCEDURE test_deep2;
88+
DROP PROCEDURE test_deep3;
89+
DROP PROCEDURE test_deep4;
90+
DROP PROCEDURE test_deep5;
91+
-- Test 4: FORMAT_ERROR_BACKTRACE - Function calls
92+
CREATE OR REPLACE FUNCTION test_func_error RETURN NUMBER AS
93+
BEGIN
94+
RAISE EXCEPTION 'Error in function';
95+
RETURN 1;
96+
END;
97+
/
98+
CREATE OR REPLACE PROCEDURE test_func_caller AS
99+
v_result NUMBER;
100+
v_backtrace VARCHAR2(4000);
101+
BEGIN
102+
v_result := test_func_error();
103+
EXCEPTION
104+
WHEN OTHERS THEN
105+
v_backtrace := DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
106+
RAISE INFO 'Function backtrace: %', v_backtrace;
107+
END;
108+
/
109+
CALL test_func_caller();
110+
INFO: Function backtrace: ORA-06512: at "PUBLIC.TEST_FUNC_ERROR", line 2
111+
ORA-06512: at "PUBLIC.TEST_FUNC_CALLER", line 4
112+
113+
DROP PROCEDURE test_func_caller;
114+
DROP FUNCTION test_func_error;
115+
-- Test 5: FORMAT_ERROR_BACKTRACE - Anonymous block
116+
DO $$
117+
DECLARE
118+
v_backtrace VARCHAR2(4000);
119+
BEGIN
120+
RAISE EXCEPTION 'Error in anonymous block';
121+
EXCEPTION
122+
WHEN OTHERS THEN
123+
v_backtrace := DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
124+
RAISE INFO 'Anonymous block backtrace: %', v_backtrace;
125+
END;
126+
$$;
127+
INFO: Anonymous block backtrace: ORA-06512: at line 5
128+
129+
-- Test 6: FORMAT_ERROR_BACKTRACE - No exception (should return empty)
130+
CREATE OR REPLACE PROCEDURE test_no_error AS
131+
v_backtrace VARCHAR2(4000);
132+
BEGIN
133+
v_backtrace := DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
134+
RAISE INFO 'No error - backtrace: [%]', v_backtrace;
135+
END;
136+
/
137+
CALL test_no_error();
138+
INFO: No error - backtrace: [<NULL>]
139+
DROP PROCEDURE test_no_error;
140+
-- Test 7: FORMAT_ERROR_BACKTRACE - Multiple exception levels
141+
CREATE OR REPLACE PROCEDURE test_multi_inner AS
142+
BEGIN
143+
RAISE EXCEPTION 'Inner error';
144+
END;
145+
/
146+
CREATE OR REPLACE PROCEDURE test_multi_middle AS
147+
BEGIN
148+
BEGIN
149+
test_multi_inner();
150+
EXCEPTION
151+
WHEN OTHERS THEN
152+
RAISE INFO 'Caught at middle level';
153+
RAISE;
154+
END;
155+
END;
156+
/
157+
CREATE OR REPLACE PROCEDURE test_multi_outer AS
158+
v_backtrace VARCHAR2(4000);
159+
BEGIN
160+
test_multi_middle();
161+
EXCEPTION
162+
WHEN OTHERS THEN
163+
v_backtrace := DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
164+
RAISE INFO 'Outer backtrace: %', v_backtrace;
165+
END;
166+
/
167+
CALL test_multi_outer();
168+
INFO: Caught at middle level
169+
INFO: Outer backtrace: ORA-06512: at "PUBLIC.TEST_MULTI_INNER", line 2
170+
ORA-06512: at "PUBLIC.TEST_MULTI_MIDDLE", line 3
171+
ORA-06512: at "PUBLIC.TEST_MULTI_OUTER", line 3
172+
173+
DROP PROCEDURE test_multi_outer;
174+
DROP PROCEDURE test_multi_middle;
175+
DROP PROCEDURE test_multi_inner;
176+
-- Test 8: FORMAT_ERROR_BACKTRACE - Package procedure
177+
CREATE OR REPLACE PACKAGE test_pkg IS
178+
PROCEDURE pkg_error;
179+
PROCEDURE pkg_caller;
180+
END test_pkg;
181+
/
182+
CREATE OR REPLACE PACKAGE BODY test_pkg IS
183+
PROCEDURE pkg_error IS
184+
BEGIN
185+
RAISE EXCEPTION 'Error in package procedure';
186+
END pkg_error;
187+
PROCEDURE pkg_caller IS
188+
v_backtrace VARCHAR2(4000);
189+
BEGIN
190+
pkg_error();
191+
EXCEPTION
192+
WHEN OTHERS THEN
193+
v_backtrace := DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
194+
RAISE INFO 'Package backtrace: %', v_backtrace;
195+
END pkg_caller;
196+
END test_pkg;
197+
/
198+
CALL test_pkg.pkg_caller();
199+
INFO: Package backtrace: ORA-06512: at "PUBLIC.PKG_ERROR", line 3
200+
ORA-06512: at "PUBLIC.PKG_CALLER", line 8
201+
202+
DROP PACKAGE test_pkg;
203+
-- Test 9: FORMAT_ERROR_BACKTRACE - Schema-qualified calls
204+
CREATE SCHEMA test_schema;
205+
CREATE OR REPLACE PROCEDURE test_schema.schema_error AS
206+
BEGIN
207+
RAISE EXCEPTION 'Error in schema procedure';
208+
END;
209+
/
210+
CREATE OR REPLACE PROCEDURE test_schema.schema_caller AS
211+
v_backtrace VARCHAR2(4000);
212+
BEGIN
213+
test_schema.schema_error();
214+
EXCEPTION
215+
WHEN OTHERS THEN
216+
v_backtrace := DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
217+
RAISE INFO 'Schema-qualified backtrace: %', v_backtrace;
218+
END;
219+
/
220+
CALL test_schema.schema_caller();
221+
INFO: Schema-qualified backtrace: ORA-06512: at "PUBLIC.TEST_SCHEMA.SCHEMA_ERROR", line 2
222+
ORA-06512: at "PUBLIC.TEST_SCHEMA.SCHEMA_CALLER", line 3
223+
224+
DROP SCHEMA test_schema CASCADE;
225+
NOTICE: drop cascades to 2 other objects
226+
DETAIL: drop cascades to function test_schema.schema_error()
227+
drop cascades to function test_schema.schema_caller()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
src/datatype/datatype
22
src/builtin_functions/builtin_functions
3+
src/builtin_functions/dbms_utility
34
src/sysview/sysview
45
src/xml_functions/xml_functions

0 commit comments

Comments
 (0)