Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6a527c6

Browse files
authored
Merge pull request #417 from jgebal/feature/table_access_iprovements
Improved performance and stability of access to internal framework tables
2 parents f5cc486 + a8d4ac7 commit 6a527c6

9 files changed

Lines changed: 90 additions & 65 deletions

File tree

source/api/ut_runner.pkb

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,6 @@ create or replace package body ut_runner is
4343
return ut_utils.gc_version;
4444
end;
4545

46-
procedure cleanup_temp_tables is
47-
pragma autonomous_transaction;
48-
begin
49-
delete from ut_cursor_data where 1 = 1;
50-
commit;
51-
end;
52-
5346
procedure run(
5447
a_paths ut_varchar2_list, a_reporters ut_reporters, a_color_console boolean := false,
5548
a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null,
@@ -78,11 +71,11 @@ create or replace package body ut_runner is
7871
);
7972
l_items_to_run.do_execute(l_listener);
8073

81-
cleanup_temp_tables;
74+
ut_utils.cleanup_temp_tables;
8275
ut_output_buffer.close(l_listener.reporters);
8376
exception
8477
when others then
85-
cleanup_temp_tables;
78+
ut_utils.cleanup_temp_tables;
8679
ut_output_buffer.close(l_listener.reporters);
8780
dbms_output.put_line(dbms_utility.format_error_backtrace);
8881
dbms_output.put_line(dbms_utility.format_error_stack);

source/core/coverage/ut_coverage.pkb

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ create or replace package body ut_coverage is
2828
-- The subquery is optimized by:
2929
-- - COALESCE function -> it will execute only for TRIGGERS
3030
-- - scalar subquery cache -> it will only execute once for one trigger source code.
31-
function populate_sources_tmp_table(a_coverage_options ut_coverage_options) return varchar2 is
31+
function get_populate_sources_tmp_sql(a_coverage_options ut_coverage_options) return varchar2 is
3232
l_result varchar2(32767);
3333
l_full_name varchar2(100);
3434
begin
@@ -98,6 +98,31 @@ create or replace package body ut_coverage is
9898
return l_result;
9999
end;
100100

101+
function is_tmp_table_populated return boolean is
102+
l_result integer;
103+
begin
104+
select 1 into l_result from ut_coverage_sources_tmp where rownum = 1;
105+
return (l_result = 1);
106+
exception
107+
when no_data_found then
108+
return false;
109+
end;
110+
111+
procedure populate_tmp_table(a_coverage_options ut_coverage_options, a_skipped_objects ut_object_names) is
112+
pragma autonomous_transaction;
113+
l_schema_names ut_varchar2_rows;
114+
begin
115+
delete from ut_coverage_sources_tmp;
116+
l_schema_names := coalesce(a_coverage_options.schema_names, ut_varchar2_rows(sys_context('USERENV','CURRENT_SCHEMA')));
117+
if a_coverage_options.file_mappings is not empty then
118+
execute immediate get_populate_sources_tmp_sql(a_coverage_options) using a_coverage_options.file_mappings, a_skipped_objects, a_coverage_options.include_objects;
119+
else
120+
execute immediate get_populate_sources_tmp_sql(a_coverage_options) using l_schema_names, a_skipped_objects, a_coverage_options.include_objects;
121+
end if;
122+
commit;
123+
end;
124+
125+
101126
/**
102127
* Public functions
103128
*/
@@ -132,41 +157,24 @@ create or replace package body ut_coverage is
132157
end;
133158

134159
function get_coverage_data(a_coverage_options ut_coverage_options) return t_coverage is
135-
136-
pragma autonomous_transaction;
137-
138-
type t_coverage_row is record(
139-
name varchar2(500),
140-
line_number integer,
141-
total_occur number(38,0)
142-
);
143-
type tt_coverage_rows is table of t_coverage_row;
144160
l_line_calls ut_coverage_helper.unit_line_calls;
145161
l_result t_coverage;
146162
l_new_unit t_unit_coverage;
147163
l_skipped_objects ut_object_names := ut_object_names();
148164

149165
type t_source_lines is table of binary_integer;
150-
l_source_lines t_source_lines;
151166
line_no binary_integer;
152-
l_schema_names ut_varchar2_rows;
153-
l_query varchar2(32767);
154167
begin
155-
l_schema_names := coalesce(a_coverage_options.schema_names, ut_varchar2_rows(sys_context('USERENV','CURRENT_SCHEMA')));
156168

157169
if not ut_coverage_helper.is_develop_mode() then
158170
--skip all the utplsql framework objects and all the unit test packages that could potentially be reported by coverage.
159171
l_skipped_objects := ut_utils.get_utplsql_objects_list() multiset union all coalesce(a_coverage_options.exclude_objects, ut_object_names());
160172
end if;
161173

162174
--prepare global temp table with sources
163-
delete from ut_coverage_sources_tmp;
164-
if a_coverage_options.file_mappings is not null and a_coverage_options.file_mappings.count > 0 then
165-
execute immediate populate_sources_tmp_table(a_coverage_options) using a_coverage_options.file_mappings, l_skipped_objects, a_coverage_options.include_objects;
166-
else
167-
execute immediate populate_sources_tmp_table(a_coverage_options) using l_schema_names, l_skipped_objects, a_coverage_options.include_objects;
175+
if not is_tmp_table_populated() or ut_coverage_helper.is_develop_mode() then
176+
populate_tmp_table(a_coverage_options, l_skipped_objects);
168177
end if;
169-
commit;
170178

171179
for src_object in (
172180
select o.owner, o.name, o.full_name, max(o.line) lines_count,
@@ -224,7 +232,6 @@ create or replace package body ut_coverage is
224232

225233
end loop;
226234

227-
commit;
228235
return l_result;
229236
end get_coverage_data;
230237

source/core/coverage/ut_coverage_helper.pkb

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,36 @@ create or replace package body ut_coverage_helper is
1616
limitations under the License.
1717
*/
1818

19-
g_coverage_id integer;
20-
g_develop_mode boolean;
19+
g_coverage_id integer;
20+
g_develop_mode boolean not null := false;
21+
g_is_started boolean not null := false;
2122

22-
function is_develop_mode return boolean is
23+
function is_develop_mode return boolean is
2324
begin
2425
return g_develop_mode;
2526
end;
2627

2728
procedure coverage_start_internal(a_run_comment varchar2) is
2829
begin
2930
dbms_profiler.start_profiler(run_comment => a_run_comment, run_number => g_coverage_id);
31+
g_is_started := true;
3032
coverage_pause();
3133
end;
3234

3335
procedure coverage_start(a_run_comment varchar2) is
3436
begin
35-
if g_develop_mode is null then
37+
if not g_is_started then
3638
g_develop_mode := false;
3739
coverage_start_internal(a_run_comment);
3840
end if;
3941
end;
4042

4143
procedure coverage_start_develop is
4244
begin
43-
g_develop_mode := true;
44-
coverage_start_internal('utPLSQL Code coverage run in development MODE '||ut_utils.to_string(systimestamp));
45+
if not g_is_started then
46+
g_develop_mode := true;
47+
coverage_start_internal('utPLSQL Code coverage run in development MODE '||ut_utils.to_string(systimestamp));
48+
end if;
4549
end;
4650

4751
procedure coverage_pause is
@@ -59,17 +63,18 @@ create or replace package body ut_coverage_helper is
5963
end;
6064

6165
procedure coverage_stop is
62-
l_return_code binary_integer;
6366
begin
6467
if not g_develop_mode then
65-
l_return_code := dbms_profiler.stop_profiler();
68+
g_is_started := false;
69+
dbms_profiler.stop_profiler();
6670
end if;
6771
end;
6872

6973
procedure coverage_stop_develop is
70-
l_return_code binary_integer;
7174
begin
72-
l_return_code := dbms_profiler.stop_profiler();
75+
g_develop_mode := false;
76+
g_is_started := false;
77+
dbms_profiler.stop_profiler();
7378
end;
7479

7580
function get_raw_coverage_data(a_object_owner varchar2, a_object_name varchar2) return unit_line_calls is
@@ -81,7 +86,13 @@ create or replace package body ut_coverage_helper is
8186
l_tmp_data coverage_rows;
8287
l_results unit_line_calls;
8388
begin
84-
select d.line#, d.total_occur
89+
select d.line#,
90+
-- This transformation addresses two issues:
91+
-- 1. dbms_profiler shows multiple unit_number for single code unit;
92+
-- to address this, we take a sum od all units by name
93+
-- 2. some lines show 0 total_occur while they were executed (time > 0)
94+
-- in this case we show 1 to indicate that there was execution even if we don't know how many there were
95+
case when sum(d.total_occur) = 0 and sum(d.total_time) > 0 then 1 else sum(d.total_occur) end total_occur
8596
bulk collect into l_tmp_data
8697
from plsql_profiler_units u
8798
join plsql_profiler_data d
@@ -91,7 +102,8 @@ create or replace package body ut_coverage_helper is
91102
and u.unit_owner = a_object_owner
92103
and u.unit_name = a_object_name
93104
--exclude specification
94-
and u.unit_type not in ('PACKAGE SPEC', 'TYPE SPEC', 'ANONYMOUS BLOCK');
105+
and u.unit_type not in ('PACKAGE SPEC', 'TYPE SPEC', 'ANONYMOUS BLOCK')
106+
group by d.line#;
95107
for i in 1 .. l_tmp_data.count loop
96108
l_results(l_tmp_data(i).line) := l_tmp_data(i).calls;
97109
end loop;

source/core/coverage/ut_coverage_helper.pks

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ create or replace package ut_coverage_helper authid definer is
1717
*/
1818

1919
--table of line calls indexed by line number
20-
-- table is sparse!!!
20+
--!!! this table is sparse!!!
2121
type unit_line_calls is table of number(38,0) index by binary_integer;
2222

2323
function is_develop_mode return boolean;

source/core/ut_utils.pkb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,5 +367,13 @@ create or replace package body ut_utils is
367367
return l_xpath;
368368
end;
369369

370+
procedure cleanup_temp_tables is
371+
pragma autonomous_transaction;
372+
begin
373+
execute immediate 'truncate table ut_cursor_data';
374+
execute immediate 'truncate table ut_coverage_sources_tmp$';
375+
commit;
376+
end;
377+
370378
end ut_utils;
371379
/

source/core/ut_utils.pks

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,5 +223,7 @@ create or replace package ut_utils authid definer is
223223

224224
function to_xpath(a_list ut_varchar2_list, a_ancestors varchar2 := '/*/') return varchar2;
225225

226+
procedure cleanup_temp_tables;
227+
226228
end ut_utils;
227229
/

tests/RunAll.cmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
echo off
22
set UT3_OWNER=ut3
3-
set UT3_OWNER_PASSWORD=ut3
3+
set UT3_OWNER_PASSWORD=XNtxj8eEgA6X6b6f
44
set ORACLE_SID=XE
55
if not [%1] == [] (set UT3_OWNER=%1)
66
if not [%2] == [] (set UT3_OWNER_PASSWORD=%2)

tests/RunAll.sql

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ set longchunksize 1000000
1010
set serveroutput on size unlimited format truncated
1111
@@lib/RunVars.sql
1212

13-
@@lib/mystats/mystats start
13+
@@lib/mystats/mystats_pkg.sql
14+
exec mystats_pkg.ms_start;
1415

1516
spool RunAll.log
1617

@@ -564,7 +565,9 @@ spool coverage.html
564565
exec ut_output_buffer.lines_to_dbms_output(:html_reporter_id);
565566
spool off
566567

567-
@@lib/mystats/mystats stop t=1000
568+
spool stats.log
569+
exec mystats_pkg.ms_stop(1000);
570+
spool off
568571

569572
--can be used by CI to check for tests status
570573
exit :failures_count

0 commit comments

Comments
 (0)