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

Skip to content

Commit 30b9097

Browse files
committed
Fixed issue with coverage reporting for TRIGGERS.
Documented the coverage query.
1 parent a5b42de commit 30b9097

1 file changed

Lines changed: 62 additions & 34 deletions

File tree

source/core/coverage/ut_coverage.pkb

Lines changed: 62 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -39,57 +39,85 @@ create or replace package body ut_coverage is
3939
return l_result;
4040
end;
4141

42+
-- The source query has two important transformations done in it.
43+
-- the flag: to_be_skipped ='Y' is set for a line of code that is badly reported by DBMS_PROFILER as executed 0 times.
44+
-- This includes lines that are:
45+
-- - PACKAGE, PROCEDURE, FUNCTION definition line,
46+
-- - BEGIN, END of a block
47+
-- Another transformation is adjustment of line number for TRIGGER body.
48+
-- DBMS_PROFILER is reporting line numbers for triggers not as defined in DBA_SOURCE, its usign line numbers as defined in DBA_TRIGGERS
49+
-- the DBA_TRIGGERS does not contain the trigger specification lines, only lines that define the trigger body.
50+
-- the query adjusts the line numbers for triggers by finding first occurrence of begin|declare|compound in the trigger body line.
51+
-- The subquery is optimized by:
52+
-- - COALESCE function -> it will execute only for TRIGGERS
53+
-- - scalar subquery cache -> it will only execute once for one trigger source code.
4254
function get_sources_query return varchar2 is
4355
l_result varchar2(32767);
56+
l_full_name varchar2(100);
4457
begin
45-
l_result := 'insert /*+ append */ into ut_coverage_sources_tmp(full_name,owner,name,line,text, to_be_skipped)';
4658
if g_file_mappings is not null then
47-
l_result := 'insert /*+ append */ into ut_coverage_sources_tmp(full_name,owner,name,line,text, to_be_skipped)
48-
select f.file_name, s.owner,s.name,s.line,s.text,';
59+
l_full_name := 'f.file_name';
4960
else
50-
l_result := 'insert /*+ append */ into ut_coverage_sources_tmp(full_name,owner,name,line,text, to_be_skipped)
51-
select lower(s.owner||''.''||s.name) as file_name, s.owner,s.name,s.line,s.text,';
61+
l_full_name := 'lower(s.owner||''.''||s.name)';
5262
end if;
53-
l_result := l_result || q'[
54-
case
55-
when
56-
-- to avoid execution of regexp_like on every line
57-
-- first do a rough check for existence of search pattern keyword
58-
(lower(s.text) like '%procedure%'
59-
or lower(s.text) like '%function%'
60-
or lower(s.text) like '%begin%'
61-
or lower(s.text) like '%end%'
62-
or lower(s.text) like '%package%'
63-
) and
64-
regexp_like(
65-
s.text,
66-
'^\s*(((not)?\s*(overriding|final|instantiable)\s*)*(static|constructor|member)?\s*(procedure|function)|package(\s+body)|begin|end(\s+\S+)?\s*;)', 'i'
67-
)
68-
then 'Y'
69-
end as to_be_skipped
70-
from all_source s]';
63+
l_result := '
64+
insert /*+ append */ into ut_coverage_sources_tmp(full_name,owner,name,line,text, to_be_skipped)
65+
select *
66+
from (
67+
select '||l_full_name||q'[,
68+
s.owner,
69+
s.name,
70+
s.line -
71+
coalesce(
72+
case when type!='TRIGGER' then 0 end,
73+
(select min(t.line) - 1
74+
from dba_source t
75+
where t.owner = s.owner and t.type = s.type and t.name = s.name
76+
and regexp_like( t.text, '\w*(begin|declare|compound).*','i'))
77+
) as line,
78+
s.text,
79+
case
80+
when
81+
-- to avoid execution of regexp_like on every line
82+
-- first do a rough check for existence of search pattern keyword
83+
(lower(s.text) like '%procedure%'
84+
or lower(s.text) like '%function%'
85+
or lower(s.text) like '%begin%'
86+
or lower(s.text) like '%end%'
87+
or lower(s.text) like '%package%'
88+
) and
89+
regexp_like(
90+
s.text,
91+
'^\s*(((not)?\s*(overriding|final|instantiable)\s*)*(static|constructor|member)?\s*(procedure|function)|package(\s+body)|begin|end(\s+\S+)?\s*;)', 'i'
92+
)
93+
then 'Y'
94+
end as to_be_skipped
95+
from all_source s]';
7196
if g_file_mappings is not null then
7297
l_result := l_result || '
73-
join table(:g_file_mappings) f
74-
on s.name = f.object_name
75-
and s.type = f.object_type
76-
and s.owner = f.object_owner
77-
where 1 = 1';
98+
join table(:g_file_mappings) f
99+
on s.name = f.object_name
100+
and s.type = f.object_type
101+
and s.owner = f.object_owner
102+
where 1 = 1';
78103
else
79104
l_result := l_result || '
80-
where s.owner in (select upper(t.column_value) from table(:l_schema_names) t)';
105+
where s.owner in (select upper(t.column_value) from table(:l_schema_names) t)';
81106
end if;
82107
l_result := l_result || q'[
83-
and s.type not in ('PACKAGE', 'TYPE')
84-
--Exclude calls to utPLSQL framework, Unit Test packages and objects from a_exclude_list parameter of coverage reporter
85-
and (s.owner, s.name) not in (select el.owner, el.name from table(:l_skipped_objects) el)]';
108+
and s.type not in ('PACKAGE', 'TYPE')
109+
--Exclude calls to utPLSQL framework, Unit Test packages and objects from a_exclude_list parameter of coverage reporter
110+
and (s.owner, s.name) not in (select el.owner, el.name from table(:l_skipped_objects) el)]';
86111
if g_include_list is null then
87112
l_result := l_result || '
88-
and :g_include_list is null';
113+
and :g_include_list is null';
89114
else
90115
l_result := l_result || '
91-
and (s.owner, s.name) in (select il.owner, il.name from table(:g_include_list) il)';
116+
and (s.owner, s.name) in (select il.owner, il.name from table(:g_include_list) il)';
92117
end if;
118+
l_result := l_result || '
119+
)
120+
where line > 0';
93121
return l_result;
94122
end;
95123
/**

0 commit comments

Comments
 (0)