@@ -10,47 +10,63 @@ caller_type varchar2(50));
1010TYPE callstack IS TABLE OF stackline;
1111*/
1212
13- function getCallStack return callstack
13+ function getCallStack(pskip number default 0) return callstack
1414IS
15+ --orcle docs say format_call stack only returns 2000.. but might as well be safe
1516 call_stack VARCHAR2(4096) DEFAULT dbms_utility.format_call_stack;
1617 n NUMBER;
1718 found_stack BOOLEAN DEFAULT FALSE;
1819 line VARCHAR2(255);
1920 cnt NUMBER := 0;
20-
21+ idx NUMBER := 0;
22+
2123 retval callstack := callstack();
2224BEGIN
23- --dbms_output.put_line(call_stack);
25+ -- dbms_output.put_line('in getCallstack');
26+ -- dbms_output.put_line('###################################################');
27+ -- dbms_output.put_line(call_stack);
28+ -- dbms_output.put_line('###################################################');
2429 --
2530 LOOP
31+
2632 n := instr( call_stack, chr(10) );
27- EXIT
28- WHEN ( n IS NULL OR n = 0 );
33+ EXIT WHEN ( n IS NULL OR n = 0 );
2934 --
3035 line := SUBSTR( call_stack, 1, n-1 );
3136 call_stack := SUBSTR( call_stack, n +1 );
3237 --
3338 IF ( NOT found_stack ) THEN
3439 IF ( line LIKE '%handle%number%name%' ) THEN
40+ -- dbms_output.put_line('found stack');
41+ -- dbms_output.put_line(' 1 2 3 4');
42+ -- dbms_output.put_line('1234567890123456789012345678901234567890');
3543 found_stack := TRUE;
3644 END IF;
3745 ELSE
3846 cnt := cnt + 1;
3947 -- cnt = 1 is ME
4048 -- cnt = 2 is MY Caller
4149 -- cnt = 3 is Their Caller
42- IF ( cnt >2 ) THEN --start with 1 to ignore this fake getCallStack call.
43-
44- retval.extend;
45-
46-
47- --dbms_output.put_line(' 1 2 3');
48- --dbms_output.put_line('123456789012345678901234567890');
49- --dbms_output.put_line(line);
50+ IF ( cnt > 1+pskip ) THEN --start with 1 to ignore this fake getCallStack call.
51+
52+ retval.EXTEND;
53+
54+ BEGIN
55+
5056 --format '0x70165ba0 104 package body S06DP3.LOGMANAGER'
51- retval(retval.last).handle := SUBSTR( line, 1, 13 );
52- retval(retval.last).line := to_number(SUBSTR( line, 13, 8 ));
53- line := SUBSTR( line, 23 ); --set to rest of line .. change from 21 to 23
57+ idx := instr(line,' ');
58+ -- dbms_output.put_line('handle:'||SUBSTR( line, 1, idx-1 )||'#');
59+ retval(retval.LAST).handle := SUBSTR( line, 1, idx-1 );
60+
61+ line := trim(substr(line,idx+1));
62+ idx := instr(line,' ');
63+
64+ -- dbms_output.put_line('lineno:'||trim(SUBSTR( line, 1,idx-1 ))||'#');
65+ retval(retval.LAST).line := TO_NUMBER(trim(SUBSTR( line, 1, idx-1 )));
66+
67+ line := trim(substr(line,idx+1)); --set to rest of line
68+ -- dbms_output.put_line('prog:'|| line||'#');
69+
5470 IF ( line LIKE 'pr%' ) THEN
5571 n := LENGTH( 'procedure ' );
5672 elsif ( line LIKE 'fun%' ) THEN
6480 ELSE
6581 n := NULL;
6682 END IF;
83+
6784 IF ( n IS NOT NULL ) THEN
6885 retval(retval.last).caller_type := ltrim(rtrim(upper(SUBSTR( line, 1, n-1 ))));
6986 ELSE
7592 --owner := ltrim(rtrim(SUBSTR( line, 1, n-1 )));
7693 --name := LTRIM(RTRIM(SUBSTR( LINE, N +1 )));
7794
95+ EXCEPTION
96+ WHEN OTHERS THEN
97+ --we cant deal with errors in this package..so just set values to something
98+ retval(retval.LAST).handle := NVL(retval(retval.LAST).handle,' ');
99+ retval(retval.LAST).line := nvl(retval(retval.LAST).line , -1);
100+ retval(retval.LAST).caller_type := nvl(retval(retval.LAST).caller_type , 'unknown');
101+ retval(retval.LAST).object_name := nvl(retval(retval.LAST).object_name , 'unknown');
102+ END;
78103 END IF;
79104 END IF;
80105 END LOOP;
@@ -85,7 +110,7 @@ END getCallStack;
85110 FUNCTION subprogram(dynamic_depth IN PLS_INTEGER) RETURN UNIT_QUALIFIED_NAME AS
86111 cs callstack;
87112 BEGIN
88- cs := getcallstack;
113+ cs := getcallstack(1) ;
89114 --RETURN UNIT_QUALIFIED_NAME(
90115 --substr(cs(dynamic_depth).object_name,1, instr(cs(dynamic_depth).object_name,'.'))
91116 --,nvl( substr(cs(dynamic_depth).object_name,instr(cs(dynamic_depth).object_name,'.')), '__anonymous_block')
@@ -97,25 +122,26 @@ END getCallStack;
97122 RETURN VARCHAR2 AS
98123 retval varchar2(2000);
99124 BEGIN
125+ IF qualified_name.FIRST IS NOT NULL THEN
100126 for i in qualified_name.first .. qualified_name.last LOOP
101127 retval := retval||'.'||qualified_name(i);
102- end loop;
128+ END loop;
129+ END IF;
103130 RETURN LTRIM(retval,'.');
104131 END concatenate_subprogram;
105132
106133 FUNCTION owner(dynamic_depth IN PLS_INTEGER) RETURN VARCHAR2 AS
107134 cs callstack;
108135 BEGIN
109- cs := getcallstack;
136+ cs := getcallstack(1) ;
110137 --RETURN subprogram(dynamic_depth)(0);
111138 RETURN substr(cs(dynamic_depth).object_name,1,instr(cs(dynamic_depth).object_name,'.')-1);
112139 END owner;
113140
114141 FUNCTION unit_line(dynamic_depth IN PLS_INTEGER) RETURN PLS_INTEGER AS
115-
116142 cs callstack;
117143 BEGIN
118- cs := getcallstack;
144+ cs := getcallstack(1) ;
119145 RETURN cs(dynamic_depth).line;
120146 END unit_line;
121147
@@ -124,12 +150,10 @@ END getCallStack;
124150 FUNCTION dynamic_depth RETURN PLS_INTEGER AS
125151 cs callstack;
126152 BEGIN
127- cs := getcallstack;
153+ cs := getcallstack(1) ;
128154 RETURN cs.count;
129155 END dynamic_depth;
130-
131-
132-
156+
133157-- --------------------------------
134158-- --------------------------------------
135159
@@ -142,7 +166,7 @@ END getCallStack;
142166 FUNCTION lexical_depth(dynamic_depth IN PLS_INTEGER) RETURN PLS_INTEGER AS
143167 cs callstack;
144168 BEGIN
145- cs := getcallstack;
169+ cs := getcallstack(1) ;
146170 return LENGTH(cs(dynamic_depth).object_name) - LENGTH(REPLACE(cs(dynamic_depth).object_name, '.'));
147171 --RETURN regexp_count(cs(dynamic_depth).object_name,'\.');
148172 --RETURN length(translate(cs(dynamic_depth).object_name,'.abcdefghijk', '.'));
0 commit comments