DBA Data[Home] [Help]

PACKAGE BODY: APPS.AD_PATCH_HISTORY_PKG

Source


1 package body ad_patch_history_pkg as
2 /* $Header: adphmntb.pls 115.5 2002/12/11 23:10:57 wjenkins ship $ */
3 
4 --
5 --
6 -- Private procedures
7 --
8 
9 --
10 /*
11 NAME:
12 Procedure bld_execs_and_copy_acts_list():
13 
14 DESCRIPTION:
15 Inserts into AD_PTCH_HST_EXE_COP_TMP records of 2 kinds (viz. executed
16 copy actions and all non-copy actions) in patches that have been uploaded
17 from applptch.txt
18 
19 COLUMNS THAT MAY NEED EXPLANATION:
20  - ACTION: 1 for "copy" actions, 2 otherwise
21  - FILE_VERSION: Relevant only for "executed" "copy" actions . Holds the
22    patch-file-version
23  - MAX-COPY-DATE: Holds the run-date of the latest "copy" action on that
24    file in that appl-top, prior to (attempting to) running the action
25    in question.
26 
27 LOGIC: For a particular action on a file in a specific appl-top (source),
28 we walk back in time starting from a some action, till we get a copy
29 action for that file on that appl-top (target). The version there (on
30 the target) can then be said to have been the "onsite" version when the
31 original action (the source) must have been attempted to be executed.
32 
33 NOTE: The only reason dynamic sql is used is bcoz PL/SQL wouldn't let me use
34 analytic functions otherwise (an analytic windowing function is used
35 here, whose start point is fixed and the end point is the row just
36 prior to the current-row)
37 
38 CAUTION: The windowing function has 2 implications related to MAX_COPY_DATE:
39  1. If the FIRST (ie. when walked back all the way to the beginning) patch
40 had 2 executed "copy" actions for the same file, then the first one
41 would have a null MAX_COPY_DATE (bcoz there is no "prior" record to walk
42 back to), and the second one would have the RUN-DATE of the first stored
43 in its MAX_COPY_DATE. But the RUN-DATE of both are the same (since they
44 are part of the same patch) Truly, we need to skip such cases. Its difficult
45 if not impossible to do it as part the single SQL, hence we delegate the
46 task of skipping such records to the caller.
47 
48  2. On subsequent uploads of applptch.txt (ie. other than the first upload.
49 In other words, say if uploaded from an applptch.txt that was created bcoz
50 a patch was run in pre-install mode), the FIRST action in the temp table
51 is not truly the first. There could be prior executed "copy" actions for
52 that file in prior normal mode patches. But the walk-back logic would not
53 look at those. As a result, the on-site version during some actions in
54 patches applied in pre-install mode may not be known. This is a
55 limitation, and is hoped NOT to be a severe one.
56 */
57 --
58 procedure bld_execs_and_copy_acts_list
59            (p_min_run_date date)
60 is
61    l_str varchar2(2000);
62 begin
63    l_str := 'insert into ad_ptch_hst_exe_cop_tmp '||
64    '( '||
65       'row_id, action, appl_top_id, run_date, '||
66       'file_id, file_version_id, max_copy_date '||
67    ') '||
68    'select '||
69       'prba.rowid, '||
70       'decode(pca.action_code, ''copy'', 1, 2), '||
71       'pr.appl_top_id, '||
72       'pr.end_date, '||
73       'nvl(pca.loader_data_file_id, prba.file_id), '||
74       'decode(pca.action_code, ''copy'', decode(prba.executed_flag, '||
75             '''Y'', prba.patch_file_version_id, null),  '||
76                   'null), '||
77       'max(decode(pca.action_code, ''copy'', decode(prba.executed_flag, '||
78          '''Y'', pr.end_date, to_date(''01/01/1990'',''MM/DD/YYYY'')), '||
79                'to_date(''01/01/1990'',''MM/DD/YYYY''))) over '||
80          '(partition by nvl(pca.loader_data_file_id, prba.file_id), '||
81                   'pr.appl_top_id '||
82          'order by pr.end_date, '||
83                'decode(pca.action_code, ''copy'', 1, 2) '||
84          'rows between unbounded preceding and 1 preceding) '||
85    'from ad_patch_runs pr, '||
86       'ad_patch_run_bugs prb, '||
87       'ad_files f, '||
88       'ad_patch_common_actions pca, '||
89       'ad_patch_run_bug_actions prba '||
90    'where prba.common_action_id = pca.common_action_id '||
91    'and prba.file_id = f.file_id '||
92    'and prba.patch_run_bug_id = prb.patch_run_bug_id '||
93    'and prb.patch_run_id = pr.patch_run_id '||
94    -- only look at rows uploaded from applptch.txt
95    'and pr.source_code = ''TXT'' '||
96    -- in sync with the actions considered in
97    -- adpvovGetFSVerAndAddToHash() (but excl fcopy)
98    'and pca.action_code in (''copy'', ''libin'', ''forcecopy'', '||
99             '''genfpll'', ''genform'', ''genrpll'', '||
100             '''genrep'', ''genmenu'', '||
101             '''sql'', ''exec'', ''exectier'') '||
102    -- If its a loader call but the parsing logic of
103    -- adpfilExtractFileFromArgs() failed to identify the file-id, skip it
104    'and not (pca.loader_data_file_id is null and f.filename in ( '||
105             '''FNDLOAD'', ''WFLOAD'', ''akload.class'')) '||
106    -- Only consider (1) exec(tier) calls of the ODF and loader
107      -- kinds, and (2) actions other than exec(tier).
108    'and ( '||
109       '(pca.action_code in (''exec'', ''exectier'') and '||
110          '(pca.loader_data_file_id is not null or '||
111           'pca.action_what_sql_exec like ''odf%'') '||
112       ') '||
113       'or '||
114       'pca.action_code not in (''exec'', ''exectier'') '||
115       ') '||
116    -- To allow multiple runs (incremental)
117    'and prba.onsite_file_version_id is null';
118 
119    if p_min_run_date is not null then
120       l_str := l_str || ' and pr.end_date >= :min_end_date';
121 
122       execute immediate l_str using p_min_run_date;
123    else
124       execute immediate l_str;
125    end if;
126 
127 end bld_execs_and_copy_acts_list;
128 
129 
130 --
131 --
132 -- Public procedures
133 --
134 
135 procedure backfill_onsite_versions
136            (p_min_run_date date)
137 is
138    cursor c_actions is
139       select rowidtochar(row_id)
140       from ad_ptch_hst_exe_cop_tmp
141       where max_copy_date is not null
142       and (action <> 1 or max_copy_date <> run_date);
143 
144    type T_ROWID is varray(1000) of varchar2(18);
145    l_arr_size constant number := 1000;
146 
147    l_rowid T_ROWID;
148 
149      l_cur_fetch number := 0;
150    l_prev_fetch number := 0;
151    l_row number;
152    u number := 0;
153 begin
154    -- First, build the temp area
155 
156    bld_execs_and_copy_acts_list(p_min_run_date);
157 
158    -- Commit, to free up rollback segs
159 
160    commit;
161 
162    -- Now do the actual update
163 
164    open c_actions;
165 
166    l_prev_fetch := 0;
167 
168    <<one_iter_per_limit_fetch>>
169    loop
170       fetch c_actions bulk collect into l_rowid limit l_arr_size;
171 
172       l_cur_fetch := c_actions%rowcount - l_prev_fetch;
173       l_prev_fetch := c_actions%rowcount;
174 
175       forall l_row in 1..l_cur_fetch
176       update ad_patch_run_bug_actions prba
177       set prba.onsite_file_version_id =
178       (
179          select
180          /*+ USE_NL(E)
181             INDEX (AD_PTCH_HST_EXE_COP_TMP AD_PTCH_HST_EXE_COP_TMP_U1)
182             INDEX(AD_PTCH_HST_EXE_COP_TMP AD_PTCH_HST_EXE_COP_TMP_N1)
183          */
184             distinct c.file_version_id
185             -- The "distinct" isn't really necessary. The values should
186             -- be the same. The distinct is just to throw up an error
187             -- if they aren't the same.
188          from ad_ptch_hst_exe_cop_tmp c, ad_ptch_hst_exe_cop_tmp e
189          where e.row_id = chartorowid(l_rowid(l_row))
190          and e.appl_top_id = c.appl_top_id
191          and e.file_id = c.file_id
192          and c.action = 1
193          and e.max_copy_date = c.run_date
194       )
195       where prba.rowid = chartorowid(l_rowid(l_row))
196       and prba.onsite_file_version_id is null;
197 
198       exit when c_actions%notfound;
199    end loop one_iter_per_limit_fetch;
200 
201    close c_actions;
202 
203    --
204    commit;
205    --
206 end backfill_onsite_versions;
207 
208 
209 /*
210 NAME:
211 Procedure bld_cf_repos_using_upload_hist():
212 
213 DESCRIPTION:
214 Inserts into AD_CHECK_FILES using information uploaded from applptch.txt.
215 Does something ONLY if the checkfile repository is empty AND is some patch
216 history information exists.
217 
218 NOTE: The only reason dynamic sql is used is bcoz PL/SQL wouldn't let me use
219 analytic functions otherwise (an analytic ranking function is used here)
220 */
221 --
222 procedure bld_cf_repos_using_upload_hist
223            (anything_inserted out nocopy number)
224 is
225    dummy varchar2(1);
226 begin
227    anything_inserted := 0;
228 
229    select 'x'
230    into dummy
231    from dual
232    where not exists (select 'x' from ad_check_files)
233    and exists (select 'x' from ad_patch_runs);
234    --
235    --
236    execute immediate 'insert into ad_check_files '||
237    '( '||
238       'check_file_id, file_id,  '||
239       'file_version_id, distinguisher,  '||
240       'creation_date '||
241    ') '||
242    'select  '||
243       'ad_check_files_s.nextval, max_vers.file_id, '||
244       'max_vers.file_version_id, max_vers.distinguisher, '||
245       'sysdate '||
246    'from '||
247    '( '||
248    'select '||
249       'nvl(pca.loader_data_file_id, prba.file_id)   file_id, '||
250       'fv.file_version_id                  file_version_id, '||
251       'decode(pca.action_code, ''sql'', null, '||
252          'decode(substr(pca.action_what_sql_exec, 1, 3), ''odf'', '||
253             'decode(substr(pca.action_phase, 1,  '||
254                'decode(instr(pca.action_phase, ''+''), 0,  '||
255                   'length(pca.action_phase),  '||
256                   'instr(pca.action_phase, ''+'')-1)), '||
257                '''tab'', ''tab_tables'', '||
258                '''seq'', ''seq_sequences'', '||
259                '''vw'', ''vw_views'', '||
260                'null), '||
261             'null))                  distinguisher, '||
262       'rank() over (partition by nvl(pca.loader_data_file_id,  '||
263                         'prba.file_id), '||
264          'decode(pca.action_code, ''sql'', null, '||
265             'decode(substr(pca.action_what_sql_exec, 1, 3), ''odf'', '||
266                'decode(substr(pca.action_phase, 1,  '||
267                   'decode(instr(pca.action_phase, ''+''), 0,  '||
268                      'length(pca.action_phase),  '||
269                      'instr(pca.action_phase, ''+'')-1)), '||
270                   '''tab'', ''tab_tables'', '||
271                   '''seq'', ''seq_sequences'', '||
272                   '''vw'', ''vw_views'', '||
273                   'null), '||
274                'null)) '||
275          'order by fv.version_segment1 desc, '||
276          'fv.version_segment2 desc, fv.version_segment3 desc, '||
277          'fv.version_segment4 desc, fv.version_segment5 desc, '||
278          'fv.version_segment6 desc, fv.version_segment7 desc, '||
279          'fv.version_segment8 desc, fv.version_segment9 desc, '||
280          'fv.version_segment10 desc,  '||
281          'fv.translation_level desc) as rank1 '||
282    'from '||
283       'ad_file_versions fv, '||
284       'ad_patch_runs pr, '||
285       'ad_patch_run_bugs prb, '||
286       'ad_patch_common_actions pca, '||
287       'ad_patch_run_bug_actions prba '||
288    'where prba.common_action_id = pca.common_action_id '||
289    'and prba.patch_run_bug_id = prb.patch_run_bug_id '||
290    'and prb.patch_run_id = pr.patch_run_id '||
291    'and prba.onsite_file_version_id = fv.file_version_id '||
292    'and pca.action_code in (''sql'', ''exec'', ''exectier'') '||
293    'and prba.executed_flag = ''Y'' '||
294    'and pr.source_code = ''TXT'' '||
295    'group by '||
296       -- The group-by is necessary to suppress repeated entries if the
297       -- SAME version of the SAME file was (executed) in different
298       -- patches (or in different bugs in the same patch)
299       'nvl(pca.loader_data_file_id, prba.file_id), fv.file_version_id, '||
300       'decode(pca.action_code, ''sql'', null, '||
301          'decode(substr(pca.action_what_sql_exec, 1, 3), ''odf'', '||
302             'decode(substr(pca.action_phase, 1,  '||
303                'decode(instr(pca.action_phase, ''+''), 0,  '||
304                   'length(pca.action_phase),  '||
308                '''vw'', ''vw_views'', '||
305                   'instr(pca.action_phase, ''+'')-1)), '||
306                '''tab'', ''tab_tables'', '||
307                '''seq'', ''seq_sequences'', '||
309                'null), '||
310             'null)), '||
311       'fv.version_segment1, fv.version_segment2, fv.version_segment3, '||
312       'fv.version_segment4, fv.version_segment5, fv.version_segment6, '||
313       'fv.version_segment7, fv.version_segment8, fv.version_segment9, '||
314       'fv.version_segment10, fv.translation_level '||
315    ') max_vers '||
316    'where max_vers.rank1 = 1';
317    --
318    anything_inserted := sql%rowcount;
319    --
320    commit;
321    --
322    --
323 exception when no_data_found then
324    -- If ad_check_files already has data, or patch-hist is NOT
325    -- populated, simply return.
326    --
327    null;
328 end bld_cf_repos_using_upload_hist;
329 
330 
331 end ad_patch_history_pkg;