diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index b6a832038..954de825c 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -31,6 +31,7 @@ create or replace package body ut_coverage is function get_populate_sources_tmp_sql(a_coverage_options ut_coverage_options) return varchar2 is l_result varchar2(32767); l_full_name varchar2(100); + l_view_name varchar2(200) := ut_metadata.get_dba_view('dba_source'); begin if a_coverage_options.file_mappings is not null and a_coverage_options.file_mappings.count > 0 then l_full_name := 'f.file_name'; @@ -48,7 +49,7 @@ create or replace package body ut_coverage is coalesce( case when type!='TRIGGER' then 0 end, (select min(t.line) - 1 - from all_source t + from ]'||l_view_name||q'[ t where t.owner = s.owner and t.type = s.type and t.name = s.name and regexp_like( t.text, '[A-Za-z0-9$#_]*(begin|declare|compound).*','i')) ) as line, @@ -69,7 +70,7 @@ create or replace package body ut_coverage is ) then 'Y' end as to_be_skipped - from all_source s]'; + from ]'||l_view_name||q'[ s]'; if a_coverage_options.file_mappings is not null and a_coverage_options.file_mappings.count > 0 then l_result := l_result || ' join table(:file_mappings) f diff --git a/source/core/ut_metadata.pkb b/source/core/ut_metadata.pkb index b6d44342f..69283bfbf 100644 --- a/source/core/ut_metadata.pkb +++ b/source/core/ut_metadata.pkb @@ -16,6 +16,9 @@ create or replace package body ut_metadata as limitations under the License. */ + type t_cache is table of all_source.text%type; + g_source_cache t_cache; + g_cached_object varchar2(500); ------------------------------ --public definitions @@ -63,6 +66,7 @@ create or replace package body ut_metadata as l_schema varchar2(200); l_package_name varchar2(200); l_procedure_name varchar2(200); + l_view_name varchar2(200) := get_dba_view('dba_objects'); begin l_schema := a_owner_name; @@ -70,12 +74,12 @@ create or replace package body ut_metadata as do_resolve(l_schema, l_package_name, l_procedure_name); - select count(decode(status, 'VALID', 1, null)) / count(*) - into l_cnt - from all_objects - where owner = l_schema - and object_name = l_package_name - and object_type in ('PACKAGE'); + execute immediate q'[select count(decode(status, 'VALID', 1, null)) / count(*) + from ]'||l_view_name||q'[ + where owner = :l_schema + and object_name = :l_package_name + and object_type in ('PACKAGE')]' + into l_cnt using l_schema, l_package_name; -- expect both package and body to be valid return l_cnt = 1; @@ -90,6 +94,7 @@ create or replace package body ut_metadata as l_schema varchar2(200); l_package_name varchar2(200); l_procedure_name varchar2(200); + l_view_name varchar2(200) := get_dba_view('dba_procedures'); begin l_schema := a_owner_name; @@ -98,12 +103,10 @@ create or replace package body ut_metadata as do_resolve(l_schema, l_package_name, l_procedure_name); - select count(*) - into l_cnt - from all_procedures - where owner = l_schema - and object_name = l_package_name - and procedure_name = l_procedure_name; + execute immediate + 'select count(*) from '||l_view_name + ||' where owner = :l_schema and object_name = :l_package_name and procedure_name = :l_procedure_name' + into l_cnt using l_schema, l_package_name, l_procedure_name; --expect one method only for the package with that name. return l_cnt = 1; @@ -113,38 +116,59 @@ create or replace package body ut_metadata as end; function get_package_spec_source(a_owner varchar2, a_object_name varchar2) return clob is - l_lines sys.dbms_preprocessor.source_lines_t; - l_source clob; + l_lines sys.dbms_preprocessor.source_lines_t; + l_cursor sys_refcursor; + l_source clob; + l_view_name varchar2(128) := get_dba_view('dba_source'); begin - begin - l_lines := sys.dbms_preprocessor.get_post_processed_source(object_type => 'PACKAGE', - schema_name => a_owner, - object_name => a_object_name); - - for i in 1..l_lines.count loop - ut_utils.append_to_clob(l_source, l_lines(i)); - end loop; - - end; + open l_cursor for 'select text from '||l_view_name||q'[ s + where s.owner = :a_owner and s.name = :a_object_name and s.type = 'PACKAGE' + order by s.line]' using upper(a_owner), upper(a_object_name); + fetch l_cursor bulk collect into l_lines; + -- we fetch the source explicitly as dbms_preprocessor is very sow on 12.1 and 12.2 when grabbing the sources. + l_lines := sys.dbms_preprocessor.get_post_processed_source(l_lines); + for i in 1..l_lines.count loop + ut_utils.append_to_clob(l_source, l_lines(i)); + end loop; return l_source; end; function get_source_definition_line(a_owner varchar2, a_object_name varchar2, a_line_no integer) return varchar2 is - l_line varchar2(4000); l_cursor sys_refcursor; + l_view_name varchar2(128) := get_dba_view('dba_source'); + l_line all_source.text%type; + c_key constant varchar2(500) := a_owner || '.' || a_object_name; begin - open l_cursor for - select text from all_source s - where s.owner = a_owner and s.name = a_object_name and s.line = a_line_no - -- skip the declarations, consider only definitions - and s.type not in ('PACKAGE','TYPE'); - fetch l_cursor into l_line; - close l_cursor; - return ltrim(rtrim( l_line, chr(10) )); - exception - when no_data_found then - return null; + if not nvl(c_key = g_cached_object, false) then + g_cached_object := c_key; + execute immediate + 'select trim(text) text + from '||l_view_name||q'[ s + where s.owner = :a_owner + and s.name = :a_object_name + /*skip the declarations, consider only definitions*/ + and s.type not in ('PACKAGE', 'TYPE') + order by line]' + bulk collect into g_source_cache + using a_owner, a_object_name; + end if; + + if g_source_cache.exists(a_line_no) then + l_line := g_source_cache(a_line_no); + end if; + return l_line; end; + function get_dba_view(a_view_name varchar2) return varchar2 is + l_invalid_object_name exception; + l_result varchar2(128) := lower(a_view_name); + pragma exception_init(l_invalid_object_name,-44002); + begin + l_result := dbms_assert.sql_object_name(l_result); + return l_result; + exception + when l_invalid_object_name then + return replace(l_result,'dba_','all_'); + end; end; / diff --git a/source/core/ut_metadata.pks b/source/core/ut_metadata.pks index 8b1922e51..88db52d4a 100644 --- a/source/core/ut_metadata.pks +++ b/source/core/ut_metadata.pks @@ -79,5 +79,12 @@ create or replace package ut_metadata authid current_user as */ function get_source_definition_line(a_owner varchar2, a_object_name varchar2, a_line_no integer) return varchar2; + /* + function: get_dba_view + + return the dba_xxx view name if it is accessible or all_xxx view otherwise + */ + function get_dba_view(a_view_name varchar2) return varchar2; + end ut_metadata; / diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb index ec88cf205..5bf5a4c30 100644 --- a/source/core/ut_suite_manager.pkb +++ b/source/core/ut_suite_manager.pkb @@ -34,12 +34,14 @@ create or replace package body ut_suite_manager is function get_schema_info(a_owner_name varchar2) return t_schema_info is l_info t_schema_info; + l_view_name varchar2(200) := ut_metadata.get_dba_view('all_objects'); begin + execute immediate q'[ select nvl(max(t.last_ddl_time), date '4999-12-31'), count(*) - into l_info - from all_objects t - where t.owner = a_owner_name - and t.object_type in ('PACKAGE'); + from ]'||l_view_name||q'[ t + where t.owner = :a_owner_name + and t.object_type in ('PACKAGE')]' + into l_info using a_owner_name; return l_info; end; @@ -206,6 +208,15 @@ create or replace package body ut_suite_manager is l_root varchar2(4000 char); l_root_suite ut_logical_suite; + type t_object_name is record( + owner all_objects.owner%type, + object_name all_objects.object_name%type + ); + type t_object_names is table of t_object_name; + + l_object_names t_object_names; + l_view_name varchar2(200) := ut_metadata.get_dba_view('dba_objects'); + l_schema_suites tt_schema_suites; procedure put(a_root_suite in out nocopy ut_logical_suite, a_path varchar2, a_suite ut_logical_suite, a_parent_path varchar2 default null) is @@ -270,14 +281,13 @@ create or replace package body ut_suite_manager is begin -- form the single-dimension list of suites constructed from parsed packages - for rec in (select t.owner - ,t.object_name - from all_objects t - where t.owner = a_owner_name - and t.status = 'VALID' -- scan only valid specifications - and t.object_type in ('PACKAGE')) loop + execute immediate + 'select t.owner, t.object_name from '||l_view_name||' t ' + ||q'[ where t.owner = :a_owner_name and t.status = 'VALID' and t.object_type in ('PACKAGE')]' + bulk collect into l_object_names using a_owner_name; + for i in 1 .. cardinality(l_object_names) loop -- parse the source of the package - l_suite := config_package(rec.owner, rec.object_name); + l_suite := config_package(l_object_names(i).owner, l_object_names(i).object_name); if l_suite is not null then l_all_suites(l_suite.path) := l_suite;