DBA Data[Home] [Help]

PACKAGE BODY: APPS.AD_ZD

Source


1 package body AD_ZD as
2 /* $Header: ADZDXB.pls 120.52.12020000.23 2013/06/21 13:16:40 rputchak ship $ */
3 
4 C_PACKAGE    CONSTANT VARCHAR2(80) := 'ad.plsql.ad_zd.';
5 
6 
7 
8 /*
9 ** --------------------------------------------------------------------
10 **    Helper Functions
11 ** --------------------------------------------------------------------
12 */
13 
14 
15 /*
16 ** log message
17 */
18 procedure LOG(X_MODULE varchar2, X_LOG_TYPE varchar2, X_MESSAGE varchar2) is
19 begin
20   ad_zd_log.message(x_module, x_log_type, x_message);
21 end;
22 
23 /*
24 ** log error message and raise exception
25 */
26 procedure ERROR(X_MODULE varchar2, X_MESSAGE varchar2) is
27 begin
28   ad_zd_log.message(x_module, 'ERROR', x_message);
29   raise_application_error(-20001, x_message);
30 end;
31 
32 
33 
34 /*
35 ** Execute constructed SQL statement (VARCHAR2 version)
36 **   X_SQL     - statement to execute
37 **   X_LOG_MOD - calling module (for logging)
38 **   X_IGNORE  - ignore errors
39 **
40 ** Note: ignores "success with compilation error"
41 */
42 procedure EXEC(X_SQL in varchar2, X_LOG_MOD in varchar2, X_IGNORE in boolean default false) is
43   SUCCESS_WITH_COMPILATION_ERROR exception;
44   pragma exception_init(success_with_compilation_error, -24344);
45 begin
46 
47   log(x_log_mod, 'STATEMENT', 'SQL: '||x_sql);
48   execute immediate x_sql;
49 
50 exception
51   when success_with_compilation_error then
52     -- ignore "success with compilation error"
53     log(x_log_mod, 'STATEMENT', 'Ignored: '||SQLERRM);
54   when others then
55     -- ignore or raise other errors as requested
56     if x_ignore then
57       log(x_log_mod, 'STATEMENT', 'Ignored: '||SQLERRM);
58     else
59       log(x_log_mod, 'ERROR', 'ERROR: '||SQLERRM|| ', SQL: '||x_sql);
60       raise;
61     end if;
62 end;
63 
64 
65 /*
66 ** Execute constructed SQL statement (LOB version)
67 **   X_SQL     - statement to execute
68 **   X_LOG_MOD - calling module (for logging)
69 **   X_IGNORE  - ignore errors
70 **
71 ** Note: ignores "success with compilation error"
72 */
73 procedure EXEC(X_SQL in clob, X_LOG_MOD in varchar2, X_IGNORE in boolean default false) is
74   SUCCESS_WITH_COMPILATION_ERROR exception;
75   pragma exception_init(success_with_compilation_error, -24344);
76   L_CUR integer;
77   L_RET integer;
78 begin
79 
80   log(x_log_mod, 'STATEMENT', 'SQL(CLOB): '||dbms_lob.substr(x_sql, 3900));
81 
82   l_cur :=  dbms_sql.open_cursor;
83   dbms_sql.parse(l_cur, x_sql, dbms_sql.native);
84   l_ret := dbms_sql.execute(l_cur);
85   dbms_sql.close_cursor(l_cur);
86 
87 exception
88   when success_with_compilation_error then
89     if dbms_sql.is_open(l_cur) then
90       dbms_sql.close_cursor(l_cur);
91    end if;
92     -- ignore "success with compilation error"
93     log(x_log_mod, 'STATEMENT', 'Ignored: '||SQLERRM);
94   when others then
95     if dbms_sql.is_open(l_cur) then
96       dbms_sql.close_cursor(l_cur);
97     end if;
98     -- ignore or raise other errors as requested
99     if x_ignore then
100       log(x_log_mod, 'STATEMENT', 'Ignored: '||SQLERRM);
101     else
102       log(x_log_mod, 'ERROR', 'ERROR: '||SQLERRM|| 'SQL(CLOB): '||dbms_lob.substr(x_sql, 3900));
103       raise;
104     end if;
105 end;
106 
107 
108 /*
109 ** Store statement for deferred for execution
110 **   x_phase - execution phase where statement should be run
111 **   x_sql   - sql statement or pl/sql block to be executed.
112 */
113 procedure LOAD_DDL(X_PHASE in varchar2,  X_SQL in varchar2) is
114 begin
115   ad_zd_parallel_exec.load(
116     x_phase => x_phase,
117     x_sql   => to_clob(x_sql),
118     x_unique => true); -- check for uniqueness
119 end;
120 
121 
122 /*
123 ** Return APPS schema name
124 */
125 function APPS_SCHEMA return varchar2 is
126   L_SCHEMA varchar2(30);
127 begin
128   select oracle_username into l_schema
129   from   system.fnd_oracle_userid
130   where  read_only_flag ='U';
131 
132   return l_schema;
133 end;
134 
135 
136 /*
137 ** Return APPLSYS schema name
138 */
139 function APPLSYS_SCHEMA return varchar2 is
140   L_SCHEMA varchar2(30);
141 begin
142   select oracle_username into l_schema
143   from   system.fnd_oracle_userid
144   where  read_only_flag ='E';
145 
146   return l_schema;
147 end;
148 
149 /*
150 ** Update LOGON trigger status.
151    X_STATUS - 'ENABLE' or 'DISABLE' the trigger
152 */
153 procedure ALTER_LOGON_TRIGGER(X_STATUS varchar2)
154 is
155   C_MODULE  varchar2(80) := c_package||'alter_logon_trigger';
156 begin
157   log(c_module, 'EVENT', 'alter logon trigger : '|| x_status);
158   -- If anyone passes DISABLED or DISABLE or disable
159   if(upper(x_status) like 'DISABLE%') then
160     sys.ad_zd_sys.alter_logon_trigger('DISABLE');
161   elsif (upper(x_status) like 'ENABLE%') then
162     sys.ad_zd_sys.alter_logon_trigger('ENABLE');
163   else
164     error(c_module, 'The status: ' || x_status ||' is not a valid trigger status');
165   end if;
166 end ALTER_LOGON_TRIGGER;
167 
168 /*
169 ** Return LOGON trigger status [ENABLED | DISABLED]
170 */
171 function LOGON_TRIGGER_STATUS return varchar2 is
172   L_STATUS varchar2(8) := null;
173   C_MODULE  varchar2(80) := c_package||'logon_trigger_status';
174 begin
175 
176   select status into l_status
177   from  dba_triggers
178   where owner='SYSTEM'
179   and   trigger_name='EBS_LOGON';
180 
181   return l_status;
182 exception
183   when no_data_found then
184     error(c_module, 'SYSTEM.EBS_LOGON trigger does not exist');
185 end LOGON_TRIGGER_STATUS;
186 
187 
188 /*
189 ** Is database editioned ('Y'/'N')
190 */
191 function IS_EDITIONS_ENABLED return varchar2 is
192   C_MODULE            varchar2(80) := c_package||'is_editions_enabled';
193   L_EDITIONS_ENABLED  varchar2(30);
194 begin
195   -- test if this is an editioned database, do nothing if not.
196   select du.editions_enabled
197   into   l_editions_enabled
198   from   system.fnd_oracle_userid fou, dba_users du
199   where  fou.read_only_flag = 'U'
200     and  du.username = fou.oracle_username;
201 
202   return l_editions_enabled;
203 end;
204 
205 
206 /*
207 ** Gets the name of the indicated edition type (NULL if none)
208 **   x_edition_type - type of edition to query
209 **     'RUN'     - current run edition
210 **     'PATCH'   - current patch edition
211 **     'OLD'     - old run edition (to be cleaned up after patch)
212 **     NULL      - current edition
213 */
214 function GET_EDITION(x_edition_type in varchar2 default NULL) return varchar2 is
215   C_MODULE          varchar2(80) := c_package||'get_edition';
216   L_DEFAULT         varchar2(30);
217   L_EDITION         varchar2(30);
218 begin
219   if x_edition_type is NULL then
220      return sys_context('userenv', 'current_edition_name');
221   end if;
222 
223   /* Get default edition first */
224   select property_value into l_default
225   from   database_properties
226   where  property_name = 'DEFAULT_EDITION';
227 
228   if x_edition_type = 'RUN' then
229 
230      /* RUNTIME edition is always the default */
231      l_edition := l_default;
232 
233   elsif x_edition_type = 'PATCH' then
234 
235      /* PATCH edition is always the child of the default */
236      begin
237        select aed.edition_name into l_edition
238        from   all_editions AED
239        where  aed.parent_edition_name = l_default;
240      exception
241        when no_data_found then
242           l_edition := NULL;
243      end;
244 
245   elsif x_edition_type = 'OLD' then
246 
247      /* OLD edition is always the parent of the default */
248      begin
249        select aed.parent_edition_name into l_edition
250        from   all_editions AED
251        where  aed.edition_name = l_default;
252      exception
253        when no_data_found then
254            l_edition := NULL;
255      end;
256 
257   else
258 
259      log(c_module, 'ERROR', 'Invalid Edition Type: '||x_edition_type);
260      l_edition := NULL;
261 
262   end if;
263 
264   return l_edition;
265 end;
266 
267 
268 /*
269 ** Sets the current edition based on type
270 **   x_edition_type - type of edition to set
271 **     'RUN'     - run edition
272 **     'PATCH'   - patch edition
273 **
274 ** Note: this procedure will not take effect until the next top-level SQL call
275 */
276 procedure SET_EDITION(x_edition_type in varchar2) is
277   C_MODULE          varchar2(80) := c_package||'set_edition';
278   L_EDITION         varchar2(30);
279 begin
280   l_edition := get_edition(x_edition_type);
281 
282   if (l_edition is not null) then
283      log(c_module, 'STATEMENT', 'Setting current edition to '||l_edition);
284      dbms_session.set_edition_deferred(l_edition);
285   else
286      error(c_module, 'Unable to set edition. Invalid edition type : '||x_edition_type);
287   end if;
288 end;
289 
290 
291 /*
292 ** Gets the edition type (NULL is Acestor of OLD or Edition does not exist )
293 **   x_edition - name of the edition
294 **     Pass NULL to find the current edition type
295 */
299   L_EDITION      varchar2(30);
296 function GET_EDITION_TYPE(x_edition_name in varchar2 default NULL) return varchar2 is
297   C_MODULE       varchar2(80) := c_package||'get_edition_type';
298   L_EDITION_TYPE varchar2(8)  := NULL;
300 begin
301   if (x_edition_name is NULL) then
302      l_edition := sys_context('userenv', 'current_edition_name');
303   else
304      l_edition := upper(x_edition_name);
305   end if;
306 
307   if l_edition = get_edition('RUN') then
308     l_edition_type := 'RUN';
309   elsif l_edition = get_edition('PATCH') then
310     l_edition_type := 'PATCH';
311   elsif l_edition = get_edition('OLD') then
312     l_edition_type := 'OLD';
313   end if;
314 
315   return l_edition_type;
316 end GET_EDITION_TYPE;
317 
318 
319 /*
320 ** Check if there is enough free space in critical tablespaces
321 **    Free space requirements
322 **    SYSTEM tablespace: 25 GB free
323 **    APPS_TS_SEED tablespace: 5 GB free
324 **
325 **    RETURNS -  Y - Enough free space
326 **            -  N - Not enough free space
327 */
328 function CHECK_SPACE return varchar2 is
329   C_MODULE          varchar2(80) := c_package|| 'check_space';
330   L_ALLOCATED_BYTES number;
331   L_FREE_BYTES      number;
332   V_COUNT           number := 0;
333 
334   cursor C_FREE_SPACE(p_tablespace varchar2) is
335     select df.bytes       allocated_bytes,
336            sum(fs.bytes)  free_bytes
337     from dba_free_space fs,
338          (select sum(bytes) bytes
339           from   dba_data_files
340           where  tablespace_name = p_tablespace ) df
341     where fs.tablespace_name   = p_tablespace
342     group by df.bytes;
343 
344   type TS_NAMES_T is table of varchar2(30);
345   type TS_FREE_T is table of number;
346 
347   TS_NAMES ts_names_t;   -- tablespace name list
348   TS_FREE  ts_free_t;    -- tablespace minimum freespace list (gigabytes)
349   TS_COUNT number;       -- number of tablespaces to check
350 begin
351 
352   -- tablespace requirements
353   ts_names := new ts_names_t('SYSTEM', 'APPS_TS_SEED');
354   ts_free  := new ts_free_t (25, 5);  -- gigabytes
355   ts_count := 2;
356 
357   -- check each tablespace for required freespace
358   for i in 1..ts_count loop
359 
360     select count(*) into v_count
361     from   dba_data_files
362     where tablespace_name = ts_names(i)
363     and autoextensible = 'yes';
364 
365     if (v_count = 0) then
366       open  c_free_space(ts_names(i));
367       fetch c_free_space into l_allocated_bytes, l_free_bytes;
368       close c_free_space;
369 
370       if l_free_bytes < (ts_free(i)*power(2, 30)) then
371         log(c_module, 'WARNING',
372             'Not enough free space in '||ts_names(i)||' tablespace. '||ts_free(i)||'GB free space required.');
373         return 'N';
374       end if;
375     end if;
376 
377   end loop;
378 
379   return 'Y';
380 end check_space;
381 
382 
383 
384 /*
385 ** Drop Covered Objects
386 **
387 ** Drop objects in retired editions that have a replacement object in any newer edition.
388 */
389 procedure DROP_COVERED_OBJECTS
390 IS
391   C_MODULE          varchar2(80) :=  c_package||'drop_covered_objects';
392   L_PRIV_COUNT      integer;
393   L_OWNER           varchar2(30) := 'SYS';
394   L_LAST_EDITION    varchar2(30);
395   L_SUCCESS         boolean;
396 
397   C_USER_CANCEL     exception;
398     pragma exception_init(c_user_cancel, -1013);
399 
400   -- Covered Objects are
401   --    actual objects in an Old Edition
402   --    that have a replacement object in a newer edition
403   -- Note: to minimize stub invalidation the result order
404   --    drop objects in newer editions first
408     select
405   --    drop objects in dependancy order (dependent object, then parent)
406   -- Never drop objects in the RUN or PATCH edition
407   cursor C_COVERED_OBJECTS is
409         oe.created edition_date
410       , oe.object_name edition_name
411       , decode(co.object_type,
412           'TRIGGER',       1,
413           'PACKAGE BODY',  2,
414           'TYPE BODY',     3,
415           'PROCEDURE',     4,
416           'FUNCTION',      5,
420           'TYPE',          9,
417           'PACKAGE',       6,
418           'VIEW',          7,
419           'SYNONYM',       8,
421           /*other*/       99 ) drop_order
422       , co.owner
423       , co.object_type
424       , co.object_name
425     from
426         ( select
427               eusr.edition_name
428             , eusr.user_name owner
429             , obj.name object_name
430             , obj.type#
431             , decode(obj.type#,
432                 4, 'VIEW',
433                 5, 'SYNONYM',
434                 7, 'PROCEDURE',
435 		        8, 'FUNCTION',
436                 9, 'PACKAGE',
437                 10, 'NON-EXISTENT',
438                 11, 'PACKAGE BODY',
439                 12, 'TRIGGER',
440                 13, 'TYPE',
441                 14, 'TYPE BODY', 'ERROR') object_type
442             , obj.namespace namespace
443             , obj.obj# object_id
444           from
445                 sys.obj$ obj
446               , ( select
447                       xusr.user#
448                     , xusr.ext_username user_name
449                     , ed.name edition_name
450                   from
451                       (select * from sys.user$ where type# = 2) xusr
452                     , (select * from sys.obj$
453                        where owner# = 0 and type# = 57) ed
454                   where xusr.spare2 = ed.obj#
455                   union
456                   select
457                       busr.user#
458                     , busr.name user_name
459                     , ed.name edition_name
460                   from
461                       (select * from sys.user$ where type#=1 or user#=1) busr
462                     , (select * from sys.obj$ where owner#=0 and type#=57) ed
463                   where ed.name = 'ORA$BASE' ) eusr
464             where obj.owner# = eusr.user#
465               and obj.type# not in (10, 0, 88)
466               and obj.remoteowner is null ) co
467       , dba_objects_ae oe       /* old edition */
468       , dba_objects_ae re       /* run edition */
469       , database_properties run /* run edition name */
470     where run.property_name = 'DEFAULT_EDITION'
471       /* run edition */
472       and re.owner        = 'SYS'
473       and re.object_type  = 'EDITION'
474       and re.object_name  = run.property_value
475       /* old edition */
476       and oe.owner        = 'SYS'
477       and oe.object_type  = 'EDITION'
478       and oe.created      < re.created
479       /* covered object */
480       and co.edition_name = oe.object_name
481       and co.object_type  in
482             ('SYNONYM', 'VIEW',
483              'PACKAGE', 'PACKAGE BODY', 'TYPE', 'TYPE BODY',
484              'PROCEDURE', 'FUNCTION', 'TRIGGER') /* editioned type */
485       and exists
486             ( select null
487               from dba_objects_ae ro /* replacement object */
488                  , dba_objects_ae ne /* newer edition */
489               where ro.owner        = co.owner
490                 and ro.object_type  in (co.object_type, 'NON-EXISTENT')
491                 and ro.object_name  = co.object_name
492                 and ro.namespace    = co.namespace
493                 and ro.edition_name = ne.object_name
494                 and ne.owner        = 'SYS'
495                 and ne.object_type  = 'EDITION'
496                 and ne.created      > oe.created
497                 and ne.created      <= re.created )
498     order by edition_date DESC, drop_order, co.owner, co.object_name;
499 
500 BEGIN
501   log(c_module, 'PROCEDURE', 'begin');
502 
503   -- verify all old editions are retired
504   select count(*)
505   into   l_priv_count
506   from   dba_tab_privs
507   where  privilege = 'USE'
508   and    owner = l_owner  /* Added for GSCC error */
509   and    table_name in ( select parent_edition_name from dba_editions);
510 
511   if l_priv_count > 0 then
512      error(c_module, 'Ancestors of Current RUN Edition are not retired');
513   end if;
514 
515   -- repeat the procedure until no covered objects remain
516   for loop_count in 1..3 loop
517     l_last_edition := 'NONE';
518     l_success := true;
519 
520     -- Drop each covered object, in correct order
521     for objrec in c_covered_objects loop
522       if objrec.edition_name <> l_last_edition then
523         log(c_module, 'STATEMENT', 'Dropping covered objects in '||objrec.edition_name);
524         l_last_edition := objrec.edition_name;
525       end if;
526       begin
527         sys.ad_zd_sys.drop_covered_object(objrec.owner, objrec.object_name, objrec.object_type, objrec.edition_name);
528       exception
529         when c_user_cancel then
530           error(c_module, 'Cleanup cancelled');
531         when others then
532           l_success := false;
533       end;
534     end loop;
535 
536     exit when l_success;
537   end loop;
538 
539   if not l_success then
540     log(c_module, 'WARNING', 'Could not remove all covered objects');
541   end if;
542 
543   commit;
544   log(c_module, 'PROCEDURE', 'end');
545 END;
546 
547 
548 /*
549 ** --------------------------------------------------------------------
550 **    Edition Control
551 ** --------------------------------------------------------------------
552 */
553 
554 
555 /*
556 ** Create new database Edition as child of current edition
557 **
558 ** Note: New edition names are expected to sort after old edition names.
559 */
560 procedure CREATE_EDITION is
561   C_MODULE      varchar2(80) := c_package||'create_edition';
562   L_EDITION     varchar2(30);
563   L_CUR_EDITION varchar2(30);
567   -- must not be an existing patch edition
564   L_DT_FMT    varchar2(30) := 'YYYYMMDD_HH24MI';
565 begin
566 
568   if ad_zd.get_edition('PATCH') is not null then
569     error(c_module, 'Patch Edition already exists');
570   end if;
571 
572   -- Generate new edition name
573   l_cur_edition := ad_zd.get_edition('RUN');
574   l_edition := 'V_'||to_char(SYSDATE, l_dt_fmt);
575 
576   if greatest(l_edition,l_cur_edition) = l_cur_edition then
577     l_edition := 'V_'||to_char(to_date(substr(l_cur_edition,3),l_dt_fmt)+1/(24*60),l_dt_fmt);
578   end if;
579 
580   log(c_module, 'EVENT', 'Create Edition : '||l_edition);
581   exec('create edition '||l_edition, c_module);
582   exec('grant use on edition '||l_edition||' to PUBLIC', c_module);
583 
584 end;
585 
586 
587 /*
588 ** Retire Edition
589 **   Revoke grants to USE edition, if it exists
590 **   x_edition_type - type of edition to retire
591 **     'PATCH'   - patch edition
592 **     'OLD'     - old edition
593 */
594 procedure RETIRE_EDITION(x_edition_type in varchar2) is
595   C_MODULE      varchar2(80) := c_package|| 'retire_edition';
596   L_EDITION     varchar2(30);
597   L_GRANTOR     varchar2(30);
598   L_OWNER       varchar2(30) := 'SYS';
599 begin
600 
601   -- get edition and validate
602   l_edition := ad_zd.get_edition(x_edition_type);
603   if (l_edition is null) then
604     error(c_module, 'Edition Type '||nvl(x_edition_type, 'NULL')||' does not exist.');
605   end if;
606   if (l_edition = get_edition('RUN')) then
607     error(c_module, 'Cannot retire RUN edition.');
608   end if;
609 
610   -- do it
611   begin
612     select grantor into l_grantor
613       from  dba_tab_privs
614       where privilege = 'USE'
615         and owner = l_owner  /* Added for GSCC error */
616         and table_name = l_edition
617         and grantee = 'PUBLIC';
618 
619     if (l_grantor = 'SYS') then
620       sys.ad_zd_sys.retire_edition(l_edition);
621     else
622       log(c_module, 'EVENT', 'Retire Edition: '||l_edition);
623       exec('revoke use on edition '||l_edition||' from PUBLIC', c_module);
624     end if;
625 
626   exception
627     when others then
628       log(c_module, 'STATEMENT', 'Edition '||l_edition||' is already retired');
629   end;
630 
631 end;
632 
633 
634 /*
635 ** Drop old editions which have no actual objects
636 */
637 procedure DROP_OLD_EDITIONS is
638   C_MODULE          varchar2(80) := c_package||'drop_old_editions';
639   L_EMPTY           varchar2(2);
640   -- Old Editions
641   cursor C_OLD_EDITIONS is
642     select oe.edition_name
643     from dba_editions oe, database_properties re
644     where re.property_name = 'DEFAULT_EDITION'
645       and oe.edition_name < re.property_value
646     order by oe.edition_name;
647 begin
648   log(c_module, 'PROCEDURE', 'begin: no parameter(s)');
649 
650   for erec in c_old_editions loop
651     -- test if edition is empty of objects
652     begin
653       select 'N' into l_empty
654       from dba_objects_ae obj
655       where obj.edition_name = erec.edition_name
656         and obj.object_type <> 'NON-EXISTENT'
657         and rownum = 1;
658     exception
659       when no_data_found then
660         l_empty := 'Y';
661     end;
662     exit when l_empty = 'N';
663 
664     -- drop empty old edition
665     begin
666       sys.ad_zd_sys.drop_edition(erec.edition_name);
667     exception
668       when others then
672   end loop;
669         log(c_module, 'WARNING', 'Could not drop empty edition '||erec.edition_name);
670         exit;
671     end;
673 
674   log(c_module, 'PROCEDURE', 'end');
675 end;
676 
677 
678 /*
679 ** Drop unwanted database edition
680 **   x_edition_type - type of edition to drop
681 **     'PATCH'   - current patch edition
682 **     'OLD'     - old run edition (to be cleaned up after patch)
683 */
684 procedure DROP_EDITION(x_edition_type in varchar2) is
685   C_MODULE      varchar2(80) := c_package||'drop_edition';
686   L_EDITION     varchar2(30);
687 begin
688   log(c_module, 'PROCEDURE', 'begin: '||x_edition_type);
689 
690   -- get edition and validate
691   l_edition := ad_zd.get_edition(x_edition_type);
692   if (l_edition is null) then
693     error(c_module, 'Edition Type '||nvl(x_edition_type, 'NULL')||' does not exist.');
694   end if;
695   if (l_edition = get_edition('RUN')) then
696     error(c_module, 'Cannot drop RUN edition.');
697   end if;
698 
699   -- do it
700   if x_edition_type = 'OLD' then
701     ad_zd.drop_old_editions;
702   else
703     sys.ad_zd_sys.drop_edition(l_edition);
704   end if;
705 
706   log(c_module, 'PROCEDURE', 'end');
707 end;
708 
709 
710 /*
711 ** --------------------------------------------------------------------
712 **    Phase Control
713 ** --------------------------------------------------------------------
714 */
715 
716 
717 /*
718 ** Prepare System (create Patch Edition)
719 **   X_MODE - unused
720 */
721 procedure PREPARE(X_MODE in varchar2 default NULL) is
722   C_MODULE         varchar2(80) := c_package||'prepare';
723 begin
724   log(c_module, 'PROCEDURE', 'begin: '||x_mode);
725   ad_zd_log.clear;
726 
727   -- Clear ALL ddls
728   ad_zd_parallel_exec.cleanup;
729 
730   -- TODO: verify EBS_LOGON trigger exists and is enabled.
731 
732   -- Check freespace: does not work
733   /*
734   if check_space = 'N' then
735      log(c_module, 'WARNING', 'Not Enough free space');
736   end if;
737   */
738 
739   log(c_module, 'EVENT', 'Prepare System');
740 
741   -- Create Patch Edition
742   ad_zd.create_edition;
743 
744   log(c_module, 'PROCEDURE', 'end');
745   -- commit;
746 end;
747 
748 
749 /*
750 ** Finalize System (step 1 of finalize process)
751 **   X_MODE - controls finalize processing
752 **     QUICK - standard finalize processing (default)
753 **     FULL  - recompute dictionary stats
754 */
755 procedure FINALIZE(X_MODE in varchar2 default NULL) is
756   C_MODULE      varchar2(80) := c_package||'finalize';
757 begin
758   log(c_module, 'PROCEDURE', 'begin: '||x_mode);
759 
760   if (get_edition_type = 'RUN') and (get_edition('PATCH') is not null) then
761      error(c_module, 'Finalize can only be run from the Patch Edition.');
762   end if;
763 
764   log(c_module, 'EVENT', 'Finalize System');
765 
766   -- Finalize sub components
767   ad_zd_table.finalize;
768   ad_zd_mview.finalize;
769 
770   -- Get post-finalize stats
771   if (x_mode = 'FULL') then
772     dbms_stats.gather_fixed_objects_stats;
773     dbms_stats.gather_dictionary_stats;
774   end if;
775 
776   log(c_module, 'PROCEDURE', 'end');
777 end;
778 
779 
780 /*
781 ** Compile System (step 2 of finialize process)
782 **   must be called as a top level command
783 **
787 procedure COMPILE(X_MODE in varchar2 default NULL) is
784 ** X_MODE - NULL   = compile current edition
785 **          'FULL' = compile entire system
786 */
788   C_MODULE        varchar2(80) := c_package||'compile';
789   NOT_IMPLEMENTED exception;   pragma exception_init(not_implemented, -6550);
790 begin
791   -- For now, use FULL compile mode all the time
792   if x_mode = 'FULL' then
793     log(c_module, 'EVENT', 'Compile System');
794     execute immediate 'begin sys.utl_recomp.recomp_parallel; end;';
795   else
796     begin
797       log(c_module, 'EVENT', 'Compile Edition: '||get_edition);
798       execute immediate 'begin sys.utl_recomp.recomp_parallel(flags => sys.utl_recomp.new_edition); end;';
799     exception
800       when not_implemented then
801         log(c_module, 'STATEMENT', 'Note: Edition-specific compilation not supported on this system.');
802         compile('FULL');
803     end;
804   end if;
805 end;
806 
807 
808 /*
809 ** Cutover to patch edition
810 **
811 ** X_MODE - indicates how to process cutover actions
812 **   (default) - execute cutover actions inline
813 **   'QUICK'   - assume cutover actions were processed externally
814 **               by parallel workers, just do edition cutover
815 **
816 ** Note: this API now supports running in the Run Edition when
817 ** there is no Patch Edition.  This is to support "developer mode",
818 ** which lets you execute cutover actions without actually changing
819 ** editions.
820 */
821 procedure CUTOVER(X_MODE in varchar2 default NULL) is
822   C_MODULE      varchar2(80) := c_package||'cutover';
823   L_EDITION     varchar2(30);
824 
825 begin
826   log(c_module, 'PROCEDURE', 'begin: '||x_mode);
827 
828   -- If there is a Patch Edition, then we must be in it
829   l_edition := ad_zd.get_edition('PATCH');
830   if (l_edition is not null) and (l_edition <> sys_context('userenv', 'current_edition_name')) then
831     error(c_module, 'Cutover can only be run from the Patch Edition.');
832   end if;
833 
834   log(c_module, 'EVENT', 'Cutover System');
835 
836   -- Execute cutover actions
837   if (x_mode is null) then
838     log(c_module, 'EVENT', 'Executing CUTOVER actions');
839 
840     -- Execute stored CUTOVER DDL
841     ad_zd_parallel_exec.execute('CUTOVER', 1, 1, NULL);
842 
843     -- Cutover sub-components
844     ad_zd_seed.cutover;
845     ad_zd_mview.cutover(x_execute => 1);
846   end if;
847 
848   -- switch default edition to patch edition
849   if (l_edition is not null) then
850     log(c_module, 'EVENT', 'Switching to Patch Edition');
851     exec('alter database default edition = '||l_edition, c_module);
852   end if;
853 
854   -- Retire Old Edition
855   begin
856     retire_edition('OLD');
857   exception
858   when others then
859     null;
860   end;
861 
862   -- Kill Old Sessions
863   log(c_module, 'EVENT', 'Killing old sessions');
864   kill_sessions('OLD');
865 
866   log(c_module, 'PROCEDURE', 'end');
867 end;
868 
869 
870 /*
871 ** Cleanup obsolete objects and data
872 **
873 ** X_MODE
874 **   'QUICK'  - minimal cleanup required to start a new patching cycle
875 **    NULL    - standard cleanup, includes drop covered objects
876 **   'FULL'   - also marks unused columns (todo: drop old editions)
877 */
878 procedure CLEANUP(X_MODE in varchar2 default NULL) is
879   C_MODULE      varchar2(80) := c_package||'cleanup';
880   L_EDITION     varchar2(30);
881 begin
882   log(c_module, 'PROCEDURE', 'begin: '||x_mode);
883 
884   l_edition := ad_zd.get_edition('RUN');
885   if (l_edition <> sys_context('userenv', 'current_edition_name'))  then
886     error(c_module, 'Cleanup can only be run from the Run Edition');
887   end if;
888 
889   if (ad_zd.get_edition('PATCH') is not null) then
890     error(c_module, 'Cannot Cleanup while Patch Edition exists');
891   end if;
892 
893   log(c_module, 'EVENT', 'Cleanup System');
894 
895   -- Drop covered objects, except in QUICK mode
896   if (x_mode = 'FULL') then
897     log(c_module, 'EVENT', 'Drop Covered Objects');
898     drop_covered_objects;
899   end if;
900 
901   -- Execute stored CLEANUP DDL
902   ad_zd_parallel_exec.execute('CLEANUP', 1, 1, NULL);
903 
904   -- Cleanup sub-components
905   ad_zd_seed.cleanup;
906   ad_zd_table.cleanup(NULL, NULL, x_mode);
907 
911     ad_zd.drop_old_editions();
908   ad_zd_parallel_exec.cleanup(ad_zd_parallel_exec.c_phase_cutover);
909   ad_zd_parallel_exec.cleanup(ad_zd_parallel_exec.c_phase_abort);
910   if ( x_mode = 'FULL') then
912   end if;
913   log(c_module, 'PROCEDURE', 'end');
914 end;
915 
916 
917 /*
918 ** Abort patch edition
919 **
920 ** X_MODE - unused
921 */
922 procedure ABORT(X_MODE in varchar2 default null) is
923   C_MODULE      varchar2(80) := c_package||'abort';
924   L_EDITION     varchar2(30);
925 begin
926   log(c_module, 'PROCEDURE', 'begin: '||x_mode);
927 
928   -- Must have Patch Edition
929   l_edition := ad_zd.get_edition('PATCH');
930   if (l_edition is null)  then
931     error(c_module, 'There is no Patch Edition to abort.');
932   end if;
933   -- Must be in Run Edition
934   if (get_edition_type <> 'RUN') then
935     error(c_module, 'Abort can only be run from the Run Edition.');
936   end if;
937 
938   -- Kill sessions connected to patch edition, other wise cannot drop it.
939   log(c_module, 'EVENT', 'Killing Patch Edition Sessions');
940   kill_sessions('PATCH');
941 
942   log(c_module, 'EVENT', 'Aborting Patch Edition');
943   -- Cleanup deferred DDLs that are no longer relevant
944   ad_zd_parallel_exec.cleanup('CUTOVER');
945   ad_zd_parallel_exec.cleanup('CLEANUP');
946 
947   -- Undo any effectively editioned changes
948   ad_zd_seed.abort;
949   ad_zd_table.abort;
950 
951   -- Add product specific APIs
952   exec('begin fnd_conc.cancel_patch_requests; end;', c_module, true);
953 
954   -- Drop Pach Edition
955   ad_zd.retire_edition('PATCH');
956   -- per bug 16237350 - we need to kill again right before the drop edition
957   log(c_module, 'EVENT', 'Killing Patch Edition Sessions');
958   kill_sessions('PATCH');
959   -- end fix for bug 16237350
960   ad_zd.drop_edition('PATCH');
961 
962   log(c_module, 'PROCEDURE', 'end');
963 end;
964 
965 /*
966 ** Kill sessions
967 **/
968 procedure KILL_SESSIONS(x_edition_type VARCHAR2) is
969   C_MODULE      varchar2(80) := c_package||'kill_sessions';
970 
971   -- Sessions of editions specified by parameter
972   cursor C_KILL is
973     select
977       , v$process p
974         'alter system kill session '||''''||s.sid||','||s.serial#||'''' kill
975     from
976         v$session s
978       , dba_objects_ae e
979     where s.type <> 'BACKGROUND'
980       and p.addr    = s.paddr
981       and e.object_id = s.session_edition_id
982       and e.object_name = ad_zd.get_edition(x_edition_type)
983       and e.object_type = 'EDITION';
984 begin
985   log(c_module, 'PROCEDURE', 'begin: ');
986 
987   for srec in c_kill loop
988     exec(srec.kill, c_module, true);
989   end loop;
990 
991   log(c_module, 'PROCEDURE', 'end');
992 end;
993 
994 end AD_ZD;